Changeset: 017580f64a06 for MonetDB
URL: https://dev.monetdb.org/hg/MonetDB?cmd=changeset;node=017580f64a06
Added Files:
sql/test/miscellaneous/Tests/simple_plans.stable.out.single
Modified Files:
sql/server/rel_exp.c
sql/server/rel_optimizer.c
sql/server/rel_unnest.c
sql/test/BugTracker-2018/Tests/sqlitelogictest-cast-null-add.Bug-6630.stable.out
sql/test/BugTracker-2018/Tests/sqlitelogictest-groupby-having-in.Bug-6560.stable.out
sql/test/BugTracker-2020/Tests/select-and.Bug-6878.stable.out
sql/test/SQLancer/Tests/sqlancer01.sql
sql/test/SQLancer/Tests/sqlancer01.stable.out
Branch: default
Log Message:
Merged with Jun2020
diffs (truncated from 985 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
@@ -2186,7 +2186,7 @@ exp_unsafe( sql_exp *e, int allow_identi
if (e->type == e_convert && e->l)
return exp_unsafe(e->l, allow_identity);
- if (e->type == e_func && e->l) {
+ if ((e->type == e_func || e->type == e_aggr) && e->l) {
sql_subfunc *f = e->f;
list *args = e->l;
node *n;
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
@@ -1325,22 +1325,8 @@ exp_rename(mvc *sql, sql_exp *e, sql_rel
}
static int
-math_unsafe(sql_subfunc *f)
-{
- if (!f->func->s) {
- if (strcmp(f->func->base.name, "sql_div") == 0 ||
- strcmp(f->func->base.name, "sqrt") == 0 ||
- strcmp(f->func->base.name, "atan") == 0 )
- return 1;
- }
- return 0;
-}
-
-static int
can_push_func(sql_exp *e, sql_rel *rel, int *must)
{
- if (!e)
- return 0;
switch(e->type) {
case e_cmp: {
int mustl = 0, mustr = 0, mustf = 0;
@@ -1349,24 +1335,21 @@ can_push_func(sql_exp *e, sql_rel *rel,
if (e->flag == cmp_or || e->flag == cmp_in || e->flag ==
cmp_notin || e->flag == cmp_filter)
return 0;
return ((l->type == e_column || can_push_func(l, rel, &mustl))
&& (*must = mustl)) ||
- (!f && (r->type == e_column || can_push_func(r, rel,
&mustr)) && (*must = mustr)) ||
- (f &&
- (r->type == e_column || can_push_func(r, rel, &mustr))
&&
- (f->type == e_column || can_push_func(f, rel, &mustf))
&& (*must = (mustr || mustf)));
+ (!f && (r->type == e_column || can_push_func(r,
rel, &mustr)) && (*must = mustr)) ||
+ (f &&
+ (r->type == e_column || can_push_func(r, rel,
&mustr)) &&
+ (f->type == e_column || can_push_func(f, rel, &mustf))
&& (*must = (mustr || mustf)));
}
case e_convert:
return can_push_func(e->l, rel, must);
+ case e_aggr:
case e_func: {
list *l = e->l;
- node *n;
int res = 1, lmust = 0;
-
- if (e->f){
- sql_subfunc *f = e->f;
- if (math_unsafe(f) || f->func->type != F_FUNC)
- return 0;
- }
- if (l) for (n = l->h; n && res; n = n->next)
+
+ if (exp_unsafe(e, 0))
+ return 0;
+ if (l) for (node *n = l->h; n && res; n = n->next)
res &= can_push_func(n->data, rel, &lmust);
if (res && !lmust)
return 1;
@@ -1378,7 +1361,6 @@ can_push_func(sql_exp *e, sql_rel *rel,
return 0;
(*must) = 1;
/* fall through */
- case e_atom:
default:
return 1;
}
@@ -1387,15 +1369,13 @@ can_push_func(sql_exp *e, sql_rel *rel,
static int
exps_can_push_func(list *exps, sql_rel *rel)
{
- node *n;
-
- for(n = exps->h; n; n = n->next) {
+ for(node *n = exps->h; n; n = n->next) {
sql_exp *e = n->data;
int must = 0, mustl = 0, mustr = 0;
if (is_joinop(rel->op) && ((can_push_func(e, rel->l, &mustl) &&
mustl) || (can_push_func(e, rel->r, &mustr) && mustr)))
return 1;
- else if (is_select(rel->op) && can_push_func(e, NULL, &must) &&
must)
+ else if (is_select(rel->op) && can_push_func(e, rel->l, &must)
&& must)
return 1;
}
return 0;
@@ -1404,8 +1384,6 @@ exps_can_push_func(list *exps, sql_rel *
static int
exp_needs_push_down(sql_exp *e)
{
- if (!e)
- return 0;
switch(e->type) {
case e_cmp:
if (e->flag == cmp_or || e->flag == cmp_in || e->flag ==
cmp_notin || e->flag == cmp_filter)
@@ -1413,8 +1391,8 @@ exp_needs_push_down(sql_exp *e)
return exp_needs_push_down(e->l) || exp_needs_push_down(e->r)
|| (e->f && exp_needs_push_down(e->f));
case e_convert:
return exp_needs_push_down(e->l);
- case e_aggr:
- case e_func:
+ case e_aggr:
+ case e_func:
return 1;
case e_column:
case e_atom:
@@ -1426,13 +1404,79 @@ exp_needs_push_down(sql_exp *e)
static int
exps_need_push_down( list *exps )
{
- node *n;
- for(n = exps->h; n; n = n->next)
+ for(node *n = exps->h; n; n = n->next)
if (exp_needs_push_down(n->data))
return 1;
return 0;
}
+static sql_exp *exp_push_single_func_down(mvc *sql, sql_rel *rel, sql_rel *l,
sql_rel *r, sql_exp *e, int *changes);
+
+static list *
+exps_push_single_func_down(mvc *sql, sql_rel *rel, sql_rel *l, sql_rel *r,
list *exps, int *changes)
+{
+ if (THRhighwater())
+ return sql_error(sql, 10, SQLSTATE(42000) "Query too complex:
running out of stack space");
+
+ for (node *n = exps->h; n; n = n->next)
+ if ((n->data = exp_push_single_func_down(sql, rel, l, r,
n->data, changes)) == NULL)
+ return NULL;
+ return exps;
+}
+
+static sql_exp *
+exp_push_single_func_down(mvc *sql, sql_rel *rel, sql_rel *l, sql_rel *r,
sql_exp *e, int *changes)
+{
+ if (THRhighwater())
+ return sql_error(sql, 10, SQLSTATE(42000) "Query too complex:
running out of stack space");
+
+ switch(e->type) {
+ case e_cmp: {
+ if (e->flag == cmp_or || e->flag == cmp_filter) {
+ if ((e->l = exps_push_single_func_down(sql, rel, l, r,
e->l, changes)) == NULL)
+ return NULL;
+ if ((e->r = exps_push_single_func_down(sql, rel, l, r,
e->r, changes)) == NULL)
+ return NULL;
+ } else if (e->flag == cmp_in || e->flag == cmp_notin) {
+ if ((e->l = exp_push_single_func_down(sql, rel, l, r,
e->l, changes)) == NULL)
+ return NULL;
+ if ((e->r = exps_push_single_func_down(sql, rel, l, r,
e->r, changes)) == NULL)
+ return NULL;
+ } else {
+ if ((e->l = exp_push_single_func_down(sql, rel, l, r,
e->l, changes)) == NULL)
+ return NULL;
+ if ((e->r = exp_push_single_func_down(sql, rel, l, r,
e->r, changes)) == NULL)
+ return NULL;
+ if (e->f && (e->f = exp_push_single_func_down(sql, rel,
l, r, e->f, changes)) == NULL)
+ return NULL;
+ }
+ } break;
+ case e_convert:
+ case e_aggr:
+ case e_func: {
+ int must = 0, mustl = 0, mustr = 0;
+
+ if (exp_unsafe(e, 0))
+ return e;
+ if ((is_joinop(rel->op) && ((can_push_func(e, l, &mustl) &&
mustl) || (can_push_func(e, r, &mustr) && mustr))) ||
+ (is_select(rel->op) && can_push_func(e, l, &must) &&
must)) {
+ exp_label(sql->sa, e, ++sql->label);
+ if (mustr)
+ append(r->exps, e);
+ else
+ append(l->exps, e);
+ e = exp_ref(sql, e);
+ (*changes)++;
+ }
+ } break;
+ case e_atom:
+ case e_column:
+ case e_psm:
+ break;
+ }
+ return e;
+}
+
static sql_rel *
rel_push_func_down(mvc *sql, sql_rel *rel, int *changes)
{
@@ -1445,7 +1489,6 @@ rel_push_func_down(mvc *sql, sql_rel *re
sql_rel *nrel;
sql_rel *l = rel->l, *ol = l;
sql_rel *r = rel->r, *or = r;
- node *n;
/* we need a full projection, group by's and unions
cannot be extended
* with more expressions */
@@ -1454,85 +1497,18 @@ rel_push_func_down(mvc *sql, sql_rel *re
if (l->op != op_project) {
if (is_subquery(l))
return rel;
- rel->l = l = rel_project(sql->sa, l,
- rel_projections(sql, l, NULL, 1, 1));
+ rel->l = l = rel_project(sql->sa, l,
rel_projections(sql, l, NULL, 1, 1));
}
if (is_joinop(rel->op) && rel_is_ref(r))
return rel;
if (is_joinop(rel->op) && r->op != op_project) {
if (is_subquery(r))
return rel;
- rel->r = r = rel_project(sql->sa, r,
- rel_projections(sql, r, NULL, 1, 1));
+ rel->r = r = rel_project(sql->sa, r,
rel_projections(sql, r, NULL, 1, 1));
}
nrel = rel_project(sql->sa, rel, rel_projections(sql,
rel, NULL, 1, 1));
- for(n = exps->h; n; n = n->next) {
- sql_exp *e = n->data, *ne = NULL;
- int must = 0, mustl = 0, mustr = 0;
-
- if (e->type == e_column)
- continue;
- if ((is_joinop(rel->op) && ((can_push_func(e,
l, &mustl) && mustl) || (can_push_func(e, r, &mustr) && mustr))) ||
- (is_select(rel->op) && can_push_func(e,
NULL, &must) && must)) {
- must = 0; mustl = 0; mustr = 0;
- if (e->type != e_cmp) { /* predicate */
- if ((is_joinop(rel->op) &&
((can_push_func(e, l, &mustl) && mustl) || (can_push_func(e, r, &mustr) &&
mustr))) ||
- (is_select(rel->op) &&
can_push_func(e, NULL, &must) && must)) {
- exp_label(sql->sa, e,
++sql->label);
- if (mustr)
- append(r->exps,
e);
- else
- append(l->exps,
e);
- e = exp_ref(sql, e);
- n->data = e;
- (*changes)++;
- }
- } else {
- ne = e->l;
- if ((is_joinop(rel->op) &&
((can_push_func(ne, l, &mustl) && mustl) || (can_push_func(ne, r, &mustr) &&
mustr))) ||
- (is_select(rel->op) &&
can_push_func(ne, NULL, &must) && must)) {
- exp_label(sql->sa, ne,
++sql->label);
- if (mustr)
- append(r->exps,
ne);
- else
- append(l->exps,
ne);
- ne = exp_ref(sql, ne);
- (*changes)++;
- }
- e->l = ne;
-
- must = 0; mustl = 0; mustr = 0;
- ne = e->r;
- if ((is_joinop(rel->op) &&
((can_push_func(ne, l, &mustl) && mustl) || (can_push_func(ne, r, &mustr) &&
mustr))) ||
- (is_select(rel->op) &&
can_push_func(ne, NULL, &must) && must)) {
- exp_label(sql->sa, ne,
++sql->label);
- if (mustr)
- append(r->exps,
ne);
- else
- append(l->exps,
ne);
- ne = exp_ref(sql, ne);
- (*changes)++;
- }
- e->r = ne;
-
- if (e->f) {
- must = 0; mustl = 0;
mustr = 0;
- ne = e->f;
- if ((is_joinop(rel->op)
&& ((can_push_func(ne, l, &mustl) && mustl) || (can_push_func(ne, r, &mustr) &&
mustr))) ||
- (is_select(rel->op)
&& can_push_func(ne, NULL, &must) && must)) {
-
exp_label(sql->sa, ne, ++sql->label);
- if (mustr)
-
append(r->exps, ne);
- else
-
append(l->exps, ne);
- ne =
exp_ref(sql, ne);
- (*changes)++;
- }
- e->f = ne;
- }
- }
- }
- }
+ if (!(exps = exps_push_single_func_down(sql, rel, l, r,
exps, changes)))
+ return NULL;
if (*changes) {
rel = nrel;
} else {
@@ -1554,14 +1530,12 @@ rel_push_func_down(mvc *sql, sql_rel *re
if (l->op != op_project) {
_______________________________________________
checkin-list mailing list
[email protected]
https://www.monetdb.org/mailman/listinfo/checkin-list