Changeset: a353d519760b for MonetDB
URL: https://dev.monetdb.org/hg/MonetDB?cmd=changeset;node=a353d519760b
Modified Files:
        sql/rel.txt
        sql/server/rel_exp.c
        sql/server/rel_exp.h
        sql/server/rel_optimizer.c
        sql/server/rel_select.c
        sql/server/rel_unnest.c
Branch: default
Log Message:

Merged with linear-hashing


diffs (246 lines):

diff --git a/sql/rel.txt b/sql/rel.txt
--- a/sql/rel.txt
+++ b/sql/rel.txt
@@ -146,6 +146,8 @@ e_aggr
        -> f    func / aggr
 for aggr
        -> flag DISTINCT and NO_NIL could be set
+for window functions
+       -> r contains a list with two values: the first is a list with the 
partition by expressions, and the second a list with order by expressions
 
 e_column
        -> rname alias for the relation (i.e., alias of ->l, used by higher 
expressions)
@@ -155,7 +157,6 @@ e_column
        -> r    expression name
        -> type 
 
-       
 e_psm
        -> flag
                psm_declare     name 
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
@@ -22,7 +22,7 @@
 #include "blob.h"
 
 comp_type
-compare_str2type( char *compare_op)
+compare_str2type(const char *compare_op)
 {
        comp_type type = cmp_filter;
 
@@ -243,7 +243,7 @@ exp_in_func(mvc *sql, sql_exp *le, sql_e
 }
 
 sql_exp *
-exp_compare_func(mvc *sql, sql_exp *le, sql_exp *re, sql_exp *oe, char 
*compareop, int quantifier)
+exp_compare_func(mvc *sql, sql_exp *le, sql_exp *re, sql_exp *oe, const char 
*compareop, int quantifier)
 {
        sql_subfunc *cmp_func = NULL;
        sql_exp *e;
@@ -789,7 +789,7 @@ exp_rel(mvc *sql, sql_rel *rel)
 }
 
 sql_exp *
-exp_exception(sql_allocator *sa, sql_exp *cond, char* error_message)
+exp_exception(sql_allocator *sa, sql_exp *cond, const char *error_message)
 {
        sql_exp *e = exp_create(sa, e_psm);
 
@@ -2217,7 +2217,7 @@ exps_intern(list *exps)
        return 0;
 }
 
-char *
+const char *
 compare_func( comp_type t, int anti )
 {
        switch(t) {
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
@@ -23,7 +23,7 @@
 
 #define is_notequal_func(sf) (!sf->func->s && strcmp(sf->func->base.name, 
"<>") == 0)
 
-extern comp_type compare_str2type(char *compare_op);
+extern comp_type compare_str2type(const char *compare_op);
 extern comp_type swap_compare( comp_type t );
 extern comp_type range2lcompare( int r );
 extern comp_type range2rcompare( int r );
@@ -35,7 +35,7 @@ extern sql_exp *exp_filter(sql_allocator
 extern sql_exp *exp_or(sql_allocator *sa, list *l, list *r, int anti);
 extern sql_exp *exp_in(sql_allocator *sa, sql_exp *l, list *r, int cmptype);
 extern sql_exp *exp_in_func(mvc *sql, sql_exp *le, sql_exp *vals, int 
anyequal, int is_tuple);
-extern sql_exp *exp_compare_func(mvc *sql, sql_exp *le, sql_exp *re, sql_exp 
*oe, char *compareop, int quantifier);
+extern sql_exp *exp_compare_func(mvc *sql, sql_exp *le, sql_exp *re, sql_exp 
*oe, const char *compareop, int quantifier);
 
 #define exp_fromtype(e)        ((list*)e->r)->h->data
 #define exp_totype(e)  ((list*)e->r)->h->next->data
@@ -92,7 +92,7 @@ extern sql_exp * exp_var(sql_allocator *
 extern sql_exp * exp_table(sql_allocator *sa, const char *name, sql_table *t, 
int level);
 extern sql_exp * exp_return(sql_allocator *sa, sql_exp *val, int level);
 extern sql_exp * exp_while(sql_allocator *sa, sql_exp *cond, list *stmts);
-extern sql_exp * exp_exception(sql_allocator *sa, sql_exp *cond, char* 
error_message);
+extern sql_exp * exp_exception(sql_allocator *sa, sql_exp *cond, const char 
*error_message);
 extern sql_exp * exp_if(sql_allocator *sa, sql_exp *cond, list *if_stmts, list 
*else_stmts);
 extern sql_exp * exp_rel(mvc *sql, sql_rel * r);
 
@@ -173,7 +173,7 @@ extern void exps_fix_card( list *exps, u
 extern void exps_setcard( list *exps, unsigned int card);
 extern int exps_intern(list *exps);
 
-extern char *compare_func( comp_type t, int anti );
+extern const char *compare_func( comp_type t, int anti );
 extern int is_identity( sql_exp *e, sql_rel *r);
 
 extern atom *exp_flatten(mvc *sql, sql_exp *e);
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
@@ -3413,7 +3413,6 @@ exp_simplify_math( mvc *sql, sql_exp *e,
 static sql_rel *
 rel_simplify_math(int *changes, mvc *sql, sql_rel *rel) 
 {
-       
        if ((is_project(rel->op) || (rel->op == op_ddl && rel->flag == 
ddl_psm)) && rel->exps) {
                list *exps = rel->exps;
                node *n;
@@ -3444,6 +3443,66 @@ rel_simplify_math(int *changes, mvc *sql
 }
 
 static sql_rel *
+rel_push_down_bounds(int *changes, mvc *sql, sql_rel *rel) 
+{
+       if (is_simple_project(rel->op) && rel->exps) {
+               list *exps = rel->exps;
+               node *n;
+
+               for (n = exps->h; n ; n = n->next) { 
+                       sql_exp *e = n->data;
+                       int cnt;
+                       sql_exp *b1, *b2;
+                       sql_subfunc *f;
+                       list *l;
+
+                       if (e->type != e_func || 
((sql_subfunc*)e->f)->func->type != F_ANALYTIC)
+                               continue;
+
+                       f = (sql_subfunc*) e->f;
+                       l = (list*) e->l; 
+                       if (f->func->type != F_ANALYTIC || 
!strcmp(f->func->base.name, "diff") || !strcmp(f->func->base.name, 
"window_bound"))
+                               continue;
+
+                       /* Extract sql.diff calls into a lower projection and 
re-use them */
+                       cnt = list_length(l);
+                       assert(cnt >= 3); /* There will be at least 3 
expressions in the parameters for the window function */ 
+                       b1 = (sql_exp*) list_fetch(l, cnt - 2);
+                       b2 = (sql_exp*) list_fetch(l, cnt - 1);
+                       
+                       if (b1->type == e_func && b2->type == e_func) { /* if 
both are 'window_bound' calls, push down a diff call */
+                               sql_subfunc *sf1 = (sql_subfunc*) b1->f, *sf2 = 
(sql_subfunc*) b2->f;
+
+                               if (!strcmp(sf1->func->base.name, 
"window_bound") && !strcmp(sf2->func->base.name, "window_bound")) {
+                                       list *args1 = (list*) b1->l, *args2 = 
(list*) b2->l;
+                                       sql_exp *first1 = (sql_exp*) 
args1->h->data, *first2 = (sql_exp*) args2->h->data;
+
+                                       if (first1->type == e_func && 
exp_match_exp(first1, first2)) { /* push down only function calls to avoid 
infinite recursion */
+                                               rel->l = rel_project(sql->sa, 
rel->l, rel_projections(sql, rel->l, NULL, 1, 1));
+                                               first1 = 
rel_project_add_exp(sql, rel->l, first1);
+                                               args1->h->data = 
exp_ref(sql->sa, first1);
+                                               args2->h->data = 
exp_ref(sql->sa, first1);
+
+                                               if (list_length(args1) == 6 && 
list_length(args2) == 6) {
+                                                       sql_exp *second1 = 
(sql_exp*) args1->h->next->data, *second2 = (sql_exp*) args2->h->next->data;
+
+                                                       if (second1->type == 
e_func && exp_match_exp(second1, second2)) {
+                                                               second1 = 
rel_project_add_exp(sql, rel->l, second1);
+                                                               
args1->h->next->data = exp_ref(sql->sa, second1);
+                                                               
args2->h->next->data = exp_ref(sql->sa, second1);
+                                                       }
+                                               }
+
+                                               (*changes)++;
+                                       }
+                               }
+                       }
+               }
+       }
+       return rel;
+}
+
+static sql_rel *
 rel_find_ref( sql_rel *r)
 {
        while (!rel_is_ref(r) && r->l && 
@@ -9018,6 +9077,7 @@ optimize_rel(mvc *sql, sql_rel *rel, int
                        if (value_based_opt)
                                rel = rewrite(sql, rel, &rel_simplify_math, 
&changes);
                        rel = rewrite(sql, rel, 
&rel_distinct_aggregate_on_unique_values, &changes);
+                       rel = rewrite(sql, rel, &rel_push_down_bounds, 
&changes);
                        rel = rewrite(sql, rel, &rel_distinct_project2groupby, 
&changes);
                }
        }
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
@@ -4575,7 +4575,7 @@ rel_rankop(sql_query *query, sql_rel **r
        symbol *window_function = l->h->data.sym, *partition_by_clause = NULL, 
*order_by_clause = NULL, *frame_clause = NULL;
        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_exp *in = NULL, *pe = NULL, *oe = NULL, *call = NULL, *start = 
NULL, *eend = NULL, *fstart = NULL, *fend = NULL, *ie = NULL;
        sql_rel *p;
        list *gbe = NULL, *obe = NULL, *args = NULL, *types = NULL, *fargs = 
NULL;
        sql_schema *s = sql->session->schema;
@@ -4822,6 +4822,9 @@ rel_rankop(sql_query *query, sql_rel **r
                oe = exp_atom_bool(sql->sa, 0);
        }
 
+       if (frame_clause || supports_frames)
+               ie = obe ? exp_ref(sql->sa, (sql_exp*) obe->t->data) : in;
+
        /* Frame */
        if (frame_clause) {
                dnode *d = frame_clause->data.lval->h;
@@ -4829,7 +4832,6 @@ rel_rankop(sql_query *query, sql_rel **r
                           *rend = wend->data.lval->h->data.sym;
                int excl = d->next->next->next->data.i_val;
                frame_type = d->next->next->data.i_val;
-               sql_exp *ie = obe ? exp_ref(sql->sa, (sql_exp*) obe->t->data) : 
in;
 
                if (!supports_frames)
                        return sql_error(sql, 02, SQLSTATE(42000) "OVER: frame 
extend only possible with aggregation and first_value, last_value and nth_value 
functions");
@@ -4864,10 +4866,9 @@ rel_rankop(sql_query *query, sql_rel **r
                if ((fend = calculate_window_bound(query, p, wend->token, rend, 
ie, frame_type, f | sql_window)) == NULL)
                        return NULL;
                if (generate_window_bound_call(sql, &start, &eend, s, gbe ? pe 
: NULL, ie, fstart, fend, frame_type, excl,
-                                                                         
wstart->token, wend->token) == NULL)
+                                                                          
wstart->token, wend->token) == NULL)
                        return NULL;
        } else if (supports_frames) { /* for analytic functions with no frame 
clause, we use the standard default values */
-               sql_exp *ie = obe ? exp_ref(sql->sa, (sql_exp*) obe->t->data) : 
in;
                sql_subtype *it = sql_bind_localtype("int"), *lon = 
sql_bind_localtype("lng"), *bt;
                unsigned char sclass;
 
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
@@ -314,7 +314,7 @@ rel_freevar(mvc *sql, sql_rel *rel)
                exps = exps_freevar(sql, rel->exps);
                lexps = rel_freevar(sql, rel->l);
                if (rel->r) {
-                       if (is_groupby(rel->op))
+                       if (is_groupby(rel->op) || is_simple_project(rel->op))
                                rexps = exps_freevar(sql, rel->r);
                        else
                                rexps = rel_freevar(sql, rel->r);
@@ -2326,7 +2326,6 @@ rewrite_compare(mvc *sql, sql_rel *rel, 
        return e;
 }
 
-
 static sql_rel *
 rewrite_join2semi(mvc *sql, sql_rel *rel)
 {
_______________________________________________
checkin-list mailing list
[email protected]
https://www.monetdb.org/mailman/listinfo/checkin-list

Reply via email to