Changeset: 94013ed66263 for MonetDB
URL: https://dev.monetdb.org/hg/MonetDB?cmd=changeset;node=94013ed66263
Modified Files:
        sql/backends/monet5/rel_bin.c
        sql/backends/monet5/sql_cat.c
        sql/rel.txt
        sql/server/rel_schema.c
        sql/test/merge-partitions/Tests/mergepart03.stable.err
        sql/test/merge-partitions/Tests/mergepart03.stable.out
        sql/test/merge-partitions/Tests/mergepart04.stable.err
        sql/test/merge-partitions/Tests/mergepart05.stable.err
        sql/test/merge-partitions/Tests/mergepart07.stable.err
Branch: merge-partitions
Log Message:

Do the proper validation for partitions by range.

However I found another bug :(


diffs (truncated from 432 to 300 lines):

diff --git a/sql/backends/monet5/rel_bin.c b/sql/backends/monet5/rel_bin.c
--- a/sql/backends/monet5/rel_bin.c
+++ b/sql/backends/monet5/rel_bin.c
@@ -4904,7 +4904,7 @@ rel2bin_exception(backend *be, sql_rel *
 {
        stmt *l = NULL, *r = NULL;
        node *n = NULL;
-       sql_exp *except = NULL;
+       list *slist = sa_list(be->mvc->sa);
 
        if(find_prop(rel->p, PROP_DISTRIBUTE) && be->cur_append == 0) /* create 
affected rows accumulator */
                create_merge_partitions_accumulator(be);
@@ -4914,16 +4914,17 @@ rel2bin_exception(backend *be, sql_rel *
     if (rel->r)  /* first construct the sub relation */
                r = subrel_bin(be, rel->r, refs);
 
-       if(rel->exps && list_length(rel->exps) == 1) {
-               n = rel->exps->h;
-               except = n->data;
-               return exp_bin(be, except, l, r, NULL, NULL, NULL, NULL);
+       if(rel->exps) {
+               for(n = rel->exps->h; n; n = n->next) {
+                       sql_exp *e = n->data;
+                       stmt *s = exp_bin(be, e, l, r, NULL, NULL, NULL, NULL);
+                       append(slist, s);
+               }
        } else { //if there is no exception condition, just generate a 
statement list
-               list *slist = sa_list(be->mvc->sa);
                list_append(slist, l);
                list_append(slist, r);
-               return stmt_list(be, slist);
        }
+       return stmt_list(be, slist);
 }
 
 static stmt *
diff --git a/sql/backends/monet5/sql_cat.c b/sql/backends/monet5/sql_cat.c
--- a/sql/backends/monet5/sql_cat.c
+++ b/sql/backends/monet5/sql_cat.c
@@ -185,13 +185,12 @@ alter_table_add_range_partition(mvc *sql
        sql_table *mt = NULL, *pt = NULL;
        sql_part *err = NULL;
        str msg = MAL_SUCCEED, err_min = NULL, err_max = NULL, escaped_min = 
NULL, escaped_max = NULL;
-       sql_column *col = NULL, *bcol = NULL;
-       BAT *diff1 = NULL, *diff2 = NULL, *cbind = NULL;
-       int tp1 = 0, errcode = 0, i = 0;
+       sql_column *col = NULL;
+       int tp1 = 0, errcode = 0;
        ptr pmin = NULL, pmax = NULL;
        size_t smin = 0, smax = 0, serr_min = 0, serr_max = 0;
        ssize_t (*atomtostr)(str *, size_t *, const void *);
-       int accesses[3] = {RDONLY, RD_INS, RD_UPD_VAL}, free_pmin = 1, 
free_pmax = 1;
+       int free_pmin = 1, free_pmax = 1;
 
        if((msg = validate_alter_table_add_table(sql, 
"sql.alter_table_add_range_partition", msname, mtname, psname, ptname, &mt, 
&pt))) {
                return msg;
@@ -261,62 +260,6 @@ alter_table_add_range_partition(mvc *sql
                goto finish;
        }
 
-       bcol = mvc_bind_column(sql, pt, col->base.name);
-
-       for(i = 0 ; i < 3 ; i++) {
-               if(cbind) {
-                       BBPunfix(cbind->batCacheid);
-                       cbind = NULL;
-               }
-               if(diff1) {
-                       BBPunfix(diff1->batCacheid);
-                       diff1 = NULL;
-               }
-               if(diff2) {
-                       BBPunfix(diff2->batCacheid);
-                       diff2 = NULL;
-               }
-               if((cbind = store_funcs.bind_col(sql->session->tr, bcol, 
accesses[i])) == NULL) {
-                       msg = 
createException(SQL,"sql.alter_table_add_range_partition",SQLSTATE(HY001) 
MAL_MALLOC_FAIL);
-                       goto finish;
-               }
-               if(!with_nills && cbind->tnil) {
-                       msg = 
createException(SQL,"sql.alter_table_add_range_partition",SQLSTATE(42000)
-                                                                       "ALTER 
TABLE: there are null values in the column which is not allowed for this 
partition");
-                       goto finish;
-               }
-               if(!pmin && !pmax) {
-                       if((diff1 = BATselect(cbind, NULL, ATOMnilptr(tp1), 
NULL, 1, 1, 1)) == NULL) {
-                               msg = 
createException(SQL,"sql.alter_table_add_range_partition",SQLSTATE(HY001) 
MAL_MALLOC_FAIL);
-                               goto finish;
-                       }
-                       if(BATcount(diff1) > 0) {
-                               msg = 
createException(SQL,"sql.alter_table_add_range_partition",SQLSTATE(42000)
-                                                                       "ALTER 
TABLE: there are non-null values in the column which is not allowed for this 
partition");
-                               goto finish;
-                       }
-               } else {
-                       if((diff1 = BATthetaselect(cbind, NULL, pmin, "<")) == 
NULL) {
-                               msg = 
createException(SQL,"sql.alter_table_add_range_partition",SQLSTATE(HY001) 
MAL_MALLOC_FAIL);
-                               goto finish;
-                       }
-                       if(BATcount(diff1) > 0) {
-                               msg = 
createException(SQL,"sql.alter_table_add_range_partition",SQLSTATE(42000)
-                                                                       "ALTER 
TABLE: there are values in the column %s with values lesser than the partition 
minimum", col->base.name);
-                               goto finish;
-                       }
-                       if((diff2 = BATthetaselect(cbind, NULL, pmax, ">")) == 
NULL) {
-                               msg = 
createException(SQL,"sql.alter_table_add_range_partition",SQLSTATE(HY001) 
MAL_MALLOC_FAIL);
-                               goto finish;
-                       }
-                       if(BATcount(diff2) > 0) {
-                               msg = 
createException(SQL,"sql.alter_table_add_range_partition",SQLSTATE(42000)
-                                                                       "ALTER 
TABLE: there are values in the column %s with values higher than the partition 
maximum", col->base.name);
-                               goto finish;
-                       }
-               }
-       }
-
        if(!pmin) {
                pmin = (ptr) ATOMnilptr(tp1);
                smin = ATOMsize(tp1);
@@ -378,12 +321,6 @@ finish:
                GDKfree(pmin);
        if(pmax && free_pmax)
                GDKfree(pmax);
-       if(cbind)
-               BBPunfix(cbind->batCacheid);
-       if(diff1)
-               BBPunfix(diff1->batCacheid);
-       if(diff2)
-               BBPunfix(diff2->batCacheid);
        if(msg != MAL_SUCCEED)
                pt->p = NULL;
        return msg;
diff --git a/sql/rel.txt b/sql/rel.txt
--- a/sql/rel.txt
+++ b/sql/rel.txt
@@ -23,7 +23,7 @@ TABLE         (card MULTI)
  */
 DDL    (card 0!, top of the tree always)
        -> flags        /* OUTPUT, TRANSACTION-types, CREATE/DROP/ALTER* */ 
-       -> exps         For 'OUTPUT' is list of output options, for DISTRIBUTE 
has a single exception expression
+       -> exps         For 'OUTPUT' is list of output options, for 
DDL_EXCEPTION is a list of psm_exception
                        For 'transactions' simple flags
                        for CREATE etc full sql string.
        -> l            used in DDL_OUTPUT as the relation to output and 
DDL_EXCEPTION as a DDL_LIST
diff --git a/sql/server/rel_schema.c b/sql/server/rel_schema.c
--- a/sql/server/rel_schema.c
+++ b/sql/server/rel_schema.c
@@ -85,33 +85,81 @@ rel_alter_table(sql_allocator *sa, int c
 }
 
 static sql_rel *
-rel_alter_table_add_partition_range(sql_allocator *sa, char *sname, char 
*tname, char *sname2, char *tname2, atom* min,
-                                                                       atom* 
max, int with_nills)
+rel_alter_table_add_partition_range(mvc* sql, sql_table *mt, sql_table *pt, 
char *sname, char *tname, char *sname2,
+                                                                       char 
*tname2, atom* min, atom* max, int with_nills)
 {
-       sql_rel *rel = rel_create(sa);
-       list *exps = new_exp_list(sa);
-       char *pmin = min ? atom2string(sa, min): NULL, *pmax = max ? 
atom2string(sa, max) : NULL;
-       if(!rel || !exps)
+       sql_rel *rel_psm = rel_create(sql->sa), *anti_rel;
+       list *exps = new_exp_list(sql->sa);
+       sql_exp *exception, *aggr, *anti_exp = NULL, *anti_le, *e1, *e2, 
*anti_nils;
+       sql_column *col = mt->pcol;
+       sql_subaggr *cf = sql_bind_aggr(sql->sa, sql->session->schema, "count", 
NULL);
+       int colr = mt->pcol->colnr;
+       char buf[BUFSIZ], *pmin = min ? atom2string(sql->sa, min): NULL, *pmax 
= max ? atom2string(sql->sa, max) : NULL;
+
+       if(!rel_psm || !exps)
                return NULL;
 
-       append(exps, exp_atom_clob(sa, sname));
-       append(exps, exp_atom_clob(sa, tname));
+       anti_rel = rel_basetable(sql, pt, tname2);
+       anti_le = list_fetch(anti_rel->exps, colr);
+       anti_le = exp_column(sql->sa, exp_relname(anti_le), exp_name(anti_le), 
exp_subtype(anti_le),
+                                                anti_le->card, 
has_nil(anti_le), is_intern(anti_le));
+       anti_rel->exps = new_exp_list(sql->sa);
+       append(anti_rel->exps, anti_le);
+       anti_nils = rel_unop_(sql, anti_le, NULL, "isnull", card_value);
+
+       assert((!min && !max && with_nills) || (min && max));
+       if(min && max) {
+               e1 = create_table_part_atom_exp(sql, min->tpe, 
VALget(&min->data));
+               if (subtype_cmp(&e1->tpe, &col->type) != 0)
+                       e1 = exp_convert(sql->sa, e1, &e1->tpe, &col->type);
+
+               e2 = create_table_part_atom_exp(sql, max->tpe, 
VALget(&max->data));
+               if (subtype_cmp(&e2->tpe, &col->type) != 0)
+                       e2 = exp_convert(sql->sa, e2, &e2->tpe, &col->type);
+
+               anti_exp = exp_compare2(sql->sa, anti_le, e1, e2, 3);
+               set_anti(anti_exp);
+               if(!with_nills) {
+                       anti_nils = exp_compare(sql->sa, anti_nils, 
exp_atom_bool(sql->sa, 1), cmp_equal);
+                       anti_exp = exp_or(sql->sa, 
list_append(new_exp_list(sql->sa), anti_exp),
+                                                         
list_append(new_exp_list(sql->sa), anti_nils), 0);
+               }
+       } else {
+               anti_exp = exp_compare(sql->sa, anti_nils, 
exp_atom_bool(sql->sa, 1), cmp_notequal);
+       }
+
+       anti_rel = rel_select(sql->sa, anti_rel, anti_exp);
+       anti_rel = rel_groupby(sql, anti_rel, NULL);
+       aggr = exp_aggr(sql->sa, NULL, cf, 0, 0, anti_rel->card, 0);
+       (void) rel_groupby_add_aggr(sql, anti_rel, aggr);
+       exp_label(sql->sa, aggr, ++sql->label);
+
+       //generate the exception
+       aggr = exp_column(sql->sa, exp_relname(aggr), exp_name(aggr), 
exp_subtype(aggr), aggr->card, has_nil(aggr),
+                                         is_intern(aggr));
+       snprintf(buf, BUFSIZ, "ALTER TABLE: there are values in the column %s, 
outside the partition range", col->base.name);
+       exception = exp_exception(sql->sa, aggr, buf);
+
+       //generate the psm statement
+       append(exps, exp_atom_clob(sql->sa, sname));
+       append(exps, exp_atom_clob(sql->sa, tname));
        assert((sname2 && tname2) || (!sname2 && !tname2));
        if (sname2) {
-               append(exps, exp_atom_clob(sa, sname2));
-               append(exps, exp_atom_clob(sa, tname2));
+               append(exps, exp_atom_clob(sql->sa, sname2));
+               append(exps, exp_atom_clob(sql->sa, tname2));
        }
-       append(exps, exp_atom_clob(sa, pmin));
-       append(exps, exp_atom_clob(sa, pmax));
-       append(exps, exp_atom_int(sa, with_nills));
-       rel->l = NULL;
-       rel->r = NULL;
-       rel->op = op_ddl;
-       rel->flag = DDL_ALTER_TABLE_ADD_RANGE_PARTITION;
-       rel->exps = exps;
-       rel->card = CARD_MULTI;
-       rel->nrcols = 0;
-       return rel;
+       append(exps, exp_atom_clob(sql->sa, pmin));
+       append(exps, exp_atom_clob(sql->sa, pmax));
+       append(exps, exp_atom_int(sql->sa, with_nills));
+       rel_psm->l = NULL;
+       rel_psm->r = NULL;
+       rel_psm->op = op_ddl;
+       rel_psm->flag = DDL_ALTER_TABLE_ADD_RANGE_PARTITION;
+       rel_psm->exps = exps;
+       rel_psm->card = CARD_MULTI;
+       rel_psm->nrcols = 0;
+
+       return rel_exception(sql->sa, rel_psm, anti_rel, 
list_append(new_exp_list(sql->sa), exception));
 }
 
 static sql_rel *
@@ -120,7 +168,7 @@ rel_alter_table_add_partition_list(mvc *
 {
        sql_rel *rel_psm = rel_create(sql->sa), *anti_rel;
        list *exps = new_exp_list(sql->sa), *anti_exps = new_exp_list(sql->sa), 
*lvals = new_exp_list(sql->sa);
-       sql_exp *exception, *aggr, *anti_exp, *anti_le;
+       sql_exp *exception, *aggr, *anti_exp, *anti_le, *anti_nils;
        sql_column *col = mt->pcol;
        sql_subaggr *cf = sql_bind_aggr(sql->sa, sql->session->schema, "count", 
NULL);
        int with_nills = 0, colr = mt->pcol->colnr;
@@ -135,6 +183,7 @@ rel_alter_table_add_partition_list(mvc *
                                                 anti_le->card, 
has_nil(anti_le), is_intern(anti_le));
        anti_rel->exps = new_exp_list(sql->sa);
        append(anti_rel->exps, anti_le);
+       anti_nils = rel_unop_(sql, anti_le, NULL, "isnull", card_value);
 
        for (dnode *dn = values->h; dn ; dn = dn->next) { /* parse the atoms 
and generate the expressions */
                symbol* next = dn->data.sym;
@@ -155,14 +204,12 @@ rel_alter_table_add_partition_list(mvc *
        if(list_length(anti_exps) > 0) {
                anti_exp = exp_in(sql->sa, anti_le, anti_exps, cmp_notin);
                if(!with_nills) {
-                       sql_exp *anti_nils = rel_unop_(sql, anti_le, NULL, 
"isnull", card_value);
                        anti_nils = exp_compare(sql->sa, anti_nils, 
exp_atom_bool(sql->sa, 1), cmp_equal);
                        anti_exp = exp_or(sql->sa, 
append(new_exp_list(sql->sa), anti_exp),
                                                          
append(new_exp_list(sql->sa), anti_nils), 0);
                }
        } else {
                assert(with_nills);
-               sql_exp *anti_nils = rel_unop_(sql, anti_le, NULL, "isnull", 
card_value);
                anti_exp = exp_compare(sql->sa, anti_nils, 
exp_atom_bool(sql->sa, 1), cmp_notequal);
        }
 
@@ -175,8 +222,8 @@ rel_alter_table_add_partition_list(mvc *
        //generate the exception
        aggr = exp_column(sql->sa, exp_relname(aggr), exp_name(aggr), 
exp_subtype(aggr), aggr->card, has_nil(aggr),
                                          is_intern(aggr));
-       snprintf(buf, BUFSIZ, "ALTER TABLE: there are values in the column %s 
not according to the partition values list",
-                        col->base.name);
+       snprintf(buf, BUFSIZ, "ALTER TABLE: there are values in the column %s 
which is outside the partition list of values",
+                       col->base.name);
        exception = exp_exception(sql->sa, aggr, buf);
 
        //generate the psm statement
@@ -1574,7 +1621,7 @@ sql_alter_table(mvc *sql, dlist *qname, 
                                        } else if(max) {
                                                amax = ((AtomNode *) max)->a;
                                        }
-                                       return 
rel_alter_table_add_partition_range(sql->sa, sname, tname, sname, ntname, amin, 
amax, nills);
+                                       return 
rel_alter_table_add_partition_range(sql, t, pt, sname, tname, sname, ntname, 
amin, amax, nills);
                                } else if(extra->token == SQL_PARTITION_LIST) {
_______________________________________________
checkin-list mailing list
checkin-list@monetdb.org
https://www.monetdb.org/mailman/listinfo/checkin-list

Reply via email to