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
[email protected]
https://www.monetdb.org/mailman/listinfo/checkin-list