Changeset: 11e197a303ab for MonetDB URL: https://dev.monetdb.org/hg/MonetDB?cmd=changeset;node=11e197a303ab Modified Files: sql/server/rel_optimizer.c sql/test/SQLancer/Tests/sqlancer04.sql sql/test/SQLancer/Tests/sqlancer04.stable.out Branch: default Log Message:
SQLancer assertion error and fix. e_cmp expressions are now allowed in projections. Updated exp_shares_exps diffs (133 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 @@ -2670,13 +2670,33 @@ rel_distinct_project2groupby(visitor *v, return rel; } +static int exp_shares_exps(sql_exp *e, list *shared, lng *uses); + static int -exp_shares_exps( sql_exp *e, list *shared, lng *uses) +exps_shares_exps(list *exps, list *shared, lng *uses) +{ + if (!exps || !shared) + return 0; + for (node *n = exps->h; n; n = n->next) { + sql_exp *e = n->data; + + if (exp_shares_exps(e, shared, uses)) + return 1; + } + return 0; +} + +static int +exp_shares_exps(sql_exp *e, list *shared, lng *uses) { switch(e->type) { - case e_cmp: /* not in projection list */ - case e_psm: - assert(0); + case e_cmp: + if (e->flag == cmp_or || e->flag == cmp_filter) + return exps_shares_exps(e->l, shared, uses) || exps_shares_exps(e->r, shared, uses); + else if (e->flag == cmp_in || e->flag == cmp_notin) + return exp_shares_exps(e->l, shared, uses) || exps_shares_exps(e->r, shared, uses); + else + return exp_shares_exps(e->l, shared, uses) || exp_shares_exps(e->r, shared, uses) || (e->f && exp_shares_exps(e->f, shared, uses)); case e_atom: return 0; case e_column: @@ -2697,43 +2717,31 @@ exp_shares_exps( sql_exp *e, list *share } if (ne && ne != e && (list_position(shared, e) < 0 || list_position(shared, e) > list_position(shared, ne))) /* maybe ne refers to a local complex exp */ - return exp_shares_exps( ne, shared, uses); + return exp_shares_exps(ne, shared, uses); return 0; } case e_convert: return exp_shares_exps(e->l, shared, uses); - case e_aggr: case e_func: - { - list *l = e->l; - node *n; - - if (!l) - return 0; - for (n = l->h; n; n = n->next) { - sql_exp *e = n->data; - - if (exp_shares_exps( e, shared, uses)) - return 1; - } - } + return exps_shares_exps(e->l, shared, uses); + case e_psm: + assert(0); /* not in projection list */ } return 0; } static int -exps_share_expensive_exp( list *exps, list *shared ) -{ - node *n; +exps_share_expensive_exp(list *exps, list *shared ) +{ lng uses = 0; if (!exps || !shared) return 0; - for (n = exps->h; n; n = n->next){ + for (node *n = exps->h; n; n = n->next) { sql_exp *e = n->data; - if (exp_shares_exps( e, shared, &uses)) + if (exp_shares_exps(e, shared, &uses)) return 1; } return 0; diff --git a/sql/test/SQLancer/Tests/sqlancer04.sql b/sql/test/SQLancer/Tests/sqlancer04.sql --- a/sql/test/SQLancer/Tests/sqlancer04.sql +++ b/sql/test/SQLancer/Tests/sqlancer04.sql @@ -239,3 +239,11 @@ UNION ALL SELECT count(*) FROM t1 CROSS JOIN t0 GROUP BY 0.2 HAVING (max((ltrim(')''+')) NOT IN (CAST(t0.c1 AS VARCHAR(32)), CAST(INTERVAL '6' MONTH AS VARCHAR(32)), CAST(INTERVAL '7' MONTH AS VARCHAR(32))))) IS NULL; -- empty ROLLBACK; + +START TRANSACTION; +CREATE TABLE IF NOT EXISTS t0(c0 FLOAT, c1 DECIMAL NULL UNIQUE); +CREATE TEMP TABLE t1 (c0 TIME); +SELECT 1 FROM t1 INNER JOIN (SELECT 2 FROM t0) AS sub0 ON CASE 8 WHEN 3 THEN (4) IN (5, 6, 7) END; +SELECT t1.c0 FROM t1 INNER JOIN (SELECT ALL CAST(TIMESTAMP '1970-01-07 06:59:48' AS TIMESTAMP) FROM t0) AS sub0 ON CASE t1.c0 WHEN sql_min(t1.c0, t1.c0) +THEN (((((((496867080) IN (52439321, 1596181433, -506328570))OR(((r'W1')ILIKE(r'0.48600327092830353')))))OR((t1.c0) BETWEEN SYMMETRIC (t1.c0) AND (t1.c0))))OR(NOT (FALSE))) END; +ROLLBACK; diff --git a/sql/test/SQLancer/Tests/sqlancer04.stable.out b/sql/test/SQLancer/Tests/sqlancer04.stable.out --- a/sql/test/SQLancer/Tests/sqlancer04.stable.out +++ b/sql/test/SQLancer/Tests/sqlancer04.stable.out @@ -301,6 +301,21 @@ stdout of test 'sqlancer04` in directory % bigint # type % 1 # length #ROLLBACK; +#START TRANSACTION; +#CREATE TABLE IF NOT EXISTS t0(c0 FLOAT, c1 DECIMAL NULL UNIQUE); +#CREATE TEMP TABLE t1 (c0 TIME); +#SELECT 1 FROM t1 INNER JOIN (SELECT 2 FROM t0) AS sub0 ON CASE 8 WHEN 3 THEN (4) IN (5, 6, 7) END; +% .%17 # table_name +% %17 # name +% tinyint # type +% 1 # length +#SELECT t1.c0 FROM t1 INNER JOIN (SELECT ALL CAST(TIMESTAMP '1970-01-07 06:59:48' AS TIMESTAMP) FROM t0) AS sub0 ON CASE t1.c0 WHEN sql_min(t1.c0, t1.c0) +#THEN (((((((496867080) IN (52439321, 1596181433, -506328570))OR(((r'W1')ILIKE(r'0.48600327092830353')))))OR((t1.c0) BETWEEN SYMMETRIC (t1.c0) AND (t1.c0))))OR(NOT (FALSE))) END; +% tmp.t1 # table_name +% c0 # name +% time # type +% 8 # length +#ROLLBACK; # 09:44:50 > # 09:44:50 > "Done." _______________________________________________ checkin-list mailing list checkin-list@monetdb.org https://www.monetdb.org/mailman/listinfo/checkin-list