Changeset: e9bbb982c19f for MonetDB
URL: https://dev.monetdb.org/hg/MonetDB/rev/e9bbb982c19f
Modified Files:
        sql/server/rel_optimizer.c
Branch: Jul2021
Log Message:

Stack overflow checks and don't create extra reference to not empty relation


diffs (105 lines):

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
@@ -5270,14 +5270,16 @@ rel_push_join_down_outer(visitor *v, sql
 }
 
 static int
-rel_is_empty( sql_rel *rel )
-{
+rel_is_empty(mvc *sql, sql_rel *rel)
+{
+       if (mvc_highwater(sql))
+               return 0;
        if ((is_innerjoin(rel->op) || is_left(rel->op) || is_right(rel->op) || 
is_semi(rel->op)) && !list_empty(rel->exps)) {
                sql_rel *l = rel->l, *r = rel->r;
                sql_exp *je;
 
-               if (((is_innerjoin(rel->op) || is_left(rel->op) || 
is_semi(rel->op)) && rel_is_empty(l)) ||
-                       ((is_innerjoin(rel->op) || is_right(rel->op)) && 
rel_is_empty(r)))
+               if (((is_innerjoin(rel->op) || is_left(rel->op) || 
is_semi(rel->op)) && rel_is_empty(sql, l)) ||
+                       ((is_innerjoin(rel->op) || is_right(rel->op)) && 
rel_is_empty(sql, r)))
                        return 1;
                /* check */
                if ((je = rel_is_join_on_pkey(rel, true))) {
@@ -5292,9 +5294,9 @@ rel_is_empty( sql_rel *rel )
        if (is_simple_project(rel->op) || (is_groupby(rel->op) && 
!list_empty(rel->r)) || is_select(rel->op) ||
                is_topn(rel->op) || is_sample(rel->op) || is_inter(rel->op) || 
is_except(rel->op)) {
                if (rel->l)
-                       return rel_is_empty(rel->l);
+                       return rel_is_empty(sql, rel->l);
        } else if (is_innerjoin(rel->op) && list_empty(rel->exps)) { /* 
cartesian product */
-               return rel_is_empty(rel->l) || rel_is_empty(rel->r);
+               return rel_is_empty(sql, rel->l) || rel_is_empty(sql, rel->r);
        }
        return 0;
 }
@@ -5303,21 +5305,28 @@ rel_is_empty( sql_rel *rel )
 static inline sql_rel *
 rel_remove_empty_join(visitor *v, sql_rel *rel)
 {
-       if (!is_union(rel->op))
+       if (!is_union(rel->op) || rel_is_ref(rel))
                return rel;
        /* For half empty unions replace by projects */
-       sql_rel *l = rel->l, *r = rel->r;
-
-       if (rel_is_empty(l)) {
+       if (!rel_is_ref(rel->l) && rel_is_empty(v->sql, rel->l)) {
+               sql_rel *r = rel->r;
+               if (!is_project(r->op))
+                       r = rel_project(v->sql->sa, r, rel_projections(v->sql, 
r, NULL, 1, 1));
+               rel_rename_exps(v->sql, rel->exps, r->exps);
+               rel->r = NULL;
+               rel_destroy(rel);
                v->changes++;
+               return r;
+       }
+       if (!rel_is_ref(rel->r) && rel_is_empty(v->sql, rel->r)) {
+               sql_rel *l = rel->l;
+               if (!is_project(l->op))
+                       l = rel_project(v->sql->sa, l, rel_projections(v->sql, 
l, NULL, 1, 1));
+               rel_rename_exps(v->sql, rel->exps, l->exps);
                rel->l = NULL;
-               rel_destroy(l);
-               return rel_inplace_project(v->sql->sa, rel, rel_dup(r), 
rel->exps);
-       } else if (rel_is_empty(r)) {
+               rel_destroy(rel);
                v->changes++;
-               rel->r = NULL;
-               rel_destroy(r);
-               return rel_inplace_project(v->sql->sa, rel, rel_dup(l), 
rel->exps);
+               return l;
        }
        return rel;
 }
@@ -9433,7 +9442,7 @@ exp_is_zero_rows(mvc *sql, sql_rel *rel,
        sql_table *t;
        node *n;
 
-       if (!rel)
+       if (!rel || mvc_highwater(sql))
                return 0;
        rel = exp_skip_output_parts(rel);
        if (is_select(rel->op) && rel->l) {
@@ -9496,9 +9505,9 @@ statistics, similarly to the merge table
 static inline sql_rel *
 rel_remove_union_partitions(visitor *v, sql_rel *rel)
 {
-       if (!is_union(rel->op))
+       if (!is_union(rel->op) || rel_is_ref(rel))
                return rel;
-       if (exp_is_zero_rows(v->sql, rel->l, NULL)) {
+       if (!rel_is_ref(rel->l) && exp_is_zero_rows(v->sql, rel->l, NULL)) {
                sql_rel *r = rel->r;
                if (!is_project(r->op))
                        r = rel_project(v->sql->sa, r, rel_projections(v->sql, 
r, NULL, 1, 1));
@@ -9508,7 +9517,7 @@ rel_remove_union_partitions(visitor *v, 
                v->changes++;
                return r;
        }
-       if (exp_is_zero_rows(v->sql, rel->r, NULL)) {
+       if (!rel_is_ref(rel->r) && exp_is_zero_rows(v->sql, rel->r, NULL)) {
                sql_rel *l = rel->l;
                if (!is_project(l->op))
                        l = rel_project(v->sql->sa, l, rel_projections(v->sql, 
l, NULL, 1, 1));
_______________________________________________
checkin-list mailing list
checkin-list@monetdb.org
https://www.monetdb.org/mailman/listinfo/checkin-list

Reply via email to