]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
Check that a unique index uses the default collation sequences for each column before...
authordan <dan@noemail.net>
Tue, 29 Sep 2009 15:41:57 +0000 (15:41 +0000)
committerdan <dan@noemail.net>
Tue, 29 Sep 2009 15:41:57 +0000 (15:41 +0000)
FossilOrigin-Name: 64154174cf8a53bd9be818db53cb0e586c5d24cb

manifest
manifest.uuid
src/fkey.c
test/fkey2.test

index c29b0db522d31be46881c82550126a896505bfe4..e6bd3f78e6bcc7987b87635d45ec417ce34690c8 100644 (file)
--- 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
index 3ec7f2062832bb78817c8169c6831ec3262a7815..53b9377d03d086a4d9194115de55d877e7f3c127 100644 (file)
@@ -1 +1 @@
-582bd7682831362cd0e2f91ac0dba5ab2b7e2983
\ No newline at end of file
+64154174cf8a53bd9be818db53cb0e586c5d24cb
\ No newline at end of file
index 04e83b09f143c6037db03b73db170b5d0b311a92..a8e88056a347f709fd37d11128100965bcfb7321 100644 (file)
@@ -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; 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++){
             if( sqlite3StrICmp(pFKey->aCol[j].zCol, zIdxCol)==0 ){
               if( aiCol ) aiCol[i] = pFKey->aCol[j].iFrom;
index 6f56ced0ddedce31b2ca408af4fc021ca1a1da50..d26e153e3cd2ec3ea22566ad62575e32146bfe09 100644 (file)
@@ -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')"