mirror of
https://github.com/sqlite/sqlite.git
synced 2025-08-05 15:55:57 +03:00
Fix conflict handling for the case when the rowid uses REPLACE but other
unique constraints use FAIL or IGNORE. FossilOrigin-Name: 573cc27427af297185f11aac8dce88ca31f471ca
This commit is contained in:
13
manifest
13
manifest
@@ -1,5 +1,5 @@
|
|||||||
C Fix\sa\sbug\sin\ssecondary\sindex\sinitialization\swhen\sthe\ssecondary\sindex\sis\na\ssuperset\sof\sthe\sPRIMARY\sKEY\sfor\sa\sWITHOUT\sROWID\stable.
|
C Fix\sconflict\shandling\sfor\sthe\scase\swhen\sthe\srowid\suses\sREPLACE\sbut\sother\nunique\sconstraints\suse\sFAIL\sor\sIGNORE.
|
||||||
D 2013-11-05T17:30:04.337
|
D 2013-11-05T19:41:32.450
|
||||||
F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f
|
F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f
|
||||||
F Makefile.in 0522b53cdc1fcfc18f3a98e0246add129136c654
|
F Makefile.in 0522b53cdc1fcfc18f3a98e0246add129136c654
|
||||||
F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23
|
F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23
|
||||||
@@ -182,7 +182,7 @@ F src/global.c 5caf4deab621abb45b4c607aad1bd21c20aac759
|
|||||||
F src/hash.c ac3470bbf1ca4ae4e306a8ecb0fdf1731810ffe4
|
F src/hash.c ac3470bbf1ca4ae4e306a8ecb0fdf1731810ffe4
|
||||||
F src/hash.h 8890a25af81fb85a9ad7790d32eedab4b994da22
|
F src/hash.h 8890a25af81fb85a9ad7790d32eedab4b994da22
|
||||||
F src/hwtime.h d32741c8f4df852c7d959236615444e2b1063b08
|
F src/hwtime.h d32741c8f4df852c7d959236615444e2b1063b08
|
||||||
F src/insert.c 7559252147d3aad55951ecd5fadf8350729cb901
|
F src/insert.c 66c8c99920cac74abba70cb7eecc5114e02ed3ea
|
||||||
F src/journal.c b4124532212b6952f42eb2c12fa3c25701d8ba8d
|
F src/journal.c b4124532212b6952f42eb2c12fa3c25701d8ba8d
|
||||||
F src/legacy.c 0df0b1550b9cc1f58229644735e317ac89131f12
|
F src/legacy.c 0df0b1550b9cc1f58229644735e317ac89131f12
|
||||||
F src/lempar.c cdf0a000315332fc9b50b62f3b5e22e080a0952b
|
F src/lempar.c cdf0a000315332fc9b50b62f3b5e22e080a0952b
|
||||||
@@ -386,6 +386,7 @@ F test/colmeta.test 087c42997754b8c648819832241daf724f813322
|
|||||||
F test/colname.test 08948a4809d22817e0e5de89c7c0a8bd90cb551b
|
F test/colname.test 08948a4809d22817e0e5de89c7c0a8bd90cb551b
|
||||||
F test/conflict.test 841bcf7cabbfca39c577eb8411ea8601843b46a8
|
F test/conflict.test 841bcf7cabbfca39c577eb8411ea8601843b46a8
|
||||||
F test/conflict2.test 5d162ecbbde37f165de1992904dcbbed9fc7c012
|
F test/conflict2.test 5d162ecbbde37f165de1992904dcbbed9fc7c012
|
||||||
|
F test/conflict3.test dec0634c0f31dec9a4b01c63063e939f0cd21b6b
|
||||||
F test/contrib01.test 2a1cbc0f2f48955d7d073f725765da6fbceda6b4
|
F test/contrib01.test 2a1cbc0f2f48955d7d073f725765da6fbceda6b4
|
||||||
F test/corrupt.test 4aabd06cff3fe759e3e658bcc17b71789710665e
|
F test/corrupt.test 4aabd06cff3fe759e3e658bcc17b71789710665e
|
||||||
F test/corrupt2.test 9c0ab4becd50e9050bc1ebb8675456a4e5587bf0
|
F test/corrupt2.test 9c0ab4becd50e9050bc1ebb8675456a4e5587bf0
|
||||||
@@ -1133,7 +1134,7 @@ F tool/vdbe-compress.tcl f12c884766bd14277f4fcedcae07078011717381
|
|||||||
F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4
|
F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4
|
||||||
F tool/warnings.sh d1a6de74685f360ab718efda6265994b99bbea01
|
F tool/warnings.sh d1a6de74685f360ab718efda6265994b99bbea01
|
||||||
F tool/win/sqlite.vsix 030f3eeaf2cb811a3692ab9c14d021a75ce41fff
|
F tool/win/sqlite.vsix 030f3eeaf2cb811a3692ab9c14d021a75ce41fff
|
||||||
P 4b41d989e894b9214a9b973228ef8446356f9fbb
|
P 52a3d885192c5d31f956c5ee17e29e2d1f3d5c9f
|
||||||
R a05ce9adf9842de08a1d6f032363e2df
|
R 549795ebe9589f04f40d14f040b65091
|
||||||
U drh
|
U drh
|
||||||
Z 7d34ccd67e34b00bfe85d5ff3fefd3e0
|
Z c7bda7b48cde94ee0d99c42dc49f8047
|
||||||
|
@@ -1 +1 @@
|
|||||||
52a3d885192c5d31f956c5ee17e29e2d1f3d5c9f
|
573cc27427af297185f11aac8dce88ca31f471ca
|
33
src/insert.c
33
src/insert.c
@@ -1229,7 +1229,9 @@ void sqlite3GenerateConstraintChecks(
|
|||||||
int j1; /* Addresss of jump instruction */
|
int j1; /* Addresss of jump instruction */
|
||||||
int seenReplace = 0; /* True if REPLACE is used to resolve INT PK conflict */
|
int seenReplace = 0; /* True if REPLACE is used to resolve INT PK conflict */
|
||||||
int nPkField; /* Number of fields in PRIMARY KEY. 1 for ROWID tables */
|
int nPkField; /* Number of fields in PRIMARY KEY. 1 for ROWID tables */
|
||||||
u8 isUpdate;
|
int ipkTop = 0; /* Top of the rowid change constraint check */
|
||||||
|
int ipkBottom = 0; /* Bottom of the rowid change constraint check */
|
||||||
|
u8 isUpdate; /* True if this is an UPDATE operation */
|
||||||
|
|
||||||
isUpdate = regOldData!=0;
|
isUpdate = regOldData!=0;
|
||||||
db = pParse->db;
|
db = pParse->db;
|
||||||
@@ -1345,6 +1347,20 @@ void sqlite3GenerateConstraintChecks(
|
|||||||
sqlite3VdbeAddOp3(v, OP_Eq, regNewData, addrRowidOk, regOldData);
|
sqlite3VdbeAddOp3(v, OP_Eq, regNewData, addrRowidOk, regOldData);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* If the response to a rowid conflict is REPLACE but the response
|
||||||
|
** to some other UNIQUE constraint is FAIL or IGNORE, then we need
|
||||||
|
** to defer the running of the rowid conflict checking until after
|
||||||
|
** the UNIQUE constraints have run.
|
||||||
|
*/
|
||||||
|
if( onError==OE_Replace && overrideError!=OE_Replace ){
|
||||||
|
for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){
|
||||||
|
if( pIdx->onError==OE_Ignore || pIdx->onError==OE_Fail ){
|
||||||
|
ipkTop = sqlite3VdbeAddOp0(v, OP_Goto);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* Check to see if the new rowid already exists in the table. Skip
|
/* Check to see if the new rowid already exists in the table. Skip
|
||||||
** the following conflict logic if it does not. */
|
** the following conflict logic if it does not. */
|
||||||
sqlite3VdbeAddOp3(v, OP_NotExists, iDataCur, addrRowidOk, regNewData);
|
sqlite3VdbeAddOp3(v, OP_NotExists, iDataCur, addrRowidOk, regNewData);
|
||||||
@@ -1400,12 +1416,16 @@ void sqlite3GenerateConstraintChecks(
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case OE_Ignore: {
|
case OE_Ignore: {
|
||||||
assert( seenReplace==0 );
|
/*assert( seenReplace==0 );*/
|
||||||
sqlite3VdbeAddOp2(v, OP_Goto, 0, ignoreDest);
|
sqlite3VdbeAddOp2(v, OP_Goto, 0, ignoreDest);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
sqlite3VdbeResolveLabel(v, addrRowidOk);
|
sqlite3VdbeResolveLabel(v, addrRowidOk);
|
||||||
|
if( ipkTop ){
|
||||||
|
ipkBottom = sqlite3VdbeAddOp0(v, OP_Goto);
|
||||||
|
sqlite3VdbeJumpHere(v, ipkTop);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Test all UNIQUE constraints by creating entries for each UNIQUE
|
/* Test all UNIQUE constraints by creating entries for each UNIQUE
|
||||||
@@ -1475,10 +1495,6 @@ void sqlite3GenerateConstraintChecks(
|
|||||||
}else if( onError==OE_Default ){
|
}else if( onError==OE_Default ){
|
||||||
onError = OE_Abort;
|
onError = OE_Abort;
|
||||||
}
|
}
|
||||||
if( seenReplace ){
|
|
||||||
if( onError==OE_Ignore ) onError = OE_Replace;
|
|
||||||
else if( onError==OE_Fail ) onError = OE_Abort;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Check to see if the new index entry will be unique */
|
/* Check to see if the new index entry will be unique */
|
||||||
regR = sqlite3GetTempRange(pParse, nPkField);
|
regR = sqlite3GetTempRange(pParse, nPkField);
|
||||||
@@ -1544,7 +1560,6 @@ void sqlite3GenerateConstraintChecks(
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case OE_Ignore: {
|
case OE_Ignore: {
|
||||||
assert( seenReplace==0 );
|
|
||||||
sqlite3VdbeAddOp2(v, OP_Goto, 0, ignoreDest);
|
sqlite3VdbeAddOp2(v, OP_Goto, 0, ignoreDest);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -1564,6 +1579,10 @@ void sqlite3GenerateConstraintChecks(
|
|||||||
sqlite3VdbeResolveLabel(v, addrUniqueOk);
|
sqlite3VdbeResolveLabel(v, addrUniqueOk);
|
||||||
sqlite3ReleaseTempRange(pParse, regR, nPkField);
|
sqlite3ReleaseTempRange(pParse, regR, nPkField);
|
||||||
}
|
}
|
||||||
|
if( ipkTop ){
|
||||||
|
sqlite3VdbeAddOp2(v, OP_Goto, 0, ipkTop+1);
|
||||||
|
sqlite3VdbeJumpHere(v, ipkBottom);
|
||||||
|
}
|
||||||
|
|
||||||
if( pbMayReplace ){
|
if( pbMayReplace ){
|
||||||
*pbMayReplace = seenReplace;
|
*pbMayReplace = seenReplace;
|
||||||
|
356
test/conflict3.test
Normal file
356
test/conflict3.test
Normal file
@@ -0,0 +1,356 @@
|
|||||||
|
# 2013-11-05
|
||||||
|
#
|
||||||
|
# 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.
|
||||||
|
#
|
||||||
|
#***********************************************************************
|
||||||
|
# This file implements regression tests for SQLite library.
|
||||||
|
#
|
||||||
|
# This file implements tests for the conflict resolution extension
|
||||||
|
# to SQLite.
|
||||||
|
#
|
||||||
|
# This file focuses on making sure that combinations of REPLACE,
|
||||||
|
# IGNORE, and FAIL conflict resolution play well together.
|
||||||
|
#
|
||||||
|
|
||||||
|
set testdir [file dirname $argv0]
|
||||||
|
source $testdir/tester.tcl
|
||||||
|
|
||||||
|
ifcapable !conflict {
|
||||||
|
finish_test
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
do_execsql_test conflict-1.1 {
|
||||||
|
CREATE TABLE t1(
|
||||||
|
a INTEGER PRIMARY KEY ON CONFLICT REPLACE,
|
||||||
|
b UNIQUE ON CONFLICT IGNORE,
|
||||||
|
c UNIQUE ON CONFLICT FAIL
|
||||||
|
);
|
||||||
|
INSERT INTO t1(a,b,c) VALUES(1,2,3), (2,3,4);
|
||||||
|
SELECT a,b,c FROM t1 ORDER BY a;
|
||||||
|
} {1 2 3 2 3 4}
|
||||||
|
|
||||||
|
# Insert a row that conflicts on column B. The insert should be ignored.
|
||||||
|
#
|
||||||
|
do_execsql_test conflict-1.2 {
|
||||||
|
INSERT INTO t1(a,b,c) VALUES(3,2,5);
|
||||||
|
SELECT a,b,c FROM t1 ORDER BY a;
|
||||||
|
} {1 2 3 2 3 4}
|
||||||
|
|
||||||
|
# Insert two rows where the second conflicts on C. The first row show go
|
||||||
|
# and and then there should be a constraint error.
|
||||||
|
#
|
||||||
|
do_test conflict-1.3 {
|
||||||
|
catchsql {INSERT INTO t1(a,b,c) VALUES(4,5,6), (5,6,4);}
|
||||||
|
} {1 {UNIQUE constraint failed: t1.c}}
|
||||||
|
do_execsql_test conflict-1.4 {
|
||||||
|
SELECT a,b,c FROM t1 ORDER BY a;
|
||||||
|
} {1 2 3 2 3 4 4 5 6}
|
||||||
|
|
||||||
|
# Replete the tests above, but this time on a table non-INTEGER primary key.
|
||||||
|
#
|
||||||
|
do_execsql_test conflict-2.1 {
|
||||||
|
DROP TABLE t1;
|
||||||
|
CREATE TABLE t1(
|
||||||
|
a INT PRIMARY KEY ON CONFLICT REPLACE,
|
||||||
|
b UNIQUE ON CONFLICT IGNORE,
|
||||||
|
c UNIQUE ON CONFLICT FAIL
|
||||||
|
);
|
||||||
|
INSERT INTO t1(a,b,c) VALUES(1,2,3), (2,3,4);
|
||||||
|
SELECT a,b,c FROM t1 ORDER BY a;
|
||||||
|
} {1 2 3 2 3 4}
|
||||||
|
|
||||||
|
# Insert a row that conflicts on column B. The insert should be ignored.
|
||||||
|
#
|
||||||
|
do_execsql_test conflict-2.2 {
|
||||||
|
INSERT INTO t1(a,b,c) VALUES(3,2,5);
|
||||||
|
SELECT a,b,c FROM t1 ORDER BY a;
|
||||||
|
} {1 2 3 2 3 4}
|
||||||
|
|
||||||
|
# Insert two rows where the second conflicts on C. The first row show go
|
||||||
|
# and and then there should be a constraint error.
|
||||||
|
#
|
||||||
|
do_test conflict-2.3 {
|
||||||
|
catchsql {INSERT INTO t1(a,b,c) VALUES(4,5,6), (5,6,4);}
|
||||||
|
} {1 {UNIQUE constraint failed: t1.c}}
|
||||||
|
do_execsql_test conflict-2.4 {
|
||||||
|
SELECT a,b,c FROM t1 ORDER BY a;
|
||||||
|
} {1 2 3 2 3 4 4 5 6}
|
||||||
|
|
||||||
|
# Replete again on a WITHOUT ROWID table.
|
||||||
|
#
|
||||||
|
do_execsql_test conflict-3.1 {
|
||||||
|
DROP TABLE t1;
|
||||||
|
CREATE TABLE t1(
|
||||||
|
a INT PRIMARY KEY ON CONFLICT REPLACE,
|
||||||
|
b UNIQUE ON CONFLICT IGNORE,
|
||||||
|
c UNIQUE ON CONFLICT FAIL
|
||||||
|
) WITHOUT ROWID;
|
||||||
|
INSERT INTO t1(a,b,c) VALUES(1,2,3), (2,3,4);
|
||||||
|
SELECT a,b,c FROM t1 ORDER BY a;
|
||||||
|
} {1 2 3 2 3 4}
|
||||||
|
|
||||||
|
# Insert a row that conflicts on column B. The insert should be ignored.
|
||||||
|
#
|
||||||
|
do_execsql_test conflict-3.2 {
|
||||||
|
INSERT INTO t1(a,b,c) VALUES(3,2,5);
|
||||||
|
SELECT a,b,c FROM t1 ORDER BY a;
|
||||||
|
} {1 2 3 2 3 4}
|
||||||
|
|
||||||
|
# Insert two rows where the second conflicts on C. The first row show go
|
||||||
|
# and and then there should be a constraint error.
|
||||||
|
#
|
||||||
|
do_test conflict-3.3 {
|
||||||
|
catchsql {INSERT INTO t1(a,b,c) VALUES(4,5,6), (5,6,4);}
|
||||||
|
} {1 {UNIQUE constraint failed: t1.c}}
|
||||||
|
do_execsql_test conflict-3.4 {
|
||||||
|
SELECT a,b,c FROM t1 ORDER BY a;
|
||||||
|
} {1 2 3 2 3 4 4 5 6}
|
||||||
|
|
||||||
|
# Arrange the table rows in a different order and repeat.
|
||||||
|
#
|
||||||
|
do_execsql_test conflict-4.1 {
|
||||||
|
DROP TABLE t1;
|
||||||
|
CREATE TABLE t1(
|
||||||
|
b UNIQUE ON CONFLICT IGNORE,
|
||||||
|
c UNIQUE ON CONFLICT FAIL,
|
||||||
|
a INT PRIMARY KEY ON CONFLICT REPLACE
|
||||||
|
) WITHOUT ROWID;
|
||||||
|
INSERT INTO t1(a,b,c) VALUES(1,2,3), (2,3,4);
|
||||||
|
SELECT a,b,c FROM t1 ORDER BY a;
|
||||||
|
} {1 2 3 2 3 4}
|
||||||
|
|
||||||
|
# Insert a row that conflicts on column B. The insert should be ignored.
|
||||||
|
#
|
||||||
|
do_execsql_test conflict-4.2 {
|
||||||
|
INSERT INTO t1(a,b,c) VALUES(3,2,5);
|
||||||
|
SELECT a,b,c FROM t1 ORDER BY a;
|
||||||
|
} {1 2 3 2 3 4}
|
||||||
|
|
||||||
|
# Insert two rows where the second conflicts on C. The first row show go
|
||||||
|
# and and then there should be a constraint error.
|
||||||
|
#
|
||||||
|
do_test conflict-4.3 {
|
||||||
|
catchsql {INSERT INTO t1(a,b,c) VALUES(4,5,6), (5,6,4);}
|
||||||
|
} {1 {UNIQUE constraint failed: t1.c}}
|
||||||
|
do_execsql_test conflict-4.4 {
|
||||||
|
SELECT a,b,c FROM t1 ORDER BY a;
|
||||||
|
} {1 2 3 2 3 4 4 5 6}
|
||||||
|
|
||||||
|
# Arrange the table rows in a different order and repeat.
|
||||||
|
#
|
||||||
|
do_execsql_test conflict-5.1 {
|
||||||
|
DROP TABLE t1;
|
||||||
|
CREATE TABLE t1(
|
||||||
|
b UNIQUE ON CONFLICT IGNORE,
|
||||||
|
a INT PRIMARY KEY ON CONFLICT REPLACE,
|
||||||
|
c UNIQUE ON CONFLICT FAIL
|
||||||
|
);
|
||||||
|
INSERT INTO t1(a,b,c) VALUES(1,2,3), (2,3,4);
|
||||||
|
SELECT a,b,c FROM t1 ORDER BY a;
|
||||||
|
} {1 2 3 2 3 4}
|
||||||
|
|
||||||
|
# Insert a row that conflicts on column B. The insert should be ignored.
|
||||||
|
#
|
||||||
|
do_execsql_test conflict-5.2 {
|
||||||
|
INSERT INTO t1(a,b,c) VALUES(3,2,5);
|
||||||
|
SELECT a,b,c FROM t1 ORDER BY a;
|
||||||
|
} {1 2 3 2 3 4}
|
||||||
|
|
||||||
|
# Insert two rows where the second conflicts on C. The first row show go
|
||||||
|
# and and then there should be a constraint error.
|
||||||
|
#
|
||||||
|
do_test conflict-5.3 {
|
||||||
|
catchsql {INSERT INTO t1(a,b,c) VALUES(4,5,6), (5,6,4);}
|
||||||
|
} {1 {UNIQUE constraint failed: t1.c}}
|
||||||
|
do_execsql_test conflict-5.4 {
|
||||||
|
SELECT a,b,c FROM t1 ORDER BY a;
|
||||||
|
} {1 2 3 2 3 4 4 5 6}
|
||||||
|
|
||||||
|
# Arrange the table rows in a different order and repeat.
|
||||||
|
#
|
||||||
|
do_execsql_test conflict-6.1 {
|
||||||
|
DROP TABLE t1;
|
||||||
|
CREATE TABLE t1(
|
||||||
|
c UNIQUE ON CONFLICT FAIL,
|
||||||
|
a INT PRIMARY KEY ON CONFLICT REPLACE,
|
||||||
|
b UNIQUE ON CONFLICT IGNORE
|
||||||
|
);
|
||||||
|
INSERT INTO t1(a,b,c) VALUES(1,2,3), (2,3,4);
|
||||||
|
SELECT a,b,c FROM t1 ORDER BY a;
|
||||||
|
} {1 2 3 2 3 4}
|
||||||
|
|
||||||
|
# Insert a row that conflicts on column B. The insert should be ignored.
|
||||||
|
#
|
||||||
|
do_execsql_test conflict-6.2 {
|
||||||
|
INSERT INTO t1(a,b,c) VALUES(3,2,5);
|
||||||
|
SELECT a,b,c FROM t1 ORDER BY a;
|
||||||
|
} {1 2 3 2 3 4}
|
||||||
|
|
||||||
|
# Insert two rows where the second conflicts on C. The first row show go
|
||||||
|
# and and then there should be a constraint error.
|
||||||
|
#
|
||||||
|
do_test conflict-6.3 {
|
||||||
|
catchsql {INSERT INTO t1(a,b,c) VALUES(4,5,6), (5,6,4);}
|
||||||
|
} {1 {UNIQUE constraint failed: t1.c}}
|
||||||
|
do_execsql_test conflict-6.4 {
|
||||||
|
SELECT a,b,c FROM t1 ORDER BY a;
|
||||||
|
} {1 2 3 2 3 4 4 5 6}
|
||||||
|
|
||||||
|
# Change which column is the PRIMARY KEY
|
||||||
|
#
|
||||||
|
do_execsql_test conflict-7.1 {
|
||||||
|
DROP TABLE t1;
|
||||||
|
CREATE TABLE t1(
|
||||||
|
a UNIQUE ON CONFLICT REPLACE,
|
||||||
|
b INTEGER PRIMARY KEY ON CONFLICT IGNORE,
|
||||||
|
c UNIQUE ON CONFLICT FAIL
|
||||||
|
);
|
||||||
|
INSERT INTO t1(a,b,c) VALUES(1,2,3), (2,3,4);
|
||||||
|
SELECT a,b,c FROM t1 ORDER BY a;
|
||||||
|
} {1 2 3 2 3 4}
|
||||||
|
|
||||||
|
# Insert a row that conflicts on column B. The insert should be ignored.
|
||||||
|
#
|
||||||
|
do_execsql_test conflict-7.2 {
|
||||||
|
INSERT INTO t1(a,b,c) VALUES(3,2,5);
|
||||||
|
SELECT a,b,c FROM t1 ORDER BY a;
|
||||||
|
} {1 2 3 2 3 4}
|
||||||
|
|
||||||
|
# Insert two rows where the second conflicts on C. The first row show go
|
||||||
|
# and and then there should be a constraint error.
|
||||||
|
#
|
||||||
|
do_test conflict-7.3 {
|
||||||
|
catchsql {INSERT INTO t1(a,b,c) VALUES(4,5,6), (5,6,4);}
|
||||||
|
} {1 {UNIQUE constraint failed: t1.c}}
|
||||||
|
do_execsql_test conflict-7.4 {
|
||||||
|
SELECT a,b,c FROM t1 ORDER BY a;
|
||||||
|
} {1 2 3 2 3 4 4 5 6}
|
||||||
|
|
||||||
|
# Change which column is the PRIMARY KEY
|
||||||
|
#
|
||||||
|
do_execsql_test conflict-8.1 {
|
||||||
|
DROP TABLE t1;
|
||||||
|
CREATE TABLE t1(
|
||||||
|
a UNIQUE ON CONFLICT REPLACE,
|
||||||
|
b INT PRIMARY KEY ON CONFLICT IGNORE,
|
||||||
|
c UNIQUE ON CONFLICT FAIL
|
||||||
|
);
|
||||||
|
INSERT INTO t1(a,b,c) VALUES(1,2,3), (2,3,4);
|
||||||
|
SELECT a,b,c FROM t1 ORDER BY a;
|
||||||
|
} {1 2 3 2 3 4}
|
||||||
|
|
||||||
|
# Insert a row that conflicts on column B. The insert should be ignored.
|
||||||
|
#
|
||||||
|
do_execsql_test conflict-8.2 {
|
||||||
|
INSERT INTO t1(a,b,c) VALUES(3,2,5);
|
||||||
|
SELECT a,b,c FROM t1 ORDER BY a;
|
||||||
|
} {1 2 3 2 3 4}
|
||||||
|
|
||||||
|
# Insert two rows where the second conflicts on C. The first row show go
|
||||||
|
# and and then there should be a constraint error.
|
||||||
|
#
|
||||||
|
do_test conflict-8.3 {
|
||||||
|
catchsql {INSERT INTO t1(a,b,c) VALUES(4,5,6), (5,6,4);}
|
||||||
|
} {1 {UNIQUE constraint failed: t1.c}}
|
||||||
|
do_execsql_test conflict-8.4 {
|
||||||
|
SELECT a,b,c FROM t1 ORDER BY a;
|
||||||
|
} {1 2 3 2 3 4 4 5 6}
|
||||||
|
|
||||||
|
# Change which column is the PRIMARY KEY
|
||||||
|
#
|
||||||
|
do_execsql_test conflict-9.1 {
|
||||||
|
DROP TABLE t1;
|
||||||
|
CREATE TABLE t1(
|
||||||
|
a UNIQUE ON CONFLICT REPLACE,
|
||||||
|
b INT PRIMARY KEY ON CONFLICT IGNORE,
|
||||||
|
c UNIQUE ON CONFLICT FAIL
|
||||||
|
) WITHOUT ROWID;
|
||||||
|
INSERT INTO t1(a,b,c) VALUES(1,2,3), (2,3,4);
|
||||||
|
SELECT a,b,c FROM t1 ORDER BY a;
|
||||||
|
} {1 2 3 2 3 4}
|
||||||
|
|
||||||
|
# Insert a row that conflicts on column B. The insert should be ignored.
|
||||||
|
#
|
||||||
|
do_execsql_test conflict-9.2 {
|
||||||
|
INSERT INTO t1(a,b,c) VALUES(3,2,5);
|
||||||
|
SELECT a,b,c FROM t1 ORDER BY a;
|
||||||
|
} {1 2 3 2 3 4}
|
||||||
|
|
||||||
|
# Insert two rows where the second conflicts on C. The first row show go
|
||||||
|
# and and then there should be a constraint error.
|
||||||
|
#
|
||||||
|
do_test conflict-9.3 {
|
||||||
|
catchsql {INSERT INTO t1(a,b,c) VALUES(4,5,6), (5,6,4);}
|
||||||
|
} {1 {UNIQUE constraint failed: t1.c}}
|
||||||
|
do_execsql_test conflict-9.4 {
|
||||||
|
SELECT a,b,c FROM t1 ORDER BY a;
|
||||||
|
} {1 2 3 2 3 4 4 5 6}
|
||||||
|
|
||||||
|
# Change which column is the PRIMARY KEY
|
||||||
|
#
|
||||||
|
do_execsql_test conflict-10.1 {
|
||||||
|
DROP TABLE t1;
|
||||||
|
CREATE TABLE t1(
|
||||||
|
a UNIQUE ON CONFLICT REPLACE,
|
||||||
|
b UNIQUE ON CONFLICT IGNORE,
|
||||||
|
c INTEGER PRIMARY KEY ON CONFLICT FAIL
|
||||||
|
);
|
||||||
|
INSERT INTO t1(a,b,c) VALUES(1,2,3), (2,3,4);
|
||||||
|
SELECT a,b,c FROM t1 ORDER BY a;
|
||||||
|
} {1 2 3 2 3 4}
|
||||||
|
|
||||||
|
# Insert a row that conflicts on column B. The insert should be ignored.
|
||||||
|
#
|
||||||
|
do_execsql_test conflict-10.2 {
|
||||||
|
INSERT INTO t1(a,b,c) VALUES(3,2,5);
|
||||||
|
SELECT a,b,c FROM t1 ORDER BY a;
|
||||||
|
} {1 2 3 2 3 4}
|
||||||
|
|
||||||
|
# Insert two rows where the second conflicts on C. The first row show go
|
||||||
|
# and and then there should be a constraint error.
|
||||||
|
#
|
||||||
|
do_test conflict-10.3 {
|
||||||
|
catchsql {INSERT INTO t1(a,b,c) VALUES(4,5,6), (5,6,4);}
|
||||||
|
} {1 {UNIQUE constraint failed: t1.c}}
|
||||||
|
do_execsql_test conflict-10.4 {
|
||||||
|
SELECT a,b,c FROM t1 ORDER BY a;
|
||||||
|
} {1 2 3 2 3 4 4 5 6}
|
||||||
|
|
||||||
|
# Change which column is the PRIMARY KEY
|
||||||
|
#
|
||||||
|
do_execsql_test conflict-11.1 {
|
||||||
|
DROP TABLE t1;
|
||||||
|
CREATE TABLE t1(
|
||||||
|
a UNIQUE ON CONFLICT REPLACE,
|
||||||
|
b UNIQUE ON CONFLICT IGNORE,
|
||||||
|
c PRIMARY KEY ON CONFLICT FAIL
|
||||||
|
) WITHOUT ROWID;
|
||||||
|
INSERT INTO t1(a,b,c) VALUES(1,2,3), (2,3,4);
|
||||||
|
SELECT a,b,c FROM t1 ORDER BY a;
|
||||||
|
} {1 2 3 2 3 4}
|
||||||
|
|
||||||
|
# Insert a row that conflicts on column B. The insert should be ignored.
|
||||||
|
#
|
||||||
|
do_execsql_test conflict-11.2 {
|
||||||
|
INSERT INTO t1(a,b,c) VALUES(3,2,5);
|
||||||
|
SELECT a,b,c FROM t1 ORDER BY a;
|
||||||
|
} {1 2 3 2 3 4}
|
||||||
|
|
||||||
|
# Insert two rows where the second conflicts on C. The first row show go
|
||||||
|
# and and then there should be a constraint error.
|
||||||
|
#
|
||||||
|
do_test conflict-11.3 {
|
||||||
|
catchsql {INSERT INTO t1(a,b,c) VALUES(4,5,6), (5,6,4);}
|
||||||
|
} {1 {UNIQUE constraint failed: t1.c}}
|
||||||
|
do_execsql_test conflict-11.4 {
|
||||||
|
SELECT a,b,c FROM t1 ORDER BY a;
|
||||||
|
} {1 2 3 2 3 4 4 5 6}
|
||||||
|
|
||||||
|
|
||||||
|
finish_test
|
Reference in New Issue
Block a user