If a DELETE trigger fired by an UPDATE OR REPLACE statement deletes the row being updated, do not attempt to proceed with the original UPDATE operation. Fix for [d6a0fbc1].

FossilOrigin-Name: 4145b3e05051ba6729105157a876793ad14a05d895fc10fe704f437eab16ea93
This commit is contained in:
dan 2019-08-31 17:14:35 +00:00
parent 6a19865ff2
commit f66bfcb740
4 changed files with 89 additions and 22 deletions

View File

@ -1,5 +1,5 @@
C Remove\ssome\saffinity\stests\sthat\sbecame\sunreachable\sdue\sto\sthe\sprior\schange.
D 2019-08-31T01:33:19.183
C If\sa\sDELETE\strigger\sfired\sby\san\sUPDATE\sOR\sREPLACE\sstatement\sdeletes\sthe\srow\sbeing\supdated,\sdo\snot\sattempt\sto\sproceed\swith\sthe\soriginal\sUPDATE\soperation.\sFix\sfor\s[d6a0fbc1].
D 2019-08-31T17:14:35.569
F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1
F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea
F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724
@ -590,7 +590,7 @@ F src/threads.c 4ae07fa022a3dc7c5beb373cf744a85d3c5c6c3c
F src/tokenize.c d3615f0cbe4db5949503bf5916f3cd4fa5de855d5b4ef560f3b6dd5629423a1e
F src/treeview.c fc8c6c0a8a26afb3a97e3f844d65403dd27cf1450baf4415034fa4ccf00c4d7e
F src/trigger.c 845ccc08f60716c58aa28fe6470385c18ef8c4e1d88c93dcf449bc13d464eb2e
F src/update.c 3cb9150d2cf661d938e2f1b1749945f3faa767f88febdb739ab1793bbf895ff2
F src/update.c ce478c8ad297833d1acc825891e35d82a99f5986cfce1e92f44c3b0d54670114
F src/upsert.c 710c91bb13e3c3fed5b6fe17cb13e09560bdd003ad8b8c51e6b16c80cfc48b10
F src/utf.c 2f0fac345c7660d5c5bd3df9e9d8d33d4c27f366bcfb09e07443064d751a0507
F src/util.c fffdfa627be74d69ef425f92db124e7148af449bb8a3286e79577c42bca84061
@ -745,7 +745,7 @@ F test/colmeta.test 2c765ea61ee37bc43bbe6d6047f89004e6508eb1
F test/colname.test 87ad5458bb8709312dac0d6755fd30e8e4ca83298d0a9ef6e5c24277a3c3390e
F test/conflict.test c7cc007e2af151516ddf38f7412fe10d473a694f55e3df437e2c7b31c2590e8d
F test/conflict2.test bb0b94cf7196c64a3cbd815c66d3ee98c2fecd9c
F test/conflict3.test a83db76a6c3503b2fa057c7bfb08c318d8a422202d8bc5b86226e078e5b49ff9
F test/conflict3.test 56d18aedfa521a7ebffadb8254cfff10caf4e49cd8659cb54da39513aed478ba
F test/contrib01.test 2a1cbc0f2f48955d7d073f725765da6fbceda6b4
F test/corrupt.test d7cb0300e4a297147b6a05e92a1684bc8973635c3bcaa3d66e983c9cbdbf47a3
F test/corrupt2.test bb50042cf9a1f1023d73af325d47eb02a6bb11e3c52f8812644b220c5d4bca35
@ -1838,7 +1838,8 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93
F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc
F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e
F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0
P e0d909c740b774d8a46731696e33342be83206cc4a95d07f42fdb3d8cc2d7a8e
R fb7480045131ad29a415b8e551946237
U drh
Z 73deec9d190744adeeaa8d20a010bc12
P e2db1123faac26c0e0b6a1ebef1685ea7633bfcafd1ff743ba5380700f7745af
R 1a919c61b513d8917573ee41d8ce4c15
T +closed 2a0152c9f5f2ca56734189521b3b114ad6ba7ee7941d0f22d262081125436f72
U dan
Z 6965309018f410a0aa2e8d19660bb27e

View File

@ -1 +1 @@
e2db1123faac26c0e0b6a1ebef1685ea7633bfcafd1ff743ba5380700f7745af
4145b3e05051ba6729105157a876793ad14a05d895fc10fe704f437eab16ea93

View File

@ -715,28 +715,29 @@ void sqlite3Update(
}
if( !isView ){
int addr1 = 0; /* Address of jump instruction */
/* Do constraint checks. */
assert( regOldRowid>0 );
sqlite3GenerateConstraintChecks(pParse, pTab, aRegIdx, iDataCur, iIdxCur,
regNewRowid, regOldRowid, chngKey, onError, labelContinue, &bReplace,
aXRef, 0);
/* If REPLACE conflict handling may have been used, or if the PK of the
** row is changing, then the GenerateConstraintChecks() above may have
** moved cursor iDataCur. Reseek it. */
if( bReplace || chngKey ){
if( pPk ){
sqlite3VdbeAddOp4Int(v, OP_NotFound,iDataCur,labelContinue,regKey,nKey);
}else{
sqlite3VdbeAddOp3(v, OP_NotExists, iDataCur, labelContinue,regOldRowid);
}
}
/* Do FK constraint checks. */
if( hasFK ){
sqlite3FkCheck(pParse, pTab, regOldRowid, 0, aXRef, chngKey);
}
/* Delete the index entries associated with the current record. */
if( bReplace || chngKey ){
if( pPk ){
addr1 = sqlite3VdbeAddOp4Int(v, OP_NotFound, iDataCur, 0, regKey, nKey);
}else{
addr1 = sqlite3VdbeAddOp3(v, OP_NotExists, iDataCur, 0, regOldRowid);
}
VdbeCoverageNeverTaken(v);
}
sqlite3GenerateRowIndexDelete(pParse, pTab, iDataCur, iIdxCur, aRegIdx, -1);
/* If changing the rowid value, or if there are foreign key constraints
@ -766,9 +767,6 @@ void sqlite3Update(
sqlite3VdbeAddOp2(v, OP_Delete, iDataCur, 0);
}
#endif
if( bReplace || chngKey ){
sqlite3VdbeJumpHere(v, addr1);
}
if( hasFK ){
sqlite3FkCheck(pParse, pTab, 0, regNewRowid, aXRef, chngKey);

View File

@ -366,5 +366,73 @@ do_execsql_test 12.3 {
SELECT * FROM t2;
} {111 111B 112 112}
#-------------------------------------------------------------------------
ifcapable trigger {
reset_db
do_execsql_test 13.1.0 {
PRAGMA recursive_triggers = true;
CREATE TABLE t0 (c0 UNIQUE, c1 UNIQUE);
CREATE TRIGGER tr0 AFTER DELETE ON t0 BEGIN
DELETE FROM t0;
END;
INSERT INTO t0 VALUES(1, NULL);
INSERT INTO t0 VALUES(0, NULL);
}
do_execsql_test 13.1.1 {
UPDATE OR REPLACE t0 SET c1 = 1;
}
integrity_check 13.1.2
do_execsql_test 13.1.3 {
SELECT * FROM t0
} {}
do_execsql_test 13.2.0 {
CREATE TABLE t2 (a PRIMARY KEY, b UNIQUE, c UNIQUE) WITHOUT ROWID;
CREATE TRIGGER tr3 AFTER DELETE ON t2 BEGIN
DELETE FROM t2;
END;
INSERT INTO t2 VALUES(1, 1, 1);
INSERT INTO t2 VALUES(2, 2, 2);
}
do_execsql_test 13.2.1 {
UPDATE OR REPLACE t2 SET c = 0;
}
integrity_check 13.2.2
do_execsql_test 13.2.3 {
SELECT * FROM t2
} {}
do_execsql_test 13.3.0 {
CREATE TABLE t1(a, b);
CREATE TABLE log(x);
CREATE INDEX i1 ON t1(a);
INSERT INTO t1 VALUES(1, 2);
CREATE TRIGGER tb BEFORE UPDATE ON t1 BEGIN
DELETE FROM t1;
END;
CREATE TRIGGER ta AFTER UPDATE ON t1 BEGIN
INSERT INTO log VALUES('fired!');
END;
UPDATE t1 SET b=3;
}
do_execsql_test 13.3.1 {
SELECT * FROM t1;
} {}
do_execsql_test 13.3.2 {
SELECT * FROM log;
} {}
}
finish_test