Changeset: ec5c7a5d7a16 for MonetDB
URL: https://dev.monetdb.org/hg/MonetDB?cmd=changeset;node=ec5c7a5d7a16
Added Files:
        sql/test/merge-partitions/Tests/mergepart06.stable.err
        sql/test/merge-partitions/Tests/mergepart06.stable.out
        sql/test/merge-partitions/Tests/mergepart09.stable.err
        sql/test/merge-partitions/Tests/mergepart09.stable.out
Modified Files:
        sql/backends/monet5/rel_bin.c
        sql/backends/monet5/sql_cat.c
        sql/server/rel_exp.c
        sql/server/rel_optimizer.c
        sql/test/merge-partitions/Tests/mergepart06.sql
        sql/test/merge-partitions/Tests/mergepart08.sql
        sql/test/merge-partitions/Tests/mergepart09.sql
Branch: merge-partitions
Log Message:

When inserting into a sub-table of the partition directly, create the exception 
statement as well.

Also made fixes for the other tests.


diffs (truncated from 695 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
@@ -4919,8 +4919,13 @@ rel2bin_distribute(backend *be, sql_rel 
        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);
+       } 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 exp_bin(be, except, l, r, NULL, NULL, NULL, NULL);
 }
 
 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
@@ -344,6 +344,8 @@ finish:
                BBPunfix(diff1->batCacheid);
        if(diff2)
                BBPunfix(diff2->batCacheid);
+       if(msg != MAL_SUCCEED)
+               pt->p = NULL;
        return msg;
 }
 
@@ -497,6 +499,8 @@ finish:
                BBPunfix(cbind->batCacheid);
        if(diff)
                BBPunfix(diff->batCacheid);
+       if(msg != MAL_SUCCEED)
+               pt->p = NULL;
        return msg;
 }
 
diff --git a/sql/server/rel_exp.c b/sql/server/rel_exp.c
--- a/sql/server/rel_exp.c
+++ b/sql/server/rel_exp.c
@@ -634,7 +634,7 @@ exp_exception(sql_allocator *sa, sql_exp
        if (e == NULL)
                return NULL;
        e->l = cond;
-       e->r = error_message;
+       e->r = sa_strdup(sa, error_message);
        e->flag = PSM_EXCEPTION;
        return e;
 }
diff --git a/sql/server/rel_optimizer.c b/sql/server/rel_optimizer.c
--- a/sql/server/rel_optimizer.c
+++ b/sql/server/rel_optimizer.c
@@ -8136,6 +8136,7 @@ rel_merge_table_rewrite(int *changes, mv
                sql_rel *left = rel->l;
                if(left->op == op_basetable) {
                        sql_table *t = left->l;
+                       char buf[BUFSIZ];
 
                        if(isRangePartitionTable(t) || isListPartitionTable(t)) 
{
                                int just_one = 1;
@@ -8165,13 +8166,14 @@ rel_merge_table_rewrite(int *changes, mv
                                        sel = rel_ddl_distribute(sql->sa, sel, 
NULL, NULL);
                                } else if(is_insert(rel->op)) { //on inserts 
create a selection for each partition
                                        int colr = t->pcol->colnr;
-                                       sql_rel *anti_dup = rel_dup(rel->r); /* 
the anti relation */
+                                       sql_rel *anti_dup = rel_dup(rel->r) /* 
the anti relation */, *new_table = NULL;
                                        sql_exp *anti_exp = NULL, *anti_le = 
list_fetch(anti_dup->exps, colr), *accum = NULL, *aggr = NULL,
                                                        *exception = NULL;
                                        list *anti_exps = new_exp_list(sql->sa);
                                        sql_subaggr *cf = 
sql_bind_aggr(sql->sa, sql->session->schema, "count", NULL);
                                        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));
+                                       int found_nils = 0;
 
                                        for (node *n = t->members.set->h; n; n 
= n->next) {
                                                sql_part *pt = (sql_part *) 
n->data;
@@ -8202,11 +8204,11 @@ rel_merge_table_rewrite(int *changes, mv
                                                                nils = 
exp_compare(sql->sa, nils, exp_atom_bool(sql->sa, 1), cmp_equal);
 
                                                                if(accum) {
-                                                                       sql_exp 
*nr = exp_compare(sql->sa, anti_nils, exp_atom_bool(sql->sa, 1), cmp_equal);
+                                                                       sql_exp 
*nr = exp_compare(sql->sa, anti_nils, exp_atom_bool(sql->sa, 1), cmp_notequal);
                                                                        accum = 
exp_or(sql->sa, list_append(new_exp_list(sql->sa), accum),
                                                                                
                   list_append(new_exp_list(sql->sa), nr), 1);
                                                                } else {
-                                                                       accum = 
exp_compare(sql->sa, anti_nils, exp_atom_bool(sql->sa, 1), cmp_equal);
+                                                                       accum = 
exp_compare(sql->sa, anti_nils, exp_atom_bool(sql->sa, 1), cmp_notequal);
                                                                }
                                                                extra = 
rel_select(sql->sa, rel->r, nils);
                                                                dup = 
rel_or(sql, NULL, dup, extra, NULL, NULL, NULL);
@@ -8222,18 +8224,24 @@ rel_merge_table_rewrite(int *changes, mv
                                                                
list_append(anti_exps, exp_copy(sql->sa, e1));
                                                        }
 
+                                                       ein = exp_in(sql->sa, 
le, exps, cmp_in);
                                                        if(pt->with_nills) { /* 
handle the nulls case */
-                                                               sql_exp *e2 = 
exp_atom(sql->sa, atom_general(sql->sa, &(t->pcol->type), NULL));
-                                                               
list_append(exps, e2);
-                                                               
list_append(anti_exps, exp_copy(sql->sa, e2));
+                                                               sql_exp *nils = 
rel_unop_(sql, le, NULL, "isnull", card_value);
+                                                               nils = 
exp_compare(sql->sa, nils, exp_atom_bool(sql->sa, 1), cmp_equal);
+                                                               ein = 
exp_or(sql->sa, list_append(new_exp_list(sql->sa), ein),
+                                                                               
           list_append(new_exp_list(sql->sa), nils), 0);
+                                                               found_nils = 1;
                                                        }
-                                                       ein = exp_in(sql->sa, 
le, exps, cmp_in);
                                                        dup = 
rel_select(sql->sa, dup, ein);
                                                } else {
                                                        assert(0);
                                                }
 
-                                               s1 = rel_insert(sql, 
rel_basetable(sql, sub, sub->base.name), dup);
+                                               new_table = rel_basetable(sql, 
sub, sub->base.name);
+                                               
if(list_length(sub->members.set) == 0) //if this table has no partitions, set 
it as used
+                                                       new_table->p = 
prop_create(sql->sa, PROP_USED, new_table->p);
+
+                                               s1 = rel_insert(sql, new_table, 
dup);
                                                if (just_one == 0) {
                                                        sel = rel_list(sql->sa, 
sel, s1);
                                                } else {
@@ -8249,6 +8257,12 @@ rel_merge_table_rewrite(int *changes, mv
                                                anti_exp = accum;
                                        } else if(isListPartitionTable(t)) {
                                                anti_exp = exp_in(sql->sa, 
anti_le, anti_exps, cmp_notin);
+                                               if(!found_nils) {
+                                                       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, list_append(new_exp_list(sql->sa), anti_exp),
+                                                                               
         list_append(new_exp_list(sql->sa), anti_nils), 0);
+                                               }
                                        } else {
                                                assert(0);
                                        }
@@ -8263,10 +8277,68 @@ rel_merge_table_rewrite(int *changes, mv
                                        //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));
-                                       exception = exp_exception(sql->sa, aggr,
-                                                                               
          "INSERT INTO: There are values in the insert not corresponding to any 
partition");
+                                       snprintf(buf, BUFSIZ, "INSERT: the 
insert violates the partition %s of values",
+                                                        
isRangePartitionTable(t) ? "range" : "list");
+                                       exception = exp_exception(sql->sa, 
aggr, buf);
                                        sel = rel_ddl_distribute(sql->sa, sel, 
anti_dup, list_append(new_exp_list(sql->sa), exception));
                                }
+                       } else if(t->p && (isRangePartitionTable(t->p) || 
isListPartitionTable(t->p))
+                                         && !find_prop(left->p, PROP_USED) && 
is_insert(rel->op)) {
+                               //is part of a partition table and not been 
used yet
+                               sql_table *upper = t->p;
+                               int colr = upper->pcol->colnr;
+                               sql_part *pt = find_sql_part(upper, 
t->base.name);
+                               sql_rel *anti_dup = rel_dup(rel->r) /* the anti 
relation */, *right = rel->r;
+                               sql_exp *le = list_fetch(right->exps, colr), 
*anti_exp = NULL,
+                                               *anti_le = 
list_fetch(anti_dup->exps, colr), *aggr = NULL, *exception = NULL;
+                               list *anti_exps = new_exp_list(sql->sa);
+                               sql_subaggr *cf = sql_bind_aggr(sql->sa, 
sql->session->schema, "count", NULL);
+
+                               le = exp_column(sql->sa, exp_relname(le), 
exp_name(le), exp_subtype(le), le->card, has_nil(le), is_intern(le));
+                               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));
+
+                               if(isRangePartitionTable(upper)) {
+                                       sql_exp *e1 = 
create_table_part_atom_exp(sql, pt->tpe, pt->part.range.minvalue),
+                                                       *e2 = 
create_table_part_atom_exp(sql, pt->tpe, pt->part.range.maxvalue);
+                                       anti_exp = exp_compare2(sql->sa, 
anti_le, exp_copy(sql->sa, e1), exp_copy(sql->sa, e2), 3);
+                                       set_anti(anti_exp);
+                               } else if(isListPartitionTable(upper)) {
+                                       for(node *n = pt->part.values->h ; n ; 
n = n->next) {
+                                               sql_part_value *next = 
(sql_part_value*) n->data;
+                                               sql_exp *e1 = 
create_table_part_atom_exp(sql, next->tpe, next->value);
+                                               list_append(anti_exps, 
exp_copy(sql->sa, e1));
+                                       }
+                                       anti_exp = exp_in(sql->sa, anti_le, 
anti_exps, cmp_notin);
+                               } else {
+                                       assert(0);
+                               }
+                               if(!pt->with_nills) { /* handle the nulls case 
*/
+                                       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, 
list_append(new_exp_list(sql->sa), anti_exp),
+                                                                         
list_append(new_exp_list(sql->sa), anti_nils), 0);
+                               }
+
+                               //generate a count aggregation for the values 
not present in any of the partitions
+                               anti_dup = rel_select(sql->sa, anti_dup, 
anti_exp);
+                               anti_dup = rel_project(sql->sa, anti_dup, 
rel_projections(sql, anti_dup, NULL, 1, 1));
+                               anti_dup = rel_groupby(sql, anti_dup, NULL);
+                               aggr = exp_aggr(sql->sa, NULL, cf, 0, 0, 
anti_dup->card, 0);
+                               (void) rel_groupby_add_aggr(sql, anti_dup, 
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, "INSERT: table %s.%s is 
part of merge table %s.%s and the insert violates the "
+                                                       "partition %s of 
values", t->s->base.name,  t->base.name, upper->s->base.name,
+                                                       upper->base.name, 
isRangePartitionTable(upper) ? "range" : "list");
+                               exception = exp_exception(sql->sa, aggr, buf);
+                               sel = rel_ddl_distribute(sql->sa, rel, 
anti_dup, list_append(new_exp_list(sql->sa), exception));
+
+                               left->p = prop_create(sql->sa, PROP_USED, 
left->p);
+                               (*changes)++;
                        }
                }
        } else {
diff --git a/sql/test/merge-partitions/Tests/mergepart06.sql 
b/sql/test/merge-partitions/Tests/mergepart06.sql
--- a/sql/test/merge-partitions/Tests/mergepart06.sql
+++ b/sql/test/merge-partitions/Tests/mergepart06.sql
@@ -20,7 +20,7 @@ INSERT INTO testrangelimits VALUES (201,
 INSERT INTO testrangelimits VALUES (444, 'another'), (305, 'error'), (4, 
'happening'); --error
 
 INSERT INTO sublimits1 VALUES (2, 'another');
-INSERT INTO sublimits2 VALUES (202, 'successful');
+INSERT INTO sublimits2 VALUES (102, 'successful');
 INSERT INTO sublimits3 VALUES (NULL, 'attempt');
 
 INSERT INTO sublimits3 VALUES (2, 'will'); --error
diff --git a/sql/test/merge-partitions/Tests/mergepart06.stable.err 
b/sql/test/merge-partitions/Tests/mergepart06.stable.err
new file mode 100644
--- /dev/null
+++ b/sql/test/merge-partitions/Tests/mergepart06.stable.err
@@ -0,0 +1,61 @@
+stderr of test 'mergepart06` in directory 'sql/test/merge-partitions` itself:
+
+
+# 15:49:30 >  
+# 15:49:30 >  "mserver5" "--debug=10" "--set" "gdk_nr_threads=0" "--set" 
"mapi_open=true" "--set" "mapi_port=35425" "--set" 
"mapi_usock=/var/tmp/mtest-655/.s.monetdb.35425" "--set" "monet_prompt=" 
"--forcemito" 
"--dbpath=/home/ferreira/repositories/MonetDB-merge-partitions/BUILD/var/MonetDB/mTests_sql_test_merge-partitions"
 "--set" "embedded_r=yes" "--set" "embedded_py=true" "--set" "embedded_c=true"
+# 15:49:30 >  
+
+# builtin opt  gdk_dbpath = 
/home/ferreira/repositories/MonetDB-merge-partitions/BUILD/var/monetdb5/dbfarm/demo
+# builtin opt  gdk_debug = 0
+# builtin opt  gdk_vmtrim = no
+# builtin opt  monet_prompt = >
+# builtin opt  monet_daemon = no
+# builtin opt  mapi_port = 50000
+# builtin opt  mapi_open = false
+# builtin opt  mapi_autosense = false
+# builtin opt  sql_optimizer = default_pipe
+# builtin opt  sql_debug = 0
+# cmdline opt  gdk_nr_threads = 0
+# cmdline opt  mapi_open = true
+# cmdline opt  mapi_port = 35425
+# cmdline opt  mapi_usock = /var/tmp/mtest-655/.s.monetdb.35425
+# cmdline opt  monet_prompt = 
+# cmdline opt  gdk_dbpath = 
/home/ferreira/repositories/MonetDB-merge-partitions/BUILD/var/MonetDB/mTests_sql_test_merge-partitions
+# cmdline opt  embedded_r = yes
+# cmdline opt  embedded_py = true
+# cmdline opt  embedded_c = true
+# cmdline opt  gdk_debug = 553648138
+
+# 15:49:31 >  
+# 15:49:31 >  "mclient" "-lsql" "-ftest" "-tnone" "-Eutf-8" "-i" "-e" 
"--host=/var/tmp/mtest-655" "--port=35425"
+# 15:49:31 >  
+
+MAPI  = (monetdb) /var/tmp/mtest-655/.s.monetdb.35425
+QUERY = INSERT INTO testrangelimits VALUES (1000, 'ups'); --error
+ERROR = !INSERT: the insert violates the partition range of values
+CODE  = M0M29
+MAPI  = (monetdb) /var/tmp/mtest-655/.s.monetdb.35425
+QUERY = INSERT INTO testrangelimits VALUES (201, 'oh no'); --error
+ERROR = !INSERT: the insert violates the partition range of values
+CODE  = M0M29
+MAPI  = (monetdb) /var/tmp/mtest-655/.s.monetdb.35425
+QUERY = INSERT INTO testrangelimits VALUES (444, 'another'), (305, 'error'), 
(4, 'happening'); --error
+ERROR = !INSERT: the insert violates the partition range of values
+CODE  = M0M29
+MAPI  = (monetdb) /var/tmp/mtest-655/.s.monetdb.35425
+QUERY = INSERT INTO sublimits3 VALUES (2, 'will'); --error
+ERROR = !INSERT: table sys.sublimits3 is part of merge table 
sys.testrangelimits and the insert violates the partition range of values
+CODE  = M0M29
+MAPI  = (monetdb) /var/tmp/mtest-655/.s.monetdb.35425
+QUERY = INSERT INTO sublimits1 VALUES (202, 'fail'); --error
+ERROR = !INSERT: table sys.sublimits1 is part of merge table 
sys.testrangelimits and the insert violates the partition range of values
+CODE  = M0M29
+MAPI  = (monetdb) /var/tmp/mtest-655/.s.monetdb.35425
+QUERY = INSERT INTO sublimits2 VALUES (NULL, 'again'); --error
+ERROR = !INSERT: table sys.sublimits2 is part of merge table 
sys.testrangelimits and the insert violates the partition range of values
+CODE  = M0M29
+
+# 15:49:31 >  
+# 15:49:31 >  "Done."
+# 15:49:31 >  
+
diff --git a/sql/test/merge-partitions/Tests/mergepart06.stable.out 
b/sql/test/merge-partitions/Tests/mergepart06.stable.out
new file mode 100644
--- /dev/null
+++ b/sql/test/merge-partitions/Tests/mergepart06.stable.out
@@ -0,0 +1,150 @@
+stdout of test 'mergepart06` in directory 'sql/test/merge-partitions` itself:
+
+
+# 15:49:30 >  
+# 15:49:30 >  "mserver5" "--debug=10" "--set" "gdk_nr_threads=0" "--set" 
"mapi_open=true" "--set" "mapi_port=35425" "--set" 
"mapi_usock=/var/tmp/mtest-655/.s.monetdb.35425" "--set" "monet_prompt=" 
"--forcemito" 
"--dbpath=/home/ferreira/repositories/MonetDB-merge-partitions/BUILD/var/MonetDB/mTests_sql_test_merge-partitions"
 "--set" "embedded_r=yes" "--set" "embedded_py=true" "--set" "embedded_c=true"
+# 15:49:30 >  
+
+# MonetDB 5 server v11.30.0
+# This is an unreleased version
+# Serving database 'mTests_sql_test_merge-partitions', using 8 threads
+# Compiled for x86_64-pc-linux-gnu/64bit with 128bit integers
_______________________________________________
checkin-list mailing list
[email protected]
https://www.monetdb.org/mailman/listinfo/checkin-list

Reply via email to