From: drh Date: Wed, 20 Feb 2019 12:52:47 +0000 (+0000) Subject: When an IN operator drives a query loop, mark it as "CODED" so that it X-Git-Tag: version-3.28.0~171 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=042666e4fa379ddd29eb049d77319e32dc94126f;p=thirdparty%2Fsqlite.git When an IN operator drives a query loop, mark it as "CODED" so that it will not be used afterwards for a (pointless) membership test. This is a better fix for ticket [df46dfb631f75694] than the previous fix that is now on a branch as it preserves the full optimization of check-in [e130319317e76119]. FossilOrigin-Name: fa792714ae62fa980f1767acc6d622a6727ceb677870243c88548423795dcb5b --- diff --git a/manifest b/manifest index eb13e2dec5..b85d244af4 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Enhance\sthe\sxBestIndex\smethod\son\sdelta_parse()\sto\sreturn\sSQLITE_CONSTRAINT\sif\nno\sdelta\sargument\sis\ssupplied. -D 2019-02-19T20:29:05.526 +C When\san\sIN\soperator\sdrives\sa\squery\sloop,\smark\sit\sas\s"CODED"\sso\sthat\sit\nwill\snot\sbe\sused\safterwards\sfor\sa\s(pointless)\smembership\stest.\s\sThis\sis\na\sbetter\sfix\sfor\sticket\s[df46dfb631f75694]\sthan\sthe\sprevious\sfix\sthat\sis\nnow\son\sa\sbranch\sas\sit\spreserves\sthe\sfull\soptimization\sof\ncheck-in\s[e130319317e76119]. +D 2019-02-20T12:52:47.452 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F Makefile.in 178d8eb6840771149cee40b322d1b3be30d330198c522c903c1b66fb5a1bfca4 @@ -602,7 +602,7 @@ F src/wal.h 606292549f5a7be50b6227bd685fa76e3a4affad71bb8ac5ce4cb5c79f6a176a F src/walker.c 7607f1a68130c028255d8d56094ea602fc402c79e1e35a46e6282849d90d5fe4 F src/where.c 8a207cb2ca6b99e1edb1e4bbff9b0504385a759cbf66180d1deb34d80ca4b799 F src/whereInt.h 5f14db426ca46a83eabab1ae9aa6d4b8f27504ad35b64c290916289b1ddb2e88 -F src/wherecode.c a571d8d7c19d6db786a201f2df8788b320fefcb2842f2a1eb9a85b85e91bc35f +F src/wherecode.c 5ee878f714218352a2f452907572d4bf1e4303393288458f87ffc86edaf2cfbe F src/whereexpr.c 36b47f7261d6b6f1a72d774c113b74beddf6745aba1018e64b196e29db233442 F src/window.c df2456386e0b1553a8d1fcf3a0ddc4c058fe2c650ea8c74b6bf8862082ddafc9 F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2 @@ -1007,7 +1007,7 @@ F test/hook2.test b9ff3b8c6519fb67f33192f1afe86e7782ee4ac8 F test/icu.test 41aa8847745a879b897a7febea0f8f9efc8e67fe8bf680589b6e07c7b0a1569a F test/ieee754.test 806fc0ce7f305f57e3331eaceeddcfec9339e607 F test/imposter1.test c3f1db2d3db2c24611a6596a3fc0ffc14f1466c8 -F test/in.test 2fa2dfba1afe30eb830f327e7131dfadaa7a701d677de0eb65f9303d99e18fe0 +F test/in.test 63933d7b71eed01a49df55541a73a75398302b50a05b5333f90481460a32ff49 F test/in2.test 5d4c61d17493c832f7d2d32bef785119e87bde75 F test/in3.test 3cbf58c87f4052cee3a58b37b6389777505aa0c0 F test/in4.test d2b38cba404bc4320f4fe1b595b3d163f212c068 @@ -1805,7 +1805,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P d91fcc267bf1be795dfdb1fbfb40c2aea79ddff247a51d26462136c325b7a6d3 -R c6e533968a2ece3b69b351a227132130 +P f16d127c3b4a735afae1fc236bcf90f31adff079c7d3a896f901d908ff8b8532 +R 305348511782a1081a30b2475753ee53 U drh -Z d8453dece5a7987c62030d39d3c1b091 +Z ef9d1f96fc42c68bd56fd0d4769bee0b diff --git a/manifest.uuid b/manifest.uuid index f9ba20353f..a0b2fe474e 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -f16d127c3b4a735afae1fc236bcf90f31adff079c7d3a896f901d908ff8b8532 \ No newline at end of file +fa792714ae62fa980f1767acc6d622a6727ceb677870243c88548423795dcb5b \ No newline at end of file diff --git a/src/wherecode.c b/src/wherecode.c index 19315779bf..5441752ed1 100644 --- a/src/wherecode.c +++ b/src/wherecode.c @@ -1344,6 +1344,7 @@ Bitmask sqlite3WhereCodeOneLoopStart( sqlite3VdbeAddOp3(v, OP_SeekRowid, iCur, addrNxt, iRowidReg); VdbeCoverage(v); pLevel->op = OP_Noop; + pTerm->wtFlags |= TERM_CODED; }else if( (pLoop->wsFlags & WHERE_IPK)!=0 && (pLoop->wsFlags & WHERE_COLUMN_RANGE)!=0 ){ diff --git a/test/in.test b/test/in.test index 478c0087b8..246cd76edf 100644 --- a/test/in.test +++ b/test/in.test @@ -651,4 +651,68 @@ do_execsql_test in-14.1 { SELECT * FROM c1 WHERE a IN (SELECT a FROM c1) ORDER BY 1 } {1 2 3 4} +# 2019-02-20 Ticket https://www.sqlite.org/src/tktview/df46dfb631f75694fbb97033b69 +# +do_execsql_test in-15.0 { + DROP TABLE IF EXISTS t1; + CREATE TABLE IF NOT EXISTS t1(id INTEGER PRIMARY KEY); + INSERT INTO t1 VALUES(1); + SELECT a.id FROM t1 AS a JOIN t1 AS b ON a.id=b.id WHERE a.id IN (1,2,3); +} {1} +do_execsql_test in-15.1 { + DROP TABLE IF EXISTS t2; + CREATE TABLE t2(a INTEGER PRIMARY KEY,b); + INSERT INTO t2 VALUES(1,11); + INSERT INTO t2 VALUES(2,22); + INSERT INTO t2 VALUES(3,33); + SELECT b, a IN (3,4,5) FROM t2 ORDER BY b; +} {11 0 22 0 33 1} +do_execsql_test in-15.2 { + DROP TABLE IF EXISTS t3; + CREATE TABLE t3(x INTEGER PRIMARY KEY); + INSERT INTO t3 VALUES(8); + SELECT CASE WHEN x NOT IN (5,6,7) THEN 'yes' ELSE 'no' END FROM t3; + SELECT CASE WHEN x NOT IN (NULL,6,7) THEN 'yes' ELSE 'no' END FROM t3; +} {yes no} +do_execsql_test in-15.3 { + SELECT CASE WHEN x NOT IN (5,6,7) OR x=0 THEN 'yes' ELSE 'no' END FROM t3; + SELECT CASE WHEN x NOT IN (NULL,6,7) OR x=0 THEN 'yes' ELSE 'no' END FROM t3; +} {yes no} +do_execsql_test in-15.4 { + DROP TABLE IF EXISTS t4; + CREATE TABLE t4(a INTEGER PRIMARY KEY, b INT); + WITH RECURSIVE c(x) AS (VALUES(1) UNION ALL SELECT x+1 FROM c WHERE x<20) + INSERT INTO t4(a,b) SELECT x, x+100 FROM c; + SELECT b FROM t4 WHERE a IN (3,null,8) ORDER BY +b; +} {103 108} +do_execsql_test in-15.5 { + SELECT b FROM t4 WHERE a NOT IN (3,null,8); +} {} +do_execsql_test in-15.6 { + DROP TABLE IF EXISTS t5; + DROP TABLE IF EXISTS t6; + CREATE TABLE t5(id INTEGER PRIMARY KEY, name TEXT); + CREATE TABLE t6(id INTEGER PRIMARY KEY, name TEXT, t5_id INT); + INSERT INTO t5 VALUES(1,'Alice'),(2,'Emma'); + INSERT INTO t6 VALUES(1,'Bob',1),(2,'Cindy',1),(3,'Dave',2); + SELECT a.* + FROM t5 AS 'a' JOIN t5 AS 'b' ON b.id=a.id + WHERE b.id IN ( + SELECT t6.t5_id + FROM t6 + WHERE name='Bob' + AND t6.t5_id IS NOT NULL + AND t6.id IN ( + SELECT id + FROM (SELECT t6.id, count(*) AS x + FROM t6 + WHERE name='Bob' + ) AS 't' + WHERE x=1 + ) + AND t6.id IN (1,id) + ); +} {1 Alice} + + finish_test