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