]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
Fix the Bloom-filter optimization so that it does not use IS NULL or
authordrh <>
Fri, 25 Mar 2022 01:31:18 +0000 (01:31 +0000)
committerdrh <>
Fri, 25 Mar 2022 01:31:18 +0000 (01:31 +0000)
IS NOT NULL constraints from the WHERE clause when operating on a LEFT JOIN.
[forum:/forumpost/031e262a89b6a9d2|Forum thread 031e262a89b6a9d2].

FossilOrigin-Name: 8246bfbc1643497fbbebe950b5e297fdc2a90359603e5c01a79ba67168bd7d02

manifest
manifest.uuid
src/where.c
test/join5.test

index a897703089f00c7c9274553dada95bc6c8c483ed..0aae693d787ad8a535b4d7e73d14082a812a4c91 100644 (file)
--- a/manifest
+++ b/manifest
@@ -1,5 +1,5 @@
-C Ensure\sthat\sdatabase\scorruption\sdoes\snot\scause\sthe\scursor\spassed\sinto\nsqlite3BtreeDelete()\sto\sbe\sinvalid.\ndbsqlfuzz\s209bf3de9ee11ae440848ab9bc9c13858f9be2e4.
-D 2022-03-22T23:47:25.190
+C Fix\sthe\sBloom-filter\soptimization\sso\sthat\sit\sdoes\snot\suse\sIS\sNULL\sor\nIS\sNOT\sNULL\sconstraints\sfrom\sthe\sWHERE\sclause\swhen\soperating\son\sa\sLEFT\sJOIN.\n[forum:/forumpost/031e262a89b6a9d2|Forum\sthread\s031e262a89b6a9d2].
+D 2022-03-25T01:31:18.885
 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1
 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea
 F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724
@@ -639,7 +639,7 @@ F src/vxworks.h d2988f4e5a61a4dfe82c6524dd3d6e4f2ce3cdb9
 F src/wal.c b9df133a705093da8977da5eb202eaadb844839f1c7297c08d33471f5491843d
 F src/wal.h c3aa7825bfa2fe0d85bef2db94655f99870a285778baa36307c0a16da32b226a
 F src/walker.c f890a3298418d7cba3b69b8803594fdc484ea241206a8dfa99db6dd36f8cbb3b
-F src/where.c ae2a3d271c7599d2944b9e2f460b9eaf0ea5bcc385e221a15ff20ec8b6226556
+F src/where.c 468d64f65ffc4ebb2ad2791091bf1dda84885eb65caea8999b5db60d096e5d88
 F src/whereInt.h 15d2975c3b4c193c78c26674400a840da8647fe1777ae3b026e2d15937b38a03
 F src/wherecode.c 84be340684393248b9f3ecbce9b87c8a6f818149b52302702ea0b8d2a9d51faf
 F src/whereexpr.c 2a71f5491798460c9590317329234d332d9eb1717cba4f3403122189a75c465e
@@ -1143,7 +1143,7 @@ F test/join.test 25cf0ac11c3b81fedfd166f9062166bdb39dea92f5a7c16cacbf6dc1f7f6702
 F test/join2.test 9bdc615841b91c97a16d68bad9508aea11fa0c6b34e5689847bcc4dac70e4990
 F test/join3.test 6f0c774ff1ba0489e6c88a3e77b9d3528fb4fda0
 F test/join4.test 1a352e4e267114444c29266ce79e941af5885916
-F test/join5.test 3d51c4ae5f1f373a03164ca3c88d438f64bed7a2c01cf69810e2ca3d0e9071c8
+F test/join5.test 0d63c7e43b3160b9d4b93f196ef83b6efc7751b9edd0d18c53a46fbec7a49cfc
 F test/join6.test f809c025fa253f9e150c0e9afd4cef8813257bceeb6f46e04041228c9403cc2c
 F test/journal1.test c7b768041b7f494471531e17abc2f4f5ebf9e5096984f43ed17c4eb80ba34497
 F test/journal2.test 9dac6b4ba0ca79c3b21446bbae993a462c2397c4
@@ -1944,9 +1944,9 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93
 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc
 F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e
 F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0
-P 06d4c4d17c49b98701e4b09c19c0cc68e65a0413850fda33b4991fa24fc84fa0
-Q +a85126f96614c53b030c6e6c43ff239eae458048597a10e9a0361fcec8628ecf
-R aba1355516868cd709d449bf9dbe81b7
+P 780d00d4ec8c87229a639671a610c4561f2ab2b1729bb9a4386547ac18772dd4
+Q +1a6328f2a5b4973094e5f85787145d652119822c86ec01a61f3f985c9d2903f2
+R 7b8c03ac7c46cd4184845651aea6ceca
 U drh
-Z f525e6a4adcf92804064f386dbd84060
+Z 9bba9a7d11c4db11fd2304c9ab735477
 # Remove this line to create a well-formed Fossil manifest.
index 4a99693678a918706939b9f2ac558b79cd77a378..53b4bd4b9925c1771b5dd66a63c4cfe94d221930 100644 (file)
@@ -1 +1 @@
-780d00d4ec8c87229a639671a610c4561f2ab2b1729bb9a4386547ac18772dd4
\ No newline at end of file
+8246bfbc1643497fbbebe950b5e297fdc2a90359603e5c01a79ba67168bd7d02
\ No newline at end of file
index 02f563785ae9c4c17be38d0e63deb737299a2f2a..6e645964b9fee6334e05511b4b9b3ff15c5a8975 100644 (file)
@@ -2594,8 +2594,17 @@ static void whereLoopOutputAdjust(
         /* If there are extra terms in the WHERE clause not used by an index
         ** that depend only on the table being scanned, and that will tend to
         ** cause many rows to be omitted, then mark that table as
-        ** "self-culling". */
-        pLoop->wsFlags |= WHERE_SELFCULL;
+        ** "self-culling".
+        **
+        ** 2022-03-24:  Self-culling only applies if either the extra terms
+        ** are straight comparison operators that are non-true with NULL
+        ** operand, or if the loop is not a LEFT JOIN.
+        */
+        if( (pTerm->eOperator & 0x3f)!=0
+         || (pWC->pWInfo->pTabList->a[pLoop->iTab].fg.jointype & JT_LEFT)==0
+        ){
+          pLoop->wsFlags |= WHERE_SELFCULL;
+        }
       }
       if( pTerm->truthProb<=0 ){
         /* If a truth probability is specified using the likelihood() hints,
index 518fab7a92da0b1d0cea2888725063de942d579c..a5cedd8cb28d09cd1562fb0ce097a659ab218890 100644 (file)
@@ -300,6 +300,13 @@ do_execsql_test 7.3 {
 
 do_eqp_test 7.4 {
   SELECT * FROM t3 LEFT JOIN t4 ON (t4.x = t3.x) WHERE (t4.y = ? OR t4.z = ?);
+} {
+  QUERY PLAN
+  |--SCAN t3
+  `--SEARCH t4 USING INDEX t4xz (x=?)
+} 
+do_eqp_test 7.4b {
+  SELECT * FROM t3 CROSS JOIN t4 ON (t4.x = t3.x) WHERE (+t4.y = ? OR t4.z = ?);
 } {
   QUERY PLAN
   |--SCAN t3
@@ -360,5 +367,32 @@ do_execsql_test 10.1 {
   SELECT x FROM v3; 
 } {0}
 
+# 2022-03-24 https://sqlite.org/forum/forumpost/031e262a89b6a9d2
+# Bloom-filter on a LEFT JOIN with NULL-based WHERE constraints.
+#
+reset_db
+do_execsql_test 11.1 {
+  CREATE TABLE t1(a INTEGER PRIMARY KEY, b INT);
+  CREATE TABLE t2(c INTEGER PRIMARY KEY, d INT);
+  WITH RECURSIVE c(x) AS (VALUES(1) UNION ALL SELECT x+1 FROM c WHERE x<8)
+  INSERT INTO t1(a,b) SELECT x, 10*x FROM c;
+  INSERT INTO t2(c,d) SELECT b*2, 100*a FROM t1;
+  ANALYZE;
+  DELETE FROM sqlite_stat1;
+  INSERT INTO sqlite_stat1(tbl,idx,stat) VALUES
+    ('t1',NULL,150105),('t2',NULL,98747);
+  ANALYZE sqlite_schema;
+} {}
+do_execsql_test 11.2 {
+  SELECT count(*) FROM t1 LEFT JOIN t2 ON c=b WHERE d IS NULL;
+} {4}
+do_execsql_test 11.3 {
+  SELECT count(*) FROM t1 LEFT JOIN t2 ON c=b WHERE d=100;
+} {1}
+do_execsql_test 11.4 {
+  SELECT count(*) FROM t1 LEFT JOIN t2 ON c=b WHERE d>=300;
+} {2}
+
+
 
 finish_test