Changeset: 8002219d9426 for MonetDB
URL: https://dev.monetdb.org/hg/MonetDB?cmd=changeset;node=8002219d9426
Modified Files:
        sql/server/rel_optimizer.c
        sql/server/rel_rel.c
        sql/server/rel_rel.h
        sql/server/rel_unnest.c
        sql/test/SQLancer/Tests/sqlancer02.stable.out
        sql/test/merge-partitions/Tests/mergepart31.stable.out
Branch: Oct2020
Log Message:

On union relations, the expression's properties cannot be propagated. Also make 
sure to call rel_setop_set_exps on set relations when setting exressions


diffs (truncated from 375 to 300 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
@@ -2077,6 +2077,7 @@ rel_push_topn_and_sample_down(visitor *v
                        ur = func(v->sql->sa, ur, sum_limit_offset(v->sql, 
rel));
 
                        u = rel_setop(v->sql->sa, ul, ur, op_union);
+                       /* TODO the list of expressions of u don't match ul and 
ur */
                        u->exps = exps_alias(v->sql, r->exps);
                        u->nrcols = list_length(u->exps);
                        set_processed(u);
@@ -4159,7 +4160,7 @@ rel_push_aggr_down(visitor *v, sql_rel *
                                        sql_table *mt = (bt)?bt->r:NULL;
                                        if (c && mt && 
list_find(c->t->pkey->k.columns, c, cmp) != NULL) {
                                                v->changes++;
-                                               return rel_inplace_setop(rel, 
ul, ur, op_union,
+                                               return 
rel_inplace_setop(v->sql, rel, ul, ur, op_union,
                                                       rel_projections(v->sql, 
rel, NULL, 1, 1));
                                        }
                                }
@@ -5117,7 +5118,7 @@ rel_push_join_down_union(visitor *v, sql
                        nl = rel_project(v->sql->sa, nl, 
rel_projections(v->sql, nl, NULL, 1, 1));
                        nr = rel_project(v->sql->sa, nr, 
rel_projections(v->sql, nr, NULL, 1, 1));
                        v->changes++;
-                       return rel_inplace_setop(rel, nl, nr, op_union, 
rel_projections(v->sql, rel, NULL, 1, 1));
+                       return rel_inplace_setop(v->sql, rel, nl, nr, op_union, 
rel_projections(v->sql, rel, NULL, 1, 1));
                } else if (is_union(l->op) && !need_distinct(l) &&
                           is_union(r->op) && !need_distinct(r)) {
                        sql_rel *nl, *nr;
@@ -5160,7 +5161,7 @@ rel_push_join_down_union(visitor *v, sql
                        nl = rel_project(v->sql->sa, nl, 
rel_projections(v->sql, nl, NULL, 1, 1));
                        nr = rel_project(v->sql->sa, nr, 
rel_projections(v->sql, nr, NULL, 1, 1));
                        v->changes++;
-                       return rel_inplace_setop(rel, nl, nr, op_union, 
rel_projections(v->sql, rel, NULL, 1, 1));
+                       return rel_inplace_setop(v->sql, rel, nl, nr, op_union, 
rel_projections(v->sql, rel, NULL, 1, 1));
                } else if (!is_union(l->op) &&
                           is_union(r->op) && !need_distinct(r) &&
                           !is_semi(rel->op)) {
@@ -5189,7 +5190,7 @@ rel_push_join_down_union(visitor *v, sql
                        nl = rel_project(v->sql->sa, nl, 
rel_projections(v->sql, nl, NULL, 1, 1));
                        nr = rel_project(v->sql->sa, nr, 
rel_projections(v->sql, nr, NULL, 1, 1));
                        v->changes++;
-                       return rel_inplace_setop(rel, nl, nr, op_union, 
rel_projections(v->sql, rel, NULL, 1, 1));
+                       return rel_inplace_setop(v->sql, rel, nl, nr, op_union, 
rel_projections(v->sql, rel, NULL, 1, 1));
                /* {semi}join ( A1, union (A2, B)) [A1.partkey = A2.partkey] ->
                 * {semi}join ( A1, A2 )
                 * and
@@ -5519,7 +5520,7 @@ rel_push_select_down_union(visitor *v, s
                ul->exps = exps_copy(v->sql, s->exps);
                ur->exps = exps_copy(v->sql, s->exps);
 
-               rel = rel_inplace_setop(rel, ul, ur, op_union, 
rel_projections(v->sql, rel, NULL, 1, 1));
+               rel = rel_inplace_setop(v->sql, rel, ul, ur, op_union, 
rel_projections(v->sql, rel, NULL, 1, 1));
                v->changes++;
                return rel;
        }
@@ -5648,7 +5649,7 @@ rel_push_project_down_union(visitor *v, 
                ul->exps = exps_copy(v->sql, p->exps);
                ur->exps = exps_copy(v->sql, p->exps);
 
-               rel = rel_inplace_setop(rel, ul, ur, op_union,
+               rel = rel_inplace_setop(v->sql, rel, ul, ur, op_union,
                        rel_projections(v->sql, rel, NULL, 1, 1));
                if (need_distinct)
                        set_distinct(rel);
diff --git a/sql/server/rel_rel.c b/sql/server/rel_rel.c
--- a/sql/server/rel_rel.c
+++ b/sql/server/rel_rel.c
@@ -417,18 +417,15 @@ rel_first_column(mvc *sql, sql_rel *r)
 }
 
 sql_rel *
-rel_inplace_setop(sql_rel *rel, sql_rel *l, sql_rel *r, operator_type setop, 
list *exps)
+rel_inplace_setop(mvc *sql, sql_rel *rel, sql_rel *l, sql_rel *r, 
operator_type setop, list *exps)
 {
        rel_destroy_(rel);
        rel->l = l;
        rel->r = r;
        rel->op = setop;
-       rel->exps = NULL;
        rel->card = CARD_MULTI;
        rel->flag = 0;
-       if (l && r)
-               rel->nrcols = l->nrcols + r->nrcols;
-       rel->exps = exps;
+       rel_setop_set_exps(sql, rel, exps);
        set_processed(rel);
        return rel;
 }
@@ -540,6 +537,7 @@ rel_setop_set_exps(mvc *sql, sql_rel *re
                                set_has_nil(e);
                        else
                                set_has_no_nil(e);
+                       e->p = NULL; /* remove all the properties on unions */
                        e->card = MAX(f->card, g->card);
                } else
                        e->card = f->card;
@@ -1452,7 +1450,7 @@ rel_or(mvc *sql, sql_rel *rel, sql_rel *
        rel = rel_setop_check_types(sql, l, r, ls, rs, op_union);
        if (!rel)
                return NULL;
-       rel->exps = rel_projections(sql, rel, NULL, 1, 1);
+       rel_setop_set_exps(sql, rel, rel_projections(sql, rel, NULL, 1, 1));
        set_processed(rel);
        rel->nrcols = list_length(rel->exps);
        rel = rel_distinct(rel);
diff --git a/sql/server/rel_rel.h b/sql/server/rel_rel.h
--- a/sql/server/rel_rel.h
+++ b/sql/server/rel_rel.h
@@ -68,7 +68,7 @@ extern sql_exp *rel_bind_column( mvc *sq
 extern sql_exp *rel_bind_column2( mvc *sql, sql_rel *rel, const char *tname, 
const char *cname, int f );
 extern sql_exp *rel_first_column(mvc *sql, sql_rel *rel);
 
-extern sql_rel *rel_inplace_setop(sql_rel *rel, sql_rel *l, sql_rel *r, 
operator_type setop, list *exps);
+extern sql_rel *rel_inplace_setop(mvc *sql, sql_rel *rel, sql_rel *l, sql_rel 
*r, operator_type setop, list *exps);
 extern sql_rel *rel_inplace_project(sql_allocator *sa, sql_rel *rel, sql_rel 
*l, list *e);
 extern sql_rel *rel_inplace_groupby(sql_rel *rel, sql_rel *l, list 
*groupbyexps, list *exps );
 
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
@@ -2007,9 +2007,9 @@ rewrite_or_exp(visitor *v, sql_rel *rel)
                                        list *rs = rel_projections(v->sql, rel, 
NULL, 1, 1);
                                        if (!(rel = 
rel_setop_check_types(v->sql, l, r, ls, rs, op_union)))
                                                return NULL;
+                                       rel_setop_set_exps(v->sql, rel, exps);
                                        set_processed(rel);
                                        rel = rel_distinct(rel);
-                                       rel_set_exps(rel, exps);
                                        v->changes++;
                                        return rel;
                                }
@@ -3183,7 +3183,7 @@ rewrite_outer2inner_union(visitor *v, sq
                                        prel,
                                        rel_project(v->sql->sa, nrel, 
rel_projections(v->sql, nrel, NULL, 1, 1)),
                                        op_union);
-                       rel_set_exps(nrel, rel_projections(v->sql, rel, NULL, 
1, 1));
+                       rel_setop_set_exps(v->sql, nrel, 
rel_projections(v->sql, rel, NULL, 1, 1));
                        set_processed(nrel);
                        return nrel;
                } else if (is_right(rel->op)) {
@@ -3200,7 +3200,7 @@ rewrite_outer2inner_union(visitor *v, sq
                                        prel,
                                        rel_project(v->sql->sa, nrel, 
rel_projections(v->sql, nrel, NULL, 1, 1)),
                                        op_union);
-                       rel_set_exps(nrel, rel_projections(v->sql, rel, NULL, 
1, 1));
+                       rel_setop_set_exps(v->sql, nrel, 
rel_projections(v->sql, rel, NULL, 1, 1));
                        set_processed(nrel);
                        return nrel;
                } else if (is_full(rel->op)) {
@@ -3292,7 +3292,7 @@ rewrite_values(visitor *v, sql_rel *rel)
                        }
                        if (cur) {
                                nrel = rel_setop(v->sql->sa, cur, nrel, 
op_union);
-                               rel_set_exps(nrel, exps);
+                               rel_setop_set_exps(v->sql, nrel, exps);
                                set_processed(nrel);
                        }
                        cur = nrel;
diff --git a/sql/test/SQLancer/Tests/sqlancer02.stable.out 
b/sql/test/SQLancer/Tests/sqlancer02.stable.out
--- a/sql/test/SQLancer/Tests/sqlancer02.stable.out
+++ b/sql/test/SQLancer/Tests/sqlancer02.stable.out
@@ -1363,6 +1363,30 @@ stdout of test 'sqlancer02` in directory
 % tinyint # type
 % 1 # length
 #ROLLBACK;
+#START TRANSACTION;
+#CREATE TABLE "t1" ("c0" BOOLEAN NOT NULL,CONSTRAINT "t1_c0_pkey" PRIMARY KEY 
("c0"),CONSTRAINT "t1_c0_unique" UNIQUE ("c0"));
+#INSERT INTO "t1" VALUES (false), (true);
+[ 2    ]
+#create view v5(vc0) as (values (1), (4));
+#create view v8(vc1) as ((select l0t1.c0 from t1 as l0t1) union distinct 
(select false));
+#SELECT v5.vc0 FROM v5, v8 JOIN (VALUES (0.3, 10.0),(0.5, 8.0)) AS sub0 ON 
+#true WHERE least(CASE v5.vc0 WHEN v5.vc0 THEN v8.vc1 END, true);
+% .v5 # table_name
+% vc0 # name
+% tinyint # type
+% 1 # length
+[ 1    ]
+[ 1    ]
+[ 4    ]
+[ 4    ]
+#SELECT CAST(SUM(count) AS BIGINT) FROM (SELECT CAST(least(CASE v5.vc0 WHEN 
v5.vc0 THEN v8.vc1 END, true) AS INT) as count
+#FROM v5, v8 JOIN (VALUES (0.3, 10.0),(0.5, 8.0)) AS sub0 ON true) as res;
+% .%22 # table_name
+% %22 # name
+% bigint # type
+% 1 # length
+[ 4    ]
+#ROLLBACK;
 
 # 17:04:12 >  
 # 17:04:12 >  "Done."
diff --git a/sql/test/merge-partitions/Tests/mergepart31.stable.out 
b/sql/test/merge-partitions/Tests/mergepart31.stable.out
--- a/sql/test/merge-partitions/Tests/mergepart31.stable.out
+++ b/sql/test/merge-partitions/Tests/mergepart31.stable.out
@@ -53,7 +53,7 @@ union (
 | | | table("sys"."second_decade") [ "second_decade"."stamp" as 
"splitted"."stamp" ] COUNT 
 | | ) [ "splitted"."stamp" in (timestamp(7) "2000-01-01 00:00:00.000000" as 
"%2"."%2", timestamp(7) "2010-01-01 00:00:00.000000" as "%3"."%3") ]
 | ) [ tinyint "1" ]
-) [ "%6"."%6" NOT NULL ]
+) [ "%10"."%10" NOT NULL ]
 #plan select 1 from splitted where stamp IN (TIMESTAMP '2000-02-01 00:00:00', 
TIMESTAMP '2010-02-01 00:00:00', TIMESTAMP '2020-02-01 00:00:00'); --nothing 
gets pruned
 % .plan # table_name
 % rel # name
@@ -71,13 +71,13 @@ union (
 | | | | table("sys"."second_decade") [ "second_decade"."stamp" as 
"splitted"."stamp" ] COUNT 
 | | | ) [ "splitted"."stamp" in (timestamp(7) "2000-02-01 00:00:00.000000" as 
"%2"."%2", timestamp(7) "2010-02-01 00:00:00.000000" as "%3"."%3", timestamp(7) 
"2020-02-01 00:00:00.000000" as "%4"."%4") ]
 | | ) [ tinyint "1" ]
-| ) [ "%11"."%11" NOT NULL ],
+| ) [ "%15"."%15" NOT NULL ],
 | project (
 | | select (
 | | | table("sys"."third_decade") [ "third_decade"."stamp" as 
"splitted"."stamp" ] COUNT 
 | | ) [ "splitted"."stamp" in (timestamp(7) "2000-02-01 00:00:00.000000" as 
"%2"."%2", timestamp(7) "2010-02-01 00:00:00.000000" as "%3"."%3", timestamp(7) 
"2020-02-01 00:00:00.000000" as "%4"."%4") ]
 | ) [ tinyint "1" ]
-) [ "%10"."%10" NOT NULL ]
+) [ "%14"."%14" NOT NULL ]
 #plan select 1 from splitted where stamp BETWEEN TIMESTAMP '2020-01-01 
00:00:00' AND TIMESTAMP '2020-10-01 00:00:00'; --only third child passes
 % .plan # table_name
 % rel # name
@@ -104,7 +104,7 @@ union (
 | | | table("sys"."second_decade") [ "second_decade"."stamp" as 
"splitted"."stamp" ] COUNT 
 | | ) [ timestamp(7) "2020-01-01 00:00:00.000000" ! <= "splitted"."stamp" ! <= 
timestamp(7) "2020-10-01 00:00:00.000000" BETWEEN  ]
 | ) [ tinyint "1" ]
-) [ "%3"."%3" NOT NULL ]
+) [ "%5"."%5" NOT NULL ]
 #plan select 1 from splitted where stamp BETWEEN TIMESTAMP '2010-01-01 
00:00:00' AND TIMESTAMP '2020-03-01 00:00:00'; --first child pruned
 % .plan # table_name
 % rel # name
@@ -121,7 +121,7 @@ union (
 | | | table("sys"."third_decade") [ "third_decade"."stamp" as 
"splitted"."stamp" ] COUNT 
 | | ) [ timestamp(7) "2010-01-01 00:00:00.000000" <= "splitted"."stamp" <= 
timestamp(7) "2020-03-01 00:00:00.000000" BETWEEN  ]
 | ) [ tinyint "1" ]
-) [ "%3"."%3" NOT NULL ]
+) [ "%5"."%5" NOT NULL ]
 #plan select 1 from splitted where stamp BETWEEN TIMESTAMP '2000-02-01 
00:00:00' AND TIMESTAMP '2020-03-01 00:00:00'; --nothing gets pruned
 % .plan # table_name
 % rel # name
@@ -139,13 +139,13 @@ union (
 | | | | table("sys"."second_decade") [ "second_decade"."stamp" as 
"splitted"."stamp" ] COUNT 
 | | | ) [ timestamp(7) "2000-02-01 00:00:00.000000" <= "splitted"."stamp" <= 
timestamp(7) "2020-03-01 00:00:00.000000" BETWEEN  ]
 | | ) [ tinyint "1" ]
-| ) [ "%5"."%5" NOT NULL ],
+| ) [ "%11"."%11" NOT NULL ],
 | project (
 | | select (
 | | | table("sys"."third_decade") [ "third_decade"."stamp" as 
"splitted"."stamp" ] COUNT 
 | | ) [ timestamp(7) "2000-02-01 00:00:00.000000" <= "splitted"."stamp" <= 
timestamp(7) "2020-03-01 00:00:00.000000" BETWEEN  ]
 | ) [ tinyint "1" ]
-) [ "%4"."%4" NOT NULL ]
+) [ "%10"."%10" NOT NULL ]
 #plan select 1 from splitted where stamp NOT BETWEEN TIMESTAMP '2000-02-01 
00:00:00' AND TIMESTAMP '2020-03-01 00:00:00'; --all children pruned
 % .plan # table_name
 % rel # name
@@ -177,7 +177,7 @@ union (
 | | | table("sys"."third_decade") [ "third_decade"."stamp" as 
"splitted"."stamp" ] COUNT 
 | | ) [ "splitted"."stamp" > timestamp(7) "2010-03-01 00:00:00.000000" ]
 | ) [ tinyint "1" ]
-) [ "%3"."%3" NOT NULL ]
+) [ "%5"."%5" NOT NULL ]
 #plan select 1 from splitted where stamp <= TIMESTAMP '2009-01-01 00:00:00';  
--only first child passes
 % .plan # table_name
 % rel # name
@@ -215,13 +215,13 @@ union (
 | | | | table("sys"."second_decade") [ "second_decade"."stamp" as 
"splitted"."stamp" ] COUNT 
 | | | ) [ "splitted"."stamp" <= timestamp(7) "2020-10-01 00:00:00.000000" ]
 | | ) [ tinyint "1" ]
-| ) [ "%5"."%5" NOT NULL ],
+| ) [ "%11"."%11" NOT NULL ],
 | project (
 | | select (
 | | | table("sys"."third_decade") [ "third_decade"."stamp" as 
"splitted"."stamp" ] COUNT 
 | | ) [ "splitted"."stamp" <= timestamp(7) "2020-10-01 00:00:00.000000" ]
 | ) [ tinyint "1" ]
-) [ "%4"."%4" NOT NULL ]
+) [ "%10"."%10" NOT NULL ]
 #plan select 1 from splitted where stamp < TIMESTAMP '2000-01-01 00:00:00'; 
--all children pruned
 % .plan # table_name
 % rel # name
@@ -288,7 +288,7 @@ union (
 | | | table("sys"."second_decade") [ "second_decade"."stamp" as 
"splitted"."stamp" ] COUNT 
 | | ) [ timestamp(7) "2000-01-01 00:00:00.000000" <= "splitted"."stamp" < 
timestamp(7) "2020-01-01 00:00:00.000000" BETWEEN  ]
 | ) [ tinyint "1" ]
-) [ "%3"."%3" NOT NULL ]
+) [ "%5"."%5" NOT NULL ]
 #plan select 1 from splitted where stamp > TIMESTAMP '2010-01-01 00:00:00' and 
stamp < TIMESTAMP '2020-01-01 00:00:00'; --only second child passes
 % .plan # table_name
 % rel # name
@@ -325,7 +325,7 @@ union (
 | | | table("sys"."second_decade") [ "second_decade"."stamp" as 
"splitted"."stamp" ] COUNT 
 | | ) [ timestamp(7) "2001-01-02 00:00:00.000000" < "splitted"."stamp" < 
timestamp(7) "2015-01-01 00:00:00.000000" BETWEEN  ]
 | ) [ tinyint "1" ]
-) [ "%3"."%3" NOT NULL ]
+) [ "%5"."%5" NOT NULL ]
 #plan select 1 from splitted where stamp > TIMESTAMP '2010-01-01 00:00:00' and 
stamp < TIMESTAMP '2010-01-01 00:00:00'; --all children pruned
 % .plan # table_name
 % rel # name
@@ -352,7 +352,7 @@ union (
 | | | table("sys"."second_decade") [ "second_decade"."stamp" as 
"splitted"."stamp" ] COUNT 
_______________________________________________
checkin-list mailing list
checkin-list@monetdb.org
https://www.monetdb.org/mailman/listinfo/checkin-list

Reply via email to