]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
Fix a problem in the sessions extension allowing changesets containing foreign key...
authordan <Dan Kennedy>
Sat, 4 Jan 2025 16:30:05 +0000 (16:30 +0000)
committerdan <Dan Kennedy>
Sat, 4 Jan 2025 16:30:05 +0000 (16:30 +0000)
FossilOrigin-Name: e09a0c022903d88d5d6de34b2527565ef60c6bb049f2fb42f037e1520abf0f93

ext/session/session1.test
ext/session/session9.test
ext/session/sessionnoact.test
ext/session/sqlite3session.c
manifest
manifest.uuid
test/fkey6.test

index bcd7b03d5c8dc1ab7b4273e55fd06ff86facd864..dfc1aa895719f6a49ced069c5a870031a16064ce 100644 (file)
@@ -204,7 +204,9 @@ proc do_conflict_test {tn args} {
   foreach t $O(-tables) { S attach $t }
   execsql $O(-sql)
   set ::xConflict [list]
-  sqlite3changeset_apply db2 [S changeset] xConflict
+  catch {
+    sqlite3changeset_apply db2 [S changeset] xConflict
+  }
 
   set conflicts [list]
   foreach c $O(-conflicts) {
@@ -283,7 +285,7 @@ do_conflict_test $tn.3.2.3 -tables t2 -sql {
   {FOREIGN_KEY 1}
 }
 do_execsql_test $tn.3.2.4 "SELECT * FROM t2" {}
-do_db2_test $tn.3.2.5 "SELECT * FROM t2" {4 five}
+do_db2_test $tn.3.2.5 "SELECT * FROM t2" {1 one 2 two 4 five}
 
 # Test UPDATE changesets.
 #
index ebb88ffade7303438ee4c0f814b37d4692dc0383..6b7d1648b2a4796f58928995b0d40400f6a2f1c3 100644 (file)
@@ -80,8 +80,10 @@ foreach {tn delrow trans conflictargs conflictret} {
   8   3 1 {FOREIGN_KEY 1} ABORT
 } {
 
-  set A(OMIT)  {0 {}}
-  set A(ABORT) {1 SQLITE_CONSTRAINT}
+  set A(OMIT,0)  {1 SQLITE_CONSTRAINT}
+  set A(OMIT,1)  {0 {}}
+  set A(ABORT,0) {1 SQLITE_CONSTRAINT}
+  set A(ABORT,1) {1 SQLITE_CONSTRAINT}
   do_test 1.2.$tn.1 {
     populate_db
     execsql { DELETE FROM p1 WHERE a=($delrow+0) }
@@ -89,20 +91,24 @@ foreach {tn delrow trans conflictargs conflictret} {
 
     set ::xConflict [list]
     list [catch {sqlite3changeset_apply db $::cc xConflict} msg] $msg
-  } $A($conflictret)
+  } $A($conflictret,$trans)
 
   do_test 1.2.$tn.2 { set ::xConflict } $conflictargs
 
-  set A(OMIT)  {1 1}
-  set A(ABORT) {0 0}
+  set A(OMIT,0)  {0 0}
+  set A(OMIT,1)  {1 1}
+  set A(ABORT,0) {0 0}
+  set A(ABORT,1) {0 0}
+
   do_test 1.2.$tn.3 {
     execsql { SELECT count(*) FROM c1 UNION ALL SELECT count(*) FROM c2 }
-  } $A($conflictret)
+  } $A($conflictret,$trans)
 
   do_test 1.2.$tn.4 { expr ![sqlite3_get_autocommit db] } $trans
   do_test 1.2.$tn.5 {
-    if { $trans } { execsql COMMIT }
+    if { $trans && $conflictret=="ABORT" } { execsql COMMIT }
   } {}
+  catchsql ROLLBACK
 }
 
 #--------------------------------------------------------------------
index aa1cde4749a72e6287f1f72932efd02a4ad73725..f605e6108ef4710c3e153a8f4ff199542565b6cd 100644 (file)
@@ -82,7 +82,6 @@ do_execsql_test 1.5 {
   UPDATE p1 SET c=12345 WHERE a = 45;
 }
 
-breakpoint
 sqlite3changeset_apply_v2 -noaction db $C conflict
 do_execsql_test 1.6 {
   SELECT * FROM c1
@@ -108,4 +107,47 @@ do_execsql_test 1.8 {
   PRAGMA foreign_key_check
 }
 
+#-------------------------------------------------------------------------
+# Check that a changeset that causes an FK violation may not be applied,
+# even if SQLITE_CHANGESETAPPLY_FKNOACTION is specified.
+#
+reset_db
+do_execsql_test 2.0 {
+  CREATE TABLE p1(a INTEGER PRIMARY KEY, b, c UNIQUE);
+  INSERT INTO p1 VALUES(1, 1, 'one');
+  INSERT INTO p1 VALUES(2, 2, 'two');
+
+  CREATE TABLE c1(x REFERENCES p1(c) ON DELETE CASCADE);
+  INSERT INTO c1 VALUES('two');
+}
+
+db_save
+
+set C [changeset_from_sql {
+  DELETE FROM p1 WHERE a=2;
+}]
+
+db_restore_and_reopen
+
+do_test 2.1 {
+  sqlite3changeset_apply_v2 -noaction db $C conflict
+} {}
+do_execsql_test 2.2 {
+  SELECT * FROM p1
+} {1 1 one}
+
+db_restore_and_reopen
+db eval { PRAGMA foreign_keys = 1 }
+
+do_test 2.3 {
+  list [catch { sqlite3changeset_apply_v2 -noaction db $C conflict } msg] $msg
+} {1 SQLITE_CONSTRAINT}
+do_execsql_test 2.4 {
+  SELECT * FROM p1;
+} {1 1 one 2 2 two}
+do_execsql_test 2.5 {
+  SELECT * FROM c1;
+} {two}
+
 finish_test
+
index f2eb942e6872d09c961e85cfe8884080ec0e4b1e..a3f132add897d335d93f2fabb9bb6b877638431c 100644 (file)
@@ -5283,12 +5283,12 @@ static int sessionChangesetApply(
       }
     }
   }
-  sqlite3_exec(db, "PRAGMA defer_foreign_keys = 0", 0, 0, 0);
 
   if( (flags & SQLITE_CHANGESETAPPLY_NOSAVEPOINT)==0 ){
     if( rc==SQLITE_OK ){
       rc = sqlite3_exec(db, "RELEASE changeset_apply", 0, 0, 0);
-    }else{
+    }
+    if( rc!=SQLITE_OK ){
       sqlite3_exec(db, "ROLLBACK TO changeset_apply", 0, 0, 0);
       sqlite3_exec(db, "RELEASE changeset_apply", 0, 0, 0);
     }
index 3cdc3c3865bcc1aeceb7b922ac29c98000edb322..1063bced5f2ef967bef080f35914e1c39be61626 100644 (file)
--- a/manifest
+++ b/manifest
@@ -1,5 +1,5 @@
-C Add\sthe\sdocument\sdescribing\stest\sprocedures\sfor\sthe\sTCL\sextension\sbuild\nprocess.\s\sUpdate\sthe\sWindows\smakefile\sso\sthat\sit\sbuilds\sthe\sTCL\sextensions\nsuccessfully\swith\sa\sdefault\sinstallation\sof\sTcl8.6.
-D 2025-01-04T15:52:40.069
+C Fix\sa\sproblem\sin\sthe\ssessions\sextension\sallowing\schangesets\scontaining\sforeign\skey\sviolations\sto\sbe\scommitted\sunder\ssome\scircumstances.
+D 2025-01-04T16:30:05.359
 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1
 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea
 F LICENSE.md e108e1e69ae8e8a59e93c455654b8ac9356a11720d3345df2a4743e9590fb20d
@@ -576,14 +576,14 @@ F ext/rtree/visual01.txt e9c2564083bcd30ec51b07f881bffbf0e12b50a3f6fced0c222c5c1
 F ext/session/changeset.c 7a1e6a14c7e92d36ca177e92e88b5281acd709f3b726298dc34ec0fb58869cb5
 F ext/session/changesetfuzz.c 227076ab0ae4447d742c01ee88a564da6478bbf26b65108bf8fac9cd8b0b24aa
 F ext/session/changesetfuzz1.test 15b629004e58d5ffcc852e6842a603775bb64b1ce51254831f3d12b113b616cd
-F ext/session/session1.test e94f764fbfb672147c0ef7026b195988133b371dc8cf9e52423eba6cad69717e
+F ext/session/session1.test 8d0509cd3fcfdee6a33422d5fe5c95a9770d62a0b8588adb0177ecdf79b2c345
 F ext/session/session2.test ee83bb973b9ce17ccce4db931cdcdae65eb40bbb22089b2fe6aa4f6be3b9303f
 F ext/session/session3.test 2cc1629cfb880243aec1a7251145e07b78411d851b39b2aa1390704550db8e6a
 F ext/session/session4.test 823f6f018fcbb8dacf61e2960f8b3b848d492b094f8b495eae1d9407d9ab7219
 F ext/session/session5.test 716bc6fafd625ce60dfa62ae128971628c1a1169
 F ext/session/session6.test 35279f2ec45448cd2e24a61688219dc6cf7871757716063acf4a8b5455e1e926
 F ext/session/session8.test 326f3273abf9d5d2d7d559eee8f5994c4ea74a5d935562454605e6607ee29904
-F ext/session/session9.test 5409d90d8141881d08285ed1c2c0d8d10fb92069
+F ext/session/session9.test be090b1420f3824a573da9e56ff542b1e1c2a4f772118e9ab2f75774e66d25d0
 F ext/session/sessionA.test 1feeab0b8e03527f08f2f1defb442da25480138f
 F ext/session/sessionB.test c4fb7f8a688787111606e123a555f18ee04f65bb9f2a4bb2aa71d55ce4e6d02c
 F ext/session/sessionC.test f8a5508bc059ae646e5ec9bdbca66ad24bc92fe99fda5790ac57e1f59fce2fdf
@@ -606,7 +606,7 @@ F ext/session/sessionfault2.test b0d6a7c1d7398a7e800d84657404909c7d385965ea8576d
 F ext/session/sessionfault3.test ce0b5d182133935c224d72507dbf1c5be1a1febf7e85d0b0fbd6d2f724b32b96
 F ext/session/sessioninvert.test 04075517a9497a80d39c495ba6b44f3982c7371129b89e2c52219819bc105a25
 F ext/session/sessionmem.test f2a735db84a3e9e19f571033b725b0b2daf847f3f28b1da55a0c1a4e74f1de09
-F ext/session/sessionnoact.test 2563dff62a2a80dc7c88002241b2fd1578c3e5438735e180fb7e941ebbc66214
+F ext/session/sessionnoact.test 1ea34324b7be2fa9d63870d44969e6bb5290a6d1603ddfd4151c51df73fad291
 F ext/session/sessionnoop.test a9366a36a95ef85f8a3687856ebef46983df399541174cb1ede2ee53b8011bc7
 F ext/session/sessionnoop2.test de4672dce88464396ec9f30ed08c6c01643a69c53ae540fadbbf6d30642d64e8
 F ext/session/sessionrebase.test 702378bdcb5062f1106e74457beca8797d09c113a81768734a58b197b5b334e2
@@ -614,7 +614,7 @@ F ext/session/sessionrowid.test 85187c2f1b38861a5844868126f69f9ec62223a03449a98a
 F ext/session/sessionsize.test 8fcf4685993c3dbaa46a24183940ab9f5aa9ed0d23e5fb63bfffbdb56134b795
 F ext/session/sessionstat1.test 5e718d5888c0c49bbb33a7a4f816366db85f59f6a4f97544a806421b85dc2dec
 F ext/session/sessionwor.test 6fd9a2256442cebde5b2284936ae9e0d54bde692d0f5fd009ecef8511f4cf3fc
-F ext/session/sqlite3session.c 3d0a7f0f7a1c946e01818c716a55a40ae30542a29a9045cb05daf7fb658cdafa
+F ext/session/sqlite3session.c d6f5e3e83b9b0bbc4a8db4837284f0ecc6af5321d4c8e7136380b456b278c46a
 F ext/session/sqlite3session.h 683ccbf16e2c2521661fc4c1cf918ce57002039efbcabcd8097fa4bca569104b
 F ext/session/test_session.c aa29abdcc9011ac02f4fa38e8ede226106eaeee7c3ea7d8b2b999a124e0c368c
 F ext/wasm/EXPORTED_FUNCTIONS.fiddle.in 27450c8b8c70875a260aca55435ec927068b34cef801a96205adb81bdcefc65c
@@ -1153,7 +1153,7 @@ F test/fkey2.test 1063d65e5923c054cfb8f0555a92a3ae0fa8c067275a33ee1715bd856cdb30
 F test/fkey3.test 76d475c80b84ee7a5d062e56ccb6ea68882e2b49
 F test/fkey4.test 86446017011273aad8f9a99c1a65019e7bd9ca9d
 F test/fkey5.test 6727452e163a427147e84e739da18713da553d79f9783559b04fdcd36d5c7421
-F test/fkey6.test d078a1e323a740062bed38df32b8a736fd320dc0
+F test/fkey6.test bdb9c808349a149575b87cf4bfd82d4c81612f0c4d954d27b3f42f043a385396
 F test/fkey7.test 64fb28da03da5dfe3cdef5967aa7e832c2507bf7fb8f0780cacbca1f2338d031
 F test/fkey8.test 51deda7f1a1448bca95875e4a6e1a3a75b4bd7215e924e845bd60de60e4d84bf
 F test/fkey_malloc.test 594a7ea1fbab553c036c70813cd8bd9407d63749
@@ -2205,9 +2205,8 @@ F tool/version-info.c 3b36468a90faf1bbd59c65fd0eb66522d9f941eedd364fabccd7227350
 F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee87c1b31a7
 F tool/warnings.sh 49a486c5069de041aedcbde4de178293e0463ae9918ecad7539eedf0ec77a139
 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f
-P 9ee57a30a49d9813bf2669a5d8346f7e018e3fbf1792739951311a8d3a249d45 0c2cdc632f26d6acac2d508def4ecfcc97462ebcddc20c84f8847e02e42b3a1d
-R c39856b8b1c55486d94efa9f4d6e65f7
-T +closed 0c2cdc632f26d6acac2d508def4ecfcc97462ebcddc20c84f8847e02e42b3a1d
-U drh
-Z 0b107a7817bd289dd55ee148db24c6d9
+P 3263db9249444203b7a9a9f2b0be309c74944315dde7ed192366b709fff93f1b
+R dd67c57d38ae3918a7498e739dc242d4
+U dan
+Z 0beeea9f83c0978752782d269e0f987a
 # Remove this line to create a well-formed Fossil manifest.
index f286bc29e132cac1a7e9f0da1ebedf692882fb1a..613d99cd96ef3a4a588d5554daf07ba292c3fe3e 100644 (file)
@@ -1 +1 @@
-3263db9249444203b7a9a9f2b0be309c74944315dde7ed192366b709fff93f1b
+e09a0c022903d88d5d6de34b2527565ef60c6bb049f2fb42f037e1520abf0f93
index b658f20fea19665ef32cf00ea13ab1c9fa4edbdc..865875952359700a6ab40c406f06aacd7cd8b771 100644 (file)
@@ -225,5 +225,32 @@ do_execsql_test 3.3.4 {
   SELECT * FROM p2;
 } {0 one 1 deleted!}
 
+#-------------------------------------------------------------------------
+# Verify that, even with "PRAGMA defer_foreign_keys", a transaction cannot
+# be committed if there are outstanding foreign key violations.
+#
+reset_db
+do_execsql_test 4.0 {
+  CREATE TABLE p1(a INTEGER PRIMARY KEY, b UNIQUE);
+  CREATE TABLE c1(x REFERENCES p1(b));
+
+  INSERT INTO p1 VALUES(1, 'one'), (2, 'two'), (3, 'three');
+  INSERT INTO c1 VALUES('two');
+
+  PRAGMA foreign_keys = 1;
+  PRAGMA defer_foreign_keys = 1;
+}
+
+do_execsql_test 4.1 {
+  BEGIN;
+    DELETE FROM p1 WHERE a=2;
+}
+
+do_catchsql_test 4.2 {
+  COMMIT;
+} {1 {FOREIGN KEY constraint failed}}
+
+
+
 
 finish_test