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