1
0
mirror of https://github.com/sqlite/sqlite.git synced 2025-11-12 13:01:09 +03:00

Make sure one-pass DELETE for WITHOUT ROWID tables correctly positions the

PRIMARY KEY cursor.  Make the same fix for UPDATE.

FossilOrigin-Name: 6bd5750b7d5da221b0689f6df6be5ed0dce61bec
This commit is contained in:
drh
2013-11-17 02:42:02 +00:00
parent c51331d16d
commit 83d47afe24
4 changed files with 27 additions and 16 deletions

View File

@@ -1,5 +1,5 @@
C Fix\sa\scouple\sof\sminor\sproblems\swith\sthe\snew\sdelete\slogic. 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-16T23:16:31.845 D 2013-11-17T02:42:02.540
F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f
F Makefile.in 8a07bebafbfda0eb67728f4bd15a36201662d1a1 F Makefile.in 8a07bebafbfda0eb67728f4bd15a36201662d1a1
F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23
@@ -174,7 +174,7 @@ F src/callback.c f99a8957ba2adf369645fac0db09ad8adcf1caa2
F src/complete.c dc1d136c0feee03c2f7550bafc0d29075e36deac F src/complete.c dc1d136c0feee03c2f7550bafc0d29075e36deac
F src/ctime.c ea4b7f3623a0fcb1146e7f245d7410033e86859c F src/ctime.c ea4b7f3623a0fcb1146e7f245d7410033e86859c
F src/date.c 593c744b2623971e45affd0bde347631bdfa4625 F src/date.c 593c744b2623971e45affd0bde347631bdfa4625
F src/delete.c b612d06c095acc5df50a208a9b023c96deb11e5a F src/delete.c d88e4fbfeca5a8cf48b7d358b9a68d5e81f314b7
F src/expr.c 1a295d8b0a2ba08919ad9300ebf7b67988ff4030 F src/expr.c 1a295d8b0a2ba08919ad9300ebf7b67988ff4030
F src/fault.c 160a0c015b6c2629d3899ed2daf63d75754a32bb F src/fault.c 160a0c015b6c2629d3899ed2daf63d75754a32bb
F src/fkey.c 78364daed38e26269c53ddb94c515bceac1063c6 F src/fkey.c 78364daed38e26269c53ddb94c515bceac1063c6
@@ -276,7 +276,7 @@ F src/test_vfstrace.c 34b544e80ba7fb77be15395a609c669df2e660a2
F src/test_wsd.c 41cadfd9d97fe8e3e4e44f61a4a8ccd6f7ca8fe9 F src/test_wsd.c 41cadfd9d97fe8e3e4e44f61a4a8ccd6f7ca8fe9
F src/tokenize.c ec4c1a62b890bf1dbcdb966399e140b904c700a4 F src/tokenize.c ec4c1a62b890bf1dbcdb966399e140b904c700a4
F src/trigger.c d84e1f3669e9a217731a14a9d472b1c7b87c87ba F src/trigger.c d84e1f3669e9a217731a14a9d472b1c7b87c87ba
F src/update.c 18e9b11b499c1205ec2b6e87322a7edc8772e550 F src/update.c cc3d826923f7b61566dedbb3cfce5f13964f35a4
F src/utf.c 6fc6c88d50448c469c5c196acf21617a24f90269 F src/utf.c 6fc6c88d50448c469c5c196acf21617a24f90269
F src/util.c 2fa6c821d28bbdbeec1b2a7b091a281c9ef8f918 F src/util.c 2fa6c821d28bbdbeec1b2a7b091a281c9ef8f918
F src/vacuum.c 3728d74919d4fb1356f9e9a13e27773db60b7179 F src/vacuum.c 3728d74919d4fb1356f9e9a13e27773db60b7179
@@ -1140,7 +1140,7 @@ F tool/vdbe-compress.tcl f12c884766bd14277f4fcedcae07078011717381
F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4
F tool/warnings.sh d1a6de74685f360ab718efda6265994b99bbea01 F tool/warnings.sh d1a6de74685f360ab718efda6265994b99bbea01
F tool/win/sqlite.vsix 030f3eeaf2cb811a3692ab9c14d021a75ce41fff F tool/win/sqlite.vsix 030f3eeaf2cb811a3692ab9c14d021a75ce41fff
P dc7be158b82ab9156d0fcdf3394f881eac4d23c3 P a11243f840d35aaed8ee3b9901c3950bc584a417
R 0c59b10189d7db2055b513cecd6f14e5 R f429117cda51c1a8c08160d9a3f515e6
U drh U drh
Z ca24d69af9eecebf1768d25aef1413b7 Z 2718e457b564d6fbe8d10873d690a300

View File

@@ -1 +1 @@
a11243f840d35aaed8ee3b9901c3950bc584a417 6bd5750b7d5da221b0689f6df6be5ed0dce61bec

View File

@@ -461,7 +461,8 @@ void sqlite3DeleteFrom(
sqlite3WhereEnd(pWInfo); sqlite3WhereEnd(pWInfo);
if( okOnePass ){ if( okOnePass ){
/* Bypass the delete logic below if the WHERE loop found zero rows */ /* 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); sqlite3VdbeJumpHere(v, addrDelete);
} }
@@ -483,6 +484,10 @@ void sqlite3DeleteFrom(
if( okOnePass ){ if( okOnePass ){
/* Just one row. Hence the top-of-loop is a no-op */ /* Just one row. Hence the top-of-loop is a no-op */
assert( nKey==nPk ); /* OP_Found will use an unpacked key */ 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 ){ }else if( pPk ){
addrLoop = sqlite3VdbeAddOp1(v, OP_Rewind, iEphCur); addrLoop = sqlite3VdbeAddOp1(v, OP_Rewind, iEphCur);
sqlite3VdbeAddOp2(v, OP_RowKey, iEphCur, iKey); sqlite3VdbeAddOp2(v, OP_RowKey, iEphCur, iKey);
@@ -510,7 +515,7 @@ void sqlite3DeleteFrom(
/* End of the loop over all rowids/primary-keys. */ /* End of the loop over all rowids/primary-keys. */
if( okOnePass ){ if( okOnePass ){
sqlite3VdbeJumpHere(v, addrBypass); sqlite3VdbeResolveLabel(v, addrBypass);
}else if( pPk ){ }else if( pPk ){
sqlite3VdbeAddOp2(v, OP_Next, iEphCur, addrLoop+1); sqlite3VdbeAddOp2(v, OP_Next, iEphCur, addrLoop+1);
sqlite3VdbeJumpHere(v, addrLoop); sqlite3VdbeJumpHere(v, addrLoop);
@@ -617,6 +622,7 @@ void sqlite3GenerateRowDelete(
if( sqlite3FkRequired(pParse, pTab, 0, 0) || pTrigger ){ if( sqlite3FkRequired(pParse, pTab, 0, 0) || pTrigger ){
u32 mask; /* Mask of OLD.* columns in use */ u32 mask; /* Mask of OLD.* columns in use */
int iCol; /* Iterator used while populating OLD.* */ int iCol; /* Iterator used while populating OLD.* */
int addrStart; /* Start of BEFORE trigger programs */
/* TODO: Could use temporary registers here. Also could attempt to /* TODO: Could use temporary registers here. Also could attempt to
** avoid copying the contents of the rowid register. */ ** avoid copying the contents of the rowid register. */
@@ -637,15 +643,19 @@ void sqlite3GenerateRowDelete(
} }
/* Invoke BEFORE DELETE trigger programs. */ /* Invoke BEFORE DELETE trigger programs. */
addrStart = sqlite3VdbeCurrentAddr(v);
sqlite3CodeRowTrigger(pParse, pTrigger, sqlite3CodeRowTrigger(pParse, pTrigger,
TK_DELETE, 0, TRIGGER_BEFORE, pTab, iOld, onconf, iLabel TK_DELETE, 0, TRIGGER_BEFORE, pTab, iOld, onconf, iLabel
); );
/* Seek the cursor to the row to be deleted again. It may be that /* If any BEFORE triggers were coded, then seek the cursor to the
** the BEFORE triggers coded above have already removed the row ** row to be deleted again. It may be that the BEFORE triggers moved
** being deleted. Do not attempt to delete the row a second time, and ** the cursor or of already deleted the row that the cursor was
** do not fire AFTER triggers. */ ** pointing to.
*/
if( addrStart<sqlite3VdbeCurrentAddr(v) ){
sqlite3VdbeAddOp4Int(v, opSeek, iDataCur, iLabel, iPk, nPk); sqlite3VdbeAddOp4Int(v, opSeek, iDataCur, iLabel, iPk, nPk);
}
/* Do FK processing. This call checks that any FK constraints that /* Do FK processing. This call checks that any FK constraints that
** refer to this table (i.e. constraints attached to other tables) ** refer to this table (i.e. constraints attached to other tables)

View File

@@ -426,7 +426,8 @@ void sqlite3Update(
/* Top of the update loop */ /* Top of the update loop */
if( okOnePass ){ if( okOnePass ){
if( pPk ){ if( aToOpen[iDataCur-iBaseCur] ){
assert( pPk!=0 );
sqlite3VdbeAddOp4Int(v, OP_NotFound, iDataCur, labelBreak, regKey, nKey); sqlite3VdbeAddOp4Int(v, OP_NotFound, iDataCur, labelBreak, regKey, nKey);
} }
labelContinue = labelBreak; labelContinue = labelBreak;