mirror of
https://github.com/sqlite/sqlite.git
synced 2026-10-23 21:49:02 +03:00
Move the new test cases for this branch into a new *.test file.
FossilOrigin-Name: 7bdce4ec3b9995a13536eaa2e6a5702333e792b35fa58e606b2e4fa38b85f524
This commit is contained in:
13
manifest
13
manifest
@@ -1,5 +1,5 @@
|
||||
C Test\scase\sfixes\sdue\sto\sthe\sprevious.
|
||||
D 2026-07-18T19:49:18.411
|
||||
C Move\sthe\snew\stest\scases\sfor\sthis\sbranch\sinto\sa\snew\s*.test\sfile.
|
||||
D 2026-07-20T14:37:21.102
|
||||
F .fossil-settings/binary-glob 61195414528fb3ea9693577e1980230d78a1f8b0a54c78cf1b9b24d0a409ed6a x
|
||||
F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1
|
||||
F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea
|
||||
@@ -996,6 +996,7 @@ F test/columncount.test 6fe99c2f35738b0129357a1cf3fa483f76140f4cd8a89014c88c33c8
|
||||
F test/conflict.test 3307ffdf988e04b01c4e942d8aa369a977f085bf629f43a627c9a77f39d65926
|
||||
F test/conflict2.test 5557909ce683b1073982f5d1b61dfb1d41e369533bfdaf003180c5bc87282dd1
|
||||
F test/conflict3.test 81865d9599609aca394fb3b9cd5f561d4729ea5b176bece3644f6ecb540f88ac
|
||||
F test/conflict4.test ac0d4274d63dc3531707c78d112b1f2411a03a71b9801a237fb325d2ff76f0a1
|
||||
F test/contrib01.test 2a1cbc0f2f48955d7d073f725765da6fbceda6b4
|
||||
F test/corrupt.test 54509b182b1927663e0a425b681b0935a08a01b11d8153a4a9545ed36760ebe2
|
||||
F test/corrupt2.test 4ce5eadd51baa1aedb48e141dd885d155946f5c3677bb032547e350ce91b17f4
|
||||
@@ -1947,7 +1948,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 1ae9667f734f5ba1f4be4db351020e336e661e77192fb726b211cc5b74d6ce9b
|
||||
F test/upsert1.test 55e85a95cc6e09ab436b411eb4d76b37952752e0501a57848e4296d6be585ef5
|
||||
F test/upsert2.test 720e94d09f7362a282bc69b3c6b83d51daeaaf0440eb4920a08b86518b8c7496
|
||||
F test/upsert3.test 88d7d590a1948a9cb6eac1b54b0642f67a9f35a1fc0f19b200e97d5d39e3179c
|
||||
F test/upsert4.test 25d2a1da92f149331ae0c51ca6e3eee78189577585eab92de149900d62994fa5
|
||||
@@ -2215,8 +2216,8 @@ F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee
|
||||
F tool/warnings.sh a554d13f6e5cf3760f041b87939e3d616ec6961859c3245e8ef701d1eafc2ca2
|
||||
F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f
|
||||
F tool/winmain.c 00c8fb88e365c9017db14c73d3c78af62194d9644feaf60e220ab0f411f3604c
|
||||
P e2ab286bb713e1358ae9a1d50dc894362d0ea6f1a2e8467c587f42f0e483dd3a
|
||||
R b1bddc0276aa195bc5ec2df639e3f657
|
||||
P 923665823276ee9404a9fdb19378b970eeea77a97bc2f4312446c6f6bc5e4405
|
||||
R c590c51c3034bc599664aab2db20c157
|
||||
U drh
|
||||
Z d0f0bea09313f1d71203c2b202fb85a6
|
||||
Z a7c0e72149e007f4528ceaeb8c532ec1
|
||||
# Remove this line to create a well-formed Fossil manifest.
|
||||
|
||||
@@ -1 +1 @@
|
||||
923665823276ee9404a9fdb19378b970eeea77a97bc2f4312446c6f6bc5e4405
|
||||
7bdce4ec3b9995a13536eaa2e6a5702333e792b35fa58e606b2e4fa38b85f524
|
||||
|
||||
162
test/conflict4.test
Normal file
162
test/conflict4.test
Normal file
@@ -0,0 +1,162 @@
|
||||
# 2026-07-20
|
||||
#
|
||||
# The author disclaims copyright to this source code. In place of
|
||||
# a legal notice, here is a blessing:
|
||||
#
|
||||
# May you do good and not evil.
|
||||
# May you find forgiveness for yourself and forgive others.
|
||||
# May you share freely, never taking more than you give.
|
||||
#
|
||||
#***********************************************************************
|
||||
#
|
||||
# Test cases for UNIQUE ON CONFLICT REPLACE and UNIQUE ON CONFLICT FAIL
|
||||
# behavior including when there are also triggers and/or an UPSERT.
|
||||
#
|
||||
# Forum thread 2026-07-17T09:30:42Z
|
||||
#
|
||||
set testdir [file dirname $argv0]
|
||||
source $testdir/tester.tcl
|
||||
set testprefix conflict4
|
||||
|
||||
# Combination of ON CONFLICT FAIL on a UNIQUE index and
|
||||
# an ON CONFLICT DO NOTHING in a different index leads to
|
||||
# database corruption.
|
||||
#
|
||||
do_execsql_test 1.1 {
|
||||
CREATE TABLE t0(
|
||||
a INTEGER PRIMARY KEY ON CONFLICT REPLACE,
|
||||
b INT UNIQUE ON CONFLICT FAIL,
|
||||
c INT UNIQUE ON CONFLICT ABORT
|
||||
);
|
||||
INSERT INTO t0 VALUES (1, 10, 100),(2, 20, 200);
|
||||
}
|
||||
do_catchsql_test 1.2 {
|
||||
INSERT INTO t0 VALUES (1, 20, 300) ON CONFLICT(c) DO NOTHING;
|
||||
} {1 {UNIQUE constraint failed: t0.b}}
|
||||
do_execsql_test 1.3 {
|
||||
PRAGMA integrity_check;
|
||||
} {ok}
|
||||
do_execsql_test 1.4 {
|
||||
SELECT * FROM t0 ORDER BY a;
|
||||
} {1 10 100 2 20 200}
|
||||
do_execsql_test 1.5 {
|
||||
DROP TABLE t0;
|
||||
CREATE TABLE t0(
|
||||
a INTEGER PRIMARY KEY ON CONFLICT REPLACE,
|
||||
b INT UNIQUE ON CONFLICT IGNORE,
|
||||
c INT UNIQUE ON CONFLICT ABORT
|
||||
);
|
||||
INSERT INTO t0 VALUES (1, 10, 100),(2, 20, 200);
|
||||
}
|
||||
do_catchsql_test 1.6 {
|
||||
INSERT INTO t0 VALUES (1, 20, 300) ON CONFLICT(c) DO NOTHING;
|
||||
} {0 {}}
|
||||
do_execsql_test 1.7 {
|
||||
PRAGMA integrity_check;
|
||||
} {ok}
|
||||
do_execsql_test 1.8 {
|
||||
SELECT * FROM t0 ORDER BY a;
|
||||
} {1 10 100 2 20 200}
|
||||
do_execsql_test 1.9 {
|
||||
DROP TABLE t0;
|
||||
CREATE TABLE t0(
|
||||
a INTEGER PRIMARY KEY ON CONFLICT REPLACE,
|
||||
b INT UNIQUE ON CONFLICT FAIL,
|
||||
c INT UNIQUE ON CONFLICT ABORT
|
||||
);
|
||||
INSERT INTO t0 VALUES (1, 10, 100),(2, 20, 200);
|
||||
}
|
||||
do_catchsql_test 1.10 {
|
||||
INSERT INTO t0 VALUES (1, 20, 300) ON CONFLICT(c) DO NOTHING;
|
||||
} {1 {UNIQUE constraint failed: t0.b}}
|
||||
do_execsql_test 1.11 {
|
||||
PRAGMA integrity_check;
|
||||
} {ok}
|
||||
do_execsql_test 1.12 {
|
||||
SELECT * FROM t0 ORDER BY a;
|
||||
} {1 10 100 2 20 200}
|
||||
do_execsql_test 1.13 {
|
||||
DROP TABLE t0;
|
||||
CREATE TABLE t1(
|
||||
a INTEGER PRIMARY KEY,
|
||||
b UNIQUE ON CONFLICT FAIL,
|
||||
c UNIQUE
|
||||
);
|
||||
INSERT INTO t1 VALUES(1, 1, 1);
|
||||
}
|
||||
do_catchsql_test 1.14 {
|
||||
-- Inserts 0 rows, because hitting the constraint on (b) does ABORT:
|
||||
INSERT INTO t1 VALUES(3, 3, 3), (2, 1, 2) ON CONFLICT(c) DO NOTHING;
|
||||
} {1 {UNIQUE constraint failed: t1.b}}
|
||||
do_execsql_test 1.15 {
|
||||
SELECT * FROM t1 ORDER BY a;
|
||||
} {1 1 1 3 3 3}
|
||||
do_catchsql_test 1.16 {
|
||||
-- Inserts 1 row, because hitting the constraint on (b) does FAIL:
|
||||
DELETE FROM t1 WHERE a=3;
|
||||
INSERT INTO t1 VALUES(3, 3, 3), (2, 1, 2);
|
||||
} {1 {UNIQUE constraint failed: t1.b}}
|
||||
do_execsql_test 1.17 {
|
||||
SELECT * FROM t1 ORDER BY a;
|
||||
} {1 1 1 3 3 3}
|
||||
do_execsql_test 1.18 {
|
||||
PRAGMA integrity_check;
|
||||
} ok
|
||||
|
||||
# Counter-example to the fix at check-in 2026-07-17T16:26:56.257Z
|
||||
# provided by Pavan Nambi at forum post 2026-07-18T03:35:48Z
|
||||
do_execsql_test 2.1 {
|
||||
DROP TABLE t1;
|
||||
PRAGMA recursive_triggers=ON;
|
||||
CREATE TABLE t2(
|
||||
a INTEGER PRIMARY KEY ON CONFLICT REPLACE,
|
||||
b INT UNIQUE ON CONFLICT FAIL,
|
||||
c INT UNIQUE ON CONFLICT ABORT
|
||||
);
|
||||
CREATE TRIGGER t_ad AFTER DELETE ON t2 BEGIN
|
||||
INSERT INTO t2 VALUES(99,30,999);
|
||||
END;
|
||||
INSERT INTO t2 VALUES(1,10,100),(2,20,200);
|
||||
SELECT * FROM t2 ORDER BY a;
|
||||
} {1 10 100 2 20 200}
|
||||
do_catchsql_test 2.2 {
|
||||
INSERT INTO t2 VALUES(4,40,400),(1,30,300),(5,50,500)
|
||||
ON CONFLICT(c) DO NOTHING;
|
||||
} {1 {UNIQUE constraint failed: t2.b}}
|
||||
do_execsql_test 2.3 {
|
||||
PRAGMA integrity_check;
|
||||
} ok
|
||||
do_execsql_test 2.4 {
|
||||
SELECT * FROM t2 ORDER BY a;
|
||||
} {1 10 100 2 20 200}
|
||||
|
||||
# This is a slightly simpler version of the test above. Before
|
||||
# the bug was fixed, this would:
|
||||
#
|
||||
# 1) Checks there are no instances of 'HELLO' in the index on t1(b),
|
||||
# 2) Deletes the row from t1 as a result of the REPLACE on the PK,
|
||||
# 3) Fires the trigger, inserting ('HELLO', 200) into index t1(b).
|
||||
# 4) Finishes the insert without rechecking t1(b), inserting
|
||||
# ('HELLO', 100). Corruption.
|
||||
#
|
||||
reset_db
|
||||
do_execsql_test 3.1 {
|
||||
PRAGMA recursive_triggers = ON;
|
||||
CREATE TABLE t1(
|
||||
a PRIMARY KEY ON CONFLICT REPLACE,
|
||||
b UNIQUE
|
||||
);
|
||||
INSERT INTO t1 VALUES(100, 'abcde');
|
||||
CREATE TRIGGER tr1 AFTER DELETE ON t1 BEGIN
|
||||
INSERT INTO t1 VALUES(200, 'HELLO');
|
||||
END;
|
||||
}
|
||||
do_catchsql_test 3.2 {
|
||||
INSERT INTO t1 VALUES(100, 'HELLO');
|
||||
} {1 {UNIQUE constraint failed: t1.b}}
|
||||
do_execsql_test 3.3 {
|
||||
PRAGMA integrity_check;
|
||||
SELECT * FROM t1 ORDER BY +a;
|
||||
} {ok 100 abcde}
|
||||
|
||||
finish_test
|
||||
@@ -13,47 +13,47 @@
|
||||
|
||||
set testdir [file dirname $argv0]
|
||||
source $testdir/tester.tcl
|
||||
set testprefix zipfile
|
||||
set testprefix upsert1
|
||||
|
||||
do_execsql_test upsert1-100 {
|
||||
do_execsql_test 100 {
|
||||
CREATE TABLE t1(a INTEGER PRIMARY KEY, b TEXT, c DEFAULT 0);
|
||||
CREATE UNIQUE INDEX t1x1 ON t1(b);
|
||||
INSERT INTO t1(a,b) VALUES(1,2) ON CONFLICT DO NOTHING;
|
||||
INSERT INTO t1(a,b) VALUES(1,99),(99,2) ON CONFLICT DO NOTHING;
|
||||
SELECT * FROM t1;
|
||||
} {1 2 0}
|
||||
do_execsql_test upsert1-101 {
|
||||
do_execsql_test 101 {
|
||||
DELETE FROM t1;
|
||||
INSERT INTO t1(a,b) VALUES(2,3) ON CONFLICT(a) DO NOTHING;
|
||||
INSERT INTO t1(a,b) VALUES(2,99) ON CONFLICT(a) DO NOTHING;
|
||||
SELECT * FROM t1;
|
||||
} {2 3 0}
|
||||
do_execsql_test upsert1-102 {
|
||||
do_execsql_test 102 {
|
||||
DELETE FROM t1;
|
||||
INSERT INTO t1(a,b) VALUES(3,4) ON CONFLICT(b) DO NOTHING;
|
||||
INSERT INTO t1(a,b) VALUES(99,4) ON CONFLICT(b) DO NOTHING;
|
||||
SELECT * FROM t1;
|
||||
} {3 4 0}
|
||||
do_catchsql_test upsert1-110 {
|
||||
do_catchsql_test 110 {
|
||||
INSERT INTO t1(a,b) VALUES(5,6) ON CONFLICT(x) DO NOTHING;
|
||||
SELECT * FROM t1;
|
||||
} {1 {no such column: x}}
|
||||
do_catchsql_test upsert1-120 {
|
||||
do_catchsql_test 120 {
|
||||
INSERT INTO t1(a,b) VALUES(5,6) ON CONFLICT(c) DO NOTHING;
|
||||
SELECT * FROM t1;
|
||||
} {1 {ON CONFLICT clause does not match any PRIMARY KEY or UNIQUE constraint}}
|
||||
breakpoint
|
||||
do_catchsql_test upsert1-130 {
|
||||
do_catchsql_test 130 {
|
||||
INSERT INTO t1(a,b) VALUES(5,6) ON CONFLICT(b COLLATE nocase) DO NOTHING;
|
||||
SELECT * FROM t1;
|
||||
} {1 {ON CONFLICT clause does not match any PRIMARY KEY or UNIQUE constraint}}
|
||||
do_execsql_test upsert1-140 {
|
||||
do_execsql_test 140 {
|
||||
DELETE FROM t1;
|
||||
INSERT INTO t1(a,b) VALUES(5,6) ON CONFLICT(b COLLATE binary) DO NOTHING;
|
||||
SELECT * FROM t1;
|
||||
} {5 6 0}
|
||||
|
||||
do_catchsql_test upsert1-200 {
|
||||
do_catchsql_test 200 {
|
||||
DROP TABLE t1;
|
||||
CREATE TABLE t1(a INTEGER PRIMARY KEY, b INT, c DEFAULT 0);
|
||||
CREATE UNIQUE INDEX t1x1 ON t1(a+b);
|
||||
@@ -61,28 +61,28 @@ do_catchsql_test upsert1-200 {
|
||||
INSERT INTO t1(a,b) VALUES(8,7),(9,6) ON CONFLICT(a+b) DO NOTHING;
|
||||
SELECT * FROM t1;
|
||||
} {0 {7 8 0}}
|
||||
do_catchsql_test upsert1-201 {
|
||||
do_catchsql_test 201 {
|
||||
INSERT INTO t1(a,b) VALUES(8,7),(9,6) ON CONFLICT(a) DO NOTHING;
|
||||
} {1 {UNIQUE constraint failed: index 't1x1'}}
|
||||
do_catchsql_test upsert1-210 {
|
||||
do_catchsql_test 210 {
|
||||
DELETE FROM t1;
|
||||
INSERT INTO t1(a,b) VALUES(9,10) ON CONFLICT(a+(+b)) DO NOTHING;
|
||||
SELECT * FROM t1;
|
||||
} {1 {ON CONFLICT clause does not match any PRIMARY KEY or UNIQUE constraint}}
|
||||
|
||||
do_catchsql_test upsert1-300 {
|
||||
do_catchsql_test 300 {
|
||||
DROP INDEX t1x1;
|
||||
DELETE FROM t1;
|
||||
CREATE UNIQUE INDEX t1x1 ON t1(b) WHERE b>10;
|
||||
INSERT INTO t1(a,b) VALUES(1,2),(3,2) ON CONFLICT(b) DO NOTHING;
|
||||
SELECT * FROM t1;
|
||||
} {1 {ON CONFLICT clause does not match any PRIMARY KEY or UNIQUE constraint}}
|
||||
do_catchsql_test upsert1-310 {
|
||||
do_catchsql_test 310 {
|
||||
DELETE FROM t1;
|
||||
INSERT INTO t1(a,b) VALUES(1,2),(3,2) ON CONFLICT(b) WHERE b!=10 DO NOTHING;
|
||||
SELECT * FROM t1;
|
||||
} {1 {ON CONFLICT clause does not match any PRIMARY KEY or UNIQUE constraint}}
|
||||
do_execsql_test upsert1-320 {
|
||||
do_execsql_test 320 {
|
||||
DELETE FROM t1;
|
||||
INSERT INTO t1(a,b) VALUES(1,2),(3,2),(4,20),(5,20)
|
||||
ON CONFLICT(b) WHERE b>10 DO NOTHING;
|
||||
@@ -90,7 +90,7 @@ do_execsql_test upsert1-320 {
|
||||
} {1 2 0 x 3 2 0 x 4 20 0 x}
|
||||
|
||||
# Upsert works with count_changes=on;
|
||||
do_execsql_test upsert1-400 {
|
||||
do_execsql_test 400 {
|
||||
DROP TABLE IF EXISTS t2;
|
||||
CREATE TABLE t2(a TEXT UNIQUE, b INT DEFAULT 1);
|
||||
INSERT INTO t2(a) VALUES('one'),('two'),('three');
|
||||
@@ -98,13 +98,13 @@ do_execsql_test upsert1-400 {
|
||||
INSERT INTO t2(a) VALUES('one'),('one'),('three'),('four')
|
||||
ON CONFLICT(a) DO UPDATE SET b=b+1;
|
||||
} {1}
|
||||
do_execsql_test upsert1-410 {
|
||||
do_execsql_test 410 {
|
||||
PRAGMA count_changes=OFF;
|
||||
SELECT a, b FROM t2 ORDER BY a;
|
||||
} {four 1 one 3 three 2 two 1}
|
||||
|
||||
# Problem found by AFL prior to any release
|
||||
do_execsql_test upsert1-500 {
|
||||
do_execsql_test 500 {
|
||||
DROP TABLE t1;
|
||||
CREATE TABLE t1(x INTEGER PRIMARY KEY, y INT UNIQUE);
|
||||
INSERT INTO t1(x,y) SELECT 1,2 WHERE true
|
||||
@@ -116,13 +116,13 @@ do_execsql_test upsert1-500 {
|
||||
# Ticket https://sqlite.org/src/tktview/79cad5e4b2e219dd197242e9e5f4
|
||||
# UPSERT leads to a corrupt index.
|
||||
#
|
||||
do_execsql_test upsert1-600 {
|
||||
do_execsql_test 600 {
|
||||
DROP TABLE t1;
|
||||
CREATE TABLE t1(b UNIQUE, a INT PRIMARY KEY) WITHOUT ROWID;
|
||||
INSERT OR IGNORE INTO t1(a) VALUES('1') ON CONFLICT(a) DO NOTHING;
|
||||
PRAGMA integrity_check;
|
||||
} {ok}
|
||||
do_execsql_test upsert1-610 {
|
||||
do_execsql_test 610 {
|
||||
DELETE FROM t1;
|
||||
INSERT OR IGNORE INTO t1(a) VALUES('1'),(1) ON CONFLICT(a) DO NOTHING;
|
||||
PRAGMA integrity_check;
|
||||
@@ -135,7 +135,7 @@ do_execsql_test upsert1-610 {
|
||||
# the other constraints pass or fail. In other words, the UPSERT constraint
|
||||
# should be tested first.
|
||||
#
|
||||
do_execsql_test upsert1-700 {
|
||||
do_execsql_test 700 {
|
||||
DROP TABLE t1;
|
||||
CREATE TABLE t1(a INTEGER PRIMARY KEY, b INT, c INT, d INT, e INT);
|
||||
CREATE UNIQUE INDEX t1b ON t1(b);
|
||||
@@ -145,21 +145,21 @@ do_execsql_test upsert1-700 {
|
||||
ON CONFLICT(e) DO UPDATE SET c=excluded.c;
|
||||
SELECT * FROM t1;
|
||||
} {1 2 33 4 5}
|
||||
do_execsql_test upsert1-710 {
|
||||
do_execsql_test 710 {
|
||||
DELETE FROM t1;
|
||||
INSERT INTO t1(a,b,c,d,e) VALUES(1,2,3,4,5);
|
||||
INSERT INTO t1(a,b,c,d,e) VALUES(1,2,33,44,5)
|
||||
ON CONFLICT(a) DO UPDATE SET c=excluded.c;
|
||||
SELECT * FROM t1;
|
||||
} {1 2 33 4 5}
|
||||
do_execsql_test upsert1-720 {
|
||||
do_execsql_test 720 {
|
||||
DELETE FROM t1;
|
||||
INSERT INTO t1(a,b,c,d,e) VALUES(1,2,3,4,5);
|
||||
INSERT INTO t1(a,b,c,d,e) VALUES(1,2,33,44,5)
|
||||
ON CONFLICT(b) DO UPDATE SET c=excluded.c;
|
||||
SELECT * FROM t1;
|
||||
} {1 2 33 4 5}
|
||||
do_execsql_test upsert1-730 {
|
||||
do_execsql_test 730 {
|
||||
DROP TABLE t1;
|
||||
CREATE TABLE t1(a INT, b INT, c INT, d INT, e INT);
|
||||
CREATE UNIQUE INDEX t1a ON t1(a);
|
||||
@@ -170,21 +170,21 @@ do_execsql_test upsert1-730 {
|
||||
ON CONFLICT(e) DO UPDATE SET c=excluded.c;
|
||||
SELECT * FROM t1;
|
||||
} {1 2 33 4 5}
|
||||
do_execsql_test upsert1-740 {
|
||||
do_execsql_test 740 {
|
||||
DELETE FROM t1;
|
||||
INSERT INTO t1(a,b,c,d,e) VALUES(1,2,3,4,5);
|
||||
INSERT INTO t1(a,b,c,d,e) VALUES(1,2,33,44,5)
|
||||
ON CONFLICT(a) DO UPDATE SET c=excluded.c;
|
||||
SELECT * FROM t1;
|
||||
} {1 2 33 4 5}
|
||||
do_execsql_test upsert1-750 {
|
||||
do_execsql_test 750 {
|
||||
DELETE FROM t1;
|
||||
INSERT INTO t1(a,b,c,d,e) VALUES(1,2,3,4,5);
|
||||
INSERT INTO t1(a,b,c,d,e) VALUES(1,2,33,44,5)
|
||||
ON CONFLICT(b) DO UPDATE SET c=excluded.c;
|
||||
SELECT * FROM t1;
|
||||
} {1 2 33 4 5}
|
||||
do_execsql_test upsert1-760 {
|
||||
do_execsql_test 760 {
|
||||
DROP TABLE t1;
|
||||
CREATE TABLE t1(a INT PRIMARY KEY, b INT, c INT, d INT, e INT) WITHOUT ROWID;
|
||||
CREATE UNIQUE INDEX t1a ON t1(a);
|
||||
@@ -195,14 +195,14 @@ do_execsql_test upsert1-760 {
|
||||
ON CONFLICT(e) DO UPDATE SET c=excluded.c;
|
||||
SELECT * FROM t1;
|
||||
} {1 2 33 4 5}
|
||||
do_execsql_test upsert1-770 {
|
||||
do_execsql_test 770 {
|
||||
DELETE FROM t1;
|
||||
INSERT INTO t1(a,b,c,d,e) VALUES(1,2,3,4,5);
|
||||
INSERT INTO t1(a,b,c,d,e) VALUES(1,2,33,44,5)
|
||||
ON CONFLICT(a) DO UPDATE SET c=excluded.c;
|
||||
SELECT * FROM t1;
|
||||
} {1 2 33 4 5}
|
||||
do_execsql_test upsert1-780 {
|
||||
do_execsql_test 780 {
|
||||
DELETE FROM t1;
|
||||
INSERT INTO t1(a,b,c,d,e) VALUES(1,2,3,4,5);
|
||||
INSERT INTO t1(a,b,c,d,e) VALUES(1,2,33,44,5)
|
||||
@@ -211,7 +211,7 @@ do_execsql_test upsert1-780 {
|
||||
} {1 2 33 4 5}
|
||||
|
||||
# 2019-08-30 ticket https://sqlite.org/src/info/5a3dba8104421320
|
||||
do_execsql_test upsert1-800 {
|
||||
do_execsql_test 800 {
|
||||
DROP TABLE IF EXISTS t0;
|
||||
CREATE TABLE t0(c0 REAL UNIQUE, c1);
|
||||
CREATE UNIQUE INDEX test800i0 ON t0(0 || c1);
|
||||
@@ -223,19 +223,19 @@ do_execsql_test upsert1-800 {
|
||||
|
||||
# 2019-12-06 gramfuzz find
|
||||
sqlite3 db :memory:
|
||||
do_execsql_test upsert1-900 {
|
||||
do_execsql_test 900 {
|
||||
CREATE VIEW t1(a) AS SELECT 1;
|
||||
CREATE TRIGGER t1r1 INSTEAD OF INSERT ON t1 BEGIN
|
||||
SELECT 2;
|
||||
END;
|
||||
}
|
||||
do_catchsql_test upsert1-910 {
|
||||
do_catchsql_test 910 {
|
||||
INSERT INTO t1 VALUES(3) ON CONFLICT(x) DO NOTHING;
|
||||
} {1 {cannot UPSERT a view}}
|
||||
|
||||
# 2019-12-26 ticket 7c13db5c3bf74001
|
||||
reset_db
|
||||
do_catchsql_test upsert1-1000 {
|
||||
do_catchsql_test 1000 {
|
||||
CREATE TABLE t0(c0 PRIMARY KEY, c1, c2 UNIQUE) WITHOUT ROWID;
|
||||
INSERT OR FAIL INTO t0(c2) VALUES (0), (NULL)
|
||||
ON CONFLICT(c2) DO UPDATE SET c1 = c0;
|
||||
@@ -248,7 +248,7 @@ do_catchsql_test upsert1-1000 {
|
||||
# in a NULL pointer dereference.
|
||||
#
|
||||
reset_db
|
||||
do_execsql_test upsert1-1100 {
|
||||
do_execsql_test 1100 {
|
||||
CREATE TABLE t1(a INTEGER PRIMARY KEY ON CONFLICT REPLACE, b UNIQUE);
|
||||
INSERT INTO t1(b) VALUES(22);
|
||||
INSERT INTO t1 VALUES(2,22) ON CONFLICT (b) DO NOTHING;
|
||||
@@ -259,12 +259,12 @@ do_execsql_test upsert1-1100 {
|
||||
# Bound parameters in the ON CONFLICT clause of an UPSERT.
|
||||
#
|
||||
reset_db
|
||||
do_execsql_test upsert1-1200 {
|
||||
do_execsql_test 1200 {
|
||||
CREATE TABLE t1(a INT, b INT);
|
||||
CREATE UNIQUE INDEX t1x ON t1(b+3);
|
||||
}
|
||||
sqlite3_db_config db ENABLE_QPSG 1
|
||||
do_catchsql_test upsert1-1210 {
|
||||
do_catchsql_test 1210 {
|
||||
INSERT INTO t1(a,b) VALUES(1,2) ON CONFLICT(b+?1) DO NOTHING;
|
||||
} {1 {ON CONFLICT clause does not match any PRIMARY KEY or UNIQUE constraint}}
|
||||
|
||||
@@ -273,7 +273,7 @@ do_catchsql_test upsert1-1210 {
|
||||
# an upsert.
|
||||
#
|
||||
reset_db
|
||||
do_execsql_test upsert1-1300 {
|
||||
do_execsql_test 1300 {
|
||||
CREATE TABLE t1(x INT, y TEXT);
|
||||
INSERT INTO t1 VALUES
|
||||
(11, printf('%.9000c','a')),
|
||||
@@ -292,146 +292,4 @@ 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 t0(
|
||||
a INTEGER PRIMARY KEY ON CONFLICT REPLACE,
|
||||
b INT UNIQUE ON CONFLICT FAIL,
|
||||
c INT UNIQUE ON CONFLICT ABORT
|
||||
);
|
||||
INSERT INTO t0 VALUES (1, 10, 100),(2, 20, 200);
|
||||
}
|
||||
do_catchsql_test upsert1-1401 {
|
||||
INSERT INTO t0 VALUES (1, 20, 300) ON CONFLICT(c) DO NOTHING;
|
||||
} {1 {UNIQUE constraint failed: t0.b}}
|
||||
do_execsql_test upsert1-1402 {
|
||||
PRAGMA integrity_check;
|
||||
} {ok}
|
||||
do_execsql_test upsert1-1403 {
|
||||
SELECT * FROM t0 ORDER BY a;
|
||||
} {1 10 100 2 20 200}
|
||||
do_execsql_test upsert1-1404 {
|
||||
DROP TABLE t0;
|
||||
CREATE TABLE t0(
|
||||
a INTEGER PRIMARY KEY ON CONFLICT REPLACE,
|
||||
b INT UNIQUE ON CONFLICT IGNORE,
|
||||
c INT UNIQUE ON CONFLICT ABORT
|
||||
);
|
||||
INSERT INTO t0 VALUES (1, 10, 100),(2, 20, 200);
|
||||
}
|
||||
do_catchsql_test upsert1-1405 {
|
||||
INSERT INTO t0 VALUES (1, 20, 300) ON CONFLICT(c) DO NOTHING;
|
||||
} {0 {}}
|
||||
do_execsql_test upsert1-1406 {
|
||||
PRAGMA integrity_check;
|
||||
} {ok}
|
||||
do_execsql_test upsert1-1407 {
|
||||
SELECT * FROM t0 ORDER BY a;
|
||||
} {1 10 100 2 20 200}
|
||||
do_execsql_test upsert1-1408 {
|
||||
DROP TABLE t0;
|
||||
CREATE TABLE t0(
|
||||
a INTEGER PRIMARY KEY ON CONFLICT REPLACE,
|
||||
b INT UNIQUE ON CONFLICT FAIL,
|
||||
c INT UNIQUE ON CONFLICT ABORT
|
||||
);
|
||||
INSERT INTO t0 VALUES (1, 10, 100),(2, 20, 200);
|
||||
}
|
||||
do_catchsql_test upsert1-1409 {
|
||||
INSERT INTO t0 VALUES (1, 20, 300) ON CONFLICT(c) DO NOTHING;
|
||||
} {1 {UNIQUE constraint failed: t0.b}}
|
||||
do_execsql_test upsert1-1490 {
|
||||
PRAGMA integrity_check;
|
||||
} {ok}
|
||||
do_execsql_test upsert1-1410 {
|
||||
SELECT * FROM t0 ORDER BY a;
|
||||
} {1 10 100 2 20 200}
|
||||
do_execsql_test upsert1-1411 {
|
||||
DROP TABLE t0;
|
||||
CREATE TABLE t1(
|
||||
a INTEGER PRIMARY KEY,
|
||||
b UNIQUE ON CONFLICT FAIL,
|
||||
c UNIQUE
|
||||
);
|
||||
INSERT INTO t1 VALUES(1, 1, 1);
|
||||
}
|
||||
do_catchsql_test upsert1-1412 {
|
||||
-- Inserts 0 rows, because hitting the constraint on (b) does ABORT:
|
||||
INSERT INTO t1 VALUES(3, 3, 3), (2, 1, 2) ON CONFLICT(c) DO NOTHING;
|
||||
} {1 {UNIQUE constraint failed: t1.b}}
|
||||
do_execsql_test upsert1-1413 {
|
||||
SELECT * FROM t1 ORDER BY a;
|
||||
} {1 1 1 3 3 3}
|
||||
do_catchsql_test upsert1-1414 {
|
||||
-- Inserts 1 row, because hitting the constraint on (b) does FAIL:
|
||||
DELETE FROM t1 WHERE a=3;
|
||||
INSERT INTO t1 VALUES(3, 3, 3), (2, 1, 2);
|
||||
} {1 {UNIQUE constraint failed: t1.b}}
|
||||
do_execsql_test upsert1-1415 {
|
||||
SELECT * FROM t1 ORDER BY a;
|
||||
} {1 1 1 3 3 3}
|
||||
do_execsql_test upsert1-1416 {
|
||||
PRAGMA integrity_check;
|
||||
} ok
|
||||
# Counter-example to the fix at check-in 2026-07-17T16:26:56.257Z
|
||||
# provided by Pavan Nambi at forum post 2026-07-18T03:35:48Z
|
||||
do_execsql_test upsert1-1417 {
|
||||
DROP TABLE t1;
|
||||
PRAGMA recursive_triggers=ON;
|
||||
CREATE TABLE t2(
|
||||
a INTEGER PRIMARY KEY ON CONFLICT REPLACE,
|
||||
b INT UNIQUE ON CONFLICT FAIL,
|
||||
c INT UNIQUE ON CONFLICT ABORT
|
||||
);
|
||||
CREATE TRIGGER t_ad AFTER DELETE ON t2 BEGIN
|
||||
INSERT INTO t2 VALUES(99,30,999);
|
||||
END;
|
||||
INSERT INTO t2 VALUES(1,10,100),(2,20,200);
|
||||
SELECT * FROM t2 ORDER BY a;
|
||||
} {1 10 100 2 20 200}
|
||||
do_catchsql_test upsert1-1418 {
|
||||
INSERT INTO t2 VALUES(4,40,400),(1,30,300),(5,50,500)
|
||||
ON CONFLICT(c) DO NOTHING;
|
||||
} {1 {UNIQUE constraint failed: t2.b}}
|
||||
do_execsql_test upsert1-1419 {
|
||||
PRAGMA integrity_check;
|
||||
} ok
|
||||
do_execsql_test upsert1-1420 {
|
||||
SELECT * FROM t2 ORDER BY a;
|
||||
} {1 10 100 2 20 200}
|
||||
|
||||
# This is a slightly simpler version of the test above (1417-1420). Before
|
||||
# the bug was fixed, this would:
|
||||
#
|
||||
# 1) Checks there are no instances of 'HELLO' in the index on t1(b),
|
||||
# 2) Deletes the row from t1 as a result of the REPLACE on the PK,
|
||||
# 3) Fires the trigger, inserting ('HELLO', 200) into index t1(b).
|
||||
# 4) Finishes the insert without rechecking t1(b), inserting
|
||||
# ('HELLO', 100). Corruption.
|
||||
#
|
||||
reset_db
|
||||
do_execsql_test upsert-1421 {
|
||||
PRAGMA recursive_triggers = ON;
|
||||
CREATE TABLE t1(
|
||||
a PRIMARY KEY ON CONFLICT REPLACE,
|
||||
b UNIQUE
|
||||
);
|
||||
INSERT INTO t1 VALUES(100, 'abcde');
|
||||
CREATE TRIGGER tr1 AFTER DELETE ON t1 BEGIN
|
||||
INSERT INTO t1 VALUES(200, 'HELLO');
|
||||
END;
|
||||
}
|
||||
do_catchsql_test upsert-1422 {
|
||||
INSERT INTO t1 VALUES(100, 'HELLO');
|
||||
} {1 {UNIQUE constraint failed: t1.b}}
|
||||
do_execsql_test upsert-1423 {
|
||||
PRAGMA integrity_check;
|
||||
SELECT * FROM t1 ORDER BY +a;
|
||||
} {ok 100 abcde}
|
||||
|
||||
finish_test
|
||||
|
||||
Reference in New Issue
Block a user