1
0
mirror of https://github.com/sqlite/sqlite.git synced 2025-07-30 19:03:16 +03:00

Add extra tests for foreign key support.

FossilOrigin-Name: 7d086afe69da4d03bd1de5408626858273f91e8f
This commit is contained in:
dan
2009-09-23 12:06:52 +00:00
parent 8099ce6f4a
commit a8f0bf643e
5 changed files with 169 additions and 16 deletions

View File

@ -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

View File

@ -1 +1 @@
540c2d18e14c277b55f95729fbafc04ca66466b2
7d086afe69da4d03bd1de5408626858273f91e8f

View 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);

View 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

View 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