From: dan Date: Tue, 29 Sep 2009 15:41:57 +0000 (+0000) Subject: Check that a unique index uses the default collation sequences for each column before... X-Git-Tag: fts3-refactor~138 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=9707c7b104cc22e67532cc7f5e7bb9f00cd2ccc6;p=thirdparty%2Fsqlite.git 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 --- diff --git a/manifest b/manifest index c29b0db522..e6bd3f78e6 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Remove\san\sunused\svariable\sfrom\sfkey.c. -D 2009-09-29T11:28:52 +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-29T15:41:58 F Makefile.arm-wince-mingw32ce-gcc fcd5e9cd67fe88836360bb4f9ef4cb7f8e2fb5a0 F Makefile.in 4ca3f1dd6efa2075bcb27f4dc43eef749877740d F Makefile.linux-gcc d53183f4aa6a9192d249731c90dbdffbd2c68654 @@ -116,7 +116,7 @@ F src/date.c 657ff12ca0f1195b531561afacbb38b772d16638 F src/delete.c 2a3d6fc0861b2f8dbd9feb7847b390267b281c60 F src/expr.c c7f3f718bd5c392344ec8694a41c1824f30cf375 F src/fault.c dc88c821842157460750d2d61a8a8b4197d047ff -F src/fkey.c 93b4f9a94828046164db48c09844f1e6ec393917 +F src/fkey.c aed9dc4cb046a014f6ea1b6a88cfb440eb9e505d F src/func.c e536218d193b8d326aab91120bc4c6f28aa2b606 F src/global.c 271952d199a8cc59d4ce840b3bbbfd2f30c8ba32 F src/hash.c ebcaa921ffd9d86f7ea5ae16a0a29d1c871130a7 @@ -330,7 +330,7 @@ F test/expr.test 9f521ae22f00e074959f72ce2e55d46b9ed23f68 F test/filectrl.test 8923a6dc7630f31c8a9dd3d3d740aa0922df7bf8 F test/filefmt.test 84e3d0fe9f12d0d2ac852465c6f8450aea0d6f43 F test/fkey1.test 01c7de578e11747e720c2d9aeef27f239853c4da -F test/fkey2.test 73f7f72f9890f53b3e6a6c9c121d110761d8801c +F test/fkey2.test dbed32250f12630eba0c7f5753b00163b1894f98 F test/fkey3.test c17565b40c97a0dd5102610183c744611171b5ec F test/fkey_malloc.test da912d000bb6ceb1cd11b655de1989762fa71ceb F test/format4.test 1f0cac8ff3895e9359ed87e41aaabee982a812eb @@ -755,7 +755,7 @@ F tool/speedtest2.tcl ee2149167303ba8e95af97873c575c3e0fab58ff F tool/speedtest8.c 2902c46588c40b55661e471d7a86e4dd71a18224 F tool/speedtest8inst1.c 293327bc76823f473684d589a8160bde1f52c14e F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f -P e4eb227b14e4bfcb9f7f284692a391b7355f0204 -R 9bd832543a2e03237ad6098a8f125dae +P 582bd7682831362cd0e2f91ac0dba5ab2b7e2983 +R 3ab2e65e80babb1c9a5df9ed1abb2dff U dan -Z 526a624040eb93cff35148e0dfdd82cd +Z 01b8ddbb56d6c81de7ecc57f15cb5ec5 diff --git a/manifest.uuid b/manifest.uuid index 3ec7f20628..53b9377d03 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -582bd7682831362cd0e2f91ac0dba5ab2b7e2983 \ No newline at end of file +64154174cf8a53bd9be818db53cb0e586c5d24cb \ No newline at end of file diff --git a/src/fkey.c b/src/fkey.c index 04e83b09f1..a8e88056a3 100644 --- a/src/fkey.c +++ b/src/fkey.c @@ -241,10 +241,24 @@ static int locateFkeyIndex( }else{ /* 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 - ** index matches those columns. */ + ** index matches those columns. Also, check that the index uses + ** the default collation sequences for each column. */ int i, j; for(i=0; iaCol[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; jaCol[j].zCol, zIdxCol)==0 ){ if( aiCol ) aiCol[i] = pFKey->aCol[j].iFrom; diff --git a/test/fkey2.test b/test/fkey2.test index 6f56ced0dd..d26e153e3c 100644 --- a/test/fkey2.test +++ b/test/fkey2.test @@ -166,10 +166,23 @@ foreach {tn zSql res} $FkeySimpleTests { execsql { PRAGMA count_changes = 0 } 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 # the IPK is not applied to the child key value before it is inserted # into the child table. -do_test fkey2-1.4.1 { +do_test fkey2-1.5.1 { execsql { CREATE TABLE i(i INTEGER PRIMARY KEY); CREATE TABLE j(j REFERENCES i); @@ -178,13 +191,13 @@ do_test fkey2-1.4.1 { SELECT j, typeof(j) FROM j; } } {35.0 text} -do_test fkey2-1.4.2 { +do_test fkey2-1.5.2 { catchsql { DELETE FROM i } } {1 {foreign key constraint failed}} # Same test using a regular primary key with integer affinity. drop_all_tables -do_test fkey2-1.5.1 { +do_test fkey2-1.6.1 { execsql { CREATE TABLE i(i INT UNIQUE); CREATE TABLE j(j REFERENCES i(i)); @@ -194,13 +207,13 @@ do_test fkey2-1.5.1 { SELECT i, typeof(i) FROM i; } } {35.0 text 35 integer} -do_test fkey2-1.5.2 { +do_test fkey2-1.6.2 { catchsql { DELETE FROM i } } {1 {foreign key constraint failed}} # Use a collation sequence on the parent key. drop_all_tables -do_test fkey2-1.6.1 { +do_test fkey2-1.7.1 { execsql { CREATE TABLE i(i TEXT COLLATE nocase PRIMARY KEY); 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 # has an explicit value. drop_all_tables -do_test fkey2-1.6.2 { +do_test fkey2-1.7.2 { execsql { CREATE TABLE i(i TEXT PRIMARY KEY); -- Colseq is "BINARY" 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') } } {1 {foreign key constraint failed}} -do_test fkey2-1.6.3 { +do_test fkey2-1.7.3 { execsql { INSERT INTO i VALUES('sqlite'); INSERT INTO j VALUES('sqlite'); @@ -394,6 +407,7 @@ do_test fkey2-3.1.5 { execsql COMMIT; execsql { SELECT * FROM ab; SELECT * FROM cd; SELECT * FROM ef } } {1 b 1 d 1 e} + do_test fkey2-3.2.1 { execsql BEGIN; catchsql { DELETE FROM ab } @@ -608,6 +622,36 @@ do_test fkey2-9.1.5 { catchsql { DELETE FROM t1 } } {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 # other errors. @@ -622,6 +666,10 @@ foreach zSql [list { } { CREATE TABLE p(a, b, PRIMARY KEY(a, b)); 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 @@ -699,7 +747,6 @@ do_test fkey2-12.1.1 { INSERT INTO t1 VALUES(3, 'three'); } } {} - do_test fkey2-12.1.2 { execsql "BEGIN" execsql "INSERT INTO t2 VALUES('two')"