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