Changeset: 6707bb552537 for MonetDB URL: https://dev.monetdb.org/hg/MonetDB/rev/6707bb552537 Modified Files: sql/server/rel_optimize_proj.c sql/test/miscellaneous/Tests/simple_plans.test Branch: default Log Message:
Another corner case. If the underlying projection has to be sorted/distinct/multiple refs, then the new optimization cannot be done diffs (93 lines): diff --git a/sql/server/rel_optimize_proj.c b/sql/server/rel_optimize_proj.c --- a/sql/server/rel_optimize_proj.c +++ b/sql/server/rel_optimize_proj.c @@ -1444,7 +1444,25 @@ rel_simplify_sum(visitor *v, sql_rel *re if ((!e1ok && e2ok) || (e1ok && !e2ok)) { sql_exp *ocol = e1ok ? e2 : e1, *constant = e1ok ? e1 : e2, *mul, *colref, *naggr, *newop, *col = ocol, *match; - bool add_col = true; + bool add_col = true, prepend = false; + + /* if 'col' is a projection from the under relation, then use it */ + while (is_numeric_upcast(col)) + col = col->l; + if (col->type == e_column) { + sql_exp *colf = exps_find_exp(l->exps, col); + + /* col is already found in the inner relation. Also look for a new reference for col, eg sql_add(col, 1), 1 as col */ + if (colf && list_position(l->exps, colf) < list_position(l->exps, oexp)) { + add_col = false; + } else if (!colf && is_simple_project(l->op) && list_empty(l->r) && !rel_is_ref(l) && !need_distinct(l)) { + prepend = true; + add_col = false; + } else if (!colf && (is_simple_project(l->op) || is_groupby(l->op))) { + /* on these scenarios the new column expression will be ordered/(grouped for distinct) or create potential ambiguity (multiple ref), so skip */ + continue; + } + } /* add count star */ count_star_exp = rel_groupby_add_count_star(v->sql, groupby, count_star_exp, &count_added); @@ -1457,20 +1475,6 @@ rel_simplify_sum(visitor *v, sql_rel *re if (!has_label(mul)) exp_label(v->sql->sa, mul, ++v->sql->label); - /* if 'col' is a projection from the under relation, then use it */ - while (is_numeric_upcast(col)) - col = col->l; - if (col->type == e_column) { - sql_exp *colf = exps_find_exp(l->exps, col); - - /* col is already found in the inner relation. Also look for a new reference for col, eg sql_add(col, 1), 1 as col */ - if (colf && list_position(l->exps, colf) < list_position(l->exps, oexp)) { - add_col = false; - } else if (!colf && is_simple_project(l->op) && list_empty(l->r) && !rel_is_ref(l) && !need_distinct(l)) { - list_prepend(l->exps, exp_ref(v->sql, col)); - add_col = false; - } - } colref = exp_ref(v->sql, ocol); if (add_col) /* if 'col' will be added, then make sure it has an unique label */ exp_label(v->sql->sa, colref, ++v->sql->label); @@ -1505,6 +1509,10 @@ rel_simplify_sum(visitor *v, sql_rel *re continue; } + /* a column reference can be prepended to the inner relation, add it after all the check type calls succeed */ + if (prepend) + list_prepend(l->exps, exp_ref(v->sql, col)); + /* the new generate function calls are valid, update relations */ /* we need a new relation for the multiplication and addition/subtraction */ if (!upper) { @@ -1654,6 +1662,9 @@ rel_simplify_groupby_columns(visitor *v, sql_exp *ne = exp_ref(v->sql, col); list_prepend(l->exps, ne); n->data = exp_ref(v->sql, ne); + } else if (!colf && (is_simple_project(l->op) || is_groupby(l->op))) { + /* on these scenarios the new column expression will be ordered/(grouped for distinct) or create potential ambiguity (multiple ref), so skip */ + continue; } else { sql_exp *ne = exp_ref(v->sql, col); @@ -1713,7 +1724,7 @@ rel_groupby_cse(visitor *v, sql_rel *rel if (!needed) return rel; - if (!is_simple_project(l->op) || !list_empty(l->r) || rel_is_ref(l) || need_distinct(l) || is_single(l)) + if (!is_simple_project(l->op) || !list_empty(l->r) || rel_is_ref(l) || need_distinct(l)) rel->l = l = rel_project(v->sql->sa, l, rel_projections(v->sql, l, NULL, 1, 1)); for (node *n=((list*)rel->r)->h; n ; ) { diff --git a/sql/test/miscellaneous/Tests/simple_plans.test b/sql/test/miscellaneous/Tests/simple_plans.test --- a/sql/test/miscellaneous/Tests/simple_plans.test +++ b/sql/test/miscellaneous/Tests/simple_plans.test @@ -701,3 +701,8 @@ SELECT sum(CASE x.x WHEN 1 THEN 1 END + ---- 3 3 + +query I nosort +SELECT sum(y.y) FROM (SELECT DISTINCT x + 1 FROM (SELECT 1) x(x)) y(y) +---- +2 _______________________________________________ checkin-list mailing list -- checkin-list@monetdb.org To unsubscribe send an email to checkin-list-le...@monetdb.org