]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
Add extra tests for foreign key support.
authordan <dan@noemail.net>
Wed, 23 Sep 2009 12:06:52 +0000 (12:06 +0000)
committerdan <dan@noemail.net>
Wed, 23 Sep 2009 12:06:52 +0000 (12:06 +0000)
FossilOrigin-Name: 7d086afe69da4d03bd1de5408626858273f91e8f

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

index fa0d67b36e0f368aa989cad7ed39f91c37d8c63c..0849f799c30fda02a9ad3764ce923c34b612e7d0 100644 (file)
--- a/manifest
+++ b/manifest
@@ -1,5 +1,5 @@
-C Add\smissing\scomments\sto\sfkey.c.\sAlso,\schange\sthe\sterminology\sused\sfor\scomments\sand\snames\sin\sfkey.c\sfrom\s"referenced/referencing"\sto\s"parent/child".\sThis\sis\sarguably\sless\scorrect,\sbut\sis\seasier\sto\sfollow.
-D 2009-09-23T08:43:36
+C Add\sextra\stests\sfor\sforeign\skey\ssupport.
+D 2009-09-23T12:06:52
 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 15499f5d10047d38e68ce991b3f88cbddb6e0931
 F src/expr.c 8a663240f374a5326ee157df3d27751f58b7676a
 F src/fault.c dc88c821842157460750d2d61a8a8b4197d047ff
-F src/fkey.c da1a63c1cb22f4b93ceb743ab471a54648466732
+F src/fkey.c 320b318d3131139424ad36514cb376d326920610
 F src/func.c e536218d193b8d326aab91120bc4c6f28aa2b606
 F src/global.c 271952d199a8cc59d4ce840b3bbbfd2f30c8ba32
 F src/hash.c ebcaa921ffd9d86f7ea5ae16a0a29d1c871130a7
@@ -330,8 +330,8 @@ F test/expr.test 80f3cf99f786ffbac19d2b0083673e7fc797030f
 F test/filectrl.test 8923a6dc7630f31c8a9dd3d3d740aa0922df7bf8
 F test/filefmt.test 84e3d0fe9f12d0d2ac852465c6f8450aea0d6f43
 F test/fkey1.test 01c7de578e11747e720c2d9aeef27f239853c4da
-F test/fkey2.test b752d0290886063b42b96584eca5ddeada4c3db1
-F test/fkey_malloc.test 91fb797bca97fd2cb170a3c7e2be7035e5f95244
+F test/fkey2.test 24668ccff4a2dc3177cc3271ffcbed158d90adca
+F test/fkey_malloc.test a18bdb482c6a7b9a61865616a516584d17f04a04
 F test/format4.test 1f0cac8ff3895e9359ed87e41aaabee982a812eb
 F test/fts1a.test 46090311f85da51bb33bd5ce84f7948359c6d8d7
 F test/fts1b.test 5d8a01aefbecc8b7442b36c94c05eb7a845462d5
@@ -753,7 +753,7 @@ F tool/speedtest2.tcl ee2149167303ba8e95af97873c575c3e0fab58ff
 F tool/speedtest8.c 2902c46588c40b55661e471d7a86e4dd71a18224
 F tool/speedtest8inst1.c 293327bc76823f473684d589a8160bde1f52c14e
 F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f
-P 71ac8e28e55ff0250ebe2fe239159ce2458d9165
-R 2ced32012b9c68891c37e1608fd90d15
+P 540c2d18e14c277b55f95729fbafc04ca66466b2
+R b1701f6c56797f01143914d74ba130c0
 U dan
-Z 2fdc28dc4452275cfa2178c7993f269c
+Z 96e574304d094136cffd4148dd456947
index eab8d53d665dfb4d0bdb65ae9db72123ad230a6a..df45e300db35ea680dd4117589c2937de5d7663f 100644 (file)
@@ -1 +1 @@
-540c2d18e14c277b55f95729fbafc04ca66466b2
\ No newline at end of file
+7d086afe69da4d03bd1de5408626858273f91e8f
\ No newline at end of file
index 2dc93b66a2e33c3e944c0386187c86f802494987..fef04b7ace8f6ae58cdd8171fdf7a38c55c54495 100644 (file)
@@ -407,11 +407,8 @@ static void fkScanChildren(
       pLeft->iTable = (pIdx ? (regData+pIdx->aiColumn[i]+1) : regData);
     }
     iCol = aiCol ? aiCol[i] : pFKey->aCol[0].iFrom;
-    if( iCol<0 ){
-      zCol = "rowid";
-    }else{
-      zCol = pFKey->pFrom->aCol[iCol].zName;
-    }
+    assert( iCol>=0 );
+    zCol = pFKey->pFrom->aCol[iCol].zName;
     pRight = sqlite3Expr(db, TK_ID, zCol);
     pEq = sqlite3PExpr(pParse, TK_EQ, pLeft, pRight, 0);
     pWhere = sqlite3ExprAnd(db, pWhere, pEq);
@@ -797,8 +794,9 @@ static Trigger *fkActionTrigger(
       Expr *pEq;                  /* tFromCol = OLD.tToCol */
 
       iFromCol = aiCol ? aiCol[i] : pFKey->aCol[0].iFrom;
+      assert( iFromCol>=0 );
       tToCol.z = pIdx ? pTab->aCol[pIdx->aiColumn[i]].zName : "oid";
-      tFromCol.z = iFromCol<0 ? "oid" : pFKey->pFrom->aCol[iFromCol].zName;
+      tFromCol.z = pFKey->pFrom->aCol[iFromCol].zName;
 
       tToCol.n = sqlite3Strlen30(tToCol.z);
       tFromCol.n = sqlite3Strlen30(tFromCol.z);
index 8c6936e1856d2aa3a6a5a5cd161176854c77ea61..ad1390601915dc0536e7b3cb0efd11122583836c 100644 (file)
@@ -49,6 +49,12 @@ ifcapable {!foreignkey||!trigger} {
 #
 # fkey2-9.*: Test SET DEFAULT actions.
 #
+# fkey2-10.*: Test errors.
+#
+# fkey2-11.*: Test CASCADE actions.
+#
+# fkey2-12.*: Test RESTRICT actions.
+#
 # fkey2-genfkey.*: Tests that were used with the shell tool .genfkey
 #            command. Recycled to test the built-in implementation.
 #
@@ -518,6 +524,100 @@ do_test fkey2-9.1.5 {
   catchsql { DELETE FROM t1 }
 } {1 {foreign key constraint failed}}
 
+#-------------------------------------------------------------------------
+# The following tests, fkey2-10.*, test "foreign key mismatch" and 
+# other errors.
+#
+
+set tn 1
+foreach zSql [list {
+  CREATE TABLE p(a PRIMARY KEY, b);
+  CREATE TABLE c(x REFERENCES p(c));
+}] {
+  drop_all_tables
+
+  do_test fkey2-10.1.$tn {
+    execsql $zSql
+    catchsql { INSERT INTO c DEFAULT VALUES }
+  } {1 {foreign key mismatch}}
+}
+
+# "rowid" cannot be used as part of a child key definition unless it
+# happens to be the name of an explicitly declared column.
+#
+do_test fkey2-10.2.1 {
+  drop_all_tables
+  catchsql {
+    CREATE TABLE t1(a PRIMARY KEY, b);
+    CREATE TABLE t2(c, d, FOREIGN KEY(rowid) REFERENCES t1(a));
+  }
+} {1 {unknown column "rowid" in foreign key definition}}
+do_test fkey2-10.2.2 {
+  drop_all_tables
+  catchsql {
+    CREATE TABLE t1(a PRIMARY KEY, b);
+    CREATE TABLE t2(rowid, d, FOREIGN KEY(rowid) REFERENCES t1(a));
+  }
+} {0 {}}
+
+
+#-------------------------------------------------------------------------
+# The following tests, fkey2-11.*, test CASCADE actions.
+#
+drop_all_tables
+do_test fkey2-11.1.1 {
+  execsql {
+    CREATE TABLE t1(a INTEGER PRIMARY KEY, b);
+    CREATE TABLE t2(c, d, FOREIGN KEY(c) REFERENCES t1(a) ON UPDATE CASCADE);
+
+    INSERT INTO t1 VALUES(10, 100);
+    INSERT INTO t2 VALUES(10, 100);
+    UPDATE t1 SET a = 15;
+    SELECT * FROM t2;
+  }
+} {15 100}
+
+#-------------------------------------------------------------------------
+# The following tests, fkey2-12.*, test RESTRICT actions.
+#
+drop_all_tables
+do_test fkey2-12.1.1 {
+  execsql {
+    CREATE TABLE t1(a, b PRIMARY KEY);
+    CREATE TABLE t2(
+      x REFERENCES t1 ON UPDATE RESTRICT DEFERRABLE INITIALLY DEFERRED 
+    );
+    INSERT INTO t1 VALUES(1, 'one');
+    INSERT INTO t1 VALUES(2, 'two');
+    INSERT INTO t1 VALUES(3, 'three');
+  }
+} {}
+
+do_test fkey2-12.1.2 { 
+  execsql "BEGIN"
+  execsql "INSERT INTO t2 VALUES('two')"
+} {}
+do_test fkey2-12.1.3 { 
+  execsql "UPDATE t1 SET b = 'four' WHERE b = 'one'"
+} {}
+do_test fkey2-12.1.4 { 
+  catchsql "UPDATE t1 SET b = 'five' WHERE b = 'two'"
+} {1 {foreign key constraint failed}}
+do_test fkey2-12.1.5 { 
+  execsql "DELETE FROM t1 WHERE b = 'two'"
+} {}
+do_test fkey2-12.1.6 { 
+  catchsql "COMMIT"
+} {1 {foreign key constraint failed}}
+do_test fkey2-12.1.7 { 
+  execsql {
+    INSERT INTO t1 VALUES(2, 'two');
+    COMMIT;
+  }
+} {}
+
+
+
 #-------------------------------------------------------------------------
 # The following block of tests, those prefixed with "fkey2-genfkey.", are 
 # the same tests that were used to test the ".genfkey" command provided 
index a8bf28c182f9fb18676b9d70951240059d9e3a12..bd24bc7042ce3f7b63aedfa74c7b6d6ad41081f4 100644 (file)
@@ -22,7 +22,7 @@ source $testdir/malloc_common.tcl
 
 do_malloc_test fkey_malloc-1 -sqlprep {
   PRAGMA foreign_keys = 1;
-  CREATE TABLE t1(a PRIMARY KEY, b);
+  CREATE TABLE t1(a PRIMARY KEY, b UNIQUE);
   CREATE TABLE t2(x REFERENCES t1 ON UPDATE CASCADE ON DELETE CASCADE);
 } -sqlbody {
   INSERT INTO t1 VALUES('aaa', 1);
@@ -48,6 +48,61 @@ do_malloc_test fkey_malloc-2 -sqlprep {
   COMMIT;
 }
 
+do_malloc_test fkey_malloc-3 -sqlprep {
+  PRAGMA foreign_keys = 1;
+  CREATE TABLE t1(x INTEGER PRIMARY KEY);
+  CREATE TABLE t2(y REFERENCES t1(rowid) ON UPDATE CASCADE);
+  CREATE TABLE t3(y DEFAULT 14 REFERENCES t1(x) ON UPDATE SET DEFAULT);
+  CREATE TABLE t4(y REFERENCES t1 ON UPDATE SET NULL);
+  INSERT INTO t1 VALUES(13);
+  INSERT INTO t2 VALUES(13);
+  INSERT INTO t3 VALUES(13);
+  INSERT INTO t4 VALUES(13);
+} -sqlbody {
+  UPDATE t1 SET x = 14;
+}
+
+proc catch_fk_error {zSql} {
+  set rc [catch {db eval $zSql} msg]
+  if {$rc==0} {
+    return $msg
+  }
+  if {[string match {*foreign key*} $msg]} {
+    return ""
+  }
+  if {$msg eq "out of memory"} {
+    error 1
+  }
+  error $msg
+}
+
+do_malloc_test fkey_malloc-4 -sqlprep {
+  PRAGMA foreign_keys = 1;
+  CREATE TABLE t1(x INTEGER PRIMARY KEY, y UNIQUE);
+  CREATE TABLE t2(z REFERENCES t1(x), a REFERENCES t1(y));
+  CREATE TABLE t3(x);
+  CREATE TABLE t4(z REFERENCES t3);
+  CREATE TABLE t5(x, y);
+  CREATE TABLE t6(z REFERENCES t5(x));
+  CREATE INDEX i51 ON t5(x);
+  CREATE INDEX i52 ON t5(y, x);
+  INSERT INTO t1 VALUES(1, 2);
+} -tclbody {
+  catch_fk_error {INSERT INTO t2 VALUES(1, 3)}
+  catch_fk_error {INSERT INTO t4 VALUES(2)}
+  catch_fk_error {INSERT INTO t6 VALUES(2)}
+}
+
+do_malloc_test fkey_malloc-5 -sqlprep {
+  PRAGMA foreign_keys = 1;
+  CREATE TABLE t1(x, y, PRIMARY KEY(x, y));
+  CREATE TABLE t2(a, b, FOREIGN KEY(a, b) REFERENCES t1 ON UPDATE CASCADE);
+  INSERT INTO t1 VALUES(1, 2);
+  INSERT INTO t2 VALUES(1, 2);
+} -sqlbody {
+  UPDATE t1 SET x = 5;
+}
+
 finish_test