]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
Ensure that a write with REPLACE conflict resolution on an integer primary key column...
authordan <Dan Kennedy>
Fri, 17 Jul 2026 16:26:56 +0000 (16:26 +0000)
committerdan <Dan Kennedy>
Fri, 17 Jul 2026 16:26:56 +0000 (16:26 +0000)
FossilOrigin-Name: 1875249ab30fb110bc09963b592c8f48d2fb57066d770ad7e1da7e8bc8602977

manifest
manifest.tags
manifest.uuid
src/insert.c
test/upsert1.test

index b3a06aaa885d858407d64ec8447b25084dba45ef..eb751f2c8fcdbe106052af1c99ad546d4c54b5b5 100644 (file)
--- a/manifest
+++ b/manifest
@@ -1,5 +1,5 @@
-C Add\sthe\sSQLITE_SHELL_EDITION\scompile-time\soption,\swhich\sif\sset\sto\sa\ndate\snumber\sof\sthe\sform\sYYYYMMDD\swill\stry\sto\sconfigure\sthe\sdefaults\nto\sbe\ssimilar\sto\sthe\slatest\srelease\sat\sor\sprior\sto\sthat\sdate.
-D 2026-07-16T23:55:15.551
+C Ensure\sthat\sa\swrite\swith\sREPLACE\sconflict\sresolution\son\san\sinteger\sprimary\skey\scolumn\sis\shandled\safter\sany\sIGNORE\sor\sFAIL\sconflicts,\seven\sif\sthere\sis\salso\san\sexplicit\s"ON\sCONFLICT"\sclause\sunrelated\sto\sthe\sIPK.\sForum\spost\s[forum:/info/2026-07-17T09:30:42Z\s|\s2026-07-17T09:30:42Z].
+D 2026-07-17T16:26:56.257
 F .fossil-settings/binary-glob 61195414528fb3ea9693577e1980230d78a1f8b0a54c78cf1b9b24d0a409ed6a x
 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1
 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea
@@ -702,7 +702,7 @@ F src/hash.c 03c8c0f4be9e8bcb6de65aa26d34a61d48a9430747084a69f9469fbb00ea52ca
 F src/hash.h 46b92795a95bfefb210f52f0c316e9d7cdbcdd7e7fcfb0d8be796d3a5767cddf
 F src/hwtime.h 5cb15147c8583d0fc4748e1c12ea6f38c9deaeefa147a4d8d379fd9bc81fee9a
 F src/in-operator.md 10cd8f4bcd225a32518407c2fb2484089112fd71
-F src/insert.c e6e9b574b4863649e2c433f2260f226183e697df1ab73fcb8da9a85d5abcd390
+F src/insert.c 71776cca5bf05b05b1427fa1dc1b0d391e7f3805abaf9b6f3c24ec7350040838
 F src/json.c e4af4d799e4e7630c633b3b356d65e92d1781e42343ab77b8ef747c932762012
 F src/legacy.c d7874bc885906868cd51e6c2156698f2754f02d9eee1bae2d687323c3ca8e5aa
 F src/loadext.c 5cd4cd7ec6e1a46416806899086363fbf95eecd3bfb9a388b436c9a77243c902
@@ -1947,7 +1947,7 @@ F test/upfrom2.test 66f3ebf721b3cebd922faee5c386bf244f816d416b57c000753ff51af623
 F test/upfrom3.test 6130f24ebf97f5ea865e5d2a14a2d543fe5428a62e87cc60f62d875e45c1f5f0
 F test/upfrom4.test 78f742a6577c91a7a55c64edb8811004e7c6aa99b8d57b2320f70a918c357807
 F test/upfromfault.test 3a10075a0043f0c4fad6614b2c371f88a8ba5a4acab68b907438413865d6a8d6
-F test/upsert1.test 77e3cbabd6b5c773056aca39bda7a690901f1dbd08b0a26ee3b5aec9e9e26198
+F test/upsert1.test cfaa6eab3c0d3e8512664a92570348482c61e71b02e0ec75837e4fb37fe4e430
 F test/upsert2.test 720e94d09f7362a282bc69b3c6b83d51daeaaf0440eb4920a08b86518b8c7496
 F test/upsert3.test 88d7d590a1948a9cb6eac1b54b0642f67a9f35a1fc0f19b200e97d5d39e3179c
 F test/upsert4.test 25d2a1da92f149331ae0c51ca6e3eee78189577585eab92de149900d62994fa5
@@ -2215,8 +2215,11 @@ F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee
 F tool/warnings.sh a554d13f6e5cf3760f041b87939e3d616ec6961859c3245e8ef701d1eafc2ca2
 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f
 F tool/winmain.c 00c8fb88e365c9017db14c73d3c78af62194d9644feaf60e220ab0f411f3604c
-P 9062c79fc273d9e59090ea475e7d2abaf33c7cfe9948cbfb92b979a6ed31a37f
-R 962f8f7981b575eb8d2ef8e19f91d63a
-U drh
-Z 10ca7fd768bd6c7b1db171f45c9c110e
+P 6924895d2cbc50971d8da1810423ad15c638dabc31b4f1083dd6076e20492ef4
+R 506e7819684ce1917475a4b1d4a399da
+T *branch * do-nothing-replace-bug
+T *sym-do-nothing-replace-bug *
+T -sym-trunk *
+U dan
+Z 975ed7664c025722600a0d0d2b0ab4aa
 # Remove this line to create a well-formed Fossil manifest.
index bec971799ff1b8ee641c166c7aeb22d12c785393..d04b2e9f24e12b0a6f97f500ca26d6ec21a3668e 100644 (file)
@@ -1,2 +1,2 @@
-branch trunk
-tag trunk
+branch do-nothing-replace-bug
+tag do-nothing-replace-bug
index 83d1ffb12a124faf8d207d69869201566eb2b8f9..ec96f9a1e4fcb3161b94f25d145ab783be27b3e1 100644 (file)
@@ -1 +1 @@
-6924895d2cbc50971d8da1810423ad15c638dabc31b4f1083dd6076e20492ef4
+1875249ab30fb110bc09963b592c8f48d2fb57066d770ad7e1da7e8bc8602977
index 61aabc661752beba2a111a4fb7ddab65eee4240c..15a9a5fe89f84ac91a62c37df111b08e45090a9e 100644 (file)
@@ -2281,9 +2281,13 @@ void sqlite3GenerateConstraintChecks(
     if( onError==OE_Replace      /* IPK rule is REPLACE */
      && onError!=overrideError   /* Rules for other constraints are different */
      && pTab->pIndex             /* There exist other constraints */
-     && !upsertIpkDelay          /* IPK check already deferred by UPSERT */
     ){
-      ipkTop = sqlite3VdbeAddOp0(v, OP_Goto)+1;
+      if( upsertIpkDelay ){
+        ipkTop = upsertIpkDelay + 1;
+        upsertIpkDelay = 0;
+      }else{
+        ipkTop = sqlite3VdbeAddOp0(v, OP_Goto)+1;
+      }
       VdbeComment((v, "defer IPK REPLACE until last"));
     }
 
@@ -2377,11 +2381,11 @@ void sqlite3GenerateConstraintChecks(
       }
     }
     sqlite3VdbeResolveLabel(v, addrRowidOk);
-    if( pUpsert && pUpsertClause!=pUpsert ){
-      upsertIpkReturn = sqlite3VdbeAddOp0(v, OP_Goto);
-    }else if( ipkTop ){
+    if( ipkTop ){
       ipkBottom = sqlite3VdbeAddOp0(v, OP_Goto);
       sqlite3VdbeJumpHere(v, ipkTop-1);
+    }else if( pUpsert && pUpsertClause!=pUpsert ){
+      upsertIpkReturn = sqlite3VdbeAddOp0(v, OP_Goto);
     }
   }
 
index 49168f840b1ddef978f0ff2f06f332fc5b8fb145..aecf1c8530ccd044af38196b46c078cae8f3b214 100644 (file)
@@ -292,4 +292,67 @@ do_execsql_test upsert1-1300 {
    ON CONFLICT (x) DO UPDATE SET y = excluded.y;
 } {}
 
+# 2026-07-17 Forum Post 2026-07-17T09:30:42Z
+# Combination of ON CONFLICT FAIL on a UNIQUE index and
+# an ON CONFLICT DO NOTHING in a different index leads to
+# database corruption.
+#
+reset_db
+do_execsql_test upsert1-1400 {
+  CREATE TABLE t(
+    a INTEGER PRIMARY KEY ON CONFLICT REPLACE,
+    b INT UNIQUE ON CONFLICT FAIL,
+    c INT UNIQUE
+  );
+  INSERT INTO t VALUES (1, 10, 100),(2, 20, 200);
+}
+do_catchsql_test upsert1-1410 {
+  INSERT INTO t VALUES (1, 20, 300) ON CONFLICT(c) DO NOTHING;
+} {1 {UNIQUE constraint failed: t.b}}
+do_execsql_test upsert1-1420 {
+  PRAGMA integrity_check;
+} {ok}
+do_execsql_test upsert1-1430 {
+  SELECT * FROM t ORDER BY a;
+} {1 10 100 2 20 200}
+
+do_execsql_test upsert1-1440 {
+  DROP TABLE t;
+  CREATE TABLE t(
+    a INTEGER PRIMARY KEY ON CONFLICT REPLACE,
+    b INT UNIQUE ON CONFLICT IGNORE,
+    c INT UNIQUE
+  );
+  INSERT INTO t VALUES (1, 10, 100),(2, 20, 200);
+}
+do_catchsql_test upsert1-1450 {
+  INSERT INTO t VALUES (1, 20, 300) ON CONFLICT(c) DO NOTHING;
+} {0 {}}
+do_execsql_test upsert1-1420 {
+  PRAGMA integrity_check;
+} {ok}
+do_execsql_test upsert1-1460 {
+  SELECT * FROM t ORDER BY a;
+} {1 10 100 2 20 200}
+
+do_execsql_test upsert1-1470 {
+  DROP TABLE t;
+  CREATE TABLE t(
+    a INTEGER PRIMARY KEY ON CONFLICT REPLACE,
+    b INT UNIQUE ON CONFLICT FAIL,
+    c INT UNIQUE
+  );
+  INSERT INTO t VALUES (1, 10, 100),(2, 20, 200);
+}
+do_catchsql_test upsert1-1480 {
+  INSERT INTO t VALUES (1, 20, 300) ON CONFLICT(c) DO NOTHING;
+} {1 {UNIQUE constraint failed: t.b}}
+do_execsql_test upsert1-1490 {
+  PRAGMA integrity_check;
+} {ok}
+do_execsql_test upsert1-1500 {
+  SELECT * FROM t ORDER BY a;
+} {1 10 100 2 20 200}
+
 finish_test
+