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:
16
manifest
16
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
|
||||
|
@ -1 +1 @@
|
||||
540c2d18e14c277b55f95729fbafc04ca66466b2
|
||||
7d086afe69da4d03bd1de5408626858273f91e8f
|
10
src/fkey.c
10
src/fkey.c
@ -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);
|
||||
|
100
test/fkey2.test
100
test/fkey2.test
@ -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
|
||||
|
@ -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
|
||||
|
||||
|
||||
|
Reference in New Issue
Block a user