Changeset: 4c2f4c5c4584 for MonetDB
URL: https://dev.monetdb.org/hg/MonetDB?cmd=changeset;node=4c2f4c5c4584
Modified Files:
sql/server/rel_select.c
Branch: default
Log Message:
fixed handling of multiple window and groupby results
diffs (truncated from 326 to 300 lines):
diff --git a/sql/server/rel_select.c b/sql/server/rel_select.c
--- a/sql/server/rel_select.c
+++ b/sql/server/rel_select.c
@@ -3588,15 +3588,83 @@ rel_nop(mvc *sql, sql_rel **rel, symbol
}
+static void
+rel_intermediates_add_exp(mvc *sql, sql_rel *p, sql_rel *op, sql_exp *in)
+{
+ while(op && p != op) {
+ sql_rel *pp = op;
+
+ while(pp->l && pp->l != p)
+ pp = pp->l;
+ if (pp && pp->l == p) {
+ assert(pp->op == op_project);
+ in = exp_column(sql->sa, exp_relname(in), exp_name(in),
exp_subtype(in), exp_card(in), has_nil(in), is_intern(in));
+ in = rel_project_add_exp(sql, pp, in);
+ }
+ p = pp;
+ }
+}
+
static sql_exp *
_rel_aggr(mvc *sql, sql_rel **rel, int distinct, sql_schema *s, char *aname,
dnode *args, int f)
{
exp_kind ek = {type_value, card_column, FALSE};
sql_subaggr *a = NULL;
- int no_nil = 0;
- sql_rel *groupby = *rel, *gr, *project = NULL, *iproject = NULL, *r =
(groupby)?groupby->l:NULL;
+ int no_nil = 0, group = 0;
+ sql_rel *groupby = *rel, *sel = NULL, *gr, *og = NULL, *r =
(groupby)?groupby->l:NULL;
list *exps = NULL;
+ /* find having select */
+ if (groupby && groupby->l && !is_processed(groupby) &&
is_sql_having(f)) {
+ sql_rel *gl = groupby->l;
+
+ og = groupby;
+ while(groupby->l && !is_processed(groupby)) {
+ gl = groupby->l;
+ if (is_select(gl->op))
+ break;
+ groupby = gl;
+ }
+ if (gl && is_select(gl->op)) {
+ group = 1;
+ sel = groupby = gl;
+ /* At the end we switch back to the old projection
relation og.
+ * During the partitioning and ordering we add the
expressions to the intermediate relations. */
+ }
+ if (!group)
+ groupby = og;
+
+ if (sel && sel->l)
+ groupby = sel->l;
+
+ if (groupby && groupby->op == op_project && groupby->l)
+ r = groupby->l;
+
+ if (r && r->op == op_groupby)
+ groupby = r;
+ }
+
+ /* find groupby */
+ if (groupby && groupby->l && !is_processed(groupby)) {
+ sql_rel *gl = groupby->l;
+
+ og = groupby;
+ while(groupby->l && !is_processed(groupby)) {
+ gl = groupby->l;
+ if (gl->op == op_groupby)
+ break;
+ groupby = gl;
+ }
+ if (gl && gl->op == op_groupby) {
+ group = 1;
+ groupby = gl;
+ /* At the end we switch back to the old projection
relation og.
+ * During the partitioning and ordering we add the
expressions to the intermediate relations. */
+ }
+ if (!group)
+ groupby = og;
+ }
+
if (!groupby) {
char *uaname = GDKmalloc(strlen(aname) + 1);
sql_exp *e = sql_error(sql, 02, SQLSTATE(42000) "%s: missing
group by",
@@ -3614,32 +3682,20 @@ static sql_exp *
return e;
}
- if (is_sql_having(f) && is_select(groupby->op))
- groupby = groupby->l;
-
- if (groupby->l && groupby->op == op_project) {
- sql_rel *r = groupby->l;
-
- if (!is_processed(r) && is_sql_sel(f) && r->op == op_project) {
- project = r;
- r = r->l;
- }
-
- if (is_sql_having(f) || (r->op == op_groupby &&
is_sql_partitionby(f)))
- project = groupby;
- if (is_sql_having(f) && r->op == op_select && r->l)
- r = r->l;
- if (is_sql_having(f) && r->op == op_project && r->l) {
- iproject = r;
- r = r->l;
- }
-
- if (r->op == op_groupby)
- groupby = r;
- }
-
- if (groupby->op != op_groupby) /* implicit groupby */
- *rel = rel_project2groupby(sql, groupby);
+ if (groupby->op != op_groupby) { /* implicit groupby */
+ sql_rel *ng = rel_project2groupby(sql, groupby);
+
+ if (*rel == groupby) {
+ *rel = ng;
+ } else {
+ sql_rel *l = *rel;
+ while(l->l && l->l != groupby) {
+ l = l->l;
+ }
+ if (l->l && l->l == groupby)
+ l->l = ng;
+ }
+ }
if (!*rel)
return NULL;
@@ -3654,6 +3710,7 @@ static sql_exp *
if (!args->data.sym) { /* count(*) case */
sql_exp *e;
+ sql_rel *l;
if (strcmp(aname, "count") != 0) {
char *uaname = GDKmalloc(strlen(aname) + 1);
@@ -3667,15 +3724,21 @@ static sql_exp *
e = exp_aggr(sql->sa, NULL, a, distinct, 0, groupby->card, 0);
if (*rel == groupby && is_sql_sel(f)) /* selection */
return e;
- if (!project)
- return rel_groupby_add_aggr(sql, groupby, e);
+
e = rel_groupby_add_aggr(sql, groupby, e);
- if (iproject) {
- e = rel_project_add_exp(sql, iproject, e);
- e = exp_column(sql->sa, exp_relname(e), exp_name(e),
exp_subtype(e), exp_card(e), has_nil(e), is_intern(e));
- }
- e = rel_project_add_exp(sql, project, e);
- e = exp_column(sql->sa, exp_relname(e), exp_name(e),
exp_subtype(e), exp_card(e), has_nil(e), is_intern(e));
+ if (!group)
+ return e;
+
+ if (og)
+ l = og->l;
+ if (l && is_sql_sel(f))
+ rel_intermediates_add_exp(sql, groupby, l, e);
+ else if (sel) {
+ rel_intermediates_add_exp(sql, groupby, sel->l, e);
+ if (sel != *rel)
+ rel_intermediates_add_exp(sql, sel, *rel, e);
+ } else
+ rel_intermediates_add_exp(sql, groupby, *rel, e);
return e;
}
@@ -3807,16 +3870,21 @@ static sql_exp *
sql_exp *e = exp_aggr(sql->sa, exps, a, distinct, no_nil,
groupby->card, have_nil(exps));
if (*rel != groupby || !is_sql_sel(f)) { /* selection */
+ sql_rel *l;
+
e = rel_groupby_add_aggr(sql, groupby, e);
- if (!e || !project)
+ if (!group)
return e;
- if (iproject) {
- e = rel_project_add_exp(sql, iproject, e);
- e = exp_column(sql->sa, exp_relname(e),
exp_name(e), exp_subtype(e), exp_card(e), has_nil(e), is_intern(e));
- }
- e = rel_project_add_exp(sql, project, e);
- if (iproject || !is_sql_sel(f))
- e = exp_column(sql->sa, exp_relname(e),
exp_name(e), exp_subtype(e), exp_card(e), has_nil(e), is_intern(e));
+ if (og)
+ l = og->l;
+ if (l && is_sql_sel(f))
+ rel_intermediates_add_exp(sql, groupby, l, e);
+ else if (sel) {
+ rel_intermediates_add_exp(sql, groupby, sel->l,
e);
+ if (sel != *rel)
+ rel_intermediates_add_exp(sql, sel,
*rel, e);
+ } else
+ rel_intermediates_add_exp(sql, groupby, *rel,
e);
}
return e;
} else {
@@ -4703,23 +4771,6 @@ get_window_clauses(mvc *sql, char* ident
return window_specification; //return something to say there were no
errors
}
-static void
-rel_intermediates_add_exp(mvc *sql, sql_rel *p, sql_rel *op, sql_exp *in)
-{
- while(op && p != op) {
- sql_rel *pp = op;
-
- while(pp->l && pp->l != p)
- pp = pp->l;
- if (pp && pp->l == p) {
- assert(pp->op == op_project);
- in = exp_column(sql->sa, exp_relname(in), exp_name(in),
exp_subtype(in), exp_card(in), has_nil(in), is_intern(in));
- in = rel_project_add_exp(sql, pp, in);
- }
- p = pp;
- }
-}
-
static sql_exp*
opt_groupby_add_exp(mvc *sql, sql_rel *p, sql_rel *pp, sql_exp *in)
{
@@ -4852,7 +4903,7 @@ rel_rankop(mvc *sql, sql_rel **rel, symb
if (p && is_processed(p) && p->op == op_groupby)
group = 1;
- if (p->l && !is_processed(p)) { /* ADD check for processed ! */
+ if (p->l && !is_processed(p)) {
sql_rel *pl = p->l;
op = p;
@@ -4871,8 +4922,10 @@ rel_rankop(mvc *sql, sql_rel **rel, symb
if (!group)
p = op;
}
- if (!group && list_length(r->exps))
+ if (!group && list_length(r->exps)) {
p = pp = rel_project(sql->sa, p, rel_projections(sql, p, NULL,
1, 1));
+ reset_processed(p);
+ }
if (pp && pp->op == op_groupby)
nf = sql_partitionby;
@@ -4884,6 +4937,7 @@ rel_rankop(mvc *sql, sql_rel **rel, symb
sql->session->status = 0;
sql->errstr[0] = '\0';
p = pp = rel_project(sql->sa, p, sa_list(sql->sa));
+ reset_processed(p);
gbe = rel_group_by(sql, &p, partition_by_clause, NULL
/* cannot use (selection) column references, as this result is a selection
column */, f);
}
if (!gbe)
@@ -4894,6 +4948,9 @@ rel_rankop(mvc *sql, sql_rel **rel, symb
pp = p;
p = rel_project(sql->sa, npp, rel_projections(sql, npp,
NULL, 1, 0));
+ reset_processed(p);
+ if (group && op)
+ op = p;
}
for(n = gbe->h ; n ; n = n->next) {
@@ -4912,6 +4969,7 @@ rel_rankop(mvc *sql, sql_rel **rel, symb
sql->session->status = 0;
sql->errstr[0] = '\0';
p = pp = rel_project(sql->sa, p, sa_list(sql->sa));
+ reset_processed(p);
obe = rel_order_by(sql, &p, order_by_clause, f);
}
if (!obe)
@@ -4922,6 +4980,9 @@ rel_rankop(mvc *sql, sql_rel **rel, symb
pp = p;
p = rel_project(sql->sa, npp, rel_projections(sql, npp,
NULL, 1, 0));
+ reset_processed(p);
+ if (group && op)
+ op = p;
}
for(n = obe->h ; n ; n = n->next) {
@@ -4971,7 +5032,9 @@ rel_rankop(mvc *sql, sql_rel **rel, symb
if (!lr || !is_project(lr->op)) {
p = pp = rel_project(sql->sa, p,
rel_projections(sql, p, NULL, 1, 0));
+ reset_processed(p);
lr = p->l;
+ assert(!op);
}
in = lr->exps->h->data;
in = exp_column(sql->sa, exp_relname(in), exp_name(in),
exp_subtype(in), exp_card(in), has_nil(in), is_intern(in));
@@ -5019,7 +5082,9 @@ rel_rankop(mvc *sql, sql_rel **rel, symb
if (!lr || !is_project(lr->op)) {
p = pp = rel_project(sql->sa, p,
rel_projections(sql, p, NULL, 1, 0));
+ reset_processed(p);
_______________________________________________
checkin-list mailing list
[email protected]
https://www.monetdb.org/mailman/listinfo/checkin-list