Changeset: ab0a0b3be4f4 for MonetDB
URL: https://dev.monetdb.org/hg/MonetDB?cmd=changeset;node=ab0a0b3be4f4
Modified Files:
        sql/include/sql_relation.h
        sql/server/rel_rel.c
        sql/server/rel_select.c
        sql/server/rel_unnest.c
        sql/server/rel_updates.c
        sql/test/SQLancer/Tests/sqlancer02.stable.out
Branch: Oct2020
Log Message:

Fixing SQLancer crash and other bugs.

As a projection, if an expression cannot be found on a set relation don't look 
further.
Make sure a set relation is always processed.
Don't look for expressions on ordering columns.


diffs (209 lines):

diff --git a/sql/include/sql_relation.h b/sql/include/sql_relation.h
--- a/sql/include/sql_relation.h
+++ b/sql/include/sql_relation.h
@@ -197,7 +197,6 @@ typedef enum operator_type {
 #define is_simple_project(op)  (op == op_project)
 #define is_project(op)                 (op == op_project || op == op_groupby 
|| is_set(op))
 #define is_groupby(op)                 (op == op_groupby)
-#define is_sort(rel)           (((rel)->op == op_project && (rel)->r) || 
(rel)->op == op_topn)
 #define is_topn(op)            (op == op_topn)
 #define is_modify(op)          (op == op_insert || op == op_update || op == 
op_delete || op == op_truncate)
 #define is_sample(op)          (op == op_sample)
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
@@ -378,6 +378,9 @@ rel_bind_column2( mvc *sql, sql_rel *rel
        if ((is_simple_project(rel->op) || is_groupby(rel->op)) && rel->l) {
                if (!is_processed(rel))
                        return rel_bind_column2(sql, rel->l, tname, cname, f);
+       } else if (is_set(rel->op)) {
+               assert(is_processed(rel));
+               return NULL;
        } else if (is_join(rel->op)) {
                sql_exp *e = rel_bind_column2(sql, rel->l, tname, cname, f);
 
@@ -389,9 +392,7 @@ rel_bind_column2( mvc *sql, sql_rel *rel
                                set_has_nil(e);
                }
                return e;
-       } else if (is_set(rel->op) ||
-                  is_sort(rel) ||
-                  is_semi(rel->op) ||
+       } else if (is_semi(rel->op) ||
                   is_select(rel->op) ||
                   is_topn(rel->op) ||
                   is_sample(rel->op)) {
@@ -1564,17 +1565,27 @@ rel_find_column( sql_allocator *sa, sql_
                if (e && !ambiguous && !multi)
                        return exp_alias(sa, exp_relname(e), exp_name(e), 
exp_relname(e), cname, exp_subtype(e), e->card, has_nil(e), is_intern(e));
        }
-       if (is_project(rel->op) && rel->l && !is_processed(rel)) {
-               return rel_find_column(sa, rel->l, tname, cname);
+       if ((is_simple_project(rel->op) || is_groupby(rel->op)) && rel->l) {
+               if (!is_processed(rel))
+                       return rel_find_column(sa, rel->l, tname, cname);
+       } else if (is_set(rel->op)) {
+               assert(is_processed(rel));
+               return NULL;
        } else if (is_join(rel->op)) {
                sql_exp *e = rel_find_column(sa, rel->l, tname, cname);
-               if (!e)
+
+               if (e && (is_right(rel->op) || is_full(rel->op)))
+                       set_has_nil(e);
+               if (!e) {
                        e = rel_find_column(sa, rel->r, tname, cname);
+                       if (e && (is_left(rel->op) || is_full(rel->op)))
+                               set_has_nil(e);
+               }
                return e;
-       } else if (is_set(rel->op) ||
-                  is_sort(rel) ||
-                  is_semi(rel->op) ||
-                  is_select(rel->op)) {
+       } else if (is_semi(rel->op) ||
+                  is_select(rel->op) ||
+                  is_topn(rel->op) ||
+                  is_sample(rel->op)) {
                if (rel->l)
                        return rel_find_column(sa, rel->l, tname, cname);
        }
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
@@ -5718,8 +5718,11 @@ rel_setquery(sql_query *query, symbol *q
                res = rel_setquery_(query, t1, t2, corresponding, op_except );
        else if ( q->token == SQL_INTERSECT)
                res = rel_setquery_(query, t1, t2, corresponding, op_inter );
-       if (res && distinct)
-               res = rel_distinct(res);
+       if (res) {
+               set_processed(res);
+               if (distinct)
+                       res = rel_distinct(res);
+       }
        return res;
 }
 
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,6 +2007,7 @@ 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;
+                                       set_processed(rel);
                                        rel = rel_distinct(rel);
                                        rel_set_exps(rel, exps);
                                        v->changes++;
@@ -3174,6 +3175,7 @@ rewrite_outer2inner_union(visitor *v, sq
                                        rel_project(v->sql->sa, 
rel_dup(rel->l), rel_projections(v->sql, rel->l, NULL, 1, 1)),
                                        rel_project(v->sql->sa, rel_dup(prel), 
rel_projections(v->sql, rel->l, NULL, 1, 1)), op_except);
                        rel_setop_set_exps(v->sql, except, 
rel_projections(v->sql, rel->l, NULL, 1, 1));
+                       set_processed(except);
                        sql_rel *nrel = rel_crossproduct(v->sql->sa, except, 
rel_dup(rel->r),  op_left);
                        rel_join_add_exp(v->sql->sa, nrel, f);
                        rel->op = op_join;
@@ -3182,6 +3184,7 @@ rewrite_outer2inner_union(visitor *v, sq
                                        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));
+                       set_processed(nrel);
                        return nrel;
                } else if (is_right(rel->op)) {
                        sql_rel *prel = rel_project(v->sql->sa, rel, 
rel_projections(v->sql, rel, NULL, 1, 1));
@@ -3189,6 +3192,7 @@ rewrite_outer2inner_union(visitor *v, sq
                                        rel_project(v->sql->sa, 
rel_dup(rel->r), rel_projections(v->sql, rel->r, NULL, 1, 1)),
                                        rel_project(v->sql->sa, rel_dup(prel), 
rel_projections(v->sql, rel->r, NULL, 1, 1)), op_except);
                        rel_setop_set_exps(v->sql, except, 
rel_projections(v->sql, rel->r, NULL, 1, 1));
+                       set_processed(except);
                        sql_rel *nrel = rel_crossproduct(v->sql->sa, 
rel_dup(rel->l), except, op_right);
                        rel_join_add_exp(v->sql->sa, nrel, f);
                        rel->op = op_join;
@@ -3197,6 +3201,7 @@ rewrite_outer2inner_union(visitor *v, sq
                                        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));
+                       set_processed(nrel);
                        return nrel;
                } else if (is_full(rel->op)) {
                        sql_rel *prel = rel_project(v->sql->sa, rel, 
rel_projections(v->sql, rel, NULL, 1, 1));
@@ -3204,6 +3209,7 @@ rewrite_outer2inner_union(visitor *v, sq
                                        rel_project(v->sql->sa, 
rel_dup(rel->l), rel_projections(v->sql, rel->l, NULL, 1, 1)),
                                        rel_project(v->sql->sa, rel_dup(prel), 
rel_projections(v->sql, rel->l, NULL, 1, 1)), op_except);
                        rel_setop_set_exps(v->sql, except, 
rel_projections(v->sql, rel->l, NULL, 1, 1));
+                       set_processed(except);
                        sql_rel *lrel = rel_crossproduct(v->sql->sa, except, 
rel_dup(rel->r),  op_left);
                        rel_join_add_exp(v->sql->sa, lrel, f);
 
@@ -3211,6 +3217,7 @@ rewrite_outer2inner_union(visitor *v, sq
                                        rel_project(v->sql->sa, 
rel_dup(rel->r), rel_projections(v->sql, rel->r, NULL, 1, 1)),
                                        rel_project(v->sql->sa, rel_dup(prel), 
rel_projections(v->sql, rel->r, NULL, 1, 1)), op_except);
                        rel_setop_set_exps(v->sql, except, 
rel_projections(v->sql, rel->r, NULL, 1, 1));
+                       set_processed(except);
                        sql_rel *rrel = rel_crossproduct(v->sql->sa, 
rel_dup(rel->l), except, op_right);
                        rel_join_add_exp(v->sql->sa, rrel, f);
                        lrel = rel_setop(v->sql->sa,
@@ -3218,12 +3225,14 @@ rewrite_outer2inner_union(visitor *v, sq
                                        rel_project(v->sql->sa, rrel, 
rel_projections(v->sql, rrel, NULL, 1, 1)),
                                        op_union);
                        rel_setop_set_exps(v->sql, lrel, 
rel_projections(v->sql, rel, NULL, 1, 1));
+                       set_processed(lrel);
                        rel->op = op_join;
                        lrel = rel_setop(v->sql->sa,
                                        rel_project(v->sql->sa, prel,  
rel_projections(v->sql, rel, NULL, 1, 1)),
                                        rel_project(v->sql->sa, lrel, 
rel_projections(v->sql, lrel, NULL, 1, 1)),
                                        op_union);
                        rel_setop_set_exps(v->sql, lrel, 
rel_projections(v->sql, rel, NULL, 1, 1));
+                       set_processed(lrel);
                        return lrel;
                }
        }
diff --git a/sql/server/rel_updates.c b/sql/server/rel_updates.c
--- a/sql/server/rel_updates.c
+++ b/sql/server/rel_updates.c
@@ -1366,6 +1366,7 @@ merge_into_table(sql_query *query, dlist
                        no_tid = rel_project(sql->sa, rel_dup(joined), 
rel_projections(sql, joined, NULL, 1, 0));
                        extra_project = rel_setop(sql->sa, no_tid, 
extra_project, op_except);
                        rel_setop_set_exps(sql, extra_project, 
rel_projections(sql, extra_project, NULL, 1, 0));
+                       set_processed(extra_project);
 
                        if (!(insert = merge_generate_inserts(query, t, 
extra_project, sts->h->data.lval, sts->h->next->data.sym)))
                                return NULL;
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
@@ -296,8 +296,8 @@ stdout of test 'sqlancer02` in directory
 [ 5    ]
 #create view v0(c0) as (select t0.c2 from t0 where (t0.c2) not between 
asymmetric (date '1970-01-23') and (case when r'true' then t0.c2 when case true 
when (true) = true then substr(r' x+㶴9rr7긬X0陷?F5{W>gg0N*#Sꖿs', 1) end then 
nullif(t0.c2, t0.c2) end));
 #SELECT 1 FROM v0 JOIN t0 ON '4321901' LIKE CAST(COALESCE(TIME '21:08:38', 
TIME '14:42:56') AS STRING);
-% .%2 # table_name
-% %2 # name
+% .%3 # table_name
+% %3 # name
 % tinyint # type
 % 1 # length
 #SELECT ALL t0.c0, v0.c0 FROM v0 JOIN t0 ON ((upper(COALESCE(r'', 
r'4321901')))ILIKE(CAST(COALESCE(sql_max(TIME '05:11:41', TIME '21:08:38'), 
COALESCE(TIME '05:10:13', TIME '14:42:56'), sql_min(TIME '16:14:39', TIME 
'03:01:13')) AS STRING(586))));
@@ -1347,6 +1347,22 @@ stdout of test 'sqlancer02` in directory
 % 1 # length
 [ 0    ]
 #DROP TABLE mycount;
+#START TRANSACTION;
+#create view v20(vc0) as (values (-214362849));
+#create view v40(vc0) as (values (false), (true));
+#create view v43(vc0) as (values (null), (true));
+#create view v54(vc0, vc1, vc2) as (values ('S12^h)y{[]', false, 
9.000000000000),('0.9516513734508343', true, null));
+#create view v1(vc0) as (with cte0(c0,c1,c2) as ((select 7, 0, 2.00000000) 
union all
+#(select 5, 5.1, 4)) select '8#<Fk#]R' from v40 as l0v40, v43 as l0v43, cte0 
as l0cte0);
+#create view v27(vc0, vc1, vc2, vc3, vc4) as (select 1, 2, 1, 0.920, -4 from 
v40 as l0v40 right outer join (
+#select true, case l1v54.vc0 when 'a' then -1 when 'b' then 3 end, 1
+#from v54 as l1v54, v1 as l1v1 where l1v54.vc1) as sub1 on not l0v40.vc0 where 
l0v40.vc0);
+#select 1 from v20 as l0v20, v27 as l0v27, v1 as l0v1 where (l0v20.vc0) in 
(-3, l0v20.vc0, l0v27.vc1);
+% .%70 # table_name
+% %70 # name
+% tinyint # type
+% 1 # length
+#ROLLBACK;
 
 # 17:04:12 >  
 # 17:04:12 >  "Done."
_______________________________________________
checkin-list mailing list
checkin-list@monetdb.org
https://www.monetdb.org/mailman/listinfo/checkin-list

Reply via email to