Changeset: a3936e6b1061 for MonetDB
URL: https://dev.monetdb.org/hg/MonetDB/rev/a3936e6b1061
Modified Files:
sql/backends/monet5/rel_bin.c
sql/backends/monet5/sql_statement.c
sql/server/rel_optimize_sel.c
Branch: ordered-set-aggregates
Log Message:
use new groupedfirstn
diffs (236 lines):
diff --git a/sql/backends/monet5/rel_bin.c b/sql/backends/monet5/rel_bin.c
--- a/sql/backends/monet5/rel_bin.c
+++ b/sql/backends/monet5/rel_bin.c
@@ -4463,10 +4463,36 @@ rel2bin_project(backend *be, sql_rel *re
/* distinct, topn returns at least N (unique groups) */
int distinct = need_distinct(rel);
stmt *limit = NULL, *lpiv = NULL, *lgid = NULL;
-
- for (n=oexps->h; n; n = n->next) {
+ int last = list_length(oexps);
+
+ /* check for partition columns */
+ stmt *grp = NULL, *ext = NULL, *cnt = NULL;
+ for (n=oexps->h; n; n = n->next, last--) {
+ sql_exp *gbe = n->data;
+ bool last = (!n->next ||
!is_partitioning((sql_exp*)n->next->data));
+
+ if (!is_partitioning(gbe))
+ break;
+ /* create group by */
+ stmt *gbcol = exp_bin(be, gbe, sub, NULL, NULL, NULL,
NULL, NULL, 0, 0, 0);
+
+ if (!gbcol) {
+ assert(sql->session->status == -10); /* Stack
overflow errors shouldn't terminate the server */
+ return NULL;
+ }
+ if (!gbcol->nrcols)
+ gbcol = stmt_const(be,
bin_find_smallest_column(be, sub), gbcol);
+ stmt *groupby = stmt_group(be, gbcol, grp, ext, cnt,
last);
+ grp = stmt_result(be, groupby, 0);
+ ext = stmt_result(be, groupby, 1);
+ cnt = stmt_result(be, groupby, 2);
+ gbcol = stmt_alias(be, gbcol, gbe->alias.label,
exp_find_rel_name(gbe), exp_name(gbe));
+ }
+
+ if (grp)
+ lgid = grp;
+ for (; n; n = n->next) {
sql_exp *orderbycole = n->data;
- int last = (n->next == NULL);
stmt *orderbycolstmt = exp_bin(be, orderbycole, sub,
psub, NULL, NULL, NULL, NULL, 0, 0, 0);
@@ -4474,7 +4500,7 @@ rel2bin_project(backend *be, sql_rel *re
return NULL;
/* handle constants */
- if (orderbycolstmt->nrcols == 0 && !last) /* no need to
sort on constant */
+ if (orderbycolstmt->nrcols == 0 && n->next) /* no need
to sort on constant */
continue;
orderbycolstmt = column(be, orderbycolstmt);
if (!limit) { /* topn based on a single column */
@@ -4494,6 +4520,8 @@ rel2bin_project(backend *be, sql_rel *re
}
limit = lpiv;
+ if (limit)
+ limit = stmt_project(be, stmt_selectnonil(be, limit,
NULL), limit);
stmt *s;
for (n=pl->h ; n; n = n->next) {
stmt *os = n->data;
@@ -4813,8 +4841,9 @@ rel2bin_topn(backend *be, sql_rel *rel,
if (!l || !o)
return NULL;
+
sc = column(be, sc);
- limit = stmt_limit(be, sc /*stmt_alias(be, sc, 0, tname,
cname)*/, NULL, NULL, o, l, 0,0,0,0,0);
+ limit = stmt_limit(be, sc, NULL, NULL, o, l, 0,0,0,0,0);
for ( ; n; n = n->next) {
stmt *sc = n->data;
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
@@ -1207,13 +1207,14 @@ stmt_result(backend *be, stmt *s, int nr
stmt *
stmt_limit(backend *be, stmt *col, stmt *piv, stmt *gid, stmt *offset, stmt
*limit, int distinct, int dir, int nullslast, int last, int order)
{
+ int new = 1;
MalBlkPtr mb = be->mb;
InstrPtr q = NULL;
int l, p, g, c;
if (col == NULL || offset == NULL || limit == NULL || col->nr < 0 ||
offset->nr < 0 || limit->nr < 0)
goto bailout;
- if (piv && (piv->nr < 0 || gid->nr < 0))
+ if (piv && (piv->nr < 0 || (gid && gid->nr < 0)))
goto bailout;
c = (col) ? col->nr : 0;
@@ -1241,38 +1242,74 @@ stmt_limit(backend *be, stmt *col, stmt
c = k;
}
if (order) {
- int topn = 0;
-
- q = newStmt(mb, calcRef, plusRef);
- if (q == NULL)
- goto bailout;
- q = pushArgument(mb, q, offset->nr);
- q = pushArgument(mb, q, limit->nr);
- topn = getDestVar(q);
- pushInstruction(mb, q);
-
- q = newStmtArgs(mb, algebraRef, firstnRef, 9);
- if (q == NULL)
- goto bailout;
- if (!last) /* we need the groups for the next firstn */
- q = pushReturn(mb, q, newTmpVariable(mb, TYPE_any));
- q = pushArgument(mb, q, c);
- if (p)
- q = pushArgument(mb, q, p);
- else
- q = pushNilBat(mb, q);
- if (g)
- q = pushArgument(mb, q, g);
- else
- q = pushNilBat(mb, q);
- q = pushArgument(mb, q, topn);
- q = pushBit(mb, q, dir);
- q = pushBit(mb, q, nullslast);
- q = pushBit(mb, q, distinct != 0);
-
- l = getArg(q, 0);
- l = getDestVar(q);
- pushInstruction(mb, q);
+ if (new && piv) {
+ q = piv->q;
+ q = pushArgument(mb, q, c);
+ q = pushBit(mb, q, dir);
+ q = pushBit(mb, q, nullslast);
+ return piv;
+ } else if (new) {
+ int topn = 0;
+
+ q = newStmt(mb, calcRef, plusRef);
+ if (q == NULL)
+ goto bailout;
+ q = pushArgument(mb, q, offset->nr);
+ q = pushArgument(mb, q, limit->nr);
+ topn = getDestVar(q);
+ pushInstruction(mb, q);
+
+ q = newStmtArgs(mb, algebraRef, "groupedfirstn",
(last*3)+6);
+ if (q == NULL)
+ goto bailout;
+ q = pushArgument(mb, q, topn);
+ q = pushNilBat(mb, q); /* candidates */
+ if (g) /* grouped case
*/
+ q = pushArgument(mb, q, g);
+ else
+ q = pushNilBat(mb, q);
+
+ q = pushArgument(mb, q, c);
+ q = pushBit(mb, q, dir);
+ q = pushBit(mb, q, nullslast);
+
+ l = getArg(q, 0);
+ l = getDestVar(q);
+ pushInstruction(mb, q);
+ } else {
+ int topn = 0;
+
+ q = newStmt(mb, calcRef, plusRef);
+ if (q == NULL)
+ goto bailout;
+ q = pushArgument(mb, q, offset->nr);
+ q = pushArgument(mb, q, limit->nr);
+ topn = getDestVar(q);
+ pushInstruction(mb, q);
+
+ q = newStmtArgs(mb, algebraRef, firstnRef, 9);
+ if (q == NULL)
+ goto bailout;
+ if (!last) /* we need the groups for the next firstn */
+ q = pushReturn(mb, q, newTmpVariable(mb,
TYPE_any));
+ q = pushArgument(mb, q, c);
+ if (p)
+ q = pushArgument(mb, q, p);
+ else
+ q = pushNilBat(mb, q);
+ if (g)
+ q = pushArgument(mb, q, g);
+ else
+ q = pushNilBat(mb, q);
+ q = pushArgument(mb, q, topn);
+ q = pushBit(mb, q, dir);
+ q = pushBit(mb, q, nullslast);
+ q = pushBit(mb, q, distinct != 0);
+
+ l = getArg(q, 0);
+ l = getDestVar(q);
+ pushInstruction(mb, q);
+ }
} else {
int len;
diff --git a/sql/server/rel_optimize_sel.c b/sql/server/rel_optimize_sel.c
--- a/sql/server/rel_optimize_sel.c
+++ b/sql/server/rel_optimize_sel.c
@@ -3572,6 +3572,7 @@ get_partition_by_key_columns(allocator *
return NULL;
}
+/*
static bool
rank_exp_has_partition_key(sql_exp *e)
{
@@ -3588,6 +3589,7 @@ rank_exp_has_partition_key(sql_exp *e)
}
return false;
}
+*/
/*
* Checks if a filter column is also used as an aggregation key, so it can be
later safely pushed down.
@@ -3832,14 +3834,14 @@ rel_push_select_down(visitor *v, sql_rel
sql_subfunc *rankf =
ranke->f;
if (rankf->func->type
== F_ANALYTIC) { /* rank functions cannot have a frame */
// For now only
for rank/row_number without partition by
- if
(strcmp(rankf->func->base.name, "rank") == 0 && is_simple_project(pl->op) &&
pl->r &&
-
!rank_exp_has_partition_key(ranke)) {
+ if
(strcmp(rankf->func->base.name, "rank") == 0 && is_simple_project(pl->op) &&
pl->r /* &&
+
!rank_exp_has_partition_key(ranke)*/) {
r->l =
rel_topn(v->sql->sa, r->l, append(sa_list(v->sql->sa), e->r));
v->changes++;
break;
}
- if
(strcmp(rankf->func->base.name, "row_number") == 0 && list_empty(r->r) &&
!is_topn(pl->op) &&
-
!rank_exp_has_partition_key(ranke)) {
+ if
(strcmp(rankf->func->base.name, "row_number") == 0 && list_empty(r->r) &&
!is_topn(pl->op) /*&&
+
!rank_exp_has_partition_key(ranke)*/) {
r->l =
rel_topn(v->sql->sa, r->l, append(sa_list(v->sql->sa), e->r));
v->changes++;
break;
_______________________________________________
checkin-list mailing list -- [email protected]
To unsubscribe send an email to [email protected]