Changeset: 98aa97822a61 for MonetDB URL: http://dev.monetdb.org/hg/MonetDB?cmd=changeset;node=98aa97822a61 Modified Files: sql/benchmarks/tpch/LOCKED/Tests/01-22.stable.out sql/benchmarks/tpch/LOCKED/Tests/02.stable.out sql/benchmarks/tpch/LOCKED/Tests/17.stable.out sql/benchmarks/tpch/Tests/01-22.stable.out sql/benchmarks/tpch/Tests/02.stable.out sql/benchmarks/tpch/Tests/17.stable.out sql/server/rel_optimizer.c sql/test/BugTracker-2011/Tests/All Branch: Apr2011 Log Message:
improved handling of push_select_down / push_down_exp We now only go through the tree once (topdown). This solves bug 2811. diffs (279 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 @@ -59,7 +59,7 @@ % rewrite, count # name % clob, int # type % 7, 1 # length -[ "joinidx", 6 ] +[ "joinidx", 7 ] # 11:48:05 > # 11:48:05 > Mtimeout -timeout 60 MapiClient -lsql -umonetdb -Pmonetdb --host=localhost --port=35781 @@ -855,7 +855,7 @@ % rewrite, count # name % clob, int # type % 7, 1 # length -[ "joinidx", 0 ] +[ "joinidx", 1 ] # 11:48:06 > # 11:48:06 > 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 @@ % rewrite, count # name % clob, int # type % 7, 1 # length -[ "joinidx", 6 ] +[ "joinidx", 7 ] # 09:17:12 > # 09:17:12 > Done. diff --git a/sql/benchmarks/tpch/LOCKED/Tests/17.stable.out b/sql/benchmarks/tpch/LOCKED/Tests/17.stable.out --- a/sql/benchmarks/tpch/LOCKED/Tests/17.stable.out +++ b/sql/benchmarks/tpch/LOCKED/Tests/17.stable.out @@ -33,7 +33,7 @@ % rewrite, count # name % clob, int # type % 7, 1 # length -[ "joinidx", 0 ] +[ "joinidx", 1 ] # 09:17:19 > # 09:17:19 > 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 @@ -59,7 +59,7 @@ % rewrite, count # name % clob, int # type % 7, 1 # length -[ "joinidx", 6 ] +[ "joinidx", 7 ] # 11:48:05 > # 11:48:05 > Mtimeout -timeout 60 MapiClient -lsql -umonetdb -Pmonetdb --host=localhost --port=35781 @@ -855,7 +855,7 @@ % rewrite, count # name % clob, int # type % 7, 1 # length -[ "joinidx", 0 ] +[ "joinidx", 1 ] # 11:48:06 > # 11:48:06 > 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 @@ % rewrite, count # name % clob, int # type % 7, 1 # length -[ "joinidx", 6 ] +[ "joinidx", 7 ] # 09:17:12 > # 09:17:12 > Done. diff --git a/sql/benchmarks/tpch/Tests/17.stable.out b/sql/benchmarks/tpch/Tests/17.stable.out --- a/sql/benchmarks/tpch/Tests/17.stable.out +++ b/sql/benchmarks/tpch/Tests/17.stable.out @@ -33,7 +33,7 @@ % rewrite, count # name % clob, int # type % 7, 1 # length -[ "joinidx", 0 ] +[ "joinidx", 1 ] # 09:17:19 > # 09:17:19 > 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 @@ -1014,7 +1014,7 @@ from relation f into expression of relation t */ -static sql_exp * exp_push_down(mvc *sql, sql_exp *e, sql_rel *f, sql_rel *t); +static sql_exp * _exp_push_down(mvc *sql, sql_exp *e, sql_rel *f, sql_rel *t); static list * exps_push_down(mvc *sql, list *exps, sql_rel *f, sql_rel *t) @@ -1025,7 +1025,7 @@ for(n = exps->h; n; n=n->next) { sql_exp *arg = n->data; - arg = exp_push_down(sql, arg, f, t); + arg = _exp_push_down(sql, arg, f, t); if (!arg) return NULL; append(nl, arg); @@ -1034,25 +1034,19 @@ } static sql_exp * -exp_push_down(mvc *sql, sql_exp *e, sql_rel *f, sql_rel *t) +_exp_push_down(mvc *sql, sql_exp *e, sql_rel *f, sql_rel *t) { int flag = e->flag; sql_exp *ne = NULL, *l, *r, *r2; - if (is_join(f->op) || is_select(f->op)) { - if (f->l && (ne = exp_push_down(sql, e, f->l, t)) != NULL) - return ne; - if (f->r && (ne = exp_push_down(sql, e, f->r, t)) != NULL) - return ne; - } switch(e->type) { case e_column: if (e->l) { - ne = exps_bind_column2(f->exps, e->l, e->r); + ne = rel_bind_column2(sql, f, e->l, e->r, 0); /* if relation name matches expressions relation name, find column based on column name alone */ } if (!ne && !e->l) - ne = exps_bind_column(f->exps, e->r, NULL); + ne = rel_bind_column(sql, f, e->r, 0); if (!ne) return NULL; e = NULL; @@ -1081,10 +1075,10 @@ return NULL; return exp_or(sql->sa, l, r); } else { - l = exp_push_down(sql, e->l, f, t); - r = exp_push_down(sql, e->r, f, t); + l = _exp_push_down(sql, e->l, f, t); + r = _exp_push_down(sql, e->r, f, t); if (e->f) { - r2 = exp_push_down(sql, e->f, f, t); + r2 = _exp_push_down(sql, e->f, f, t); if (l && r && r2) return exp_compare2(sql->sa, l, r, r2, e->flag); } else if (l && r) { @@ -1093,7 +1087,7 @@ } return NULL; case e_convert: - l = exp_push_down(sql, e->l, f, t); + l = _exp_push_down(sql, e->l, f, t); if (l) return exp_convert(sql->sa, l, exp_fromtype(e), exp_totype(e)); return NULL; @@ -1119,6 +1113,13 @@ return NULL; } +static sql_exp * +exp_push_down(mvc *sql, sql_exp *e, sql_rel *f, sql_rel *t) +{ + return _exp_push_down(sql, e, f, t); +} + + /* some projections results are order dependend (row_number etc) */ static int project_unsafe(sql_rel *rel) @@ -2067,7 +2068,7 @@ rel->l = NULL; rel_destroy(rel); (*changes)++; - return r; + return rel_push_select_down(changes, sql, r); } /* * Push select through semi/anti join @@ -3806,6 +3807,51 @@ return rel; } +static sql_rel * +rewrite_topdown(mvc *sql, sql_rel *rel, rewrite_fptr rewriter, int *has_changes) +{ + if (!rel) + return rel; + + if (!rel_is_ref(rel)) + rel = rewriter(has_changes, sql, rel); + switch (rel->op) { + case op_basetable: + case op_table: + break; + case op_join: + case op_left: + case op_right: + case op_full: + + case op_semi: + case op_anti: + + case op_union: + case op_inter: + case op_except: + rel->l = rewrite_topdown(sql, rel->l, rewriter, has_changes); + rel->r = rewrite_topdown(sql, rel->r, rewriter, has_changes); + break; + case op_project: + case op_select: + case op_groupby: + case op_topn: + rel->l = rewrite_topdown(sql, rel->l, rewriter, has_changes); + break; + case op_ddl: + rel->l = rewrite_topdown(sql, rel->l, rewriter, has_changes); + if (rel->r) + rel->r = rewrite_topdown(sql, rel->r, rewriter, has_changes); + break; + case op_insert: + case op_update: + case op_delete: + rel->r = rewrite_topdown(sql, rel->r, rewriter, has_changes); + break; + } + return rel; +} sql_rel * rel_optimizer(mvc *sql, sql_rel *rel) @@ -3871,26 +3917,26 @@ rel = rewrite(sql, rel, &rel_rewrite_semijoin, &changes); if (gp.cnt[op_select]) - rel = rewrite(sql, rel, &rel_push_select_down, &changes); + rel = rewrite_topdown(sql, rel, &rel_push_select_down, &changes); if (gp.cnt[op_select]) rel = rewrite(sql, rel, &rel_remove_empty_select, &e_changes); if (gp.cnt[op_select] && gp.cnt[op_join]) { - rel = rewrite(sql, rel, &rel_push_select_down_join, &changes); + rel = rewrite_topdown(sql, rel, &rel_push_select_down_join, &changes); rel = rewrite(sql, rel, &rel_remove_empty_select, &e_changes); } if (gp.cnt[op_topn]) - rel = rewrite(sql, rel, &rel_push_topn_down, &changes); + rel = rewrite_topdown(sql, rel, &rel_push_topn_down, &changes); /* TODO push select up. Sounds bad, but isn't. In case of an join-idx we want the selection on the 'unique/primary (right hand side)' done before the (fake)-join and the selections on the foreign part done after. */ if (gp.cnt[op_join] && gp.cnt[op_groupby]) { - rel = rewrite(sql, rel, &rel_push_count_down, &changes); - rel = rewrite(sql, rel, &rel_push_join_down, &changes); + rel = rewrite_topdown(sql, rel, &rel_push_count_down, &changes); + rel = rewrite_topdown(sql, rel, &rel_push_join_down, &changes); } if (gp.cnt[op_groupby]) { diff --git a/sql/test/BugTracker-2011/Tests/All b/sql/test/BugTracker-2011/Tests/All --- a/sql/test/BugTracker-2011/Tests/All +++ b/sql/test/BugTracker-2011/Tests/All @@ -10,4 +10,5 @@ groupby_primary_key.Bug-2807 merge_range_exp.Bug-2806 count-count-distinct.Bug-2808 +crash_in_push_exp_down.Bug-2811 subquery_in_from_clause.Bug-2812 _______________________________________________ Checkin-list mailing list Checkin-list@monetdb.org http://mail.monetdb.org/mailman/listinfo/checkin-list