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]

Reply via email to