Changeset: b50e8e2d6f02 for MonetDB URL: https://dev.monetdb.org/hg/MonetDB/rev/b50e8e2d6f02 Modified Files: sql/server/rel_optimizer.c sql/server/rel_unnest.c sql/test/miscellaneous/Tests/simple_plans.test Branch: antipush Log Message:
Merged with default diffs (truncated from 365 to 300 lines): diff --git a/sql/backends/monet5/sql_statement.c b/sql/backends/monet5/sql_statement.c --- a/sql/backends/monet5/sql_statement.c +++ b/sql/backends/monet5/sql_statement.c @@ -3410,6 +3410,8 @@ stmt_func(backend *be, stmt *ops, const if ((p = find_prop(rel->p, PROP_REMOTE))) rel->p = prop_remove(rel->p, p); + /* sql_processrelation may split projections, so make sure the topmost relation only contains references */ + rel = rel_project(be->mvc->sa, rel, rel_projections(be->mvc, rel, NULL, 1, 1)); if (!(rel = sql_processrelation(be->mvc, rel, 1, 1))) return NULL; if (p) { 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 @@ -1594,51 +1594,49 @@ rel_push_count_down(visitor *v, sql_rel r && !r->exps && r->op == op_join && !(rel_is_ref(r)) && /* currently only single count aggregation is handled, no other projects or aggregation */ list_length(rel->exps) == 1 && exp_aggr_is_count(rel->exps->h->data)) { - sql_exp *nce, *oce; - sql_rel *gbl, *gbr; /* Group By */ - sql_rel *cp; /* Cross Product */ - sql_subfunc *mult; - list *args, *types; + sql_exp *nce, *oce, *cnt1 = NULL, *cnt2 = NULL; + sql_rel *gbl = NULL, *gbr = NULL; /* Group By */ + sql_rel *cp = NULL; /* Cross Product */ sql_rel *srel; oce = rel->exps->h->data; if (oce->l) /* we only handle COUNT(*) */ return rel; - args = new_exp_list(v->sql->sa); srel = r->l; { sql_subfunc *cf = sql_bind_func(v->sql, "sys", "count", sql_bind_localtype("void"), NULL, F_AGGR); - sql_exp *cnt, *e = exp_aggr(v->sql->sa, NULL, cf, need_distinct(oce), need_no_nil(oce), oce->card, 0); + sql_exp *e = exp_aggr(v->sql->sa, NULL, cf, need_distinct(oce), need_no_nil(oce), oce->card, 0); exp_label(v->sql->sa, e, ++v->sql->label); - cnt = exp_ref(v->sql, e); + cnt1 = exp_ref(v->sql, e); gbl = rel_groupby(v->sql, rel_dup(srel), NULL); set_processed(gbl); rel_groupby_add_aggr(v->sql, gbl, e); - append(args, cnt); } srel = r->r; { sql_subfunc *cf = sql_bind_func(v->sql, "sys", "count", sql_bind_localtype("void"), NULL, F_AGGR); - sql_exp *cnt, *e = exp_aggr(v->sql->sa, NULL, cf, need_distinct(oce), need_no_nil(oce), oce->card, 0); + sql_exp *e = exp_aggr(v->sql->sa, NULL, cf, need_distinct(oce), need_no_nil(oce), oce->card, 0); exp_label(v->sql->sa, e, ++v->sql->label); - cnt = exp_ref(v->sql, e); + cnt2 = exp_ref(v->sql, e); gbr = rel_groupby(v->sql, rel_dup(srel), NULL); set_processed(gbr); rel_groupby_add_aggr(v->sql, gbr, e); - append(args, cnt); } cp = rel_crossproduct(v->sql->sa, gbl, gbr, op_join); - types = sa_list(v->sql->sa); - for(node *n = args->h; n; n = n->next) - list_append(types, exp_subtype(n->data)); - mult = sql_bind_func_(v->sql, "sys", "sql_mul", types, F_FUNC); - nce = exp_op(v->sql->sa, args, mult); + if (!(nce = rel_binop_(v->sql, NULL, cnt1, cnt2, "sys", "sql_mul", card_value))) { + v->sql->session->status = 0; + v->sql->errstr[0] = '\0'; + return rel; /* error, fallback to original expression */ + } + /* because of remote plans, make sure "sql_mul" returns bigint. The cardinality is atomic, so no major performance penalty */ + if (subtype_cmp(exp_subtype(oce), exp_subtype(nce)) != 0) + nce = exp_convert(v->sql->sa, nce, exp_subtype(nce), exp_subtype(oce)); if (exp_name(oce)) exp_prop_alias(v->sql->sa, nce, oce); diff --git a/sql/server/rel_unnest.c b/sql/server/rel_unnest.c --- a/sql/server/rel_unnest.c +++ b/sql/server/rel_unnest.c @@ -3463,6 +3463,18 @@ rewrite_groupings(visitor *v, sql_rel *r if (list_empty(exps)) append(exps, exp_atom_bool(v->sql->sa, 1)); /* protection against empty projections */ nrel->exps = exps; + if (!list_empty(rel->r) && !list_empty(nrel->r)) { /* aliases on grouping columns, ugh */ + for (node *n = ((list*)nrel->r)->h ; n ; n = n->next) { + sql_exp *e = n->data; + const char *rname = exp_relname(e), *cname = exp_name(e); + if (rname && cname) { + n->data = exp_copy(v->sql, exps_bind_column2(rel->r, rname, cname, NULL)); + } else if (cname) { + n->data = exp_copy(v->sql, exps_bind_column(rel->r, cname, NULL, NULL, 1)); + } + } + list_hash_clear(nrel->r); + } set_processed(nrel); if (list_empty(pexps)) append(pexps, exp_atom_bool(v->sql->sa, 1)); /* protection against empty projections */ diff --git a/sql/test/BugTracker-2017/Tests/side-effect.Bug-6397.test b/sql/test/BugTracker-2017/Tests/side-effect.Bug-6397.test --- a/sql/test/BugTracker-2017/Tests/side-effect.Bug-6397.test +++ b/sql/test/BugTracker-2017/Tests/side-effect.Bug-6397.test @@ -32,6 +32,8 @@ bat.pack 5 bat.single 2 +batcalc.lng +1 querylog.define 1 sql.my_generate_series diff --git a/sql/test/BugTracker-2021/Tests/All b/sql/test/BugTracker-2021/Tests/All --- a/sql/test/BugTracker-2021/Tests/All +++ b/sql/test/BugTracker-2021/Tests/All @@ -30,3 +30,4 @@ replace-transaction-conflict.Bug-7168 merge-table-join.Bug-7172 truncate-restart.Bug-7173 remote-table-large.Bug-7178 +grouping-sets-aliases.Bug-7185 diff --git a/sql/test/BugTracker-2021/Tests/grouping-sets-aliases.Bug-7185.test b/sql/test/BugTracker-2021/Tests/grouping-sets-aliases.Bug-7185.test new file mode 100644 --- /dev/null +++ b/sql/test/BugTracker-2021/Tests/grouping-sets-aliases.Bug-7185.test @@ -0,0 +1,198 @@ +statement ok +start transaction + +statement ok +create table students (course TEXT, type TEXT) + +statement ok rowcount 7 +insert into students (course, type) values ('CS', 'Bachelor'), ('CS', 'Bachelor'), ('CS', 'PhD'), ('Math', 'Masters'), ('CS', NULL), ('CS', NULL), ('Math', NULL) + +query TT nosort +select course, type from students group by grouping sets((course, type), (type)) order by 1, 2 +---- +NULL +NULL +NULL +Bachelor +NULL +Masters +NULL +PhD +CS +NULL +CS +Bachelor +CS +PhD +Math +NULL +Math +Masters + +query ITT nosort +select count(*), course, type from students group by grouping sets((course, type), (type)) order by 1, 2, 3 +---- +1 +NULL +Masters +1 +NULL +PhD +1 +CS +PhD +1 +Math +NULL +1 +Math +Masters +2 +NULL +Bachelor +2 +CS +NULL +2 +CS +Bachelor +3 +NULL +NULL + +query TITT nosort +select min(course), grouping(course), course, type from students group by grouping sets((course, type), (type)) order by 1, 2, 3, 4 +---- +CS +0 +CS +NULL +CS +0 +CS +Bachelor +CS +0 +CS +PhD +CS +1 +NULL +NULL +CS +1 +NULL +Bachelor +CS +1 +NULL +PhD +Math +0 +Math +NULL +Math +0 +Math +Masters +Math +1 +NULL +Masters + +query TT nosort +select course AS crs, type AS tp from students group by grouping sets((crs, tp), (tp)) order by 1, 2 +---- +NULL +NULL +NULL +Bachelor +NULL +Masters +NULL +PhD +CS +NULL +CS +Bachelor +CS +PhD +Math +NULL +Math +Masters + +query ITT nosort +select count(*), course AS crs, type AS tp from students group by grouping sets((crs, tp), (tp)) order by 1, 2, 3 +---- +1 +NULL +Masters +1 +NULL +PhD +1 +CS +PhD +1 +Math +NULL +1 +Math +Masters +2 +NULL +Bachelor +2 +CS +NULL +2 +CS +Bachelor +3 +NULL +NULL + +query TITT nosort +select min(course), grouping(course), course AS crs, type AS tp from students group by grouping sets((crs, tp), (tp)) order by 1, 2, 3, 4 +---- +CS +0 +CS +NULL +CS +0 +CS +Bachelor +CS +0 +CS +PhD +CS _______________________________________________ checkin-list mailing list checkin-list@monetdb.org https://www.monetdb.org/mailman/listinfo/checkin-list