Changeset: 3701dcd5a6c9 for MonetDB URL: http://dev.monetdb.org/hg/MonetDB?cmd=changeset;node=3701dcd5a6c9 Modified Files: sql/benchmarks/tpch/LOCKED/Tests/01-22.stable.out sql/benchmarks/tpch/LOCKED/Tests/01-22.stable.out.int128 sql/benchmarks/tpch/LOCKED/Tests/02.stable.out sql/benchmarks/tpch/Tests/01-22.stable.out sql/benchmarks/tpch/Tests/01-22.stable.out.int128 sql/benchmarks/tpch/Tests/02.stable.out sql/server/rel_optimizer.c sql/server/rel_updates.c sql/storage/store.c sql/test/BugTracker-2015/Tests/crash.Bug-3736.stable.out sql/test/BugTracker-2016/Tests/storagemodel.stable.out Branch: Dec2016 Log Message:
allow for update table x=1,x=2,x=n (only last is used). cleanup rel_apply_rewriter some more. diffs (truncated from 557 to 300 lines): diff --git a/sql/benchmarks/tpch/LOCKED/Tests/01-22.stable.out b/sql/benchmarks/tpch/LOCKED/Tests/01-22.stable.out --- a/sql/benchmarks/tpch/LOCKED/Tests/01-22.stable.out +++ b/sql/benchmarks/tpch/LOCKED/Tests/01-22.stable.out @@ -81,7 +81,7 @@ Ready. % rewrite, count # name % clob, int # type % 7, 1 # length -[ "joinidx", 4 ] +[ "joinidx", 7 ] # 11:48:05 > # 11:48:05 > Mtimeout -timeout 60 MapiClient -lsql -umonetdb -Pmonetdb --host=localhost --port=35781 diff --git a/sql/benchmarks/tpch/LOCKED/Tests/01-22.stable.out.int128 b/sql/benchmarks/tpch/LOCKED/Tests/01-22.stable.out.int128 --- a/sql/benchmarks/tpch/LOCKED/Tests/01-22.stable.out.int128 +++ b/sql/benchmarks/tpch/LOCKED/Tests/01-22.stable.out.int128 @@ -81,7 +81,7 @@ Ready. % rewrite, count # name % clob, int # type % 7, 1 # length -[ "joinidx", 4 ] +[ "joinidx", 7 ] # 11:48:05 > # 11:48:05 > Mtimeout -timeout 60 MapiClient -lsql -umonetdb -Pmonetdb --host=localhost --port=35781 diff --git a/sql/benchmarks/tpch/LOCKED/Tests/02.stable.out b/sql/benchmarks/tpch/LOCKED/Tests/02.stable.out --- a/sql/benchmarks/tpch/LOCKED/Tests/02.stable.out +++ b/sql/benchmarks/tpch/LOCKED/Tests/02.stable.out @@ -37,7 +37,7 @@ Ready. % rewrite, count # name % clob, int # type % 7, 1 # length -[ "joinidx", 4 ] +[ "joinidx", 7 ] # 09:17:12 > # 09:17:12 > Done. diff --git a/sql/benchmarks/tpch/Tests/01-22.stable.out b/sql/benchmarks/tpch/Tests/01-22.stable.out --- a/sql/benchmarks/tpch/Tests/01-22.stable.out +++ b/sql/benchmarks/tpch/Tests/01-22.stable.out @@ -81,7 +81,7 @@ Ready. % rewrite, count # name % clob, int # type % 7, 1 # length -[ "joinidx", 4 ] +[ "joinidx", 7 ] # 11:48:05 > # 11:48:05 > Mtimeout -timeout 60 MapiClient -lsql -umonetdb -Pmonetdb --host=localhost --port=35781 diff --git a/sql/benchmarks/tpch/Tests/01-22.stable.out.int128 b/sql/benchmarks/tpch/Tests/01-22.stable.out.int128 --- a/sql/benchmarks/tpch/Tests/01-22.stable.out.int128 +++ b/sql/benchmarks/tpch/Tests/01-22.stable.out.int128 @@ -81,7 +81,7 @@ Ready. % rewrite, count # name % clob, int # type % 7, 1 # length -[ "joinidx", 4 ] +[ "joinidx", 7 ] # 11:48:05 > # 11:48:05 > Mtimeout -timeout 60 MapiClient -lsql -umonetdb -Pmonetdb --host=localhost --port=35781 diff --git a/sql/benchmarks/tpch/Tests/02.stable.out b/sql/benchmarks/tpch/Tests/02.stable.out --- a/sql/benchmarks/tpch/Tests/02.stable.out +++ b/sql/benchmarks/tpch/Tests/02.stable.out @@ -37,7 +37,7 @@ Ready. % rewrite, count # name % clob, int # type % 7, 1 # length -[ "joinidx", 4 ] +[ "joinidx", 7 ] # 09:17:12 > # 09:17:12 > Done. 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 @@ -1650,7 +1650,6 @@ rel_push_count_down(int *changes, mvc *s r && !r->exps && r->op == op_join && !(rel_is_ref(r)) && ((sql_exp *) rel->exps->h->data)->type == e_aggr && strcmp(((sql_subaggr *) ((sql_exp *) rel->exps->h->data)->f)->aggr->base.name, "count") == 0) { -/* TODO check for count(*) */ sql_exp *nce, *oce; sql_rel *gbl, *gbr; /* Group By */ sql_rel *cp; /* Cross Product */ @@ -3631,97 +3630,6 @@ rel_push_aggr_down(int *changes, mvc *sq } /* - * Rewrite group(project(join(A,Dict)[a.i==dict.i])[...dict.n])[dict.n][ ... dict.n ] - * into - * project(join(groupby (A)[a.i],[a.i]), Dict)[a.i==dict.i])[dict.n] - * - */ - -static sql_rel * -rel_push_groupby_down(int *changes, mvc *sql, sql_rel *rel) -{ - sql_rel *p = rel->l, *j = rel->l; - list *gbe = rel->r; - - if (rel->op == op_groupby && gbe && p && p->op == op_project) { - sql_rel *j = p->l; - sql_rel *jl, *jr; - node *n; - - if (!j || j->op != op_join || list_length(j->exps) != 1) - return rel; - jl = j->l; - jr = j->r; - - /* check if jr is a dict with index and var still used */ - if (jr->op != op_basetable || jr->l || !jr->r || list_length(jr->exps) != 2) - return rel; - - /* check if group by is done on dict column */ - for(n = gbe->h; n; n = n->next) { - sql_exp *ge = n->data, *pe = NULL, *e = NULL; - - /* find group by exp in project, then in dict */ - pe = rel_find_exp(p, ge); - if (pe) /* find project exp in right hand of join, ie dict */ - e = rel_find_exp(jr, pe); - if (pe && e) { /* Rewrite: join with dict after the group by */ - list *pexps = rel_projections(sql, rel, NULL, 1, 1), *npexps; - node *m; - sql_exp *ne = j->exps->h->data; /* join exp */ - p->l = jl; /* Project now only on the left side of the join */ - - ne = ne->l; /* The left side of the compare is the index of the left */ - - /* find ge reference in new projection list */ - npexps = sa_list(sql->sa); - for (m = pexps->h; m; m = m->next) { - sql_exp *a = m->data; - - if (exp_refers(ge, a)) { - sql_exp *sc = jr->exps->t->data; - sql_exp *e = exp_column(sql->sa, exp_relname(sc), exp_name(sc), exp_subtype(sc), sc->card, has_nil(sc), is_intern(sc)); - exp_setname(sql->sa, e, exp_relname(a), exp_name(a)); - a = e; - } - append(npexps, a); - } - - /* find ge in aggr list */ - for (m = rel->exps->h; m; m = m->next) { - sql_exp *a = m->data; - - if (exp_match_exp(a, ge) || exp_refers(ge, a)) { - a = exp_column(sql->sa, exp_relname(ne), exp_name(ne), exp_subtype(ne), ne->card, has_nil(ne), is_intern(ne)); - exp_setname(sql->sa, a, exp_relname(ne), exp_name(ne)); - m->data = a; - } - } - - /* change alias pe, ie project out the index */ - pe->l = (void*)exp_relname(ne); - pe->r = (void*)exp_name(ne); - exp_setname(sql->sa, pe, exp_relname(ne), exp_name(ne)); - - /* change alias ge */ - ge->l = (void*)exp_relname(pe); - ge->r = (void*)exp_name(pe); - exp_setname(sql->sa, ge, exp_relname(pe), exp_name(pe)); - - /* zap both project and groupby name hash tables (as we changed names above) */ - rel->exps->ht = NULL; - ((list*)rel->r)->ht = NULL; - p->exps->ht = NULL; - - /* add join */ - j->l = rel; - rel = rel_project(sql->sa, j, npexps); - (*changes)++; - } - } - (void)sql; - } -/* * More general * groupby( * [ outer ] join( @@ -3743,6 +3651,13 @@ rel_push_groupby_down(int *changes, mvc * ) [ B.c1 ] [ a1, a2, .. ] * ) [ A.c1 = B.c1 ] */ +static sql_rel * +gen_push_groupby_down(int *changes, mvc *sql, sql_rel *rel) +{ + sql_rel *j = rel->l; + list *gbe = rel->r; + + (void)changes; if (rel->op == op_groupby && list_length(gbe) == 1 && is_outerjoin(j->op)) { sql_rel *jl = j->l, *jr = j->r, *cr; sql_exp *gb = gbe->h->data, *e; @@ -3812,6 +3727,99 @@ rel_push_groupby_down(int *changes, mvc } /* + * Rewrite group(project(join(A,Dict)[a.i==dict.i])[...dict.n])[dict.n][ ... dict.n ] + * into + * project(join(groupby (A)[a.i],[a.i]), Dict)[a.i==dict.i])[dict.n] + * + */ +static sql_rel * +rel_push_groupby_down(int *changes, mvc *sql, sql_rel *rel) +{ + sql_rel *p = rel->l; + list *gbe = rel->r; + + if (rel->op == op_groupby && gbe && p && p->op == op_project) { + sql_rel *j = p->l; + sql_rel *jl, *jr; + node *n; + + if (!j || j->op != op_join || list_length(j->exps) != 1) + return gen_push_groupby_down(changes, sql, rel); + jl = j->l; + jr = j->r; + + /* check if jr is a dict with index and var still used */ + if (jr->op != op_basetable || jr->l || !jr->r || list_length(jr->exps) != 2) + return gen_push_groupby_down(changes, sql, rel); + + /* check if group by is done on dict column */ + for(n = gbe->h; n; n = n->next) { + sql_exp *ge = n->data, *pe = NULL, *e = NULL; + + /* find group by exp in project, then in dict */ + pe = rel_find_exp(p, ge); + if (pe) /* find project exp in right hand of join, ie dict */ + e = rel_find_exp(jr, pe); + if (pe && e) { /* Rewrite: join with dict after the group by */ + list *pexps = rel_projections(sql, rel, NULL, 1, 1), *npexps; + node *m; + sql_exp *ne = j->exps->h->data; /* join exp */ + p->l = jl; /* Project now only on the left side of the join */ + + ne = ne->l; /* The left side of the compare is the index of the left */ + + /* find ge reference in new projection list */ + npexps = sa_list(sql->sa); + for (m = pexps->h; m; m = m->next) { + sql_exp *a = m->data; + + if (exp_refers(ge, a)) { + sql_exp *sc = jr->exps->t->data; + sql_exp *e = exp_column(sql->sa, exp_relname(sc), exp_name(sc), exp_subtype(sc), sc->card, has_nil(sc), is_intern(sc)); + exp_setname(sql->sa, e, exp_relname(a), exp_name(a)); + a = e; + } + append(npexps, a); + } + + /* find ge in aggr list */ + for (m = rel->exps->h; m; m = m->next) { + sql_exp *a = m->data; + + if (exp_match_exp(a, ge) || exp_refers(ge, a)) { + a = exp_column(sql->sa, exp_relname(ne), exp_name(ne), exp_subtype(ne), ne->card, has_nil(ne), is_intern(ne)); + exp_setname(sql->sa, a, exp_relname(ne), exp_name(ne)); + m->data = a; + } + } + + /* change alias pe, ie project out the index */ + pe->l = (void*)exp_relname(ne); + pe->r = (void*)exp_name(ne); + exp_setname(sql->sa, pe, exp_relname(ne), exp_name(ne)); + + /* change alias ge */ + ge->l = (void*)exp_relname(pe); + ge->r = (void*)exp_name(pe); + exp_setname(sql->sa, ge, exp_relname(pe), exp_name(pe)); + + /* zap both project and groupby name hash tables (as we changed names above) */ + rel->exps->ht = NULL; + ((list*)rel->r)->ht = NULL; + p->exps->ht = NULL; + + /* add join */ + j->l = rel; + rel = rel_project(sql->sa, j, npexps); + (*changes)++; + } + } + (void)sql; + } + return rel; +} + +/* * Push select down, pushes the selects through (simple) projections. Also * it cleans up the projections which become useless. */ @@ -8339,21 +8347,15 @@ rel_apply_rewrite(int *changes, mvc *sql } if (rel->flag == APPLY_LOJ && is_join(r->op)) { sql_rel *rl = r->l, *rr = r->r; - int lused = 0, rused = 0; _______________________________________________ checkin-list mailing list checkin-list@monetdb.org https://www.monetdb.org/mailman/listinfo/checkin-list