Changeset: cd9001283c0d for MonetDB
URL: https://dev.monetdb.org/hg/MonetDB?cmd=changeset;node=cd9001283c0d
Modified Files:
sql/server/rel_exp.c
sql/test/SQLancer/Tests/sqlancer07.sql
sql/test/SQLancer/Tests/sqlancer07.stable.out
Branch: octbugs
Log Message:
Fix for crashing SQLancer query, when updating a relation expression column
references, do it recursively, because they may be behind expressions such as
conversions
diffs (167 lines):
diff --git a/sql/server/rel_exp.c b/sql/server/rel_exp.c
--- a/sql/server/rel_exp.c
+++ b/sql/server/rel_exp.c
@@ -1929,18 +1929,16 @@ exp_is_atom( sql_exp *e )
return exp_is_atom(e->l);
case e_func:
case e_aggr:
- {
- int r = (e->card == CARD_ATOM);
- node *n;
- list *l = e->l;
-
- if (r && l)
- for (n = l->h; n && r; n = n->next)
- r &= exp_is_atom(n->data);
- return r;
- }
+ return e->card == CARD_ATOM && exps_are_atoms(e->l);
+ case e_cmp:
+ if (e->card != CARD_ATOM)
+ return 0;
+ if (e->flag == cmp_or || e->flag == cmp_filter)
+ return exps_are_atoms(e->l) && exps_are_atoms(e->r);
+ if (e->flag == cmp_in || e->flag == cmp_notin)
+ return exp_is_atom(e->l) && exps_are_atoms(e->r);
+ return exp_is_atom(e->l) && exp_is_atom(e->r) && (!e->f ||
exp_is_atom(e->f));
case e_column:
- case e_cmp:
case e_psm:
return 0;
}
@@ -2060,6 +2058,56 @@ exp_rel_get_rel(sql_allocator *sa, sql_e
return NULL;
}
+static void exp_rel_update_set_freevar(sql_exp *e);
+
+static void
+exps_rel_update_set_freevar(list *exps)
+{
+ if (!list_empty(exps))
+ for (node *n=exps->h; n ; n=n->next)
+ exp_rel_update_set_freevar(n->data);
+}
+
+static void
+exp_rel_update_set_freevar(sql_exp *e)
+{
+ if (!e)
+ return ;
+
+ switch(e->type){
+ case e_func:
+ case e_aggr:
+ exps_rel_update_set_freevar(e->l);
+ break;
+ case e_cmp:
+ if (e->flag == cmp_or || e->flag == cmp_filter) {
+ exps_rel_update_set_freevar(e->l);
+ exps_rel_update_set_freevar(e->r);
+ } else if (e->flag == cmp_in || e->flag == cmp_notin) {
+ exp_rel_update_set_freevar(e->l);
+ exps_rel_update_set_freevar(e->r);
+ } else {
+ exp_rel_update_set_freevar(e->l);
+ exp_rel_update_set_freevar(e->r);
+ if (e->f)
+ exp_rel_update_set_freevar(e->f);
+ }
+ break;
+ case e_convert:
+ exp_rel_update_set_freevar(e->l);
+ break;
+ case e_atom:
+ if (e->f)
+ exps_rel_update_set_freevar(e->f);
+ break;
+ case e_column:
+ set_freevar(e, 1);
+ break;
+ case e_psm:
+ break;
+ }
+}
+
static list *
exp_rel_update_exps(mvc *sql, list *exps)
{
@@ -2071,7 +2119,7 @@ exp_rel_update_exps(mvc *sql, list *exps
if (exp_has_rel(e))
n->data = exp_rel_update_exp(sql, e);
else if (!exp_is_atom(e))
- set_freevar(e,1);
+ exp_rel_update_set_freevar(e);
}
list_hash_clear(exps);
return exps;
@@ -2086,7 +2134,8 @@ exp_rel_update_exp(mvc *sql, sql_exp *e)
switch(e->type){
case e_func:
case e_aggr:
- e->l = exp_rel_update_exps(sql, e->l);
+ if (exps_have_rel_exp(e->l))
+ e->l = exp_rel_update_exps(sql, e->l);
return e;
case e_cmp:
if (e->flag == cmp_or || e->flag == cmp_filter) {
@@ -2109,7 +2158,8 @@ exp_rel_update_exp(mvc *sql, sql_exp *e)
}
return e;
case e_convert:
- e->l = exp_rel_update_exp(sql, e->l);
+ if (exp_has_rel(e->l))
+ e->l = exp_rel_update_exp(sql, e->l);
return e;
case e_psm:
if (exp_is_rel(e)) {
@@ -2143,7 +2193,7 @@ int
exps_are_atoms( list *exps)
{
int atoms = 1;
- if (exps)
+ if (!list_empty(exps))
for(node *n=exps->h; n && atoms; n=n->next)
atoms &= exp_is_atom(n->data);
return atoms;
diff --git a/sql/test/SQLancer/Tests/sqlancer07.sql
b/sql/test/SQLancer/Tests/sqlancer07.sql
--- a/sql/test/SQLancer/Tests/sqlancer07.sql
+++ b/sql/test/SQLancer/Tests/sqlancer07.sql
@@ -310,8 +310,10 @@ create view v0(vc0) as (values (interval
create view v3(vc0) as (select 1638520390);
create view v4(vc0) as (values (-1548784118));
-SELECT 1 FROM (select 2) v4(vc0) WHERE (0.6) IN (CASE WHEN v4.vc0 THEN (SELECT
0.2 WHERE TRUE) END);
+SELECT 1 FROM (SELECT 2) v4(vc0) WHERE (0.6) IN (CASE WHEN v4.vc0 THEN (SELECT
0.2 WHERE TRUE) END);
-- empty
+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));
+ -- 1
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));
-- False
ROLLBACK;
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
@@ -445,6 +445,22 @@ stdout of test 'sqlancer07` in directory
% 1 # length
[ 0 ]
#ROLLBACK;
+#START TRANSACTION;
+#create view v0(vc0) as (values (interval '100' second));
+#create view v3(vc0) as (select 1638520390);
+#create view v4(vc0) as (values (-1548784118));
+#SELECT 1 FROM (select 2) v4(vc0) WHERE (0.6) IN (CASE WHEN v4.vc0 THEN
(SELECT 0.2 WHERE TRUE) END);
+% .%10 # table_name
+% %10 # name
+% tinyint # type
+% 1 # length
+#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 ]
+#ROLLBACK;
# 10:16:14 >
# 10:16:14 > "Done."
_______________________________________________
checkin-list mailing list
[email protected]
https://www.monetdb.org/mailman/listinfo/checkin-list