Changeset: 2a9ed54b4634 for MonetDB
URL: https://dev.monetdb.org/hg/MonetDB?cmd=changeset;node=2a9ed54b4634
Modified Files:
        sql/server/rel_optimizer.c
        sql/server/rel_select.c
        sql/server/rel_unnest.c
        sql/test/SQLancer/Tests/sqlancer07.stable.out
        sql/test/SQLancer/Tests/sqlancer07.stable.out.int128
Branch: octbugs
Log Message:

fix more sqlancer bugs.

Make sure we don't push semijoins down outer joins (or wrong sides of 
left/right outer joins)
flatten simple selects a bit (1, select 2) -> 1,2 values list

fixed buts in rewrite_values (ie propagate single not always set single)

moved rewrite_values before rewrite_complex


diffs (264 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
@@ -4865,7 +4865,7 @@ rel_push_semijoin_down_or_up(visitor *v,
                        l = l->l;
                */
 
-               if (!is_join(l->op) || rel_is_ref(l))
+               if (!is_join(l->op) || is_full(l->op) || rel_is_ref(l))
                        return rel;
 
                lop = l->op;
@@ -4897,6 +4897,10 @@ rel_push_semijoin_down_or_up(visitor *v,
                        if (!right && !left)
                                return rel;
                }
+               if (left && is_right(lop))
+                       return rel;
+               if (right && is_left(lop))
+                       return rel;
                nsexps = exps_copy(v->sql, rel->exps);
                njexps = exps_copy(v->sql, l->exps);
                if (left)
@@ -4907,7 +4911,7 @@ rel_push_semijoin_down_or_up(visitor *v,
                if (left)
                        l = rel_crossproduct(v->sql->sa, l, rel_dup(lr), lop);
                else
-                       l = rel_crossproduct(v->sql->sa, l, rel_dup(ll), lop);
+                       l = rel_crossproduct(v->sql->sa, rel_dup(ll), l, lop);
                l->exps = njexps;
                rel_destroy(rel);
                rel = l;
diff --git a/sql/server/rel_select.c b/sql/server/rel_select.c
--- a/sql/server/rel_select.c
+++ b/sql/server/rel_select.c
@@ -1822,6 +1822,17 @@ rel_exists_exp(sql_query *query, sql_rel
        return NULL;
 }
 
+static int
+is_project_true(sql_rel *r)
+{
+       if (r && !r->l && list_length(r->exps) == 1) {
+               sql_exp *e = r->exps->h->data;
+               if (exp_is_atom(e) && exp_is_true(e))
+                       return 1;
+       }
+       return 0;
+}
+
 static sql_exp *
 rel_in_value_exp(sql_query *query, sql_rel **rel, symbol *sc, int f)
 {
@@ -1880,6 +1891,10 @@ rel_in_value_exp(sql_query *query, sql_r
                                if (r->nrcols != ek.type)
                                        return sql_error(sql, 02, 
SQLSTATE(42000) "Subquery has too %s columns", (r->nrcols < ek.type) ? "few" : 
"many");
                                re = exp_rel_label(sql, re);
+                       } else if (exp_is_rel(re)) {
+                               sql_rel *r = exp_rel_get_rel(sql->sa, re);
+                               if (is_project(r->op) && is_project_true(r->l) 
&& list_length(r->exps) == 1)
+                                       re = r->exps->h->data;
                        }
                        append(vals, re);
                }
@@ -5835,7 +5850,7 @@ rel_crossquery(sql_query *query, sql_rel
        rname2 = rel_name(t2);
        if (rname1 && rname2 && strcmp(rname1, rname2) == 0)
                return sql_error(sql, 02, SQLSTATE(42000) "SELECT: '%s' on both 
sides of the CROSS JOIN expression", rname1);
-       
+
        if (refs) {
                if (list_find(refs, (char *)rname1, (fcmp) &strcmp))
                        return sql_error(sql, 02, SQLSTATE(42000) "SELECT: 
relation name \"%s\" specified more than once", rname1);
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
@@ -3212,11 +3212,12 @@ rewrite_complex(visitor *v, sql_rel *rel
 static sql_rel *
 rewrite_values(visitor *v, sql_rel *rel)
 {
+       int single = is_single(rel);
        if (!is_simple_project(rel->op) || list_empty(rel->exps))
                return rel;
        sql_exp *e = rel->exps->h->data;
 
-       if (!is_values(e) || list_length(exp_get_values(e))<=1 || 
!rel_has_freevar(v->sql, rel))
+       if (!is_values(e) || list_length(exp_get_values(e))<=1 || 
(!exp_has_freevar(v->sql, e) && !exp_has_rel(e)))
                return rel;
 
        list *exps = sa_list(v->sql->sa);
@@ -3246,7 +3247,8 @@ rewrite_values(visitor *v, sql_rel *rel)
                        cur = nrel;
                }
                rel = cur;
-               set_single(rel);
+               if (single)
+                       set_single(rel);
        }
        return rel;
 }
@@ -3278,6 +3280,8 @@ rel_unnest(mvc *sql, sql_rel *rel)
        rel = rel_exp_visitor_bottomup(&v, rel, &rewrite_rank, false);
        rel = rel_visitor_bottomup(&v, rel, &rewrite_outer2inner_union);
 
+       rel = rel_visitor_bottomup(&v, rel, &rewrite_values); /* must come 
before rewrite_exp_rel */
+
        // remove empty project/groupby !
        rel = rel_visitor_bottomup(&v, rel, &rewrite_empty_project);
        rel = rel_exp_visitor_bottomup(&v, rel, &rewrite_complex, true);
@@ -3285,7 +3289,6 @@ rel_unnest(mvc *sql, sql_rel *rel)
        rel = rel_exp_visitor_bottomup(&v, rel, &rewrite_ifthenelse, false);    
/* add isnull handling */
        rel = rel_exp_visitor_bottomup(&v, rel, &reset_exp_used, false);        
/* reset used flag from ifthenelse re-writer, so it can be used again by the 
rel_dce optimizer */
 
-       rel = rel_visitor_bottomup(&v, rel, &rewrite_values); /* must come 
before rewrite_exp_rel */
        rel = rel_exp_visitor_bottomup(&v, rel, &rewrite_exp_rel, true);
        rel = rel_visitor_bottomup(&v, rel, &rewrite_join2semi);        /* 
where possible convert anyequal functions into marks */
        if (v.changes > 0)
diff --git a/sql/test/SQLancer/Tests/sqlancer07.stable.out 
b/sql/test/SQLancer/Tests/sqlancer07.stable.out
--- a/sql/test/SQLancer/Tests/sqlancer07.stable.out
+++ b/sql/test/SQLancer/Tests/sqlancer07.stable.out
@@ -152,12 +152,12 @@ stdout of test 'sqlancer07` in directory
 #INSERT INTO "t2" VALUES 
('4'),('4'),('3eSU8,'),(''),('5E~쟱'),('~'),('1386006226'),('0.19005213960704492'),('''{Mdd뒆VB'''),('\015␱%L%]'),('+'),(''),('㕚o+k');
 [ 13   ]
 #select t0.c1 from t0 where (5) in (case when t0.c1 = 'a' then 1 end, (select 
3));
-% .t0 # table_name
+% sys.t0 # table_name
 % c1 # name
 % varchar # type
 % 0 # length
 #select t0.c1 from t0 where (5) in ((select 3), case when t0.c1 = 'a' then 1 
end);
-% .t0 # table_name
+% sys.t0 # table_name
 % c1 # name
 % varchar # type
 % 0 # length
@@ -201,8 +201,8 @@ stdout of test 'sqlancer07` in directory
 #INSERT INTO "t2" VALUES (596983192), (-601428889), (1688368391);
 [ 3    ]
 #SELECT 1 FROM t2, t0 CROSS JOIN t1 WHERE t0.c0 % (SELECT 1 WHERE FALSE) <= 
t1.c0;
-% .%4 # table_name
-% %4 # name
+% .%3 # table_name
+% %3 # name
 % tinyint # type
 % 1 # length
 #SELECT t1.c0 FROM t2, t0 CROSS JOIN t1 WHERE ((((t0.c0)%((SELECT DISTINCT 
t0.c0 FROM t1, t0, t2 WHERE FALSE))))<=(t1.c0));
@@ -321,8 +321,8 @@ stdout of test 'sqlancer07` in directory
 #INSERT INTO "t1" VALUES (1);
 [ 1    ]
 #SELECT 1 FROM t0 WHERE (EXISTS (SELECT 1 WHERE FALSE)) IN ((SELECT FALSE)); 
-- rel_push_semijoin_down_or_up is causing the issue
-% .%11 # table_name
-% %11 # name
+% .%7 # table_name
+% %7 # name
 % tinyint # type
 % 1 # length
 #SELECT t0.c0 FROM t0 WHERE (EXISTS (SELECT TRUE, 0.3, INTERVAL '5' MONTH, 
TIME '16:59:58' WHERE FALSE)) IN ((SELECT DISTINCT FALSE FROM t1), (('0.9')NOT 
ILIKE('')));
@@ -426,8 +426,8 @@ stdout of test 'sqlancer07` in directory
 #INSERT INTO "t2" VALUES (446453788), (1973525566), (1604369323), 
(-907882617), (1067873323), (1615259391), (1286378024);
 [ 7    ]
 #SELECT 1 FROM t0 RIGHT OUTER JOIN t1 ON 3 IN ((SELECT 2), t1.c0);
-% .%10 # table_name
-% %10 # name
+% .%6 # table_name
+% %6 # name
 % tinyint # type
 % 1 # length
 [ 1    ]
@@ -454,6 +454,18 @@ stdout of test 'sqlancer07` in directory
 % %10 # name
 % tinyint # type
 % 1 # length
+#SELECT 1 FROM (SELECT 1) as v3(c0) RIGHT JOIN (SELECT 2) as v4(c0) ON (0.6) 
NOT IN (0.5, (SELECT 0.2));
+% .%7 # table_name
+% %7 # name
+% tinyint # type
+% 1 # length
+[ 1    ]
+#SELECT * FROM (SELECT 1) as v3(c0) LEFT JOIN (SELECT 2) as v4(c0) ON (0.6) 
NOT IN ((SELECT v4.c0), 0.5);
+% .v3, .v4 # table_name
+% c0,  c0 # name
+% tinyint,     tinyint # type
+% 1,   1 # length
+[ 1,   2       ]
 #SELECT FALSE FROM v3, v0 FULL OUTER JOIN v4 ON sql_max(FALSE, (0.6902854) NOT 
IN (0.5854332103580835, CASE WHEN v4.vc0 THEN (SELECT 0.023816515 WHERE TRUE) 
END));
 % .%16 # table_name
 % %16 # name
diff --git a/sql/test/SQLancer/Tests/sqlancer07.stable.out.int128 
b/sql/test/SQLancer/Tests/sqlancer07.stable.out.int128
--- a/sql/test/SQLancer/Tests/sqlancer07.stable.out.int128
+++ b/sql/test/SQLancer/Tests/sqlancer07.stable.out.int128
@@ -152,12 +152,12 @@ stdout of test 'sqlancer07` in directory
 #INSERT INTO "t2" VALUES 
('4'),('4'),('3eSU8,'),(''),('5E~쟱'),('~'),('1386006226'),('0.19005213960704492'),('''{Mdd뒆VB'''),('\015␱%L%]'),('+'),(''),('㕚o+k');
 [ 13   ]
 #select t0.c1 from t0 where (5) in (case when t0.c1 = 'a' then 1 end, (select 
3));
-% .t0 # table_name
+% sys.t0 # table_name
 % c1 # name
 % varchar # type
 % 0 # length
 #select t0.c1 from t0 where (5) in ((select 3), case when t0.c1 = 'a' then 1 
end);
-% .t0 # table_name
+% sys.t0 # table_name
 % c1 # name
 % varchar # type
 % 0 # length
@@ -201,8 +201,8 @@ stdout of test 'sqlancer07` in directory
 #INSERT INTO "t2" VALUES (596983192), (-601428889), (1688368391);
 [ 3    ]
 #SELECT 1 FROM t2, t0 CROSS JOIN t1 WHERE t0.c0 % (SELECT 1 WHERE FALSE) <= 
t1.c0;
-% .%4 # table_name
-% %4 # name
+% .%3 # table_name
+% %3 # name
 % tinyint # type
 % 1 # length
 #SELECT t1.c0 FROM t2, t0 CROSS JOIN t1 WHERE ((((t0.c0)%((SELECT DISTINCT 
t0.c0 FROM t1, t0, t2 WHERE FALSE))))<=(t1.c0));
@@ -321,8 +321,8 @@ stdout of test 'sqlancer07` in directory
 #INSERT INTO "t1" VALUES (1);
 [ 1    ]
 #SELECT 1 FROM t0 WHERE (EXISTS (SELECT 1 WHERE FALSE)) IN ((SELECT FALSE)); 
-- rel_push_semijoin_down_or_up is causing the issue
-% .%11 # table_name
-% %11 # name
+% .%7 # table_name
+% %7 # name
 % tinyint # type
 % 1 # length
 #SELECT t0.c0 FROM t0 WHERE (EXISTS (SELECT TRUE, 0.3, INTERVAL '5' MONTH, 
TIME '16:59:58' WHERE FALSE)) IN ((SELECT DISTINCT FALSE FROM t1), (('0.9')NOT 
ILIKE('')));
@@ -426,8 +426,8 @@ stdout of test 'sqlancer07` in directory
 #INSERT INTO "t2" VALUES (446453788), (1973525566), (1604369323), 
(-907882617), (1067873323), (1615259391), (1286378024);
 [ 7    ]
 #SELECT 1 FROM t0 RIGHT OUTER JOIN t1 ON 3 IN ((SELECT 2), t1.c0);
-% .%10 # table_name
-% %10 # name
+% .%6 # table_name
+% %6 # name
 % tinyint # type
 % 1 # length
 [ 1    ]
@@ -454,12 +454,25 @@ stdout of test 'sqlancer07` in directory
 % %10 # name
 % tinyint # type
 % 1 # length
+#SELECT 1 FROM (SELECT 1) as v3(c0) RIGHT JOIN (SELECT 2) as v4(c0) ON (0.6) 
NOT IN (0.5, (SELECT 0.2));
+% .%7 # table_name
+% %7 # name
+% tinyint # type
+% 1 # length
+[ 1    ]
+#SELECT * FROM (SELECT 1) as v3(c0) LEFT JOIN (SELECT 2) as v4(c0) ON (0.6) 
NOT IN ((SELECT v4.c0), 0.5);
+% .v3, .v4 # table_name
+% c0,  c0 # name
+% tinyint,     tinyint # type
+% 1,   1 # length
+[ 1,   2       ]
 #SELECT FALSE FROM v3, v0 FULL OUTER JOIN v4 ON sql_max(FALSE, (0.6902854) NOT 
IN (0.5854332103580835, CASE WHEN v4.vc0 THEN (SELECT 0.023816515 WHERE TRUE) 
END));
 % .%16 # table_name
 % %16 # name
 % boolean # type
 % 5 # length
 [ false        ]
+[ false        ]
 #ROLLBACK;
 #SELECT CAST(((24829)+(((0.9767751031140547)*(0.7479400824095245)))) AS 
DOUBLE) IS NULL;
 % .%3 # table_name
_______________________________________________
checkin-list mailing list
[email protected]
https://www.monetdb.org/mailman/listinfo/checkin-list

Reply via email to