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

Reply via email to