Changeset: 43ad3ab454ad for MonetDB
URL: https://dev.monetdb.org/hg/MonetDB?cmd=changeset;node=43ad3ab454ad
Added Files:
        sql/test/bugs/Tests/rtrim_bug.test
Modified Files:
        sql/backends/monet5/rel_bin.c
        sql/server/rel_optimizer.c
        sql/test/miscellaneous/Tests/simple_plans.stable.out
        sql/test/miscellaneous/Tests/simple_selects.test
Branch: default
Log Message:

Merged with Oct2020 and converted tests


diffs (294 lines):

diff --git a/sql/backends/monet5/rel_bin.c b/sql/backends/monet5/rel_bin.c
--- a/sql/backends/monet5/rel_bin.c
+++ b/sql/backends/monet5/rel_bin.c
@@ -2519,8 +2519,6 @@ rel2bin_antijoin(backend *be, sql_rel *r
        return stmt_list(be, l);
 }
 
-#define complex_join_expression(e) (exp_has_func(e) && (e)->flag != 
cmp_filter) || (e)->flag == cmp_or || ((e)->f && (e)->anti)
-
 static stmt *
 rel2bin_semijoin(backend *be, sql_rel *rel, list *refs)
 {
@@ -2565,7 +2563,7 @@ rel2bin_semijoin(backend *be, sql_rel *r
                        int idx = 0, equality_only = 1;
 
                        jexps = get_equi_joins_first(sql, jexps, 
&equality_only);
-                       if (!equality_only || list_length(jexps) > 1 || 
complex_join_expression((sql_exp*)jexps->h->data))
+                       if (!equality_only || list_length(jexps) > 1 || 
exp_has_func((sql_exp*)jexps->h->data))
                                left = subrel_project(be, left, refs, rel->l);
                        right = subrel_project(be, right, refs, rel->r);
 
@@ -2575,7 +2573,7 @@ rel2bin_semijoin(backend *be, sql_rel *r
                                stmt *s = NULL;
 
                                /* only handle simple joins here */
-                               if (complex_join_expression(e)) {
+                               if ((exp_has_func(e) && e->flag != cmp_filter) 
|| e->flag == cmp_or || (e->f && e->anti)) {
                                        if (!join && !list_length(lje)) {
                                                stmt *l = bin_first_column(be, 
left);
                                                stmt *r = bin_first_column(be, 
right);
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
@@ -1350,16 +1350,16 @@ can_push_func(sql_exp *e, sql_rel *rel, 
 {
        switch(e->type) {
        case e_cmp: {
+               int mustl = 0, mustr = 0, mustf = 0;
                sql_exp *l = e->l, *r = e->r, *f = e->f;
-               int res = 1, lmust = 0;
-
-               if (e->flag == cmp_or || e->flag == cmp_in || e->flag == 
cmp_notin || e->flag == cmp_filter)
+
+               if (is_project(rel->op) || e->flag == cmp_or || e->flag == 
cmp_in || e->flag == cmp_notin || e->flag == cmp_filter)
                        return 0;
-               res = can_push_func(l, rel, &lmust) && can_push_func(r, rel, 
&lmust) && (!f || can_push_func(f, rel, &lmust));
-               if (res && !lmust)
-                       return 1;
-               (*must) |= lmust;
-               return res;
+               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)));
        }
        case e_convert:
                return can_push_func(e->l, rel, must);
@@ -1378,8 +1378,7 @@ can_push_func(sql_exp *e, sql_rel *rel, 
                return res;
        }
        case e_column:
-                /* aliases cannot be bound on the same level, ie same 
projection */
-               if ((exp_name(e) && !has_label(e)) || (rel && 
!rel_find_exp(rel, e)))
+               if (rel && !rel_find_exp(rel, e))
                        return 0;
                (*must) = 1;
                /* fall through */
diff --git a/sql/test/bugs/Tests/rtrim_bug.sql 
b/sql/test/bugs/Tests/rtrim_bug.sql
--- a/sql/test/bugs/Tests/rtrim_bug.sql
+++ b/sql/test/bugs/Tests/rtrim_bug.sql
@@ -12,6 +12,24 @@ SELECT length("m") as data_length, "m" a
 
 CREATE VIEW v2 as select "m" from t1 where rtrim(m) in (select rtrim(m) from 
sys.t1);
 SELECT * FROM v2;
+
+PLAN SELECT length("m") as data_length, "m" as data_value FROM "sys"."v2" 
WHERE "m" IS NOT NULL AND length("m") > 1;
+
+set optimizer = 'sequential_pipe';
+create procedure profiler.starttrace() external name profiler."starttrace";
+create procedure profiler.stoptrace() external name profiler.stoptrace;
+
+call profiler."starttrace"();
+SELECT length("m") as data_length, "m" as data_value FROM "sys"."v2" WHERE "m" 
IS NOT NULL AND length("m") > 1;
+call profiler.stoptrace();
+
+select count(*) from sys.tracelog() where stmt like '% algebra.crossproduct%'; 
-- don't do crossjoin
+select count(*) from sys.tracelog() where stmt like '% algebra.join%'; -- do 
inner join
+
+drop procedure profiler.starttrace();
+drop procedure profiler.stoptrace();
+set optimizer = 'default_pipe';
+
 SELECT length("m") as data_length, "m" as data_value FROM "sys"."v2" WHERE "m" 
IS NOT NULL AND length("m") > 1;
 -- 2 rows returned !! should be 0 rows as with v1 !!
 -- This query produces wrong results!!
diff --git a/sql/test/bugs/Tests/rtrim_bug.stable.out 
b/sql/test/bugs/Tests/rtrim_bug.stable.out
--- a/sql/test/bugs/Tests/rtrim_bug.stable.out
+++ b/sql/test/bugs/Tests/rtrim_bug.stable.out
@@ -43,6 +43,48 @@ stdout of test 'rtrim_bug` in directory 
 % 1 # length
 [ "0"  ]
 [ "2"  ]
+#PLAN SELECT length("m") as data_length, "m" as data_value FROM "sys"."v2" 
WHERE "m" IS NOT NULL AND length("m") > 1;
+% .plan # table_name
+% rel # name
+% clob # type
+% 112 # length
+project (
+| semijoin (
+| | project (
+| | | select (
+| | | | table("sys"."t1") [ "t1"."m" NOT NULL ] COUNT 
+| | | ) [ "sys"."length"("t1"."m" NOT NULL) NOT NULL > int "1" ]
+| | ) [ "t1"."m" NOT NULL, "sys"."rtrim"("t1"."m" NOT NULL) NOT NULL as 
"%5"."%5" ],
+| | project (
+| | | project (
+| | | | table("sys"."t1") [ "t1"."m" NOT NULL ] COUNT 
+| | | ) [ "sys"."rtrim"("t1"."m" NOT NULL) NOT NULL as "%1"."%1" ]
+| | ) [ "%1"."%1" NOT NULL as "%4"."%4" ]
+| ) [ "%5"."%5" NOT NULL any = "%4"."%4" NOT NULL ]
+) [ "sys"."length"("t1"."m" NOT NULL as "v2"."m") NOT NULL as "data_length", 
"t1"."m" NOT NULL as "data_value" ]
+#set optimizer = 'sequential_pipe';
+#create procedure profiler.starttrace() external name profiler."starttrace";
+#create procedure profiler.stoptrace() external name profiler.stoptrace;
+#SELECT length("m") as data_length, "m" as data_value FROM "sys"."v2" WHERE 
"m" IS NOT NULL AND length("m") > 1;
+% sys.,        sys. # table_name
+% data_length, data_value # name
+% int, varchar # type
+% 1,   0 # length
+#select count(*) from sys.tracelog() where stmt like '% 
algebra.crossproduct%'; -- don't do crossjoin
+% .%2 # table_name
+% %2 # name
+% bigint # type
+% 1 # length
+[ 0    ]
+#select count(*) from sys.tracelog() where stmt like '% algebra.join%'; -- do 
inner join
+% .%2 # table_name
+% %2 # name
+% bigint # type
+% 1 # length
+[ 1    ]
+#drop procedure profiler.starttrace();
+#drop procedure profiler.stoptrace();
+#set optimizer = 'default_pipe';
 #SELECT length("m") as data_length, "m" as data_value FROM "sys"."v2" WHERE 
"m" IS NOT NULL AND length("m") > 1;
 % sys.,        sys. # table_name
 % data_length, data_value # name
diff --git a/sql/test/bugs/Tests/rtrim_bug.test 
b/sql/test/bugs/Tests/rtrim_bug.test
new file mode 100644
--- /dev/null
+++ b/sql/test/bugs/Tests/rtrim_bug.test
@@ -0,0 +1,112 @@
+statement ok
+CREATE TABLE t1 (m varchar (1) NOT NULL)
+
+statement ok
+INSERT into t1 values ('0')
+
+statement ok
+INSERT into t1 values ('2')
+
+query T rowsort
+SELECT * FROM sys.t1
+----
+0
+2
+
+query IT rowsort
+SELECT length("m") as data_length, "m" as data_value FROM "sys"."t1" WHERE "m" 
IS NOT NULL AND length("m") > 1
+----
+
+statement ok
+CREATE VIEW v1 as select "m" from t1 where m in (select m from sys.t1)
+
+query T rowsort
+SELECT * FROM v1
+----
+0
+2
+
+query IT rowsort
+SELECT length("m") as data_length, "m" as data_value FROM "sys"."v1" WHERE "m" 
IS NOT NULL AND length("m") > 1
+----
+
+statement ok
+CREATE VIEW v2 as select "m" from t1 where rtrim(m) in (select rtrim(m) from 
sys.t1)
+
+query T rowsort
+SELECT * FROM v2
+----
+0
+2
+
+query T nosort
+PLAN SELECT length("m") as data_length, "m" as data_value FROM "sys"."v2" 
WHERE "m" IS NOT NULL AND length("m") > 1
+----
+project (
+| semijoin (
+| | project (
+| | | select (
+| | | | table("sys"."t1") [ "t1"."m" NOT NULL ] COUNT 
+| | | ) [ "sys"."length"("t1"."m" NOT NULL) NOT NULL > int "1" ]
+| | ) [ "t1"."m" NOT NULL, "sys"."rtrim"("t1"."m" NOT NULL) NOT NULL as 
"%5"."%5" ],
+| | project (
+| | | project (
+| | | | table("sys"."t1") [ "t1"."m" NOT NULL ] COUNT 
+| | | ) [ "sys"."rtrim"("t1"."m" NOT NULL) NOT NULL as "%1"."%1" ]
+| | ) [ "%1"."%1" NOT NULL as "%4"."%4" ]
+| ) [ "%5"."%5" NOT NULL any = "%4"."%4" NOT NULL ]
+) [ "sys"."length"("t1"."m" NOT NULL as "v2"."m") NOT NULL as "data_length", 
"t1"."m" NOT NULL as "data_value" ]
+
+statement ok
+set optimizer = 'sequential_pipe'
+
+statement ok
+create procedure profiler.starttrace() external name profiler."starttrace"
+
+statement ok
+create procedure profiler.stoptrace() external name profiler.stoptrace
+
+statement ok
+call profiler."starttrace"()
+
+query IT rowsort
+SELECT length("m") as data_length, "m" as data_value FROM "sys"."v2" WHERE "m" 
IS NOT NULL AND length("m") > 1
+----
+
+query IT rowsort
+call profiler.stoptrace()
+----
+
+query I rowsort
+select count(*) from sys.tracelog() where stmt like '% algebra.crossproduct%'
+----
+0
+
+query I rowsort
+select count(*) from sys.tracelog() where stmt like '% algebra.join%'
+----
+1
+
+statement ok
+drop procedure profiler.starttrace()
+
+statement ok
+drop procedure profiler.stoptrace()
+
+statement ok
+set optimizer = 'default_pipe'
+
+query IT rowsort
+SELECT length("m") as data_length, "m" as data_value FROM "sys"."v2" WHERE "m" 
IS NOT NULL AND length("m") > 1
+----
+
+statement ok
+DROP VIEW v1
+
+statement ok
+DROP VIEW v2
+
+statement ok
+DROP TABLE t1
+
+
diff --git a/sql/test/miscellaneous/Tests/simple_selects.test 
b/sql/test/miscellaneous/Tests/simple_selects.test
--- a/sql/test/miscellaneous/Tests/simple_selects.test
+++ b/sql/test/miscellaneous/Tests/simple_selects.test
@@ -676,6 +676,25 @@ statement ok
 start transaction
 
 statement ok
+create table t1("kk" int)
+
+statement ok
+create table t2("kk" int)
+
+statement ok
+create table t3("tkey" int)
+
+statement error
+SELECT 1 FROM (((t1 t10 INNER JOIN t2 t20 ON t10."kk" = t20."kk") INNER JOIN 
t2 t20 ON t10."kk" = t20."kk")
+INNER JOIN t3 t31 ON t20."kk" = t31."tkey"); --error, multiple references to 
relation t20
+
+statement ok
+rollback
+
+statement ok
+start transaction
+
+statement ok
 create or replace function ups() returns int begin if null > 1 then return 1; 
else return 2; end if; end
 
 query I rowsort
_______________________________________________
checkin-list mailing list
checkin-list@monetdb.org
https://www.monetdb.org/mailman/listinfo/checkin-list

Reply via email to