Changeset: f9f30e5adfdb for MonetDB
URL: https://dev.monetdb.org/hg/MonetDB?cmd=changeset;node=f9f30e5adfdb
Modified Files:
        sql/server/rel_exp.c
        sql/server/rel_exp.h
        sql/server/rel_rel.c
        sql/server/rel_rel.h
        sql/server/rel_select.c
        sql/server/rel_unnest.c
Branch: sq2
Log Message:

pass rank/window functions a normal functions + list (group by expressions's, 
order by expression's).
rewrite these into projection(s) in the rel_unnest.c file/phase


diffs (truncated from 514 to 300 lines):

diff --git a/sql/server/rel_exp.c b/sql/server/rel_exp.c
--- a/sql/server/rel_exp.c
+++ b/sql/server/rel_exp.c
@@ -232,6 +232,21 @@ exp_op( sql_allocator *sa, list *l, sql_
 }
 
 sql_exp * 
+exp_rank_op( sql_allocator *sa, list *l, list *gbe, list *obe, sql_subfunc *f )
+{
+       sql_exp *e = exp_create(sa, e_func);
+       if (e == NULL)
+               return NULL;
+       e->card = exps_card(l);
+       if (!l || list_length(l) == 0) 
+               e->card = CARD_ATOM; /* unop returns a single atom */
+       e->l = l;
+       e->r = append(append(sa_list(sa), gbe), obe);
+       e->f = f; 
+       return e;
+}
+
+sql_exp * 
 exp_aggr( sql_allocator *sa, list *l, sql_subaggr *a, int distinct, int 
no_nils, unsigned int card, int has_nils )
 {
        sql_exp *e = exp_create(sa, e_aggr);
@@ -1704,7 +1719,7 @@ exps_bind_column( list *exps, const char
                for (en = exps->h; en; en = en->next ) {
                        sql_exp *ce = en->data;
                        if (ce->alias.name && strcmp(ce->alias.name, cname) == 
0) {
-                               if (e) {
+                               if (e && e != ce && ce->alias.rname && 
e->alias.rname && strcmp(ce->alias.rname, e->alias.rname) != 0 ) {
                                        if (ambiguous)
                                                *ambiguous = 1;
                                        return NULL;
diff --git a/sql/server/rel_exp.h b/sql/server/rel_exp.h
--- a/sql/server/rel_exp.h
+++ b/sql/server/rel_exp.h
@@ -32,6 +32,7 @@ extern sql_exp *exp_in(sql_allocator *sa
 extern sql_exp *exp_convert(sql_allocator *sa, sql_exp *exp, sql_subtype 
*fromtype, sql_subtype *totype );
 extern str number2name(str s, int len, int i);
 extern sql_exp *exp_op(sql_allocator *sa, list *l, sql_subfunc *f );
+extern sql_exp *exp_rank_op(sql_allocator *sa, list *largs, list *gbe, list 
*obe, sql_subfunc *f );
 
 #define append(l,v) list_append(l,v) 
 #define exp_unop(sa,l,f) \
diff --git a/sql/server/rel_rel.c b/sql/server/rel_rel.c
--- a/sql/server/rel_rel.c
+++ b/sql/server/rel_rel.c
@@ -348,6 +348,17 @@ rel_bind_column2( mvc *sql, sql_rel *rel
        return NULL;
 }
 
+sql_exp *
+rel_first_column(mvc *sql, sql_rel *r)
+{
+       list *exps = rel_projections(sql, r, NULL, 1, 1);
+
+       if (!list_empty(exps))
+               return exps->h->data;
+
+       return NULL;
+}
+
 sql_rel *
 rel_inplace_setop(sql_rel *rel, sql_rel *l, sql_rel *r, operator_type setop, 
list *exps)
 {
diff --git a/sql/server/rel_rel.h b/sql/server/rel_rel.h
--- a/sql/server/rel_rel.h
+++ b/sql/server/rel_rel.h
@@ -54,6 +54,7 @@ extern sql_rel *rel_select_copy(sql_allo
 
 extern sql_exp *rel_bind_column( mvc *sql, sql_rel *rel, const char *cname, 
int f );
 extern sql_exp *rel_bind_column2( mvc *sql, sql_rel *rel, const char *tname, 
const char *cname, int f );
+extern sql_exp *rel_first_column(mvc *sql, sql_rel *rel);
 
 extern sql_rel *rel_inplace_setop(sql_rel *rel, sql_rel *l, sql_rel *r, 
operator_type setop, list *exps);
 extern sql_rel *rel_inplace_project(sql_allocator *sa, sql_rel *rel, sql_rel 
*l, list *e);
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
@@ -5091,43 +5091,6 @@ get_window_clauses(mvc *sql, char* ident
        return window_specification; //return something to say there were no 
errors
 }
 
-static sql_exp*
-opt_groupby_add_exp(mvc *sql, sql_rel *p, sql_rel *pp, sql_exp *in)
-{
-       sql_exp *found;
-
-       if (p->op == op_groupby) {
-               if (!exp_name(in))
-                       exp_label(sql->sa, in, ++sql->label);
-               found = exps_find_exp( p->exps, in);
-               if (!found)
-                       append(p->exps, in);
-               else
-                       in = found;
-               in = exp_ref(sql->sa, in);
-       } else if (pp && pp->op == op_groupby) {
-               if (!exp_name(in))
-                       exp_label(sql->sa, in, ++sql->label);
-               found = exps_find_exp( p->exps, in);
-               if (!found) {
-                       sql_rel *l = p->l;
-
-                       while (l && l != pp && !is_base(l->op)) {
-                               if (!exps_find_exp(l->exps, in)) {
-                                       if (is_project(l->op))
-                                               append(l->exps, 
exp_copy(sql->sa, in));
-                               } else
-                                       break;
-                               l = l->l;
-                       }
-                       append(p->exps, in);
-               } else
-                       in = found;
-               in = exp_ref(sql->sa, in);
-       }
-       return in;
-}
-
 /*
  * select x, y, rank_op() over (partition by x order by y) as, ...
                 aggr_op(z) over (partition by y order by x) as, ...
@@ -5153,11 +5116,11 @@ rel_rankop(sql_query *query, sql_rel **r
        char *aname = NULL, *sname = NULL, *window_ident = NULL;
        sql_subfunc *wf = NULL;
        sql_exp *in = NULL, *pe = NULL, *oe = NULL, *call = NULL, *start = 
NULL, *eend = NULL, *fstart = NULL, *fend = NULL;
-       sql_rel *r = *rel, *p, *pp, *g = NULL;
+       sql_rel /**r = *rel,*/ *p, *pp/*, *g = NULL*/;
        list *gbe = NULL, *obe = NULL, *args = NULL, *types = NULL, *fargs = 
NULL;
        sql_schema *s = sql->session->schema;
        dnode *dn = window_function->data.lval->h;
-       int distinct = 0, project_added = 0, is_last, frame_type, pos, group = 
0, nf = f;
+       int distinct = 0, is_last, frame_type, pos, nf = f;
        bool is_nth_value, supports_frames;
 
        stack_clear_frame_visited_flag(sql); //clear visited flags before 
iterating
@@ -5209,144 +5172,36 @@ rel_rankop(sql_query *query, sql_rel **r
                return NULL;
        }
 
-       /* 
-        * We need to keep track of the input relation, pp (projection)
-        * which may in the first step (which could be in the partitioning, 
ordering or window operator) change into a group by.
-        * then we project the partitioning/ordering + require result columns 
(p).
-        * followed by the projection with window operators. 
-        */
        /* window operations are only allowed in the projection */
-       if (r && r->op != op_project) {
-               *rel = r = rel_project(sql->sa, r, rel_projections(sql, r, 
NULL, 1, 1));
-               reset_processed(r);
-               project_added = 1;
-       }
-       if (!is_sql_sel(f) || !r || !is_project(r->op))
+       if (!is_sql_sel(f))
                return sql_error(sql, 02, SQLSTATE(42000) "OVER: only possible 
within the selection");
 
-       /* outer project (*rel) r  r->l will be rewritten!
-        *      in case of project_added (ie outer project added) we add the 
expression to r 
-        * rank project (new or existing non processed project) pp (needed for 
rank)
-        * inner project/groupby p (if groupby group is set)
-        * op used to reset p
-        */
-       p = r->l;
-       if (!p || (!is_joinop(p->op) && !p->exps->h)) { //no from clause, use a 
constant as the expression to project
-               sql_exp *exp = exp_atom_lng(sql->sa, 0);
-               exp_label(sql->sa, exp, ++sql->label);
-               if (!p) {
-                       p = rel_project(sql->sa, NULL, sa_list(sql->sa));
-                       set_processed(p);
-               }
-               append(p->exps, exp);
-       }
-
-       if (p && p->op != op_project) {
-               p = rel_project(sql->sa, p, rel_projections(sql, p, NULL, 1, 
1));
-               reset_processed(p);
-       }
-       pp = p;
-
-       g = p;
-       while (g && !group) {
-               if (g && g->op == op_groupby) {
-                       group = 1;
-               } else if (g->l && !is_processed(g) && !is_base(g->op)) {
-                       g = g->l;
-               } else {
-                       g = NULL;
-               }
-       }
+       p = pp = *rel;
        /* Partition By */
        if (partition_by_clause) {
                gbe = rel_group_by(query, &pp, partition_by_clause, NULL /* 
cannot use (selection) column references, as this result is a selection column 
*/, nf | sql_window);
-               if (!gbe && !group) { /* try with implicit groupby */
-                       /* reset error */
-                       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(query, &p, partition_by_clause, NULL 
/* cannot use (selection) column references, as this result is a selection 
column */, f | sql_window);
-               }
                if (!gbe)
                        return NULL;
-
-               if (p->op == op_groupby) {
-                       sql_rel *npp = pp;
-
-                       pp = g = p;
-                       p = rel_project(sql->sa, npp, rel_projections(sql, npp, 
NULL, 1, 0));
-                       reset_processed(p);
-               }
-
                for (n = gbe->h ; n ; n = n->next) {
                        sql_exp *en = n->data;
 
-                       n->data = en = opt_groupby_add_exp(sql, p, group?g:pp, 
en);
                        set_direction(en, 1);
                }
-               p->r = gbe;
-       }
+       }
+
        /* Order By */
        if (order_by_clause) {
                obe = rel_order_by(query, &pp, order_by_clause, nf | 
sql_window);
-               if (!obe && !group && !gbe) { /* try with implicit groupby */
-                       /* reset error */
-                       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(query, &p, order_by_clause, f | 
sql_window);
-               }
                if (!obe)
                        return NULL;
-
-               if (p->op == op_groupby) {
-                       sql_rel *npp = pp;
-
-                       pp = g = p;
-                       p = rel_project(sql->sa, npp, rel_projections(sql, npp, 
NULL, 1, 0));
-                       reset_processed(p);
-               }
-
                for (n = obe->h ; n ; n = n->next) {
-                       sql_exp *oexp = n->data, *nexp;
-
-                       if (is_sql_sel(f) && pp->op == op_project && 
!is_processed(pp) && !rel_find_exp(pp, oexp)) {
-                               append(pp->exps, oexp);
-                               if (!exp_name(oexp))
-                                       exp_label(sql->sa, oexp, ++sql->label);
-                               oexp = exp_ref(sql->sa, oexp);
-                       }
-                       n->data = nexp = opt_groupby_add_exp(sql, p, 
group?g:pp, oexp);
+                       sql_exp *oexp = n->data, *nexp = oexp;
+
                        if (is_ascending(oexp))
                                set_direction(nexp, 1);
                        if (nulls_last(oexp))
                                set_direction(nexp, 2);
                }
-               if (p->r) {
-                       p->r = list_merge(sa_list(sql->sa), p->r, (fdup)NULL); 
/* make sure the p->r is a different list than the gbe list */
-                       for(n = obe->h ; n ; n = n->next) {
-                               sql_exp *e1 = n->data;
-                               bool found = false;
-
-                               for(node *nn = ((list*)p->r)->h ; nn && !found 
; nn = nn->next) {
-                                       sql_exp *e2 = nn->data;
-                                       //the partition expression order should 
be the same as the one in the order by clause (if it's in there as well)
-                                       if(!exp_equal(e1, e2)) {
-                                               if(is_ascending(e1))
-                                                       e2->flag |= ASCENDING;
-                                               else
-                                                       e2->flag &= ~ASCENDING;
-                                               found = true;
-                                       }
-                               }
-                               if(!found)
-                                       append(p->r, e1);
-                       }
-               } else {
-                       p->r = obe;
-               }
        }
 
        fargs = sa_list(sql->sa);
@@ -5358,14 +5213,9 @@ rel_rankop(sql_query *query, sql_rel **r
                int nfargs = 0;
 
                if (!dnn || is_ntile) { //pass an input column for analytic 
functions that don't require it
-                       sql_rel *lr = p;
-
-                       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;
-                       }
_______________________________________________
checkin-list mailing list
[email protected]
https://www.monetdb.org/mailman/listinfo/checkin-list

Reply via email to