From: drh <> Date: Sat, 25 Jul 2026 18:56:31 +0000 (+0000) Subject: Improved optimization of "expr OR TRUE" and "expr OR FALSE". X-Git-Url: http://git.ipfire.org/gitweb/index.cgi?a=commitdiff_plain;h=701092f4a5e8320460219dab733f31dc7a723629;p=thirdparty%2Fsqlite.git Improved optimization of "expr OR TRUE" and "expr OR FALSE". [bugs:/info/2026-07-25T08:36:25Z|Bug 2026-07-25T08:36:25Z]. FossilOrigin-Name: 2f0bde4bc89c2b088c8f821719d7e457d9129c0493032152b8f4472673973e58 --- diff --git a/manifest b/manifest index dbdc848088..262c268b40 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Avoid\sopening\scursors\sonly\srequired\sfor\sreads\sthat\sare\soptimized\saway\sby\sthe\sexists-to-join\soptimization.\sAddresses\sreport\s[bugs:/info/2026-07-25T08:39:23Z\s|\s2026-07-25T08:39:23Z]. -D 2026-07-25T17:13:30.874 +C Improved\soptimization\sof\s"expr\sOR\sTRUE"\sand\s"expr\sOR\sFALSE".\n[bugs:/info/2026-07-25T08:36:25Z|Bug\s2026-07-25T08:36:25Z]. +D 2026-07-25T18:56:31.702 F .fossil-settings/binary-glob 61195414528fb3ea9693577e1980230d78a1f8b0a54c78cf1b9b24d0a409ed6a x F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea @@ -827,7 +827,7 @@ F src/walker.c d5006d6b005e4ea7302ad390957a8d41ed83faa177e412f89bc5600a7462a014 F src/where.c 2f5b4091f37bfac7658ea3d52b2c192d8fb2ec062f232815e0eb5152a46267db F src/whereInt.h f039ad303bc2913de673e431821ef8db3b619d249e6e5548d90072a684e72285 F src/wherecode.c dd500ffc8682ec57d3ac7edee3699b675338c4e885c6d1fdb86c791103ebe1dd -F src/whereexpr.c 07ffa5d16d970d89a2714cdd92d99058340f88c705e7e7ea6efe272a8ad1f91e +F src/whereexpr.c 89d33f43594a4a5c3028c86ff0d0f8946aca96b2e535074f23b9893f51c95705 F src/window.c 0d7dacdf2e84c6ee8ff498d5cc881dd245fcb2f14f6c5976e97e112ce96e90dc F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2 F test/affinity2.test 4d7a34d328e58ca2a2d78fd76c27614a41ca7ddf4312ded9c68c04f430b3b47d @@ -2044,7 +2044,7 @@ F test/walshared.test 42e3808582504878af237ea02c42ca793e8a0efaa19df7df26ac573370 F test/walslow.test 0c51843836c9dcf40a5ac05aa781bfb977b396ee2c872d92bd48b79d5dd9aa23 F test/walthread.test d562f51a61191ccfab64940df7aa1cef87c902fa5ab742590ef7f859dfe6a44b F test/walvfs.test e1a6ad0f3c78e98b55c3d5f0889cf366cc0d0a1cb2bccb44ac9ec67384adc4a1 -F test/where.test 5087c72d26fd075a1644c8512be9fe18de9bf2d2b0754f7fd9b74a1c6540c4fc +F test/where.test 11c35e0b861d76efd003ca64b567fdd653c45ba95d3ac603b8199ac9c4deddfd F test/where2.test 3096dc7dc70dba52d974341f4a024e468c9ea3c1aa202a2e414a5413c0c5655c F test/where3.test 4ccb156ae33de86414a52775a6f590a9d60ba2cbc7a93a24fa331b7bcf5b6030 F test/where4.test 4a371bfcc607f41d233701bdec33ac2972908ba8 @@ -2217,8 +2217,8 @@ F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee F tool/warnings.sh a554d13f6e5cf3760f041b87939e3d616ec6961859c3245e8ef701d1eafc2ca2 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f F tool/winmain.c 00c8fb88e365c9017db14c73d3c78af62194d9644feaf60e220ab0f411f3604c -P c54858eab45f71a77249c8ecdc8e107cf631e743b8b883f2b6db60e0bf7e908a -R 528d47fc0fabfd6337e81b14515c98d0 -U dan -Z 6c13a8261c5395d3405eca89304ed3b7 +P c81ec73a3780cf7a44965f1763f1e6e2c324b60132197756fdb351e98052fd02 +R d0831f21924335926bd1f401977e35b4 +U drh +Z 025136c6119946e997fbd5568ce7c23e # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 17c83bb229..9432b3c8d6 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -c81ec73a3780cf7a44965f1763f1e6e2c324b60132197756fdb351e98052fd02 +2f0bde4bc89c2b088c8f821719d7e457d9129c0493032152b8f4472673973e58 diff --git a/src/whereexpr.c b/src/whereexpr.c index 140d23445a..1fe1e67f54 100644 --- a/src/whereexpr.c +++ b/src/whereexpr.c @@ -1180,6 +1180,7 @@ static void exprAnalyze( pExpr = pTerm->pExpr; assert( pExpr!=0 ); /* Because malloc() has not failed */ assert( pExpr->op!=TK_AS && pExpr->op!=TK_COLLATE ); +exprAnalyze_restart: pMaskSet->bVarSelect = 0; prereqLeft = sqlite3WhereExprUsage(pMaskSet, pExpr->pLeft); op = pExpr->op; @@ -1346,6 +1347,11 @@ static void exprAnalyze( ** an OR operator. */ else if( pExpr->op==TK_OR && !ExprHasProperty(pExpr, EP_Collate) ){ + Expr *pAlt = sqlite3ExprSimplifiedAndOr(pExpr); + if( pAlt!=pExpr ){ + pTerm->pExpr = pExpr = sqlite3ExprSkipCollateAndLikely(pAlt); + goto exprAnalyze_restart; + } assert( pWC->op==TK_AND ); exprAnalyzeOrTerm(pSrc, pWC, idxTerm); pTerm = &pWC->a[idxTerm]; diff --git a/test/where.test b/test/where.test index c377006fb9..ef3d6337df 100644 --- a/test/where.test +++ b/test/where.test @@ -1704,4 +1704,37 @@ do_test where-30.1 { } {SCAN} # ^^^^^^-- there should only be one top-level table scan in the query plan. +# Bug 2026-07-25T08:36:25Z (really an enhancement request: a request to +# do a better job of optimizing out the OR operator in "expr OR FALSE".) +# +do_execsql_test where-31.0 { + DROP TABLE IF EXISTS t1; + CREATE TABLE t1( + id INTEGER PRIMARY KEY, + x INTEGER NOT NULL + ); + CREATE INDEX t1x ON t1(x); + WITH RECURSIVE seq(i) AS (SELECT 1 UNION ALL SELECT i+1 FROM seq WHERE i<200) + INSERT INTO t1(id, x) SELECT i, i % 13 FROM seq; + ANALYZE; +} +do_execsql_test where-31.1 { + SELECT count(*) FROM t1 WHERE x=1 OR false; +} 16 +do_eqp_test where-31.2 { + SELECT count(*) FROM t1 WHERE x=1 OR false; +} { + QUERY PLAN + `--SEARCH t1 USING COVERING INDEX t1x (x=?) +} +do_execsql_test where-31.3 { + SELECT count(*) FROM t1 WHERE x=1 OR false; +} 16 +do_eqp_test where-31.4 { + SELECT count(*) FROM t1 WHERE false OR x=1 +} { + QUERY PLAN + `--SEARCH t1 USING COVERING INDEX t1x (x=?) +} + finish_test