Changeset: 0c2ddc1a22fd for MonetDB
URL: https://dev.monetdb.org/hg/MonetDB?cmd=changeset;node=0c2ddc1a22fd
Added Files:
        sql/server/rel_propagate.c
        sql/server/rel_propagate.h
        sql/test/merge-partitions/Tests/mergepart11.sql
Modified Files:
        sql/server/Makefile.ag
        sql/server/rel_optimizer.c
        sql/test/merge-partitions/Tests/All
Branch: merge-partitions
Log Message:

Move partition related optimizations to a proper source file

Also added test for updates in partitioned column


diffs (truncated from 1068 to 300 lines):

diff --git a/sql/server/Makefile.ag b/sql/server/Makefile.ag
--- a/sql/server/Makefile.ag
+++ b/sql/server/Makefile.ag
@@ -48,6 +48,7 @@ lib_sqlserver = {
                rel_planner.c rel_planner.h \
                rel_distribute.c \
                rel_remote.c rel_remote.h \
+               rel_propagate.c rel_propagate.h \
                rel_psm.c \
                rel_xml.c \
                rel_dump.c \
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
@@ -15,9 +15,7 @@
 #include "rel_prop.h"
 #include "rel_dump.h"
 #include "rel_planner.h"
-#include "rel_select.h"
-#include "rel_updates.h"
-#include "rel_schema.h"
+#include "rel_propagate.h"
 #include "sql_mvc.h"
 #ifdef HAVE_HGE
 #include "mal.h"               /* for have_hge */
@@ -8015,198 +8013,6 @@ rel_rename_part(mvc *sql, sql_rel *p, ch
        return p;
 }
 
-static sql_rel* rel_change_base_table(mvc* sql, sql_rel* rel, sql_table* oldt, 
sql_table* newt);
-
-static sql_exp*
-exp_change_column_table(mvc *sql, sql_exp *e, sql_table* oldt, sql_table* newt)
-{
-       if (!e)
-               return NULL;
-       switch(e->type) {
-               case e_psm: {
-                       if (e->flag & PSM_RETURN) {
-                               for(node *n = ((list*)e->r)->h ; n ; n = 
n->next)
-                                       n->data = exp_change_column_table(sql, 
(sql_exp*) n->data, oldt, newt);
-                       } else if (e->flag & PSM_WHILE) {
-                               e->l = exp_change_column_table(sql, e->l, oldt, 
newt);
-                               for(node *n = ((list*)e->r)->h ; n ; n = 
n->next)
-                                       n->data = exp_change_column_table(sql, 
(sql_exp*) n->data, oldt, newt);
-                       } else if (e->flag & PSM_IF) {
-                               e->l = exp_change_column_table(sql, e->l, oldt, 
newt);
-                               for(node *n = ((list*)e->r)->h ; n ; n = 
n->next)
-                                       n->data = exp_change_column_table(sql, 
(sql_exp*) n->data, oldt, newt);
-                               if (e->f)
-                                       for(node *n = ((list*)e->f)->h ; n ; n 
= n->next)
-                                               n->data = 
exp_change_column_table(sql, (sql_exp*) n->data, oldt, newt);
-                       } else if (e->flag & PSM_REL) {
-                               rel_change_base_table(sql, e->l, oldt, newt);
-                       } else if (e->flag & PSM_EXCEPTION) {
-                               e->l = exp_change_column_table(sql, e->l, oldt, 
newt);
-                       }
-               } break;
-               case e_convert: {
-                       e->l = exp_change_column_table(sql, e->l, oldt, newt);
-               } break;
-               case e_atom:
-                       break;
-               case e_func: {
-                       for(node *n = ((list*)e->l)->h ; n ; n = n->next)
-                               n->data = exp_change_column_table(sql, 
(sql_exp*) n->data, oldt, newt);
-                       if (e->r)
-                               for(node *n = ((list*)e->r)->h ; n ; n = 
n->next)
-                                       n->data = exp_change_column_table(sql, 
(sql_exp*) n->data, oldt, newt);
-               }       break;
-               case e_aggr: {
-                       if (e->l)
-                               for(node *n = ((list*)e->l)->h ; n ; n = 
n->next)
-                                       n->data = exp_change_column_table(sql, 
(sql_exp*) n->data, oldt, newt);
-               }       break;
-               case e_column: {
-                       if(!strcmp(e->l, oldt->base.name))
-                               e->l = sa_strdup(sql->sa, newt->base.name);
-               } break;
-               case e_cmp: {
-                       if (e->flag == cmp_in || e->flag == cmp_notin) {
-                               e->l = exp_change_column_table(sql, e->l, oldt, 
newt);
-                               for(node *n = ((list*)e->r)->h ; n ; n = 
n->next)
-                                       n->data = exp_change_column_table(sql, 
(sql_exp*) n->data, oldt, newt);
-                       } else if (get_cmp(e) == cmp_or || get_cmp(e) == 
cmp_filter) {
-                               for(node *n = ((list*)e->l)->h ; n ; n = 
n->next)
-                                       n->data = exp_change_column_table(sql, 
(sql_exp*) n->data, oldt, newt);
-                               for(node *n = ((list*)e->r)->h ; n ; n = 
n->next)
-                                       n->data = exp_change_column_table(sql, 
(sql_exp*) n->data, oldt, newt);
-                       } else {
-                               if(e->l)
-                                       e->l = exp_change_column_table(sql, 
e->l, oldt, newt);
-                               if(e->r)
-                                       e->r = exp_change_column_table(sql, 
e->r, oldt, newt);
-                               if(e->f)
-                                       e->f = exp_change_column_table(sql, 
e->f, oldt, newt);
-                       }
-               } break;
-       }
-       if(e->rname && !strcmp(e->rname, oldt->base.name))
-               e->rname = sa_strdup(sql->sa, newt->base.name);
-       return e;
-}
-
-static sql_rel*
-rel_change_base_table(mvc* sql, sql_rel* rel, sql_table* oldt, sql_table* newt)
-{
-       if(!rel)
-               return NULL;
-
-       if(rel->exps)
-               for(node *n = rel->exps->h ; n ; n = n->next)
-                       n->data = exp_change_column_table(sql, (sql_exp*) 
n->data, oldt, newt);
-
-       switch(rel->op) {
-               case op_basetable:
-                       if(rel->l == oldt)
-                               rel->l = newt;
-                       if(rel->r)
-                               rel->r = rel_change_base_table(sql, rel->r, 
oldt, newt);
-                       break;
-               case op_table:
-               case op_topn:
-               case op_sample:
-               case op_project:
-               case op_groupby:
-               case op_select:
-               case op_insert:
-               case op_ddl:
-               case op_update:
-               case op_delete:
-               case op_truncate:
-               case op_union:
-               case op_inter:
-               case op_except:
-               case op_join:
-               case op_left:
-               case op_right:
-               case op_full:
-               case op_semi:
-               case op_anti:
-               case op_apply:
-                       if(rel->l)
-                               rel->l = rel_change_base_table(sql, rel->l, 
oldt, newt);
-                       if(rel->r)
-                               rel->r = rel_change_base_table(sql, rel->r, 
oldt, newt);
-       }
-       return rel;
-}
-
-static sql_rel *
-rel_truncate_duplicate(sql_allocator *sa, sql_rel *table, sql_rel *ori)
-{
-       sql_rel *r = rel_create(sa);
-
-       r->exps = exps_copy(sa, ori->exps);
-       r->op = op_truncate;
-       r->l = table;
-       r->r = NULL;
-       return r;
-}
-
-static sql_exp *
-create_table_part_atom_exp(mvc *sql, sht tpe, ptr value)
-{
-       switch (tpe) {
-               case TYPE_bit: {
-                       bit bval = *((bit*) value);
-                       return exp_atom_bool(sql->sa, bval ? 1 : 0);
-               }
-               case TYPE_bte: {
-                       bte bbval = *((bte *) value);
-                       return exp_atom_bte(sql->sa, bbval);
-               }
-               case TYPE_sht: {
-                       sht sval = *((sht*) value);
-                       return exp_atom_sht(sql->sa, sval);
-               }
-               case TYPE_int: {
-                       int ival = *((int*) value);
-                       return exp_atom_int(sql->sa, ival);
-               }
-               case TYPE_lng: {
-                       lng lval = *((lng*) value);
-                       return exp_atom_lng(sql->sa, lval);
-               }
-               case TYPE_flt: {
-                       flt fval = *((flt*) value);
-                       return exp_atom_flt(sql->sa, fval);
-               }
-               case TYPE_dbl: {
-                       dbl dval = *((dbl*) value);
-                       return exp_atom_dbl(sql->sa, dval);
-               }
-               case TYPE_str:
-                       return exp_atom_clob(sql->sa, sa_strdup(sql->sa, 
value));
-#ifdef HAVE_HGE
-               case TYPE_hge: {
-                       hge hval = *((hge*) value);
-                       return exp_atom_hge(sql->sa, hval);
-               }
-#endif
-               default:
-                       assert(0);
-       }
-}
-
-static sql_rel *
-rel_ddl_distribute(sql_allocator *sa, sql_rel *l, sql_rel *r, list *exps)
-{
-       sql_rel *rel = rel_create(sa);
-       if(!rel)
-               return NULL;
-       rel->l = l;
-       rel->r = r;
-       rel->exps = exps;
-       rel->op = op_ddl;
-       rel->flag = DDL_DISTRIBUTE;
-       return rel;
-}
-
 /* rewrite merge tables into union of base tables and call optimizer again */
 static sql_rel *
 rel_merge_table_rewrite(int *changes, mvc *sql, sql_rel *rel)
@@ -8214,251 +8020,7 @@ rel_merge_table_rewrite(int *changes, mv
        sql_rel *sel = NULL;
 
        if(is_modify(rel->op)) {
-               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;
-
-                               if(is_delete(rel->op) || is_truncate(rel->op)) 
{  //propagate deletions to the partitions
-                                       for (node *n = t->members.set->h; n; n 
= n->next) {
-                                               sql_part *pt = (sql_part *) 
n->data;
-                                               sql_table *sub = 
find_sql_table(t->s, pt->base.name);
-                                               sql_rel *s1, *dup = NULL;
-
-                                               if(rel->r) {
-                                                       dup = rel_copy(sql->sa, 
rel->r, 1);
-                                                       dup = 
rel_change_base_table(sql, dup, t, sub);
-                                               }
-                                               if(is_delete(rel->op))
-                                                       s1 = 
rel_delete(sql->sa, rel_basetable(sql, sub, sub->base.name), dup);
-                                               else
-                                                       s1 = 
rel_truncate_duplicate(sql->sa, rel_basetable(sql, sub, sub->base.name), rel);
-                                               if (just_one == 0) {
-                                                       sel = rel_list(sql->sa, 
sel, s1);
-                                               } else {
-                                                       sel = s1;
-                                                       just_one = 0;
-                                               }
-                                               (*changes)++;
-                                       }
-                                       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 */, *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;
-                                               sql_table *sub = 
find_sql_table(t->s, pt->base.name);
-                                               sql_rel *s1, *dup = 
rel_dup(rel->r);
-                                               sql_exp *le = 
list_fetch(dup->exps, colr);
-                                               le = exp_column(sql->sa, 
exp_relname(le), exp_name(le), exp_subtype(le), le->card, has_nil(le), 
is_intern(le));
-
-                                               if(isRangePartitionTable(t)) {
-                                                       sql_exp *e1, *e2;
-
-                                                       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);
-                                                       dup = 
rel_compare_exp_(sql, dup, le, e1, e2, 3, 0);
-
-                                                       if(accum) {
-                                                               sql_exp *nr = 
exp_compare2(sql->sa, anti_le, exp_copy(sql->sa, e1), exp_copy(sql->sa, e2), 3);
-                                                               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_compare2(sql->sa, anti_le, exp_copy(sql->sa, e1), exp_copy(sql->sa, e2), 3);
-                                                       }
-
-                                                       if(pt->with_nills) { /* 
handle the nulls case */
-                                                               sql_rel *extra;
-                                                               sql_exp *nils = 
rel_unop_(sql, le, NULL, "isnull", card_value),
-                                                                               
*anti_nils = rel_unop_(sql, anti_le, NULL, "isnull", card_value);
-                                                               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_notequal);
_______________________________________________
checkin-list mailing list
[email protected]
https://www.monetdb.org/mailman/listinfo/checkin-list

Reply via email to