1
0
mirror of https://github.com/sqlite/sqlite.git synced 2025-11-16 23:02:26 +03:00

Check that a unique index uses the default collation sequences for each column before using it as part of a foreign key constraint operation.

FossilOrigin-Name: 64154174cf8a53bd9be818db53cb0e586c5d24cb
This commit is contained in:
dan
2009-09-29 15:41:57 +00:00
parent 792e92012f
commit 9707c7b104
4 changed files with 79 additions and 18 deletions

View File

@@ -1,5 +1,5 @@
C Remove\san\sunused\svariable\sfrom\sfkey.c. C Check\sthat\sa\sunique\sindex\suses\sthe\sdefault\scollation\ssequences\sfor\seach\scolumn\sbefore\susing\sit\sas\spart\sof\sa\sforeign\skey\sconstraint\soperation.
D 2009-09-29T11:28:52 D 2009-09-29T15:41:58
F Makefile.arm-wince-mingw32ce-gcc fcd5e9cd67fe88836360bb4f9ef4cb7f8e2fb5a0 F Makefile.arm-wince-mingw32ce-gcc fcd5e9cd67fe88836360bb4f9ef4cb7f8e2fb5a0
F Makefile.in 4ca3f1dd6efa2075bcb27f4dc43eef749877740d F Makefile.in 4ca3f1dd6efa2075bcb27f4dc43eef749877740d
F Makefile.linux-gcc d53183f4aa6a9192d249731c90dbdffbd2c68654 F Makefile.linux-gcc d53183f4aa6a9192d249731c90dbdffbd2c68654
@@ -116,7 +116,7 @@ F src/date.c 657ff12ca0f1195b531561afacbb38b772d16638
F src/delete.c 2a3d6fc0861b2f8dbd9feb7847b390267b281c60 F src/delete.c 2a3d6fc0861b2f8dbd9feb7847b390267b281c60
F src/expr.c c7f3f718bd5c392344ec8694a41c1824f30cf375 F src/expr.c c7f3f718bd5c392344ec8694a41c1824f30cf375
F src/fault.c dc88c821842157460750d2d61a8a8b4197d047ff F src/fault.c dc88c821842157460750d2d61a8a8b4197d047ff
F src/fkey.c 93b4f9a94828046164db48c09844f1e6ec393917 F src/fkey.c aed9dc4cb046a014f6ea1b6a88cfb440eb9e505d
F src/func.c e536218d193b8d326aab91120bc4c6f28aa2b606 F src/func.c e536218d193b8d326aab91120bc4c6f28aa2b606
F src/global.c 271952d199a8cc59d4ce840b3bbbfd2f30c8ba32 F src/global.c 271952d199a8cc59d4ce840b3bbbfd2f30c8ba32
F src/hash.c ebcaa921ffd9d86f7ea5ae16a0a29d1c871130a7 F src/hash.c ebcaa921ffd9d86f7ea5ae16a0a29d1c871130a7
@@ -330,7 +330,7 @@ F test/expr.test 9f521ae22f00e074959f72ce2e55d46b9ed23f68
F test/filectrl.test 8923a6dc7630f31c8a9dd3d3d740aa0922df7bf8 F test/filectrl.test 8923a6dc7630f31c8a9dd3d3d740aa0922df7bf8
F test/filefmt.test 84e3d0fe9f12d0d2ac852465c6f8450aea0d6f43 F test/filefmt.test 84e3d0fe9f12d0d2ac852465c6f8450aea0d6f43
F test/fkey1.test 01c7de578e11747e720c2d9aeef27f239853c4da F test/fkey1.test 01c7de578e11747e720c2d9aeef27f239853c4da
F test/fkey2.test 73f7f72f9890f53b3e6a6c9c121d110761d8801c F test/fkey2.test dbed32250f12630eba0c7f5753b00163b1894f98
F test/fkey3.test c17565b40c97a0dd5102610183c744611171b5ec F test/fkey3.test c17565b40c97a0dd5102610183c744611171b5ec
F test/fkey_malloc.test da912d000bb6ceb1cd11b655de1989762fa71ceb F test/fkey_malloc.test da912d000bb6ceb1cd11b655de1989762fa71ceb
F test/format4.test 1f0cac8ff3895e9359ed87e41aaabee982a812eb F test/format4.test 1f0cac8ff3895e9359ed87e41aaabee982a812eb
@@ -755,7 +755,7 @@ F tool/speedtest2.tcl ee2149167303ba8e95af97873c575c3e0fab58ff
F tool/speedtest8.c 2902c46588c40b55661e471d7a86e4dd71a18224 F tool/speedtest8.c 2902c46588c40b55661e471d7a86e4dd71a18224
F tool/speedtest8inst1.c 293327bc76823f473684d589a8160bde1f52c14e F tool/speedtest8inst1.c 293327bc76823f473684d589a8160bde1f52c14e
F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f
P e4eb227b14e4bfcb9f7f284692a391b7355f0204 P 582bd7682831362cd0e2f91ac0dba5ab2b7e2983
R 9bd832543a2e03237ad6098a8f125dae R 3ab2e65e80babb1c9a5df9ed1abb2dff
U dan U dan
Z 526a624040eb93cff35148e0dfdd82cd Z 01b8ddbb56d6c81de7ecc57f15cb5ec5

View File

@@ -1 +1 @@
582bd7682831362cd0e2f91ac0dba5ab2b7e2983 64154174cf8a53bd9be818db53cb0e586c5d24cb

View File

@@ -241,10 +241,24 @@ static int locateFkeyIndex(
}else{ }else{
/* If zKey is non-NULL, then this foreign key was declared to /* If zKey is non-NULL, then this foreign key was declared to
** map to an explicit list of columns in table pParent. Check if this ** map to an explicit list of columns in table pParent. Check if this
** index matches those columns. */ ** index matches those columns. Also, check that the index uses
** the default collation sequences for each column. */
int i, j; int i, j;
for(i=0; i<nCol; i++){ for(i=0; i<nCol; i++){
char *zIdxCol = pParent->aCol[pIdx->aiColumn[i]].zName; int iCol = pIdx->aiColumn[i]; /* Index of column in parent tbl */
char *zDfltColl; /* Def. collation for column */
char *zIdxCol; /* Name of indexed column */
/* If the index uses a collation sequence that is different from
** the default collation sequence for the column, this index is
** unusable. Bail out early in this case. */
zDfltColl = pParent->aCol[iCol].zColl;
if( !zDfltColl ){
zDfltColl = "BINARY";
}
if( sqlite3StrICmp(pIdx->azColl[i], zDfltColl) ) break;
zIdxCol = pParent->aCol[iCol].zName;
for(j=0; j<nCol; j++){ for(j=0; j<nCol; j++){
if( sqlite3StrICmp(pFKey->aCol[j].zCol, zIdxCol)==0 ){ if( sqlite3StrICmp(pFKey->aCol[j].zCol, zIdxCol)==0 ){
if( aiCol ) aiCol[i] = pFKey->aCol[j].iFrom; if( aiCol ) aiCol[i] = pFKey->aCol[j].iFrom;

View File

@@ -166,10 +166,23 @@ foreach {tn zSql res} $FkeySimpleTests {
execsql { PRAGMA count_changes = 0 } execsql { PRAGMA count_changes = 0 }
drop_all_tables drop_all_tables
do_test fkey2-1.4.0 {
execsql [string map {/D/ {}} $FkeySimpleSchema]
execsql { PRAGMA count_changes = 1 }
} {}
foreach {tn zSql res} $FkeySimpleTests {
if {$res == "0 {}"} { set res {0 1} }
execsql BEGIN
do_test fkey2-1.4.$tn { catchsql $zSql } $res
execsql COMMIT
}
execsql { PRAGMA count_changes = 0 }
drop_all_tables
# Special test: When the parent key is an IPK, make sure the affinity of # Special test: When the parent key is an IPK, make sure the affinity of
# the IPK is not applied to the child key value before it is inserted # the IPK is not applied to the child key value before it is inserted
# into the child table. # into the child table.
do_test fkey2-1.4.1 { do_test fkey2-1.5.1 {
execsql { execsql {
CREATE TABLE i(i INTEGER PRIMARY KEY); CREATE TABLE i(i INTEGER PRIMARY KEY);
CREATE TABLE j(j REFERENCES i); CREATE TABLE j(j REFERENCES i);
@@ -178,13 +191,13 @@ do_test fkey2-1.4.1 {
SELECT j, typeof(j) FROM j; SELECT j, typeof(j) FROM j;
} }
} {35.0 text} } {35.0 text}
do_test fkey2-1.4.2 { do_test fkey2-1.5.2 {
catchsql { DELETE FROM i } catchsql { DELETE FROM i }
} {1 {foreign key constraint failed}} } {1 {foreign key constraint failed}}
# Same test using a regular primary key with integer affinity. # Same test using a regular primary key with integer affinity.
drop_all_tables drop_all_tables
do_test fkey2-1.5.1 { do_test fkey2-1.6.1 {
execsql { execsql {
CREATE TABLE i(i INT UNIQUE); CREATE TABLE i(i INT UNIQUE);
CREATE TABLE j(j REFERENCES i(i)); CREATE TABLE j(j REFERENCES i(i));
@@ -194,13 +207,13 @@ do_test fkey2-1.5.1 {
SELECT i, typeof(i) FROM i; SELECT i, typeof(i) FROM i;
} }
} {35.0 text 35 integer} } {35.0 text 35 integer}
do_test fkey2-1.5.2 { do_test fkey2-1.6.2 {
catchsql { DELETE FROM i } catchsql { DELETE FROM i }
} {1 {foreign key constraint failed}} } {1 {foreign key constraint failed}}
# Use a collation sequence on the parent key. # Use a collation sequence on the parent key.
drop_all_tables drop_all_tables
do_test fkey2-1.6.1 { do_test fkey2-1.7.1 {
execsql { execsql {
CREATE TABLE i(i TEXT COLLATE nocase PRIMARY KEY); CREATE TABLE i(i TEXT COLLATE nocase PRIMARY KEY);
CREATE TABLE j(j TEXT COLLATE binary REFERENCES i(i)); CREATE TABLE j(j TEXT COLLATE binary REFERENCES i(i));
@@ -213,7 +226,7 @@ do_test fkey2-1.6.1 {
# Use the parent key collation even if it is default and the child key # Use the parent key collation even if it is default and the child key
# has an explicit value. # has an explicit value.
drop_all_tables drop_all_tables
do_test fkey2-1.6.2 { do_test fkey2-1.7.2 {
execsql { execsql {
CREATE TABLE i(i TEXT PRIMARY KEY); -- Colseq is "BINARY" CREATE TABLE i(i TEXT PRIMARY KEY); -- Colseq is "BINARY"
CREATE TABLE j(j TEXT COLLATE nocase REFERENCES i(i)); CREATE TABLE j(j TEXT COLLATE nocase REFERENCES i(i));
@@ -221,7 +234,7 @@ do_test fkey2-1.6.2 {
} }
catchsql { INSERT INTO j VALUES('sqlite') } catchsql { INSERT INTO j VALUES('sqlite') }
} {1 {foreign key constraint failed}} } {1 {foreign key constraint failed}}
do_test fkey2-1.6.3 { do_test fkey2-1.7.3 {
execsql { execsql {
INSERT INTO i VALUES('sqlite'); INSERT INTO i VALUES('sqlite');
INSERT INTO j VALUES('sqlite'); INSERT INTO j VALUES('sqlite');
@@ -394,6 +407,7 @@ do_test fkey2-3.1.5 {
execsql COMMIT; execsql COMMIT;
execsql { SELECT * FROM ab; SELECT * FROM cd; SELECT * FROM ef } execsql { SELECT * FROM ab; SELECT * FROM cd; SELECT * FROM ef }
} {1 b 1 d 1 e} } {1 b 1 d 1 e}
do_test fkey2-3.2.1 { do_test fkey2-3.2.1 {
execsql BEGIN; execsql BEGIN;
catchsql { DELETE FROM ab } catchsql { DELETE FROM ab }
@@ -608,6 +622,36 @@ do_test fkey2-9.1.5 {
catchsql { DELETE FROM t1 } catchsql { DELETE FROM t1 }
} {1 {foreign key constraint failed}} } {1 {foreign key constraint failed}}
do_test fkey2-9.2.1 {
execsql {
CREATE TABLE pp(a, b, c, PRIMARY KEY(b, c));
CREATE TABLE cc(d DEFAULT 3, e DEFAULT 1, f DEFAULT 2,
FOREIGN KEY(f, d) REFERENCES pp
ON UPDATE SET DEFAULT
ON DELETE SET NULL
);
INSERT INTO pp VALUES(1, 2, 3);
INSERT INTO pp VALUES(4, 5, 6);
INSERT INTO pp VALUES(7, 8, 9);
}
} {}
do_test fkey2-9.2.2 {
execsql {
INSERT INTO cc VALUES(6, 'A', 5);
INSERT INTO cc VALUES(6, 'B', 5);
INSERT INTO cc VALUES(9, 'A', 8);
INSERT INTO cc VALUES(9, 'B', 8);
UPDATE pp SET b = 1 WHERE a = 7;
SELECT * FROM cc;
}
} {6 A 5 6 B 5 3 A 2 3 B 2}
do_test fkey2-9.2.3 {
execsql {
DELETE FROM pp WHERE a = 4;
SELECT * FROM cc;
}
} {{} A {} {} B {} 3 A 2 3 B 2}
#------------------------------------------------------------------------- #-------------------------------------------------------------------------
# The following tests, fkey2-10.*, test "foreign key mismatch" and # The following tests, fkey2-10.*, test "foreign key mismatch" and
# other errors. # other errors.
@@ -622,6 +666,10 @@ foreach zSql [list {
} { } {
CREATE TABLE p(a, b, PRIMARY KEY(a, b)); CREATE TABLE p(a, b, PRIMARY KEY(a, b));
CREATE TABLE c(x REFERENCES p); CREATE TABLE c(x REFERENCES p);
} {
CREATE TABLE p(a COLLATE binary, b);
CREATE UNIQUE INDEX i ON p(a COLLATE nocase);
CREATE TABLE c(x REFERENCES p(a));
}] { }] {
drop_all_tables drop_all_tables
@@ -699,7 +747,6 @@ do_test fkey2-12.1.1 {
INSERT INTO t1 VALUES(3, 'three'); INSERT INTO t1 VALUES(3, 'three');
} }
} {} } {}
do_test fkey2-12.1.2 { do_test fkey2-12.1.2 {
execsql "BEGIN" execsql "BEGIN"
execsql "INSERT INTO t2 VALUES('two')" execsql "INSERT INTO t2 VALUES('two')"