Changeset: bff4d8dd5d4d for MonetDB URL: https://dev.monetdb.org/hg/MonetDB?cmd=changeset;node=bff4d8dd5d4d Modified Files: monetdb5/optimizer/opt_pushselect.c sql/test/SQLancer/Tests/sqlancer10.test Branch: default Log Message:
SQLancer bug, when rewriting batalgebra.like + [theta]select -> likeselect, look for a possible negative case (= false), then swap 'anti' flag on those cases diffs (135 lines): diff --git a/monetdb5/optimizer/opt_pushselect.c b/monetdb5/optimizer/opt_pushselect.c --- a/monetdb5/optimizer/opt_pushselect.c +++ b/monetdb5/optimizer/opt_pushselect.c @@ -328,23 +328,45 @@ OPTpushselectImplementation(Client cntxt !isaBatType(getArgType(mb, q, 2)) && /* pattern is a value */ (q->argc != 4 || !isaBatType(getArgType(mb, q, 3))) /* escape is a value */ ) { - bool has_null_semantics = false; + bool selectok = true; int has_cand = (getArgType(mb, p, 2) == newBatType(TYPE_oid)), offset = 0; int a, anti = (getFunctionId(q)[0] == 'n'), ignore_case = (getFunctionId(q)[anti?4:0] == 'i'); /* TODO at the moment we cannot convert if the select statement has NULL semantics - we can convert it into VAL is NULL or PATERN is NULL or ESCAPE is NULL + we can convert it into VAL is NULL or PATTERN is NULL or ESCAPE is NULL */ - if (getFunctionId(p) == selectRef && isVarConstant(mb,getArg(p, 2 + has_cand)) && isVarConstant(mb,getArg(p, 3 + has_cand)) - && isVarConstant(mb,getArg(p, 4 + has_cand)) && isVarConstant(mb,getArg(p, 5 + has_cand))) { - ValRecord low = getVarConstant(mb, getArg(p, 2 + has_cand)), high = getVarConstant(mb, getArg(p, 3 + has_cand)); + if (getFunctionId(p) == selectRef) { + bit low = *(bit*)getVarValue(mb, getArg(p, 2 + has_cand)), high = *(bit*)getVarValue(mb, getArg(p, 3 + has_cand)); bit li = *(bit*)getVarValue(mb, getArg(p, 4 + has_cand)), hi = *(bit*)getVarValue(mb, getArg(p, 5 + has_cand)); + bit santi = *(bit*)getVarValue(mb, getArg(p, 6 + has_cand)), sunknown = (p->argc == (has_cand ? 9 : 8)) ? 0 : *(bit*)getVarValue(mb, getArg(p, 7 + has_cand)); - if (li && hi && VALisnil(&low) && VALisnil(&high)) - has_null_semantics = true; + /* semantic or not symmetric cases, it cannot be converted */ + if (is_bit_nil(low) || is_bit_nil(li) || is_bit_nil(santi) || low != high || li != hi || sunknown) + selectok = false; + + /* there are no negative candidate lists so on = false situations swap anti flag */ + if (low == 0) + anti = !anti; + if (li == 0) + anti = !anti; + if (santi) + anti = !anti; + } else if (getFunctionId(p) == thetaselectRef) { + bit truth_value = *(bit*)getVarValue(mb, getArg(p, 3)); + str comparison = (str)getVarValue(mb, getArg(p, 4)); + + /* there are no negative candidate lists so on = false situations swap anti flag */ + if (truth_value == 0) + anti = !anti; + else if (is_bit_nil(truth_value)) + selectok = false; + if (strcmp(comparison, "<>") == 0) + anti = !anti; + else if (strcmp(comparison, "==") != 0) + selectok = false; } - if (!has_null_semantics) { + if (selectok) { InstrPtr r = newInstruction(mb, algebraRef, likeselectRef); getArg(r,0) = getArg(p,0); r = addArgument(mb, r, getArg(q, 1)); diff --git a/sql/test/SQLancer/Tests/sqlancer10.test b/sql/test/SQLancer/Tests/sqlancer10.test --- a/sql/test/SQLancer/Tests/sqlancer10.test +++ b/sql/test/SQLancer/Tests/sqlancer10.test @@ -35,6 +35,74 @@ statement ok START TRANSACTION statement ok +CREATE TABLE "sys"."t1" ("c0" INTERVAL DAY,"c1" TIME,"c3" INTERVAL DAY,"c5" TIME) + +statement ok +COPY 6 RECORDS INTO "sys"."t1" FROM stdin USING DELIMITERS E'\t',E'\n','"' +<COPY_INTO_DATA> +NULL 01:00:00 345600.000 01:00:08 +NULL 02:50:32 NULL 01:00:00 +NULL 02:50:32 NULL 01:00:00 +432000.000 01:00:00 259200.000 NULL +179900573616000.000 01:00:00 12666182976000.000 NULL +86400.000 02:04:32 2.000 01:00:00 + +query T rowsort +SELECT ALL t1.c3 FROM t1 WHERE (((COALESCE(r'', r'㉁*3', r'w1ZR'))ILIKE(r'-6739257'))) = FALSE +---- +0 +146599340 +3 +4 +NULL +NULL + +statement ok +set optimizer = 'sequential_pipe' + +query T python .explain.function_histogram +EXPLAIN SELECT 1 FROM t1 WHERE (((COALESCE('b', 'a'))ILIKE('c'))) = FALSE +---- +user.main +1 +querylog.define +1 +sql.mvc +1 +sql.tid +1 +sql.bind +1 +algebra.project +5 +algebra.thetaselect +2 +bat.replace +2 +algebra.likeselect +1 +algebra.projection +1 +bat.pack +5 +sql.resultSet +1 + +statement ok +set optimizer = 'default_pipe' + +query I rowsort +SELECT CAST(SUM(count) AS BIGINT) FROM (SELECT CAST((((COALESCE(r'', r'㉁*3', r'w1ZR'))ILIKE(r'-6739257'))) = FALSE AS INT) as count FROM t1) as res +---- +6 + +statement ok +ROLLBACK + +statement ok +START TRANSACTION + +statement ok CREATE TABLE "sys"."t2" ("c0" BOOLEAN,"c2" INTEGER) statement ok _______________________________________________ checkin-list mailing list checkin-list@monetdb.org https://www.monetdb.org/mailman/listinfo/checkin-list