]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
If a DELETE trigger fired by an UPDATE OR REPLACE statement deletes the row being...
authordan <dan@noemail.net>
Sat, 31 Aug 2019 17:14:35 +0000 (17:14 +0000)
committerdan <dan@noemail.net>
Sat, 31 Aug 2019 17:14:35 +0000 (17:14 +0000)
FossilOrigin-Name: 4145b3e05051ba6729105157a876793ad14a05d895fc10fe704f437eab16ea93

manifest
manifest.uuid
src/update.c
test/conflict3.test

index 6bede4ab76cdae0b98c6176dfc74ac86395e6435..7d0e3d14ee22c275a5aa228f02a4cd165b06ec35 100644 (file)
--- a/manifest
+++ b/manifest
@@ -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
index 9ee4cd5bb4fae084056306cc30d3195c43b0636f..5a00355cf955e33805fb2b31d5bbb61335dc3f82 100644 (file)
@@ -1 +1 @@
-e2db1123faac26c0e0b6a1ebef1685ea7633bfcafd1ff743ba5380700f7745af
\ No newline at end of file
+4145b3e05051ba6729105157a876793ad14a05d895fc10fe704f437eab16ea93
\ No newline at end of file
index bbeaa3d5cee46069ef81143bd84a1372a21f425e..05cef6f58e6441ef466f91344cc6e447a22ac1b2 100644 (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);
index 751a44268519678e91b9270a9be0a1a0734d786a..413e8241fec95fc21749a8dec77c3530651ed1d5 100644 (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
+