]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
Improved Bloom-filter invariant checking.
authordrh <>
Thu, 23 Jul 2026 18:55:12 +0000 (18:55 +0000)
committerdrh <>
Thu, 23 Jul 2026 18:55:12 +0000 (18:55 +0000)
FossilOrigin-Name: f38f4167110df11ba54816932126f695dc6e114d4001d0261669807a55ad7966

manifest
manifest.uuid
src/expr.c
src/select.c
src/whereexpr.c

index 73441c4ea8b0312dba0bdd7ae60fb9386d6e528b..013559ad648b96f56e3fad10427d9886cad52449 100644 (file)
--- a/manifest
+++ b/manifest
@@ -1,5 +1,5 @@
-C Fix\sthe\snew\sfilterHash()\sfunction\sso\sthat\sit\sworks\scorrectly\sfor\szeroblobs.
-D 2026-07-23T17:41:10.955
+C Improved\sBloom-filter\sinvariant\schecking.
+D 2026-07-23T18:55:12.383
 F .fossil-settings/binary-glob 61195414528fb3ea9693577e1980230d78a1f8b0a54c78cf1b9b24d0a409ed6a x
 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1
 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea
@@ -693,7 +693,7 @@ F src/date.c e1a002a4199bfa85e8778c0f72182c679580b131147d8e46d9221cfceffb8500
 F src/dbpage.c c6a9de13b0a01f0bc94a41e16213ab1ecd15ccfe86df7255ced40fda9446257d
 F src/dbstat.c 73362c0df0f40ad5523a6f5501224959d0976757b511299bf892313e79d14f5c
 F src/delete.c 59eeca3fb88c29329afc41bb803ee568b120d9dd7470b5f38ab55cc38390b451
-F src/expr.c b63b6d46f4531df5d35307cec69b0bda3b1c50dfcde6f0c14915291e02012ca3
+F src/expr.c fb5075dc231746e795817b096c39d0d1423d8ec29697e97959a50db84dcff211
 F src/fault.c 460f3e55994363812d9d60844b2a6de88826e007
 F src/fkey.c 931f74cec1dc8038a0217ef340c91ce147dd1bbed08dc40c47ee0ec6edfffb08
 F src/func.c 208b4d073a1e823df8d0e19d0529093c09a9984851dcfda9808445541cefe6d0
@@ -742,7 +742,7 @@ F src/printf.c b480176bd0aaed9d64e804cfa3ca27fc585f65a73e7c7ca2fe9b9016db2cf6d5
 F src/random.c 606b00941a1d7dd09c381d3279a058d771f406c5213c9932bbd93d5587be4b9c
 F src/resolve.c 54395ee97eb710e695202d4112cf2b1c1c7767a57afcea745df71abb1c917768
 F src/rowset.c 8432130e6c344b3401a8874c3cb49fefe6873fec593294de077afea2dce5ec97
-F src/select.c 586ccc75f2fa289c51554330f9ff549d00dae4122ac7e2af712437e2ef737cc8
+F src/select.c d2ad83d49c41c30d213873bac8481c6bf099438c61dcb597de52ddb55a6324fb
 F src/shell.c.in 0df571dd1eae1a15577361902eb5487a072d3290ea94e1e72e757050b641f870
 F src/sqlite.h.in 2101a2b494cbc282d0dc1c3f631c4fb83060c52876cc9d7615b091ad66d932b1
 F src/sqlite3.rc 015537e6ac1eec6c7050e17b616c2ffe6f70fca241835a84a4f0d5937383c479
@@ -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 40264a22a796358bd56440daa0355a6513651115fd79bb39ef9cd934a184fdeb
+F src/whereexpr.c 07ffa5d16d970d89a2714cdd92d99058340f88c705e7e7ea6efe272a8ad1f91e
 F src/window.c 0d7dacdf2e84c6ee8ff498d5cc881dd245fcb2f14f6c5976e97e112ce96e90dc
 F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2
 F test/affinity2.test 4d7a34d328e58ca2a2d78fd76c27614a41ca7ddf4312ded9c68c04f430b3b47d
@@ -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 2577edc796505a0a6dabccbcc1bb6a828457092caa4d074561da5e58a6f065a2
-R 87295a0ea0d1f9c5765acc4473724fdc
+P 3013d6ab4afd4f63fa63a773778adcf07821cfcb33e3ae42752aea13fd2b6224
+R 0e1584e2f9d4a83856c66208401cbfea
 U drh
-Z 0a7b98af243154566c4b036f9155b275
+Z 3049f8ec6b5a896c591d2da0158d3d82
 # Remove this line to create a well-formed Fossil manifest.
index 9de6a99890308d5b92edb957691d6e580d9fc742..e9cfa467fd1a601a81a84e65fb6cd73b2ace164c 100644 (file)
@@ -1 +1 @@
-3013d6ab4afd4f63fa63a773778adcf07821cfcb33e3ae42752aea13fd2b6224
+f38f4167110df11ba54816932126f695dc6e114d4001d0261669807a55ad7966
index 790b7611635652a4edef910d7f0679d1442da7f6..d549169593020b88cfa6e46adb1f625e058d484a 100644 (file)
@@ -3740,6 +3740,8 @@ void sqlite3CodeRhsOfIN(
         addrBloom = sqlite3VdbeAddOp2(v, OP_Blob, 10000, regBloom);
         VdbeComment((v, "Bloom filter"));
         dest.iSDParm2 = regBloom;
+        sqlite3VdbeChangeP4(v, addr, (void *)pKeyInfo, P4_KEYINFO);
+        pKeyInfo = 0;
       }
       testcase( pSelect->selFlags & SF_Distinct );
       pCopy = sqlite3SelectDup(pParse->db, pSelect, 0);
@@ -3779,10 +3781,9 @@ void sqlite3CodeRhsOfIN(
     }else if( affinity==SQLITE_AFF_REAL ){
       affinity = SQLITE_AFF_NUMERIC;
     }
-    if( pKeyInfo ){
-      assert( sqlite3KeyInfoIsWriteable(pKeyInfo) );
-      pKeyInfo->aColl[0] = sqlite3ExprCollSeq(pParse, pExpr->pLeft);
-    }
+    assert( pKeyInfo!=0 );
+    assert( sqlite3KeyInfoIsWriteable(pKeyInfo) );
+    pKeyInfo->aColl[0] = sqlite3ExprCollSeq(pParse, pExpr->pLeft);
 
     /* Loop through each expression in <exprlist>. */
     r1 = sqlite3GetTempReg(pParse);
index 073b30f7e641178d69b176f3a162e02521a77a33..b8854519ee15d49530de4bd21fab03c62ac3cb74 100644 (file)
@@ -1127,6 +1127,48 @@ static void selectExprDefer(
 }
 #endif
 
+#ifdef SQLITE_DEBUG
+/*
+** This is a byte-code validation check that only runs when SQLITE_DEBUG
+** is defined.  This routine looks backwards through the bytecode
+** for the definition of cursor with index iCur.  It extracts the KeyInfo from
+** that cursor (it must be an index cursor) and verifies that the cursor
+** does not use any collating seqeuences other than BINARY for its first
+** nCol columns.
+**
+** This routine is used inside of an assert().  So it should return true
+** on success and false if the invariant is not satisfied.
+**
+** tag-202607231411
+*/
+static int sqlite3CursorBloomable(Parse *pParse, int iCur, int nCol){
+  int i,k;
+  Vdbe *v = pParse->pVdbe;
+  if( pParse->nErr ) return 1;
+  assert( v );
+  for(k=sqlite3VdbeCurrentAddr(v)-1; k>0; k--){
+    const VdbeOp *pOp = sqlite3VdbeGetOp(v, k);
+    const KeyInfo *pKeyInfo;
+    if( pOp->p1!=iCur ) continue;
+    if( pOp->opcode!=OP_OpenRead
+     && pOp->opcode!=OP_OpenWrite
+     && pOp->opcode!=OP_OpenEphemeral
+    ){
+      continue;
+    }
+    assert( pOp->p4type==P4_KEYINFO );
+    pKeyInfo = (const KeyInfo*)pOp->p4.pKeyInfo;
+    assert( pKeyInfo!=0 );
+    for(i=0; i<nCol; i++){
+      assert( sqlite3IsBinary(pKeyInfo->aColl[i]) );
+    }
+    return 1;
+  }
+  return 0;
+}
+#endif /* SQLITE_DEBUG */
+
+
 /*
 ** This routine generates the code for the inside of the inner loop
 ** of a SELECT.
@@ -1397,6 +1439,7 @@ static void selectInnerLoop(
             r1, pDest->zAffSdst, nResultCol);
         sqlite3VdbeAddOp4Int(v, OP_IdxInsert, iParm, r1, regResult, nResultCol);
         if( pDest->iSDParm2 ){
+          assert( sqlite3CursorBloomable(pParse,iParm,nResultCol) );
           sqlite3VdbeAddOp4Int(v, OP_FilterAdd, pDest->iSDParm2, 0,
                                regResult, nResultCol);
           ExplainQueryPlan((pParse, 0, "CREATE BLOOM FILTER"));
@@ -3206,6 +3249,7 @@ static int generateOutputSubroutine(
       sqlite3VdbeAddOp4Int(v, OP_IdxInsert, pDest->iSDParm, r1,
                            pIn->iSdst, pIn->nSdst);
       if( pDest->iSDParm2>0 ){
+        assert( sqlite3CursorBloomable(pParse, pDest->iSDParm, pIn->nSdst) );
         sqlite3VdbeAddOp4Int(v, OP_FilterAdd, pDest->iSDParm2, 0,
                              pIn->iSdst, pIn->nSdst);
         ExplainQueryPlan((pParse, 0, "CREATE BLOOM FILTER"));
index 4c77e3b753468f70d3963762441651ae08902c4e..140d23445a0b239c19d4e9c12a7fe55546b324ea 100644 (file)
@@ -1985,8 +1985,6 @@ void sqlite3WhereTabFuncArgs(
 */
 int sqlite3WhereLoopBloomable(const WhereLoop *pLoop){
   if( pLoop->wsFlags & WHERE_IPK ) return 1;
-  if( (pLoop->wsFlags & WHERE_INDEXED)!=0 ){
-    return sqlite3IndexBloomable(pLoop->u.btree.pIndex, pLoop->u.btree.nEq);
-  }
-  return 0;
+  if( NEVER((pLoop->wsFlags & WHERE_INDEXED)==0) ) return 0;
+  return sqlite3IndexBloomable(pLoop->u.btree.pIndex, pLoop->u.btree.nEq);
 }