]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
Do not attempt to use a covering index based purely on columns-used
authordrh <>
Fri, 9 Aug 2024 17:09:18 +0000 (17:09 +0000)
committerdrh <>
Fri, 9 Aug 2024 17:09:18 +0000 (17:09 +0000)
when doing an UPDATE or DELETE of a WITHOUT ROWID table.  Raise an
SQLITE_INTERNAL error if there is ever a situation where a table reference
cannot be converted into an index reference when the query planner thinks
that a covering index is appropriate.

FossilOrigin-Name: fae39ae9320c0f4fcc2e3b3baf0a4170ba2b9a04634a0a1fa41dd4918a74b106

manifest
manifest.uuid
src/where.c

index 10fc3d74d8a8182ddabf6f336d0eb54c1125fb13..3b74d15e9f23c76e3e1e34dce9d8c59b5559c8b2 100644 (file)
--- a/manifest
+++ b/manifest
@@ -1,5 +1,5 @@
-C Bind\sthe\snew\sdebug\sparameters\sin\sfuzzinvariants.c.
-D 2024-08-09T12:35:27.067
+C Do\snot\sattempt\sto\suse\sa\scovering\sindex\sbased\spurely\son\scolumns-used\nwhen\sdoing\san\sUPDATE\sor\sDELETE\sof\sa\sWITHOUT\sROWID\stable.\s\sRaise\san\nSQLITE_INTERNAL\serror\sif\sthere\sis\sever\sa\ssituation\swhere\sa\stable\sreference\ncannot\sbe\sconverted\sinto\san\sindex\sreference\swhen\sthe\squery\splanner\sthinks\nthat\sa\scovering\sindex\sis\sappropriate.
+D 2024-08-09T17:09:18.697
 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1
 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea
 F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724
@@ -846,7 +846,7 @@ F src/vxworks.h d2988f4e5a61a4dfe82c6524dd3d6e4f2ce3cdb9
 F src/wal.c 887fc4ca3f020ebb2e376f222069570834ac63bf50111ef0cbf3ae417048ed89
 F src/wal.h ba252daaa94f889f4b2c17c027e823d9be47ce39da1d3799886bbd51f0490452
 F src/walker.c 7c7ea0115345851c3da4e04e2e239a29983b61fb5b038b94eede6aba462640e2
-F src/where.c 5bbe53db73ae6c8ee34a5eab693a5586ad8ff4f094ff0e524df965b683bec884
+F src/where.c 5fa17ec4e344e57cf43dd7b2977c95a518bfc2d43edb42df0cd1d5c2b42cee04
 F src/whereInt.h 002adc3aa2cc10733b9b27958fdbe893987cd989fab25a9853941c1f9b9b0a65
 F src/wherecode.c c9cac0b0b8e809c5e7e79d7796918907fb685ad99be2aaa9737f9787aa47349c
 F src/whereexpr.c 7d0d34b42b9edfd8e8ca66beb3a6ef63fe211c001af54caf2ccbcd989b783290
@@ -2204,8 +2204,11 @@ F vsixtest/vsixtest.tcl 6195aba1f12a5e10efc2b8c0009532167be5e301abe5b31385638080
 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc
 F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e
 F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0
-P fa047c3ea7a03d76afd6a11f58ef7b84c653f583ed795e0de5be2a6b986e558e
-R 4385e87b815ad1924711e2dcdab3d5bb
+P 7e1dc263051cf50db04643d1a2aa9f91559b2b121859b750ce4446012d5f3c3e
+R a22c0892de474f9ba14db4c65993edff
+T *branch * covering-index-patch
+T *sym-covering-index-patch *
+T -sym-trunk *
 U drh
-Z 5861d6c430a2b6c91eb7ed0d9c3ba80b
+Z b1c9594c16be220e78f6cfe69b132d52
 # Remove this line to create a well-formed Fossil manifest.
index c2f77959c0a1d28cf4dba64d853a3e48c2f616ce..30b7a517ca3932bb5a630bb30335b1a7c56ac21a 100644 (file)
@@ -1 +1 @@
-7e1dc263051cf50db04643d1a2aa9f91559b2b121859b750ce4446012d5f3c3e
+fae39ae9320c0f4fcc2e3b3baf0a4170ba2b9a04634a0a1fa41dd4918a74b106
index c850121c3405fe1b9a79db16477d60c83bc170e7..15f5fe7d96bba758494311d7d858fab29170c531 100644 (file)
@@ -4047,7 +4047,9 @@ static int whereLoopAddBtree(
                   " according to whereIsCoveringIndex()\n", pProbe->zName));
             }
           }
-        }else if( m==0 ){
+        }else if( m==0 
+           && (HasRowid(pTab) || pWInfo->pSelect!=0 || sqlite3FaultSim(700))
+        ){
           WHERETRACE(0x200,
              ("-> %s a covering index according to bitmasks\n",
              pProbe->zName, m==0 ? "is" : "is not"));
@@ -7078,26 +7080,6 @@ whereBeginError:
   }
 #endif
 
-#ifdef SQLITE_DEBUG
-/*
-** Return true if cursor iCur is opened by instruction k of the
-** bytecode.  Used inside of assert() only.
-*/
-static int cursorIsOpen(Vdbe *v, int iCur, int k){
-  while( k>=0 ){
-    VdbeOp *pOp = sqlite3VdbeGetOp(v,k--);
-    if( pOp->p1!=iCur ) continue;
-    if( pOp->opcode==OP_Close ) return 0;
-    if( pOp->opcode==OP_OpenRead ) return 1;
-    if( pOp->opcode==OP_OpenWrite ) return 1;
-    if( pOp->opcode==OP_OpenDup ) return 1;
-    if( pOp->opcode==OP_OpenAutoindex ) return 1;
-    if( pOp->opcode==OP_OpenEphemeral ) return 1;
-  }
-  return 0;
-}
-#endif /* SQLITE_DEBUG */
-
 /*
 ** Generate the end of the WHERE loop.  See comments on
 ** sqlite3WhereBegin() for additional information.
@@ -7376,18 +7358,20 @@ void sqlite3WhereEnd(WhereInfo *pWInfo){
           assert( pIdx->pTable==pTab );
 #ifdef SQLITE_ENABLE_OFFSET_SQL_FUNC
           if( pOp->opcode==OP_Offset ){
-            /* Do not need to translate the column number */
+            x = 0;
           }else
 #endif
-          if( !HasRowid(pTab) ){
-            Index *pPk = sqlite3PrimaryKeyIndex(pTab);
-            x = pPk->aiColumn[x];
-            assert( x>=0 );
-          }else{
-            testcase( x!=sqlite3StorageColumnToTable(pTab,x) );
-            x = sqlite3StorageColumnToTable(pTab,x);
+          {
+            if( !HasRowid(pTab) ){
+              Index *pPk = sqlite3PrimaryKeyIndex(pTab);
+              x = pPk->aiColumn[x];
+              assert( x>=0 );
+            }else{
+              testcase( x!=sqlite3StorageColumnToTable(pTab,x) );
+              x = sqlite3StorageColumnToTable(pTab,x);
+            }
+            x = sqlite3TableColumnToIndex(pIdx, x);
           }
-          x = sqlite3TableColumnToIndex(pIdx, x);
           if( x>=0 ){
             pOp->p2 = x;
             pOp->p1 = pLevel->iIdxCur;
@@ -7397,16 +7381,10 @@ void sqlite3WhereEnd(WhereInfo *pWInfo){
             ** reference.  Verify that this is harmless - that the
             ** table being referenced really is open.
             */
-#ifdef SQLITE_ENABLE_OFFSET_SQL_FUNC
-            assert( (pLoop->wsFlags & WHERE_IDX_ONLY)==0
-                 || cursorIsOpen(v,pOp->p1,k)
-                 || pOp->opcode==OP_Offset
-            );
-#else
-            assert( (pLoop->wsFlags & WHERE_IDX_ONLY)==0
-                 || cursorIsOpen(v,pOp->p1,k)
-            );
-#endif
+            if( pLoop->wsFlags & WHERE_IDX_ONLY ){
+              sqlite3ErrorMsg(pParse, "internal query planner error");
+              pParse->rc = SQLITE_INTERNAL;
+            }
           }
         }else if( pOp->opcode==OP_Rowid ){
           pOp->p1 = pLevel->iIdxCur;