From: drh <> Date: Mon, 18 May 2026 14:28:53 +0000 (+0000) Subject: Do not attempt the OR-optimization on conjuncts that contain COLLATE X-Git-Url: http://git.ipfire.org/gitweb/index.cgi?a=commitdiff_plain;h=e087d0f266fce5bc1d2ea804a83bad68c427f654;p=thirdparty%2Fsqlite.git Do not attempt the OR-optimization on conjuncts that contain COLLATE operators because (1) such cases are rare and (2) they are tricky to get right and are thus prone to bugs and hard to test. [bugs:/forumpost/329521b269|Bugs report 329521b269] is one such bug that goes back about 20 years and thus demonstrates both points of the previous sentence. FossilOrigin-Name: 622882529558b4779dfb7246bd5a9de776555c8f940bb941397fb56fb9f97e43 --- diff --git a/manifest b/manifest index 0d92819acc..3777f17bb7 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sa\sharmless\scompiler\swarning\scaused\sby\s[460243ee4c28873d]. -D 2026-05-18T11:44:09.379 +C Do\snot\sattempt\sthe\sOR-optimization\son\sconjuncts\sthat\scontain\sCOLLATE\noperators\sbecause\s(1)\ssuch\scases\sare\srare\sand\s(2)\sthey\sare\stricky\sto\nget\sright\sand\sare\sthus\sprone\sto\sbugs\sand\shard\sto\stest.\n[bugs:/forumpost/329521b269|Bugs\sreport\s329521b269]\sis\sone\nsuch\sbug\sthat\sgoes\sback\sabout\s20\syears\sand\sthus\sdemonstrates\sboth\npoints\sof\sthe\sprevious\ssentence. +D 2026-05-18T14:28:53.777 F .fossil-settings/binary-glob 61195414528fb3ea9693577e1980230d78a1f8b0a54c78cf1b9b24d0a409ed6a x F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea @@ -821,7 +821,7 @@ F src/walker.c d5006d6b005e4ea7302ad390957a8d41ed83faa177e412f89bc5600a7462a014 F src/where.c 33e4a6558ee69f33d6a4e7069e3a40a55959d14e5653a9a83926e70305d471f3 F src/whereInt.h 8d94cb116c9e06205c3d5ac87af065fc044f8cf08bfdccd94b6ea1c1308e65da F src/wherecode.c 4d573077652f79780d6b50840ab8cbb72053dbb4eb230780dd2a146ab034475d -F src/whereexpr.c e9f7185fba366d9365aa7a97329609e4cf00b3dd0400d069fbaa5187350c17c6 +F src/whereexpr.c b6eb736dac5969c05bc1c4df624a23bd5b6b5ba267599c48924648744ac482bc F src/window.c c0a38cd32473e8e8e7bc435039f914a36ca42465506dc491c65870c01ddac9fb F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2 F test/affinity2.test 4d7a34d328e58ca2a2d78fd76c27614a41ca7ddf4312ded9c68c04f430b3b47d @@ -916,7 +916,7 @@ F test/bestindex8.test 4d8b1e8f30a7f405988ce4dbcc2b95c0775f0bed9ec08e0291a07e2f3 F test/bestindex9.test 1a4b93db117fd8abe74ae9be982f86aa72f01e60cd4ac541e6ede39673a451a0 F test/bestindexA.test e1b5def6b190797cacf008e6815ffb78fb30261999030d60a728d572eef44c7f F test/bestindexB.test 14db2f66ec9cc5064a74996033b74e5eec0fd2f3a327fbe34ff18de67e9d2671 -F test/bestindexC.test 95b4a527b1a5d07951d731604a6d4cf7e5a806b39cea0e7819d4c9667e11c3fc +F test/bestindexC.test f44eb3d77359e9487222a2dde27f8ecf11a8e4932803c0dd9477f75e114f1c55 F test/bestindexD.test 6a8f6f84990bcf17dfa59652a1f935beddb7afd96f8302830fbc86b0a13df3c3 F test/bestindexE.test 297f3ea8500a8f3c17d6f78e55bdfee089064c6144ee84a110bd005a03338f49 F test/bestindexF.test 4e53d606cbde40a2254aa016d500c5b71766a4065b8541202d195a3d9fe11b1c @@ -2033,7 +2033,7 @@ F test/walslow.test 0c51843836c9dcf40a5ac05aa781bfb977b396ee2c872d92bd48b79d5dd9 F test/walthread.test d562f51a61191ccfab64940df7aa1cef87c902fa5ab742590ef7f859dfe6a44b F test/walvfs.test e1a6ad0f3c78e98b55c3d5f0889cf366cc0d0a1cb2bccb44ac9ec67384adc4a1 F test/where.test 5087c72d26fd075a1644c8512be9fe18de9bf2d2b0754f7fd9b74a1c6540c4fc -F test/where2.test 1dbff4ab847068a52b927a0c1a7cf7faed4c8cae081fbcdac9b052a3a209aefa +F test/where2.test b73f8ee8f94b850764c429efe2d48171090628737dcc3df64a9f2214da02089f F test/where3.test 4ccb156ae33de86414a52775a6f590a9d60ba2cbc7a93a24fa331b7bcf5b6030 F test/where4.test 4a371bfcc607f41d233701bdec33ac2972908ba8 F test/where5.test fdf66f96d29a064b63eb543e28da4dfdccd81ad2 @@ -2205,8 +2205,8 @@ F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee F tool/warnings.sh a554d13f6e5cf3760f041b87939e3d616ec6961859c3245e8ef701d1eafc2ca2 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f F tool/winmain.c 00c8fb88e365c9017db14c73d3c78af62194d9644feaf60e220ab0f411f3604c -P 49a3c6ade45ea31187ac8dbba0452fcad487e76f2219bfa6435feab545b5f632 -R f29868624cf00be519c1a0fbe03bcc1c +P e076ac7b648988b48b546e19b5ef2e50061b44c85bc2645362409e295e3b4b11 +R ea458682148485135a388a8cd079072c U drh -Z b8aa284a713462e6a9458c46f7af8ebd +Z 57973d6ccb3dee1f784470469cc665de # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 06ac86b699..7e867d6575 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -e076ac7b648988b48b546e19b5ef2e50061b44c85bc2645362409e295e3b4b11 +622882529558b4779dfb7246bd5a9de776555c8f940bb941397fb56fb9f97e43 diff --git a/src/whereexpr.c b/src/whereexpr.c index 74bf624c8d..f4a370bd23 100644 --- a/src/whereexpr.c +++ b/src/whereexpr.c @@ -1316,7 +1316,7 @@ static void exprAnalyze( /* Analyze a term that is composed of two or more subterms connected by ** an OR operator. */ - else if( pExpr->op==TK_OR ){ + else if( pExpr->op==TK_OR && !ExprHasProperty(pExpr, EP_Collate) ){ assert( pWC->op==TK_AND ); exprAnalyzeOrTerm(pSrc, pWC, idxTerm); pTerm = &pWC->a[idxTerm]; diff --git a/test/bestindexC.test b/test/bestindexC.test index 8b96a19e6c..42031969f7 100644 --- a/test/bestindexC.test +++ b/test/bestindexC.test @@ -333,20 +333,39 @@ do_execsql_test 5.7 { INSERT INTO t1(rowid, a, b, c, d) VALUES(7, 'X', 'Y', 'z', 'seven'); } -do_execsql_test 5.8 { - SELECT d FROM x1 - WHERE a='x' AND ((b='y' AND c='z') OR (b='Y' AND c='z' COLLATE nocase)) -} { - zero two three -} -do_execsql_test 5.9 { - SELECT d FROM x1 - WHERE a='x' COLLATE nocase - AND ((b='y' AND c='z') OR (b='Y' AND c='z' COLLATE nocase)) -} { - zero four two - three six seven +if {1} { + # Since 2026-05-18, SQLite does not attempt the OR-optimization on + # conjuncts that contain COLLATE operators, due to + # bug report 2026-05-17T11:46:40Z. + do_catchsql_test 5.8 { + SELECT d FROM x1 + WHERE a='x' AND ((b='y' AND c='z') OR (b='Y' AND c='z' COLLATE nocase)) + } {1 {no query solution}} + + do_catchsql_test 5.9 { + SELECT d FROM x1 + WHERE a='x' COLLATE nocase + AND ((b='y' AND c='z') OR (b='Y' AND c='z' COLLATE nocase)) + } {1 {no query solution}} +} else { + # This case would work if SQLite knew how to deal with conjuncts that + # contain COLLATE operators. + do_execsql_test 5.8 { + SELECT d FROM x1 + WHERE a='x' AND ((b='y' AND c='z') OR (b='Y' AND c='z' COLLATE nocase)) + } { + zero two three + } + + do_execsql_test 5.9 { + SELECT d FROM x1 + WHERE a='x' COLLATE nocase + AND ((b='y' AND c='z') OR (b='Y' AND c='z' COLLATE nocase)) + } { + zero four two + three six seven + } } #-------------------------------------------------------------------------- @@ -422,5 +441,3 @@ do_execsql_test 6.6 { } {555} finish_test - - diff --git a/test/where2.test b/test/where2.test index 6045cb1177..21d266e118 100644 --- a/test/where2.test +++ b/test/where2.test @@ -828,7 +828,17 @@ do_execsql_test where2-16.2 { AND t1.a=t4.h; } {~/.* t[34] .* t1 .*/} - - +# 2026-05-18 bug report 2026-05-17T11:46:40Z +# +do_execsql_test where2-17.0 { + DROP TABLE IF EXISTS t1; + CREATE TABLE t1(a TEXT); + INSERT INTO t1 VALUES('A'),('b'); + SELECT * FROM t1 WHERE (a='a' COLLATE nocase) OR a='b' ORDER BY +a; +} {A b} +do_execsql_test where2-17.1 { + CREATE INDEX t1_a ON t1(a); + SELECT * FROM t1 WHERE (a='a' COLLATE nocase) OR a='b' ORDER BY +a; +} {A b} finish_test