]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
Modifications to pass a flag to internal routine sqlite3BtreeCursor() when a cursor...
authordan <dan@noemail.net>
Thu, 22 Oct 2015 20:54:33 +0000 (20:54 +0000)
committerdan <dan@noemail.net>
Thu, 22 Oct 2015 20:54:33 +0000 (20:54 +0000)
FossilOrigin-Name: cdc92919e600007cae5eb61223684f48a65babc0

14 files changed:
manifest
manifest.uuid
src/btree.c
src/btree.h
src/delete.c
src/insert.c
src/pragma.c
src/sqliteInt.h
src/test3.c
src/update.c
src/vdbe.c
src/where.c
src/whereInt.h
test/fordelete.test [new file with mode: 0644]

index 9f8c896ecdd0c88e85f1bfae3e02f0a32e233ff8..24f91f41c7bacfdb0f1b21e62085eff4dd6b6d1b 100644 (file)
--- a/manifest
+++ b/manifest
@@ -1,5 +1,5 @@
-C Alternate\scompiler\swarning\sfix\sfor\ssqlite3StatusHighwater.
-D 2015-10-22T18:06:40.381
+C Modifications\sto\spass\sa\sflag\sto\sinternal\sroutine\ssqlite3BtreeCursor()\swhen\sa\scursor\sthat\sis\sused\ssolely\sfor\sdeleting\sb-tree\sentries,\sor\sfor\sobtaining\sthe\scomponents\sof\skeys\sto\sdelete\sfrom\sother\sb-trees,\sis\sopened.
+D 2015-10-22T20:54:33.626
 F Makefile.in 2ea961bc09e441874eb3d1bf7398e04feb24f3ee
 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434
 F Makefile.msc 702d3e98f3afc6587a78481257f3c4c900efc3a4
@@ -280,8 +280,8 @@ F src/auth.c b56c78ebe40a2110fd361379f7e8162d23f92240
 F src/backup.c c3a9c4209439b806c44cf30daf466955727bf46c
 F src/bitvec.c d1f21d7d91690747881f03940584f4cc548c9d3d
 F src/btmutex.c 45a968cc85afed9b5e6cf55bf1f42f8d18107f79
-F src/btree.c ea8c62f65e57e49bd6b0988cd681aca7246b51af
-F src/btree.h 40189aefdc2b830d25c8b58fd7d56538481bfdd7
+F src/btree.c 9d684e19f84633323de7a767da2e2b8cf51fa600
+F src/btree.h ccc489437299e48ba5f7d957baa686a9adf2d1ba
 F src/btreeInt.h 8177c9ab90d772d6d2c6c517e05bed774b7c92c0
 F src/build.c d6162335d690396dfc5c4bd59e8b2b0c14ba6285
 F src/callback.c 7b44ce59674338ad48b0e84e7b72f935ea4f68b0
@@ -289,7 +289,7 @@ F src/complete.c addcd8160b081131005d5bc2d34adf20c1c5c92f
 F src/ctime.c 509ef9c64d1321f42448f111da86400b1799218a
 F src/date.c fb1c99172017dcc8e237339132c91a21a0788584
 F src/dbstat.c e637e7a7ff40ef32132a418c6fdf1cfb63aa27c7
-F src/delete.c 35c939eb8bacc9dd8a6715964e5f69feb8c20e44
+F src/delete.c c4c6fb9da78b946fcba2a6aac5b24bc5c15e752a
 F src/expr.c d9896fda47a8f67d0ed203e1fa981444424200c6
 F src/fault.c 160a0c015b6c2629d3899ed2daf63d75754a32bb
 F src/fkey.c 31900763094a3736a5fc887469202eb579fef2d0
@@ -298,7 +298,7 @@ F src/global.c 508e4087f7b41d688e4762dcf4d4fe28cfbc87f9
 F src/hash.c 4263fbc955f26c2e8cdc0cf214bc42435aa4e4f5
 F src/hash.h c8f3c31722cf3277d03713909761e152a5b81094
 F src/hwtime.h d32741c8f4df852c7d959236615444e2b1063b08
-F src/insert.c 6dadbb671c2cc035ddbbf11a0b0209185d5bfe2c
+F src/insert.c 419a947f27ce2da18eebf440a5aa80cc825defae
 F src/journal.c b4124532212b6952f42eb2c12fa3c25701d8ba8d
 F src/legacy.c ba1863ea58c4c840335a84ec276fc2b25e22bc4e
 F src/lempar.c d344a95d60c24e2f490ee59db9784b1b17439012
@@ -331,7 +331,7 @@ F src/parse.y f599aa5e871a493330d567ced93de696f61f48f7
 F src/pcache.c 24be750c79272e0ca7b6e007bc94999700f3e5ef
 F src/pcache.h 9968603796240cdf83da7e7bef76edf90619cea9
 F src/pcache1.c 902e1bc7bdaa81b40f8543407c5e2ac8ef4dc035
-F src/pragma.c dcfe3a35d2de935feeaba1455528b4a5c4f1208c
+F src/pragma.c 8fd4c8a12e25f0d916426f160255ebe25415eba7
 F src/pragma.h 631a91c8b0e6ca8f051a1d8a4a0da4150e04620a
 F src/prepare.c 82e5db1013846a819f198336fed72c44c974e7b1
 F src/printf.c 0c4bcdd1c2e2521024f0a69cb5eb334f86b3652a
@@ -343,14 +343,14 @@ F src/shell.c d25df04168d6ba5a4fa05bdbf859df667f9eb621
 F src/sqlite.h.in 839c818e16ea68703d90d17bd2bb3607191debce
 F src/sqlite3.rc 992c9f5fb8285ae285d6be28240a7e8d3a7f2bad
 F src/sqlite3ext.h 4b66e3e3435da4b4c8c83696d0349f0c503b3924
-F src/sqliteInt.h 1ad779ee62efee60494af0a75d8d45592f9f53c3
+F src/sqliteInt.h 835fce874a55144491d441f22c21a954bd17a1f3
 F src/sqliteLimit.h 216557999cb45f2e3578ed53ebefe228d779cb46
 F src/status.c 70912d7be68e9e2dbc4010c93d344af61d4c59ba
 F src/table.c 51b46b2a62d1b3a959633d593b89bab5e2c9155e
 F src/tclsqlite.c d9439b6a910985b7fff43ba6756bcef00de22649
 F src/test1.c 8fff9c5aa63d6490f516d018b70c12a9cb9a4d8a
 F src/test2.c 577961fe48961b2f2e5c8b56ee50c3f459d3359d
-F src/test3.c 64d2afdd68feac1bb5e2ffb8226c8c639f798622
+F src/test3.c 11b13d561846e5d1ffd29653be340d2f4b59a723
 F src/test4.c d168f83cc78d02e8d35567bb5630e40dcd85ac1e
 F src/test5.c 5a34feec76d9b3a86aab30fd4f6cc9c48cbab4c1
 F src/test6.c 41cacf3b0dd180823919bf9e1fbab287c9266723
@@ -397,11 +397,11 @@ F src/threads.c bbfb74450643cb5372a43ad4f6cffd7e9dfcecb0
 F src/tokenize.c 338bc8f7c9dd103188952cda7964696bacac6d22
 F src/treeview.c 154f0acc622fa3514de8777dcedf4c8a8802b4ce
 F src/trigger.c 322f23aad694e8f31d384dcfa386d52a48d3c52f
-F src/update.c aa10336a2719bd1b9f89004f3d7ba6d566623a49
+F src/update.c 40e51cd0883cb5bfd6abb7d8a7cd8aa47fab2945
 F src/utf.c fc6b889ba0779b7722634cdeaa25f1930d93820c
 F src/util.c fc612367108b74573c5fd13a85d0a23027f438bd
 F src/vacuum.c 2ddd5cad2a7b9cef7f9e431b8c7771634c6b1701
-F src/vdbe.c e9315575bed64f9aa559151283c873be34143914
+F src/vdbe.c 3f22833a67dbee98f5b8d7acac0f5097ecc4dcb5
 F src/vdbe.h 4bc88bd0e06f8046ee6ab7487c0015e85ad949ad
 F src/vdbeInt.h 777dd76d513347acb1a71d94df2be00516add637
 F src/vdbeapi.c 020681b943e77766b32ae1cddf86d7831b7374ca
@@ -415,8 +415,8 @@ F src/vxworks.h c18586c8edc1bddbc15c004fa16aeb1e1342b4fb
 F src/wal.c 18b0ed49830cf04fe2d68224b41838a73ac6cd24
 F src/wal.h df01efe09c5cb8c8e391ff1715cca294f89668a4
 F src/walker.c 2e14d17f592d176b6dc879c33fbdec4fbccaa2ba
-F src/where.c 4c4646675e794ac71e701289edefd7cd81bac844
-F src/whereInt.h 7892bb54cf9ca0ae5c7e6094491b94c9286dc647
+F src/where.c 0bb01a0545afb9ee064d64e4821f34a79742a6cf
+F src/whereInt.h 87b0b66cf0a337c8b282a33e4233e9dad14b626b
 F src/wherecode.c b924b78acd9e623fb69bfa2cb65cd7d542166dd3
 F src/whereexpr.c e63244ca06c503e5f3c5b7f3c9aea0db826089ed
 F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2
@@ -628,6 +628,7 @@ F test/fkey6.test abb59f866c1b44926fd02d1fdd217d831fe04f48
 F test/fkey7.test 72e915890ee4a005daaf3002cb208e8fe973ac13
 F test/fkey8.test 8f08203458321e6c19a263829de4cfc936274ab0
 F test/fkey_malloc.test 594a7ea1fbab553c036c70813cd8bd9407d63749
+F test/fordelete.test a30de567eb69a377e0c3ab1a8be4d74588de2a33
 F test/format4.test 1f0cac8ff3895e9359ed87e41aaabee982a812eb
 F test/fts-9fd058691.test 78b887e30ae6816df0e1fed6259de4b5a64ad33c
 F test/fts1a.test 46090311f85da51bb33bd5ce84f7948359c6d8d7
@@ -1391,7 +1392,10 @@ F tool/vdbe_profile.tcl 246d0da094856d72d2c12efec03250d71639d19f
 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4
 F tool/warnings.sh 48bd54594752d5be3337f12c72f28d2080cb630b
 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f
-P aa4e01ea1af327d1f8398ebea1c5bacc46698c3d
-R a22db3919509c137f252ea9c4c395816
-U mistachkin
-Z cd96591ebe18ee957344d1fc4f75aaa9
+P 4315d20200d578c9252dcb26e60739063a8eff1d
+R f9b9301d7918e2f3aec8c2ac058ff295
+T *branch * btree-fordelete-flag
+T *sym-btree-fordelete-flag *
+T -sym-trunk *
+U dan
+Z 49648c9fd09be094288b39d12da5947c
index 48569933f6262893bf273b1de110f140ec67ae24..ed6782c8b4a52d3ce938b7e59697e8dc5fbab6c3 100644 (file)
@@ -1 +1 @@
-4315d20200d578c9252dcb26e60739063a8eff1d
\ No newline at end of file
+cdc92919e600007cae5eb61223684f48a65babc0
\ No newline at end of file
index b26a95c80181fc8242cfdb6b480ca34c412c25cd..4ebaf4c2712d3699f17d6c7b23039f73ac1a0e24 100644 (file)
@@ -4055,13 +4055,16 @@ static int btreeCursor(
   BtCursor *pX;                          /* Looping over other all cursors */
 
   assert( sqlite3BtreeHoldsMutex(p) );
-  assert( wrFlag==0 || wrFlag==1 );
+  assert( wrFlag==0 
+       || wrFlag==BTREE_WRCSR 
+       || wrFlag==(BTREE_WRCSR|BTREE_FORDELETE) 
+  );
 
   /* The following assert statements verify that if this is a sharable 
   ** b-tree database, the connection is holding the required table locks, 
   ** and that no other connection has any open cursor that conflicts with 
   ** this lock.  */
-  assert( hasSharedCacheTableLock(p, iTable, pKeyInfo!=0, wrFlag+1) );
+  assert( hasSharedCacheTableLock(p, iTable, pKeyInfo!=0, (wrFlag?2:1)) );
   assert( wrFlag==0 || !hasReadConflicts(p, iTable) );
 
   /* Assert that the caller has opened the required transaction. */
@@ -4086,8 +4089,7 @@ static int btreeCursor(
   pCur->pKeyInfo = pKeyInfo;
   pCur->pBtree = p;
   pCur->pBt = pBt;
-  assert( wrFlag==0 || wrFlag==BTCF_WriteFlag );
-  pCur->curFlags = wrFlag;
+  pCur->curFlags = wrFlag ? BTCF_WriteFlag : 0;
   pCur->curPagerFlags = wrFlag ? 0 : PAGER_GET_READONLY;
   /* If there are two or more cursors on the same btree, then all such
   ** cursors *must* have the BTCF_Multiple flag set. */
index f7e92a26093957b628b4eccd927672e3f8cbf506..66420f8413a290c65111d017f79cfc26f856ab29 100644 (file)
@@ -165,6 +165,12 @@ int sqlite3BtreeNewDb(Btree *p);
 #define BTREE_BULKLOAD 0x00000001  /* Used to full index in sorted order */
 #define BTREE_SEEK_EQ  0x00000002  /* EQ seeks only - no range seeks */
 
+/* 
+** Flags passed as the third argument to sqlite3BtreeCursor().
+*/
+#define BTREE_WRCSR     0x00000004  /* read-write cursor */
+#define BTREE_FORDELETE 0x00000008  /* Cursor is for seek/delete only */
+
 int sqlite3BtreeCursor(
   Btree*,                              /* BTree containing table to open */
   int iTable,                          /* Index of root page */
index faef3a814e5c49ae30df579629f2039480de4b0b..cd683e37d8d4d3c9d3bde50c438bac6916dd79ca 100644 (file)
@@ -478,12 +478,13 @@ void sqlite3DeleteFrom(
     */
     if( !isView ){
       int iAddrOnce = 0;
+      u8 p5 = (eOnePass==ONEPASS_OFF ? 0 : OPFLAG_FORDELETE);
       if( eOnePass==ONEPASS_MULTI ){
         iAddrOnce = sqlite3CodeOnce(pParse); VdbeCoverage(v);
       }
       testcase( IsVirtual(pTab) );
-      sqlite3OpenTableAndIndices(pParse, pTab, OP_OpenWrite, iTabCur, aToOpen,
-                                 &iDataCur, &iIdxCur);
+      sqlite3OpenTableAndIndices(pParse, pTab, OP_OpenWrite, p5, iTabCur, 
+                                 aToOpen, &iDataCur, &iIdxCur);
       assert( pPk || IsVirtual(pTab) || iDataCur==iTabCur );
       assert( pPk || IsVirtual(pTab) || iIdxCur==iDataCur+1 );
       if( eOnePass==ONEPASS_MULTI ) sqlite3VdbeJumpHere(v, iAddrOnce);
index 9274b0771d3135bce74fd7dc504415673b6efad6..3d213a8d376f06725e1e2eea31c43c806c141bd0 100644 (file)
@@ -762,7 +762,7 @@ void sqlite3Insert(
   /* If this is not a view, open the table and and all indices */
   if( !isView ){
     int nIdx;
-    nIdx = sqlite3OpenTableAndIndices(pParse, pTab, OP_OpenWrite, -1, 0,
+    nIdx = sqlite3OpenTableAndIndices(pParse, pTab, OP_OpenWrite, 0, -1, 0,
                                       &iDataCur, &iIdxCur);
     aRegIdx = sqlite3DbMallocRaw(db, sizeof(int)*(nIdx+1));
     if( aRegIdx==0 ){
@@ -1650,6 +1650,7 @@ int sqlite3OpenTableAndIndices(
   Parse *pParse,   /* Parsing context */
   Table *pTab,     /* Table to be opened */
   int op,          /* OP_OpenRead or OP_OpenWrite */
+  u8 p5,           /* P5 value for OP_Open* instructions */
   int iBase,       /* Use this for the table cursor, if there is one */
   u8 *aToOpen,     /* If not NULL: boolean for each table and index */
   int *piDataCur,  /* Write the database source cursor number here */
@@ -1662,6 +1663,7 @@ int sqlite3OpenTableAndIndices(
   Vdbe *v;
 
   assert( op==OP_OpenRead || op==OP_OpenWrite );
+  assert( op==OP_OpenWrite || p5==0 );
   if( IsVirtual(pTab) ){
     /* This routine is a no-op for virtual tables. Leave the output
     ** variables *piDataCur and *piIdxCur uninitialized so that valgrind
@@ -1689,6 +1691,7 @@ int sqlite3OpenTableAndIndices(
     if( aToOpen==0 || aToOpen[i+1] ){
       sqlite3VdbeAddOp3(v, op, iIdxCur, pIdx->tnum, iDb);
       sqlite3VdbeSetP4KeyInfo(pParse, pIdx);
+      sqlite3VdbeChangeP5(v, p5);
       VdbeComment((v, "%s", pIdx->zName));
     }
   }
index 64614a7ebcd85716b383d496306f1e07d785b88b..14c4811746ac20349de47f0c789078cbfe0fb9a8 100644 (file)
@@ -1465,7 +1465,7 @@ void sqlite3Pragma(
         sqlite3VdbeAddOp2(v, OP_Halt, 0, 0);
         sqlite3VdbeJumpHere(v, addr);
         sqlite3ExprCacheClear(pParse);
-        sqlite3OpenTableAndIndices(pParse, pTab, OP_OpenRead,
+        sqlite3OpenTableAndIndices(pParse, pTab, OP_OpenRead, 0,
                                    1, 0, &iDataCur, &iIdxCur);
         sqlite3VdbeAddOp2(v, OP_Integer, 0, 7);
         for(j=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, j++){
index 9c28a9a8c131020473a88369235bb7ce7511c457..7d013059640fd843b6d124887b335fb0378cff67 100644 (file)
@@ -2794,7 +2794,8 @@ struct AuthContext {
 #define OPFLAG_TYPEOFARG     0x80    /* OP_Column only used for typeof() */
 #define OPFLAG_BULKCSR       0x01    /* OP_Open** used to open bulk cursor */
 #define OPFLAG_SEEKEQ        0x02    /* OP_Open** cursor uses EQ seek only */
-#define OPFLAG_P2ISREG       0x04    /* P2 to OP_Open** is a register number */
+#define OPFLAG_FORDELETE     0x08    /* OP_Open is opening for-delete csr */
+#define OPFLAG_P2ISREG       0x10    /* P2 to OP_Open** is a register number */
 #define OPFLAG_PERMUTE       0x01    /* OP_Compare: use the permutation */
 
 /*
@@ -3460,7 +3461,7 @@ void sqlite3ResolvePartIdxLabel(Parse*,int);
 void sqlite3GenerateConstraintChecks(Parse*,Table*,int*,int,int,int,int,
                                      u8,u8,int,int*);
 void sqlite3CompleteInsertion(Parse*,Table*,int,int,int,int*,int,int,int);
-int sqlite3OpenTableAndIndices(Parse*, Table*, int, int, u8*, int*, int*);
+int sqlite3OpenTableAndIndices(Parse*, Table*, int, u8, int, u8*, int*, int*);
 void sqlite3BeginWriteOperation(Parse*, int, int);
 void sqlite3MultiWrite(Parse*);
 void sqlite3MayAbort(Parse*);
index 07d12d28c03af94e4c4b9e60ac4e4cad2bda3b8e..7cb29bedcb19219fd5d1150752193486b9d652ec 100644 (file)
@@ -214,6 +214,7 @@ static int btree_cursor(
   pBt = sqlite3TestTextToPtr(argv[1]);
   if( Tcl_GetInt(interp, argv[2], &iTable) ) return TCL_ERROR;
   if( Tcl_GetBoolean(interp, argv[3], &wrFlag) ) return TCL_ERROR;
+  if( wrFlag ) wrFlag = BTREE_WRCSR;
   pCur = (BtCursor *)ckalloc(sqlite3BtreeCursorSize());
   memset(pCur, 0, sqlite3BtreeCursorSize());
   sqlite3BtreeEnter(pBt);
index 5cb5574909bd95535f1ac5e110fc766c642b20f2..1335c269ed2d55a4be032f26cdb48a5027f27e79 100644 (file)
@@ -429,7 +429,7 @@ void sqlite3Update(
       if( aiCurOnePass[0]>=0 ) aToOpen[aiCurOnePass[0]-iBaseCur] = 0;
       if( aiCurOnePass[1]>=0 ) aToOpen[aiCurOnePass[1]-iBaseCur] = 0;
     }
-    sqlite3OpenTableAndIndices(pParse, pTab, OP_OpenWrite, iBaseCur, aToOpen,
+    sqlite3OpenTableAndIndices(pParse, pTab, OP_OpenWrite, 0, iBaseCur, aToOpen,
                                0, 0);
   }
 
index b93ab160f6556d1edd0195eb7eccad68b48be6a3..9b391c14d29908bcc96449416a9f849fcdb0f798 100644 (file)
@@ -3324,7 +3324,6 @@ case OP_ReopenIdx: {
 case OP_OpenRead:
 case OP_OpenWrite:
 
-  assert( (pOp->p5&(OPFLAG_P2ISREG|OPFLAG_BULKCSR|OPFLAG_SEEKEQ))==pOp->p5 );
   assert( pOp->opcode==OP_OpenWrite || pOp->p5==0 || pOp->p5==OPFLAG_SEEKEQ );
   assert( p->bIsReader );
   assert( pOp->opcode==OP_OpenRead || pOp->opcode==OP_ReopenIdx
@@ -3345,7 +3344,8 @@ case OP_OpenWrite:
   pX = pDb->pBt;
   assert( pX!=0 );
   if( pOp->opcode==OP_OpenWrite ){
-    wrFlag = 1;
+    assert( OPFLAG_FORDELETE==BTREE_FORDELETE );
+    wrFlag = BTREE_WRCSR | (pOp->p5 & OPFLAG_FORDELETE);
     assert( sqlite3SchemaMutexHeld(db, iDb, 0) );
     if( pDb->pSchema->file_format < p->minWriteFileFormat ){
       p->minWriteFileFormat = pDb->pSchema->file_format;
@@ -3465,11 +3465,11 @@ case OP_OpenEphemeral: {
         assert( pKeyInfo->db==db );
         assert( pKeyInfo->enc==ENC(db) );
         pCx->pKeyInfo = pKeyInfo;
-        rc = sqlite3BtreeCursor(pCx->pBt, pgno, 1, pKeyInfo, pCx->pCursor);
+        rc = sqlite3BtreeCursor(pCx->pBt, pgno, BTREE_WRCSR, pKeyInfo, pCx->pCursor);
       }
       pCx->isTable = 0;
     }else{
-      rc = sqlite3BtreeCursor(pCx->pBt, MASTER_ROOT, 1, 0, pCx->pCursor);
+      rc = sqlite3BtreeCursor(pCx->pBt, MASTER_ROOT, BTREE_WRCSR, 0, pCx->pCursor);
       pCx->isTable = 1;
     }
   }
index af8e2f35fd5c95a938c475b282de186ce282e955..3f83511b04689836d99e2d74fc0540a5deb09bfa 100644 (file)
@@ -3991,6 +3991,7 @@ WhereInfo *sqlite3WhereBegin(
   int ii;                    /* Loop counter */
   sqlite3 *db;               /* Database connection */
   int rc;                    /* Return code */
+  u8 bFordelete = 0;
 
   assert( (wctrlFlags & WHERE_ONEPASS_MULTIROW)==0 || (
         (wctrlFlags & WHERE_ONEPASS_DESIRED)!=0 
@@ -4246,8 +4247,11 @@ WhereInfo *sqlite3WhereBegin(
        && 0==(wsFlags & WHERE_VIRTUALTABLE)
     )){
       pWInfo->eOnePass = bOnerow ? ONEPASS_SINGLE : ONEPASS_MULTI;
-      if( HasRowid(pTabList->a[0].pTab) ){
-        pWInfo->a[0].pWLoop->wsFlags &= ~WHERE_IDX_ONLY;
+      if( HasRowid(pTabList->a[0].pTab) && (wsFlags & WHERE_IDX_ONLY) ){
+        if( wctrlFlags & WHERE_ONEPASS_MULTIROW ){
+          bFordelete = OPFLAG_FORDELETE;
+        }
+        pWInfo->a[0].pWLoop->wsFlags = (wsFlags & ~WHERE_IDX_ONLY);
       }
     }
   }
@@ -4284,6 +4288,7 @@ WhereInfo *sqlite3WhereBegin(
         pWInfo->aiCurOnePass[0] = pTabItem->iCursor;
       };
       sqlite3OpenTable(pParse, pTabItem->iCursor, iDb, pTab, op);
+      sqlite3VdbeChangeP5(v, bFordelete);
       assert( pTabItem->iCursor==pLevel->iTabCur );
       testcase( pWInfo->eOnePass==ONEPASS_OFF && pTab->nCol==BMS-1 );
       testcase( pWInfo->eOnePass==ONEPASS_OFF && pTab->nCol==BMS );
index cae09acc8283b7d3a3a6e05c3405d54517d6cf40..f4bc4077e452fb004eb80f3ec4c28580b1a0a3b2 100644 (file)
@@ -530,3 +530,4 @@ void sqlite3WhereTabFuncArgs(Parse*, struct SrcList_item*, WhereClause*);
 #define WHERE_SKIPSCAN     0x00008000  /* Uses the skip-scan algorithm */
 #define WHERE_UNQ_WANTED   0x00010000  /* WHERE_ONEROW would have been helpful*/
 #define WHERE_PARTIALIDX   0x00020000  /* The automatic index is partial */
+#define WHERE_FORDELETE    0x00040000  /* Table cursor is "for-delete" */
diff --git a/test/fordelete.test b/test/fordelete.test
new file mode 100644 (file)
index 0000000..dd0f953
--- /dev/null
@@ -0,0 +1,80 @@
+# 2001 September 15
+#
+# The author disclaims copyright to this source code.  In place of
+# a legal notice, here is a blessing:
+#
+#    May you do good and not evil.
+#    May you find forgiveness for yourself and forgive others.
+#    May you share freely, never taking more than you give.
+#
+#***********************************************************************
+# This file implements regression tests for SQLite library.  The
+# focus of this file is testing the SELECT statement.
+#
+# $Id: select1.test,v 1.70 2009/05/28 01:00:56 drh Exp $
+
+set testdir [file dirname $argv0]
+source $testdir/tester.tcl
+set ::testprefix fordelete
+
+# This function returns a list of the tables or indexes opened with 
+# OP_OpenWrite instructions when the SQL statement passed as the only 
+# argument is executed. If the OPFLAG_FORDELETE flag is specified on
+# the OP_OpenWrite, an asterix is appended to the object name. The list 
+# is sorted in [lsort] order before it is returned.
+#
+proc analyze_delete_program {sql} {
+  # Build a map from root page to table/index name.
+  db eval {
+    SELECT name, rootpage FROM sqlite_master
+  } {
+    set T($rootpage) $name
+  }
+
+  # Calculate the results.
+  set res [list]
+  db eval "EXPLAIN $sql" R {
+    if {$R(opcode) == "OpenWrite"} {
+      set obj $T($R(p2))
+      if {"0x$R(p5)" & 0x08} { append obj *}
+      lappend res $obj
+    }
+  }
+
+  lsort $res
+}
+
+proc do_adp_test {tn sql res} {
+  uplevel [list do_test $tn [list analyze_delete_program $sql] [list {*}$res]]
+}
+
+do_execsql_test 1.0 {
+  CREATE TABLE t1(a PRIMARY KEY, b);
+}
+
+foreach {tn sql res} {
+  1 { DELETE FROM t1 WHERE a=?}          { sqlite_autoindex_t1_1  t1* }
+  2 { DELETE FROM t1 WHERE a=? AND b=? } { sqlite_autoindex_t1_1  t1 }
+  3 { DELETE FROM t1 WHERE a>? }         { sqlite_autoindex_t1_1  t1* }
+  4 { DELETE FROM t1 WHERE rowid=? }     { sqlite_autoindex_t1_1*  t1 }
+} {
+  do_adp_test 1.$tn $sql $res
+}
+
+do_execsql_test 2.0 {
+  CREATE TABLE t2(a, b, c);
+  CREATE INDEX t2a ON t2(a);
+  CREATE INDEX t2b ON t2(b);
+  CREATE INDEX t2c ON t2(c);
+}
+foreach {tn sql res} {
+  1 { DELETE FROM t2 WHERE a=?}          { t2* t2a t2b* t2c* }
+  2 { DELETE FROM t2 WHERE a=? AND +b=?} { t2 t2a t2b* t2c* }
+  3 { DELETE FROM t2 WHERE a=? OR b=?}   { t2 t2a* t2b* t2c* }
+  4 { DELETE FROM t2 WHERE +a=? }        { t2 t2a* t2b* t2c* }
+  5 { DELETE FROM t2 WHERE rowid=? }     { t2 t2a* t2b* t2c* }
+} {
+  do_adp_test 2.$tn $sql $res
+}
+finish_test