Changeset: acb9c9205f52 for MonetDB
URL: https://dev.monetdb.org/hg/MonetDB?cmd=changeset;node=acb9c9205f52
Modified Files:
        sql/server/rel_unnest.c
        sql/test/SQLancer/Tests/sqlancer10.test
Branch: default
Log Message:

If the relation rewrite generates a left join, disable NOT NULL flag


diffs (241 lines):

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
@@ -1538,28 +1538,28 @@ static sql_rel *
 }
 
 static sql_exp *
-rewrite_inner(mvc *sql, sql_rel *rel, sql_rel *inner, operator_type op)
+rewrite_inner(mvc *sql, sql_rel *rel, sql_rel *inner, operator_type *op)
 {
        int single = is_single(inner);
        sql_rel *d = NULL;
 
        reset_single(inner);
        if (single && is_project(rel->op))
-               op = op_left;
+               *op = op_left;
 
        if (!is_project(inner->op))
                inner = rel_project(sql->sa, inner, rel_projections(sql, inner, 
NULL, 1, 1));
 
        if (is_join(rel->op)){ /* TODO handle set operators etc */
                if (is_right(rel->op))
-                       d = rel->l = rel_crossproduct(sql->sa, rel->l, inner, 
op);
+                       d = rel->l = rel_crossproduct(sql->sa, rel->l, inner, 
*op);
                else
-                       d = rel->r = rel_crossproduct(sql->sa, rel->r, inner, 
op);
+                       d = rel->r = rel_crossproduct(sql->sa, rel->r, inner, 
*op);
                if (single)
                        set_single(d);
        } else if (is_project(rel->op)){ /* projection -> op_left */
-               if (rel->l || single || op == op_left) {
-                       if ((single || op == op_left) && !rel->l)
+               if (rel->l || single || *op == op_left) {
+                       if ((single || *op == op_left) && !rel->l)
                                rel->l = rel_project(sql->sa, rel->l, 
append(sa_list(sql->sa), exp_atom_bool(sql->sa, 1)));
                        d = rel->l = rel_crossproduct(sql->sa, rel->l, inner, 
op_left);
                        if (single)
@@ -1568,18 +1568,21 @@ rewrite_inner(mvc *sql, sql_rel *rel, sq
                        d = rel->l = inner;
                }
        } else {
-               d = rel->l = rel_crossproduct(sql->sa, rel->l, inner, op);
+               d = rel->l = rel_crossproduct(sql->sa, rel->l, inner, *op);
                if (single)
                        set_single(d);
        }
-       if (d && rel_has_freevar(sql, inner)) {
-               list *dv = rel_dependent_var(sql, d, inner);
-               list *fv = rel_freevar(sql, inner);
-               /* check if the inner depends on the new join (d) or one leve 
up */
-               if (list_length(dv))
-                       set_dependent(d);
-               if (list_length(fv) != list_length(dv))
-                       set_dependent(rel);
+       if (d) {
+               if (rel_has_freevar(sql, inner)) {
+                       list *dv = rel_dependent_var(sql, d, inner);
+                       list *fv = rel_freevar(sql, inner);
+                       /* check if the inner depends on the new join (d) or 
one leve up */
+                       if (list_length(dv))
+                               set_dependent(d);
+                       if (list_length(fv) != list_length(dv))
+                               set_dependent(rel);
+               }
+               *op = d->op;
        }
        return inner->exps->t->data;
 }
@@ -1592,15 +1595,17 @@ rewrite_exp_rel(visitor *v, sql_rel *rel
                if (is_single(inner)) {
                        /* use a dummy projection for the single join */
                        sql_rel *nrel = rel_project(v->sql->sa, NULL, 
append(sa_list(v->sql->sa), exp_atom_bool(v->sql->sa, 1)));
-
-                       if (!rewrite_inner(v->sql, nrel, inner, 
depth?op_left:op_join))
+                       operator_type op = depth?op_left:op_join;
+
+                       if (!rewrite_inner(v->sql, nrel, inner, &op))
                                return NULL;
                        /* has to apply recursively */
                        if (!(e->l = rel_exp_visitor_bottomup(v, nrel, 
&rewrite_exp_rel, true)))
                                return NULL;
                }
        } else if (exp_has_rel(e) && !is_ddl(rel->op)) {
-               sql_exp *ne = rewrite_inner(v->sql, rel, 
exp_rel_get_rel(v->sql->sa, e), depth?op_left:op_join);
+               operator_type op = depth?op_left:op_join;
+               sql_exp *ne = rewrite_inner(v->sql, rel, 
exp_rel_get_rel(v->sql->sa, e), &op);
 
                if (!ne)
                        return ne;
@@ -1611,11 +1616,11 @@ rewrite_exp_rel(visitor *v, sql_rel *rel
                        if (!exp_name(ne))
                                ne = exp_label(v->sql->sa, ne, ++v->sql->label);
                        e = ne;
-                       if (depth) /* a projection from an outer join may have 
nulls */
-                               set_has_nil(e);
                } else {
                        e = exp_rel_update_exp(v->sql, e);
                }
+               if (is_left(op))
+                       set_has_nil(e);
        }
        return e;
 }
@@ -2506,15 +2511,23 @@ rewrite_anyequal(mvc *sql, sql_rel *rel,
                                        lid = exp_ref(sql, lid);
                                }
 
-                               if (sq)
-                                       (void)rewrite_inner(sql, rel, lsq, 
op_join);
+                               if (sq) {
+                                       operator_type op = op_join;
+                                       (void)rewrite_inner(sql, rel, lsq, &op);
+                                       if (is_left(op))
+                                               set_has_nil(le);
+                               }
                                if (rsq) {
                                        if (on_right) {
                                                sql_rel *join = rel->l; /* the 
introduced join */
                                                join->r = 
rel_crossproduct(sql->sa, join->r, rsq, op_join);
                                                set_dependent(join);
-                                       } else
-                                               (void)rewrite_inner(sql, rel, 
rsq, !is_tuple?((depth>0)?op_left:op_join):is_anyequal(sf)?op_semi:op_anti);
+                                       } else {
+                                               operator_type op = 
!is_tuple?((depth>0)?op_left:op_join):is_anyequal(sf)?op_semi:op_anti;
+                                               (void)rewrite_inner(sql, rel, 
rsq, &op);
+                                               if (is_left(op))
+                                                       set_has_nil(re);
+                                       }
                                }
 
                                if (on_right) {
@@ -2558,10 +2571,18 @@ rewrite_anyequal(mvc *sql, sql_rel *rel,
                                        return exp_rel(sql, lsq);
                                return le;
                        } else {
-                               if (lsq)
-                                       (void)rewrite_inner(sql, rel, lsq, 
op_join);
-                               if (rsq)
-                                       (void)rewrite_inner(sql, rel, rsq, 
!is_tuple?op_join:is_anyequal(sf)?op_semi:op_anti);
+                               if (lsq) {
+                                       operator_type op = op_join;
+                                       (void)rewrite_inner(sql, rel, lsq, &op);
+                                       if (is_left(op))
+                                               set_has_nil(le);
+                               }
+                               if (rsq) {
+                                       operator_type op = 
!is_tuple?op_join:is_anyequal(sf)?op_semi:op_anti;
+                                       (void)rewrite_inner(sql, rel, rsq, &op);
+                                       if (is_left(op))
+                                               set_has_nil(re);
+                               }
                                if (is_tuple) {
                                        list *t = le->f;
                                        list *l = sa_list(sql->sa);
@@ -2684,9 +2705,12 @@ rewrite_compare(visitor *v, sql_rel *rel
 
                                if (!lsq)
                                        lsq = rel->l;
-                               if (sq)
-                                       (void)rewrite_inner(v->sql, rel, sq, 
(depth||quantifier)?op_left:op_join);
-
+                               if (sq) {
+                                       operator_type op = 
(depth||quantifier)?op_left:op_join;
+                                       (void)rewrite_inner(v->sql, rel, sq, 
&op);
+                                       if (is_left(op))
+                                               set_has_nil(le);
+                               }
                                if (quantifier) {
                                        sql_subfunc *a;
 
@@ -2709,8 +2733,12 @@ rewrite_compare(visitor *v, sql_rel *rel
                                        re = rel_groupby_add_aggr(v->sql, rsq, 
re);
                                        set_processed(rsq);
                                }
-                               if (rsq)
-                                       (void)rewrite_inner(v->sql, rel, rsq, 
((!quantifier && depth > 0)||is_cnt)?op_left:op_join);
+                               if (rsq) {
+                                       operator_type op = ((!quantifier && 
depth > 0)||is_cnt)?op_left:op_join;
+                                       (void)rewrite_inner(v->sql, rel, rsq, 
&op);
+                                       if (is_left(op))
+                                               set_has_nil(re);
+                               }
 
                                if (rel_convert_types(v->sql, NULL, NULL, &le, 
&re, 1, type_equal) < 0)
                                        return NULL;
@@ -2730,10 +2758,18 @@ rewrite_compare(visitor *v, sql_rel *rel
                                        exp_prop_alias(v->sql->sa, le, e);
                                return le;
                        } else {
-                               if (lsq)
-                                       (void)rewrite_inner(v->sql, rel, lsq, 
op_join);
-                               if (rsq)
-                                       (void)rewrite_inner(v->sql, rel, rsq, 
!is_tuple?op_join:is_anyequal(sf)?op_semi:op_anti);
+                               if (lsq) {
+                                       operator_type op = op_join;
+                                       (void)rewrite_inner(v->sql, rel, lsq, 
&op);
+                                       if (is_left(op))
+                                               set_has_nil(le);
+                               }
+                               if (rsq) {
+                                       operator_type op = 
!is_tuple?op_join:is_anyequal(sf)?op_semi:op_anti;
+                                       (void)rewrite_inner(v->sql, rel, rsq, 
&op);
+                                       if (is_left(op))
+                                               set_has_nil(re);
+                               }
                                if (is_tuple) {
                                        list *t = le->f;
                                        list *l = sa_list(v->sql->sa);
@@ -2938,7 +2974,8 @@ rewrite_exists(visitor *v, sql_rel *rel,
                                if (depth == 1 && is_ddl(rel->op)) /* exists is 
at a ddl statment, it must be inside a relation */
                                        return exp_rel(v->sql, sq);
                        } else { /* rewrite into semi/anti join */
-                               (void)rewrite_inner(v->sql, rel, sq, 
is_exists(sf)?op_semi:op_anti);
+                               operator_type op = 
is_exists(sf)?op_semi:op_anti;
+                               (void)rewrite_inner(v->sql, rel, sq, &op);
                                return exp_atom_bool(v->sql->sa, 1);
                        }
                        return le;
diff --git a/sql/test/SQLancer/Tests/sqlancer10.test 
b/sql/test/SQLancer/Tests/sqlancer10.test
--- a/sql/test/SQLancer/Tests/sqlancer10.test
+++ b/sql/test/SQLancer/Tests/sqlancer10.test
@@ -314,6 +314,18 @@ 1
 1
 1
 
+query T nosort
+PLAN SELECT (SELECT c0 FROM t0) FROM t0
+----
+project (
+| single left outer join (
+| | table("sys"."t0") [ "t0"."c0" NOT NULL ] COUNT ,
+| | project (
+| | | table("sys"."t0") [ "t0"."c0" NOT NULL ] COUNT 
+| | ) [ "t0"."c0" NOT NULL as "%1"."%1" ]
+| ) [  ]
+) [ "%1"."%1" ]
+
 statement ok
 ROLLBACK
 
_______________________________________________
checkin-list mailing list
checkin-list@monetdb.org
https://www.monetdb.org/mailman/listinfo/checkin-list

Reply via email to