]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
Make sure one-pass DELETE for WITHOUT ROWID tables correctly positions the optimize-delete
authordrh <drh@noemail.net>
Sun, 17 Nov 2013 02:42:02 +0000 (02:42 +0000)
committerdrh <drh@noemail.net>
Sun, 17 Nov 2013 02:42:02 +0000 (02:42 +0000)
PRIMARY KEY cursor.  Make the same fix for UPDATE.

FossilOrigin-Name: 6bd5750b7d5da221b0689f6df6be5ed0dce61bec

manifest
manifest.uuid
src/delete.c
src/update.c

index 609e196dbc6c182766f1212e7c9f751fa9cae84e..9f1bb087f7f52d5e388716c3db31a60b088764ea 100644 (file)
--- a/manifest
+++ b/manifest
@@ -1,5 +1,5 @@
-C Fix\sa\scouple\sof\sminor\sproblems\swith\sthe\snew\sdelete\slogic.
-D 2013-11-16T23:16:31.845
+C Make\ssure\sone-pass\sDELETE\sfor\sWITHOUT\sROWID\stables\scorrectly\spositions\sthe\nPRIMARY\sKEY\scursor.\s\sMake\sthe\ssame\sfix\sfor\sUPDATE.
+D 2013-11-17T02:42:02.540
 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f
 F Makefile.in 8a07bebafbfda0eb67728f4bd15a36201662d1a1
 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23
@@ -174,7 +174,7 @@ F src/callback.c f99a8957ba2adf369645fac0db09ad8adcf1caa2
 F src/complete.c dc1d136c0feee03c2f7550bafc0d29075e36deac
 F src/ctime.c ea4b7f3623a0fcb1146e7f245d7410033e86859c
 F src/date.c 593c744b2623971e45affd0bde347631bdfa4625
-F src/delete.c b612d06c095acc5df50a208a9b023c96deb11e5a
+F src/delete.c d88e4fbfeca5a8cf48b7d358b9a68d5e81f314b7
 F src/expr.c 1a295d8b0a2ba08919ad9300ebf7b67988ff4030
 F src/fault.c 160a0c015b6c2629d3899ed2daf63d75754a32bb
 F src/fkey.c 78364daed38e26269c53ddb94c515bceac1063c6
@@ -276,7 +276,7 @@ F src/test_vfstrace.c 34b544e80ba7fb77be15395a609c669df2e660a2
 F src/test_wsd.c 41cadfd9d97fe8e3e4e44f61a4a8ccd6f7ca8fe9
 F src/tokenize.c ec4c1a62b890bf1dbcdb966399e140b904c700a4
 F src/trigger.c d84e1f3669e9a217731a14a9d472b1c7b87c87ba
-F src/update.c 18e9b11b499c1205ec2b6e87322a7edc8772e550
+F src/update.c cc3d826923f7b61566dedbb3cfce5f13964f35a4
 F src/utf.c 6fc6c88d50448c469c5c196acf21617a24f90269
 F src/util.c 2fa6c821d28bbdbeec1b2a7b091a281c9ef8f918
 F src/vacuum.c 3728d74919d4fb1356f9e9a13e27773db60b7179
@@ -1140,7 +1140,7 @@ F tool/vdbe-compress.tcl f12c884766bd14277f4fcedcae07078011717381
 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4
 F tool/warnings.sh d1a6de74685f360ab718efda6265994b99bbea01
 F tool/win/sqlite.vsix 030f3eeaf2cb811a3692ab9c14d021a75ce41fff
-P dc7be158b82ab9156d0fcdf3394f881eac4d23c3
-R 0c59b10189d7db2055b513cecd6f14e5
+P a11243f840d35aaed8ee3b9901c3950bc584a417
+R f429117cda51c1a8c08160d9a3f515e6
 U drh
-Z ca24d69af9eecebf1768d25aef1413b7
+Z 2718e457b564d6fbe8d10873d690a300
index 501d33762c227c56cfeab41a1af7d8086ed3ed7e..01e77e462acc4732d9136891f0233ab6be172744 100644 (file)
@@ -1 +1 @@
-a11243f840d35aaed8ee3b9901c3950bc584a417
\ No newline at end of file
+6bd5750b7d5da221b0689f6df6be5ed0dce61bec
\ No newline at end of file
index 1b3d7a24bca4022ed348da62f69f4ed8c64fd3ef..c4bf8cc813701addf86af4b024956b56bccc22da 100644 (file)
@@ -461,7 +461,8 @@ void sqlite3DeleteFrom(
     sqlite3WhereEnd(pWInfo);
     if( okOnePass ){
       /* Bypass the delete logic below if the WHERE loop found zero rows */
-      addrBypass = sqlite3VdbeAddOp0(v, OP_Goto);
+      addrBypass = sqlite3VdbeMakeLabel(v);
+      sqlite3VdbeAddOp2(v, OP_Goto, 0, addrBypass);
       sqlite3VdbeJumpHere(v, addrDelete);
     }
   
@@ -483,6 +484,10 @@ void sqlite3DeleteFrom(
     if( okOnePass ){
       /* Just one row.  Hence the top-of-loop is a no-op */
       assert( nKey==nPk ); /* OP_Found will use an unpacked key */
+      if( aToOpen[iDataCur-iTabCur] ){
+        assert( pPk!=0 );
+        sqlite3VdbeAddOp4Int(v, OP_NotFound, iDataCur, addrBypass, iKey, nKey);
+      }
     }else if( pPk ){
       addrLoop = sqlite3VdbeAddOp1(v, OP_Rewind, iEphCur);
       sqlite3VdbeAddOp2(v, OP_RowKey, iEphCur, iKey);
@@ -510,7 +515,7 @@ void sqlite3DeleteFrom(
   
     /* End of the loop over all rowids/primary-keys. */
     if( okOnePass ){
-      sqlite3VdbeJumpHere(v, addrBypass);
+      sqlite3VdbeResolveLabel(v, addrBypass);
     }else if( pPk ){
       sqlite3VdbeAddOp2(v, OP_Next, iEphCur, addrLoop+1);
       sqlite3VdbeJumpHere(v, addrLoop);
@@ -617,6 +622,7 @@ void sqlite3GenerateRowDelete(
   if( sqlite3FkRequired(pParse, pTab, 0, 0) || pTrigger ){
     u32 mask;                     /* Mask of OLD.* columns in use */
     int iCol;                     /* Iterator used while populating OLD.* */
+    int addrStart;                /* Start of BEFORE trigger programs */
 
     /* TODO: Could use temporary registers here. Also could attempt to
     ** avoid copying the contents of the rowid register.  */
@@ -637,15 +643,19 @@ void sqlite3GenerateRowDelete(
     }
 
     /* Invoke BEFORE DELETE trigger programs. */
+    addrStart = sqlite3VdbeCurrentAddr(v);
     sqlite3CodeRowTrigger(pParse, pTrigger, 
         TK_DELETE, 0, TRIGGER_BEFORE, pTab, iOld, onconf, iLabel
     );
 
-    /* Seek the cursor to the row to be deleted again. It may be that
-    ** the BEFORE triggers coded above have already removed the row
-    ** being deleted. Do not attempt to delete the row a second time, and 
-    ** do not fire AFTER triggers.  */
-    sqlite3VdbeAddOp4Int(v, opSeek, iDataCur, iLabel, iPk, nPk);
+    /* If any BEFORE triggers were coded, then seek the cursor to the 
+    ** row to be deleted again. It may be that the BEFORE triggers moved
+    ** the cursor or of already deleted the row that the cursor was
+    ** pointing to.
+    */
+    if( addrStart<sqlite3VdbeCurrentAddr(v) ){
+      sqlite3VdbeAddOp4Int(v, opSeek, iDataCur, iLabel, iPk, nPk);
+    }
 
     /* Do FK processing. This call checks that any FK constraints that
     ** refer to this table (i.e. constraints attached to other tables) 
index 1783b447af36b993c50c37b042fba5e489bef67c..9405234e8c79fd32c715831de3a10ed8de61ed67 100644 (file)
@@ -426,7 +426,8 @@ void sqlite3Update(
 
   /* Top of the update loop */
   if( okOnePass ){
-    if( pPk ){
+    if( aToOpen[iDataCur-iBaseCur] ){
+      assert( pPk!=0 );
       sqlite3VdbeAddOp4Int(v, OP_NotFound, iDataCur, labelBreak, regKey, nKey);
     }
     labelContinue = labelBreak;