Changeset: ce3dc71b7633 for MonetDB URL: https://dev.monetdb.org/hg/MonetDB?cmd=changeset;node=ce3dc71b7633 Modified Files: sql/server/rel_exp.c sql/server/rel_exp.h sql/server/rel_optimizer.c Branch: Jun2020 Log Message:
merged diffs (160 lines): diff --git a/sql/server/rel_exp.c b/sql/server/rel_exp.c --- a/sql/server/rel_exp.c +++ b/sql/server/rel_exp.c @@ -1525,7 +1525,7 @@ exp_is_eqjoin(sql_exp *e) } static sql_exp * -rel_find_exp_( sql_rel *rel, sql_exp *e) +rel_find_exp_and_corresponding_rel_( sql_rel *rel, sql_exp *e, sql_rel **res) { sql_exp *ne = NULL; @@ -1540,9 +1540,11 @@ rel_find_exp_( sql_rel *rel, sql_exp *e) ne = exps_bind_column(rel->exps, e->r, NULL, 1); } } + if (ne && res) + *res = rel; return ne; case e_convert: - return rel_find_exp_(rel, e->l); + return rel_find_exp_and_corresponding_rel_(rel, e->l, res); case e_aggr: case e_func: if (e->l) { @@ -1551,7 +1553,7 @@ rel_find_exp_( sql_rel *rel, sql_exp *e) ne = n->data; while (ne != NULL && n != NULL) { - ne = rel_find_exp_(rel, n->data); + ne = rel_find_exp_and_corresponding_rel_(rel, n->data, res); n = n->next; } return ne; @@ -1568,7 +1570,7 @@ rel_find_exp_( sql_rel *rel, sql_exp *e) ne = n->data; while (ne != NULL && n != NULL) { - ne = rel_find_exp_(rel, n->data); + ne = rel_find_exp_and_corresponding_rel_(rel, n->data, res); n = n->next; } return ne; @@ -1579,9 +1581,9 @@ rel_find_exp_( sql_rel *rel, sql_exp *e) } sql_exp * -rel_find_exp( sql_rel *rel, sql_exp *e) +rel_find_exp_and_corresponding_rel(sql_rel *rel, sql_exp *e, sql_rel **res) { - sql_exp *ne = rel_find_exp_(rel, e); + sql_exp *ne = rel_find_exp_and_corresponding_rel_(rel, e, res); if (rel && !ne) { switch(rel->op) { @@ -1589,38 +1591,53 @@ rel_find_exp( sql_rel *rel, sql_exp *e) case op_right: case op_full: case op_join: - ne = rel_find_exp(rel->l, e); + ne = rel_find_exp_and_corresponding_rel(rel->l, e, res); if (!ne) - ne = rel_find_exp(rel->r, e); + ne = rel_find_exp_and_corresponding_rel(rel->r, e, res); break; case op_table: if (rel->exps && e->type == e_column && e->l && exps_bind_column2(rel->exps, e->l, e->r)) ne = e; + if (ne && res) + *res = rel; break; case op_union: case op_except: case op_inter: { if (rel->l) - ne = rel_find_exp(rel->l, e); - else if (rel->exps && e->l) + ne = rel_find_exp_and_corresponding_rel(rel->l, e, res); + else if (rel->exps && e->l) { ne = exps_bind_column2(rel->exps, e->l, e->r); - else if (rel->exps) + if (ne && res) + *res = rel; + } else if (rel->exps) { ne = exps_bind_column(rel->exps, e->r, NULL, 1); + if (ne && res) + *res = rel; + } } break; case op_basetable: if (rel->exps && e->type == e_column && e->l) ne = exps_bind_column2(rel->exps, e->l, e->r); + if (ne && res) + *res = rel; break; default: if (!is_project(rel->op) && rel->l) - ne = rel_find_exp(rel->l, e); + ne = rel_find_exp_and_corresponding_rel(rel->l, e, res); } } return ne; } +sql_exp * +rel_find_exp( sql_rel *rel, sql_exp *e) +{ + return rel_find_exp_and_corresponding_rel(rel, e, NULL); +} + int exp_is_true(mvc *sql, sql_exp *e) { diff --git a/sql/server/rel_exp.h b/sql/server/rel_exp.h --- a/sql/server/rel_exp.h +++ b/sql/server/rel_exp.h @@ -123,6 +123,7 @@ extern unsigned int exp_card(sql_exp *e) extern const char *exp_find_rel_name(sql_exp *e); extern sql_exp *rel_find_exp( sql_rel *rel, sql_exp *e); +extern sql_exp *rel_find_exp_and_corresponding_rel(sql_rel *rel, sql_exp *e, sql_rel **res); extern int exp_cmp( sql_exp *e1, sql_exp *e2); extern int exp_equal( sql_exp *e1, sql_exp *e2); 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 @@ -5454,11 +5454,27 @@ find_simple_projection_for_join2semi(sql return true; /* a single group by column in the projection list from a group by relation is guaranteed to be unique, but not an aggregate */ if (e->type == e_column) { + sql_rel *res = NULL; + sql_exp *found = NULL; + if (is_groupby(rel->op) || find_prop(e->p, PROP_HASHCOL)) return true; - sql_exp *found = rel_find_exp(rel->l, e); /* grouping column on inner relation */ - if (found && ((found->type == e_column && found->card <= CARD_AGGR) || find_prop(found->p, PROP_HASHCOL))) - return true; + + found = rel_find_exp_and_corresponding_rel(rel->l, e, &res); /* grouping column on inner relation */ + if (found) { + if (find_prop(found->p, PROP_HASHCOL)) /* primary key always unique */ + return true; + if (found->type == e_column && found->card <= CARD_AGGR) { + if (!is_groupby(res->op) && list_length(res->exps) != 1) + return false; + for (node *n = res->exps->h ; n ; n = n->next) { /* must be the single column in the group by expression list */ + sql_exp *e = n->data; + if (e != found && e->type == e_column) + return false; + } + return true; + } + } } } return false; _______________________________________________ checkin-list mailing list checkin-list@monetdb.org https://www.monetdb.org/mailman/listinfo/checkin-list