]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
Fix a problem with SQLITE_CHANGESET_CONFLICT conflicts caused by DELETE triggers...
authordan <Dan Kennedy>
Wed, 20 Aug 2025 11:21:35 +0000 (11:21 +0000)
committerdan <Dan Kennedy>
Wed, 20 Aug 2025 11:21:35 +0000 (11:21 +0000)
FossilOrigin-Name: 138e2aab43ac07aaf8c5389105ff6d3e107ff2d35badcb48233664fcb9661471

ext/session/sessionnoop2.test
ext/session/sqlite3session.c
manifest
manifest.uuid

index ab8ae74cc31e5be97576bef9bd8916c78133f307..5e8283d12de47ab5d083206928f87cada28dafeb 100644 (file)
@@ -175,44 +175,146 @@ do_test 3.5 {
 }]
 
 #-------------------------------------------------------------------------
+# Test that the conflict-handler is invoked for conflicts caused by
+# DELETE ops even if SQLITE_CHANGESETAPPLY_IGNORENOOP is specified.
+#
 set ::conflict_list [list]
 proc xConflict {args} {
   lappend ::conflict_list $args
   return "OMIT"
 }
 
-forcedelete test.db2
-do_execsql_test 4.0 {
-  CREATE TABLE x1(a, b, c, PRIMARY KEY(a)) WITHOUT ROWID;
-  INSERT INTO x1 VALUES(1, 'one', 'i');
-  INSERT INTO x1 VALUES(2, 'two', 'ii');
-  INSERT INTO x1 VALUES(3, 'three', 'iii');
-  VACUUM INTO 'test.db2';
+foreach {tn wo} {
+  1 ""
+  2 " WITHOUT ROWID "
+} {
+  reset_db
+  forcedelete test.db2
+  do_execsql_test 4.$tn.0 "
+    CREATE TABLE x1(a INTEGER PRIMARY KEY, b, c) $wo;
+    INSERT INTO x1 VALUES(1, 'one', 'i');
+    INSERT INTO x1 VALUES(2, 'two', 'ii');
+    INSERT INTO x1 VALUES(3, 'three', 'iii');
+    VACUUM INTO 'test.db2';
+  "
+  
+  set C [changeset_from_sql {
+    DELETE FROM x1 WHERE a=2;
+  }]
+  
+  sqlite3 db2 test.db2
+  do_execsql_test -db db2 4.$tn.1 {
+    UPDATE x1 SET b='four hundred' WHERE a=2;
+  }
+  
+  do_test 4.$tn.2.1 {
+    set ::conflict_list [list]
+    sqlite3changeset_apply_v2 db2 $C xConflict
+    set ::conflict_list
+  } [list {*}{
+    {DELETE x1 DATA {i 2 t two t ii} {i 2 t {four hundred} t ii}}
+  }]
+  
+  do_test 4.$tn.2.2 {
+    set ::conflict_list [list]
+    sqlite3changeset_apply_v2 -ignorenoop db2 $C xConflict
+    set ::conflict_list
+  } [list {*}{
+    {DELETE x1 DATA {i 2 t two t ii} {i 2 t {four hundred} t ii}}
+  }]
 }
 
-set C [changeset_from_sql {
-  DELETE FROM x1 WHERE a=2;
-}]
+foreach {tn wo} {
+  1 ""
+  2 " WITHOUT ROWID "
+} {
+  reset_db
+  forcedelete test.db2
+  do_execsql_test 5.$tn.0 "
+    PRAGMA foreign_keys = ON;
+    CREATE TABLE p1(a INTEGER PRIMARY KEY, b, c) $wo;
+    CREATE TABLE c1(a INTEGER PRIMARY KEY REFERENCES p1, b);
+    INSERT INTO p1 VALUES(1, 'one', 'i');
+    INSERT INTO p1 VALUES(2, 'two', 'ii');
+    INSERT INTO p1 VALUES(3, 'three', 'iii');
+    VACUUM INTO 'test.db2';
+  "
+  
+  set C [changeset_from_sql {
+    DELETE FROM p1 WHERE a=2;
+  }]
+  
+  sqlite3 db2 test.db2
+  do_execsql_test -db db2 5.$tn.1 {
+    PRAGMA foreign_keys = ON;
+    INSERT INTO c1 VALUES(2, 'xyz');
+  }
 
-sqlite3 db2 test.db2
-do_execsql_test -db db2 4.1 {
-  UPDATE x1 SET b='four hundred' WHERE a=2;
+  do_test 5.$tn.2.1 {
+    set ::conflict_list [list]
+    sqlite3changeset_apply_v2 db2 $C xConflict
+    set ::conflict_list
+  } [list {*}{
+    {FOREIGN_KEY 1}
+  }]
+
+  # Reinsert the row deleted by test case 5.$tn.2.1
+  execsql { INSERT INTO p1 VALUES(2, 'two', 'ii') } db2
+
+  do_test 5.$tn.2.2 {
+    set ::conflict_list [list]
+    sqlite3changeset_apply_v2 -ignorenoop db2 $C xConflict
+    set ::conflict_list
+  } [list {*}{
+    {FOREIGN_KEY 1}
+  }]
 }
 
-do_test 4.2.1 {
-  set ::conflict_list [list]
-  sqlite3changeset_apply_v2 db2 $C xConflict
-  set ::conflict_list
-} [list {*}{
-  {DELETE x1 DATA {i 2 t two t ii} {i 2 t {four hundred} t ii}}
-}]
-do_test 4.2.2 {
-  set ::conflict_list [list]
-  sqlite3changeset_apply_v2 -ignorenoop db2 $C xConflict
-  set ::conflict_list
-} [list {*}{
-  {DELETE x1 DATA {i 2 t two t ii} {i 2 t {four hundred} t ii}}
-}]
+foreach {tn wo} {
+  1 ""
+  2 " WITHOUT ROWID "
+} {
+  reset_db
+  forcedelete test.db2
+  do_execsql_test 6.$tn.0 "
+    CREATE TABLE x1(a INTEGER PRIMARY KEY, b, c) $wo;
+    CREATE TABLE x2(x UNIQUE);
+
+    INSERT INTO x1 VALUES(1, 'one', 'i');
+    INSERT INTO x1 VALUES(2, 'two', 'ii');
+    INSERT INTO x1 VALUES(3, 'three', 'iii');
+    VACUUM INTO 'test.db2';
+  "
+  
+  set C [changeset_from_sql {
+    DELETE FROM x1 WHERE a=2;
+  }]
+  
+  sqlite3 db2 test.db2
+  do_execsql_test -db db2 6.$tn.1 {
+    INSERT INTO x2 VALUES(0);
+    CREATE TRIGGER tr1 AFTER DELETE ON x1 BEGIN
+      INSERT INTO x2 VALUES(0);
+    END;
+  }
+
+  do_test 6.$tn.2.1 {
+    set ::conflict_list [list]
+    sqlite3changeset_apply_v2 db2 $C xConflict
+    set ::conflict_list
+  } [list {*}{
+    {DELETE x1 CONSTRAINT {i 2 t two t ii}}
+  }]
+
+breakpoint
+  do_test 6.$tn.2.2 {
+    set ::conflict_list [list]
+    sqlite3changeset_apply_v2 -ignorenoop db2 $C xConflict
+    set ::conflict_list
+  } [list {*}{
+    {DELETE x1 CONSTRAINT {i 2 t two t ii}}
+  }]
+}
 
 
 finish_test
index d92480db0fdc6d86bb7cfdfb6c6a50ff1a866388..81ba73834051172ea9d1fe80ba489a9dfc675f3e 100644 (file)
@@ -4870,7 +4870,9 @@ static int sessionConflictHandler(
       int nBlob = pIter->in.iNext - pIter->in.iCurrent;
       sessionAppendBlob(&p->constraints, aBlob, nBlob, &rc);
       return SQLITE_OK;
-    }else if( p->bIgnoreNoop==0 || op!=SQLITE_DELETE ){
+    }else if( p->bIgnoreNoop==0 || op!=SQLITE_DELETE 
+           || eType==SQLITE_CHANGESET_CONFLICT 
+    ){
       /* No other row with the new.* primary key. */
       res = xConflict(pCtx, eType+1, pIter);
       if( res==SQLITE_CHANGESET_REPLACE ) rc = SQLITE_MISUSE;
index da7f75f7beb2bd1ca5758d0a58e5a54dd9991586..25cbad0cb997122460a662736198cf056d78a0ea 100644 (file)
--- a/manifest
+++ b/manifest
@@ -1,5 +1,5 @@
-C In\sbuilds\swithout\sHAVE_FCHMOD\s(e.g.\sWASI),\smake\sthe\schmod()\sof\stemp\sfiles\sa\sno-op,\sanalog\sto\show\slack\sof\sHAVE_FCHOWN\sis\shandled,\sas\sdiscussed\sin\s[forum:98d5158d3fdd7a41\s|\sforum\spost\s98d5158d3f].
-D 2025-08-20T09:43:15.813
+C Fix\sa\sproblem\swith\sSQLITE_CHANGESET_CONFLICT\sconflicts\scaused\sby\sDELETE\striggers\swithin\sa\scall\sto\ssqlite3changset_apply_v2()\swith\sSQLITE_CHANGESETAPPLY_IGNORENOOP\sspecified.
+D 2025-08-20T11:21:35.942
 F .fossil-settings/binary-glob 61195414528fb3ea9693577e1980230d78a1f8b0a54c78cf1b9b24d0a409ed6a x
 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1
 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea
@@ -567,13 +567,13 @@ F ext/session/sessioninvert.test 9018f6a7387ac745084b6374c5e1aa14d648b372e6e1181
 F ext/session/sessionmem.test f2a735db84a3e9e19f571033b725b0b2daf847f3f28b1da55a0c1a4e74f1de09
 F ext/session/sessionnoact.test 4c7ae5c7d351cb5323bca62b6b095592ad24bd90a6713c178b62ab0063d23e19
 F ext/session/sessionnoop.test a9366a36a95ef85f8a3687856ebef46983df399541174cb1ede2ee53b8011bc7
-F ext/session/sessionnoop2.test e0d70f220495f812ea61420bc6aca83f4bfcbc13635dfbe472b818f4d26fc482
+F ext/session/sessionnoop2.test 5beecd3ffcfbc1ef199d3536e91cc3186b438d587531ff334b6b0fc9b7d8ef10
 F ext/session/sessionrebase.test 702378bdcb5062f1106e74457beca8797d09c113a81768734a58b197b5b334e2
 F ext/session/sessionrowid.test 85187c2f1b38861a5844868126f69f9ec62223a03449a98a80600a44396f7363
 F ext/session/sessionsize.test 8fcf4685993c3dbaa46a24183940ab9f5aa9ed0d23e5fb63bfffbdb56134b795
 F ext/session/sessionstat1.test 5e718d5888c0c49bbb33a7a4f816366db85f59f6a4f97544a806421b85dc2dec
 F ext/session/sessionwor.test 6fd9a2256442cebde5b2284936ae9e0d54bde692d0f5fd009ecef8511f4cf3fc
-F ext/session/sqlite3session.c 8c570698b9a81a78f43635aa674c255b2dd8bee580ea5332058cea643c025686
+F ext/session/sqlite3session.c 9205e6e8f389ea44a8118082ce3832374da92284a60e4fb3ea6b1b421f0dbc54
 F ext/session/sqlite3session.h b81e8536ce4b83babafd700f4ff67017804b6c1d71df963b30d3972958e7f4a7
 F ext/session/test_session.c 8766b5973a6323934cb51248f621c3dc87ad2a98f023c3cc280d79e7d78d36fb
 F ext/wasm/EXPORTED_FUNCTIONS.fiddle.in 27450c8b8c70875a260aca55435ec927068b34cef801a96205adb81bdcefc65c
@@ -2169,8 +2169,8 @@ F tool/version-info.c 3b36468a90faf1bbd59c65fd0eb66522d9f941eedd364fabccd7227350
 F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee87c1b31a7
 F tool/warnings.sh 1ad0169b022b280bcaaf94a7fa231591be96b514230ab5c98fbf15cd7df842dd
 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f
-P 78b543f85ac6643f3b69bf1250c6362f00e030f93f460ef7d04902682ef64ee9
-R a71f49d8d9f654e8f455c5338b9ab922
-U stephan
-Z 08af4145a8110bad977817d5c75cc90c
+P 7d13e8e403ba00d37b950caa359d74452319247495284d252efa6473bad15b64
+R ae093d0946efac31f01b7b9bdaa4b770
+U dan
+Z 7b86a84e6c2cd643602bc41c4f1ab398
 # Remove this line to create a well-formed Fossil manifest.
index 39660e68b90180dcc3f0a4e5e54173ea7b50de7b..24d8076ed2f239a7c5be6e303c40728a97f4dc1c 100644 (file)
@@ -1 +1 @@
-7d13e8e403ba00d37b950caa359d74452319247495284d252efa6473bad15b64
+138e2aab43ac07aaf8c5389105ff6d3e107ff2d35badcb48233664fcb9661471