Remove unreachable branches from fkey.c. Add a few tests to cover the remaining branches.
FossilOrigin-Name: 0a0a17d87c990a811a2755b9d9d4141b611b49db
This commit is contained in:
parent
1cf021e143
commit
f7a94543b8
16
manifest
16
manifest
@ -1,5 +1,5 @@
|
||||
C Change\sa\scouple\sof\scomments\sto\suse\s"SQLITE_MUTEX_OMIT"\sinstead\sof\sOMIT_MUTEX.
|
||||
D 2009-09-30T04:28:05
|
||||
C Remove\sunreachable\sbranches\sfrom\sfkey.c.\sAdd\sa\sfew\stests\sto\scover\sthe\sremaining\sbranches.
|
||||
D 2009-09-30T08:11:07
|
||||
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 e1128e8d2309b91d65b8c6a92b69060da3901bd1
|
||||
F src/fkey.c 8b438b1fda586519f8bb398538447fb2592bf668
|
||||
F src/func.c e536218d193b8d326aab91120bc4c6f28aa2b606
|
||||
F src/global.c 271952d199a8cc59d4ce840b3bbbfd2f30c8ba32
|
||||
F src/hash.c ebcaa921ffd9d86f7ea5ae16a0a29d1c871130a7
|
||||
@ -330,9 +330,9 @@ F test/expr.test 9f521ae22f00e074959f72ce2e55d46b9ed23f68
|
||||
F test/filectrl.test 8923a6dc7630f31c8a9dd3d3d740aa0922df7bf8
|
||||
F test/filefmt.test 84e3d0fe9f12d0d2ac852465c6f8450aea0d6f43
|
||||
F test/fkey1.test 01c7de578e11747e720c2d9aeef27f239853c4da
|
||||
F test/fkey2.test df3c11ad1e2fb5410fc7321e24adaaff070d44d3
|
||||
F test/fkey2.test 023917f6d133da94088fe4eafcdfceb81abade83
|
||||
F test/fkey3.test c17565b40c97a0dd5102610183c744611171b5ec
|
||||
F test/fkey_malloc.test da912d000bb6ceb1cd11b655de1989762fa71ceb
|
||||
F test/fkey_malloc.test a5ede29bd2f6e56dea78c3d43fb86dd696c068c8
|
||||
F test/format4.test 1f0cac8ff3895e9359ed87e41aaabee982a812eb
|
||||
F test/fts1a.test 46090311f85da51bb33bd5ce84f7948359c6d8d7
|
||||
F test/fts1b.test 5d8a01aefbecc8b7442b36c94c05eb7a845462d5
|
||||
@ -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 9a4b7ec2928307e88783223903c842accaff7ccf
|
||||
R ed18c0f6e456a209dd60cbfd23f902b1
|
||||
P b733e939f785111eac987fe4a25ccfa512e4f0b4
|
||||
R b65fcb7a6b9e80aa54f47592d37aa613
|
||||
U dan
|
||||
Z e6780d1fc41ded3235a99fa871ec0a7c
|
||||
Z bf04350be182c658296913fed86e36e0
|
||||
|
@ -1 +1 @@
|
||||
b733e939f785111eac987fe4a25ccfa512e4f0b4
|
||||
0a0a17d87c990a811a2755b9d9d4141b611b49db
|
17
src/fkey.c
17
src/fkey.c
@ -193,6 +193,7 @@ static int locateFkeyIndex(
|
||||
/* The caller is responsible for zeroing output parameters. */
|
||||
assert( ppIdx && *ppIdx==0 );
|
||||
assert( !paiCol || *paiCol==0 );
|
||||
assert( pParse );
|
||||
|
||||
/* If this is a non-composite (single column) foreign key, check if it
|
||||
** maps to the INTEGER PRIMARY KEY of table pParent. If so, leave *ppIdx
|
||||
@ -272,7 +273,7 @@ static int locateFkeyIndex(
|
||||
}
|
||||
}
|
||||
|
||||
if( pParse && !pIdx ){
|
||||
if( !pIdx ){
|
||||
if( !pParse->disableTriggers ){
|
||||
sqlite3ErrorMsg(pParse, "foreign key mismatch");
|
||||
}
|
||||
@ -542,18 +543,10 @@ static void fkScanChildren(
|
||||
** each row found. Otherwise, for deferred constraints, increment the
|
||||
** deferred constraint counter by nIncr for each row selected. */
|
||||
pWInfo = sqlite3WhereBegin(pParse, pSrc, pWhere, 0, 0);
|
||||
if( nIncr==0 ){
|
||||
/* Special case: A RESTRICT Action. Throw an error immediately if one
|
||||
** of these is encountered. */
|
||||
sqlite3HaltConstraint(
|
||||
pParse, OE_Abort, "foreign key constraint failed", P4_STATIC
|
||||
);
|
||||
}else{
|
||||
if( nIncr>0 && pFKey->isDeferred==0 ){
|
||||
sqlite3ParseToplevel(pParse)->mayAbort = 1;
|
||||
}
|
||||
sqlite3VdbeAddOp2(v, OP_FkCounter, pFKey->isDeferred, nIncr);
|
||||
if( nIncr>0 && pFKey->isDeferred==0 ){
|
||||
sqlite3ParseToplevel(pParse)->mayAbort = 1;
|
||||
}
|
||||
sqlite3VdbeAddOp2(v, OP_FkCounter, pFKey->isDeferred, nIncr);
|
||||
if( pWInfo ){
|
||||
sqlite3WhereEnd(pWInfo);
|
||||
}
|
||||
|
119
test/fkey2.test
119
test/fkey2.test
@ -74,13 +74,12 @@ ifcapable {!foreignkey||!trigger} {
|
||||
|
||||
|
||||
proc drop_all_tables {{db db}} {
|
||||
set tbls [execsql {SELECT name FROM sqlite_master WHERE type = 'table'}]
|
||||
execsql { PRAGMA foreign_keys = OFF }
|
||||
foreach t [execsql {
|
||||
SELECT name FROM sqlite_master
|
||||
WHERE type = 'table' AND name NOT like 'sqlite_%'
|
||||
foreach {t type} [execsql {
|
||||
SELECT name, type FROM sqlite_master
|
||||
WHERE type IN('table', 'view') AND name NOT like 'sqlite_%'
|
||||
}] {
|
||||
execsql "DROP TABLE $t"
|
||||
execsql "DROP $type $t"
|
||||
}
|
||||
execsql { PRAGMA foreign_keys = ON }
|
||||
}
|
||||
@ -811,6 +810,52 @@ do_test fkey2-12.2.4 {
|
||||
}
|
||||
} {A B a b}
|
||||
|
||||
drop_all_tables
|
||||
do_test fkey2-12.3.1 {
|
||||
execsql {
|
||||
CREATE TABLE up(
|
||||
c00, c01, c02, c03, c04, c05, c06, c07, c08, c09,
|
||||
c10, c11, c12, c13, c14, c15, c16, c17, c18, c19,
|
||||
c20, c21, c22, c23, c24, c25, c26, c27, c28, c29,
|
||||
c30, c31, c32, c33, c34, c35, c36, c37, c38, c39,
|
||||
PRIMARY KEY(c34, c35)
|
||||
);
|
||||
CREATE TABLE down(
|
||||
c00, c01, c02, c03, c04, c05, c06, c07, c08, c09,
|
||||
c10, c11, c12, c13, c14, c15, c16, c17, c18, c19,
|
||||
c20, c21, c22, c23, c24, c25, c26, c27, c28, c29,
|
||||
c30, c31, c32, c33, c34, c35, c36, c37, c38, c39,
|
||||
FOREIGN KEY(c39, c38) REFERENCES up ON UPDATE CASCADE
|
||||
);
|
||||
}
|
||||
} {}
|
||||
do_test fkey2-12.3.2 {
|
||||
execsql {
|
||||
INSERT INTO up(c34, c35) VALUES('yes', 'no');
|
||||
INSERT INTO down(c39, c38) VALUES('yes', 'no');
|
||||
UPDATE up SET c34 = 'possibly';
|
||||
SELECT c38, c39 FROM down;
|
||||
DELETE FROM down;
|
||||
}
|
||||
} {no possibly}
|
||||
do_test fkey2-12.3.3 {
|
||||
catchsql { INSERT INTO down(c39, c38) VALUES('yes', 'no') }
|
||||
} {1 {foreign key constraint failed}}
|
||||
do_test fkey2-12.3.4 {
|
||||
execsql {
|
||||
INSERT INTO up(c34, c35) VALUES('yes', 'no');
|
||||
INSERT INTO down(c39, c38) VALUES('yes', 'no');
|
||||
}
|
||||
catchsql { DELETE FROM up WHERE c34 = 'yes' }
|
||||
} {1 {foreign key constraint failed}}
|
||||
do_test fkey2-12.3.5 {
|
||||
execsql {
|
||||
DELETE FROM up WHERE c34 = 'possibly';
|
||||
SELECT c34, c35 FROM up;
|
||||
SELECT c39, c38 FROM down;
|
||||
}
|
||||
} {yes no yes no}
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
# The following tests, fkey2-13.*, test that FK processing is performed
|
||||
# when rows are REPLACEd.
|
||||
@ -1012,6 +1057,70 @@ do_test fkey-2.14.3.8 {
|
||||
do_test fkey-2.14.3.9 {
|
||||
execsql { DROP TABLE cc }
|
||||
} {}
|
||||
do_test fkey-2.14.3.10 {
|
||||
execsql {
|
||||
CREATE TABLE cc(a, b,
|
||||
FOREIGN KEY(a, b) REFERENCES pp DEFERRABLE INITIALLY DEFERRED
|
||||
);
|
||||
}
|
||||
execsql {
|
||||
INSERT INTO pp VALUES('a', 'b');
|
||||
INSERT INTO cc VALUES('a', 'b');
|
||||
BEGIN;
|
||||
DROP TABLE pp;
|
||||
CREATE TABLE pp(a, b, c, PRIMARY KEY(b, c));
|
||||
INSERT INTO pp VALUES(1, 'a', 'b');
|
||||
COMMIT;
|
||||
}
|
||||
} {}
|
||||
do_test fkey-2.14.3.11 {
|
||||
execsql {
|
||||
BEGIN;
|
||||
DROP TABLE cc;
|
||||
DROP TABLE pp;
|
||||
COMMIT;
|
||||
}
|
||||
} {}
|
||||
do_test fkey-2.14.3.12 {
|
||||
execsql {
|
||||
CREATE TABLE b1(a, b);
|
||||
CREATE TABLE b2(a, b REFERENCES b1);
|
||||
DROP TABLE b1;
|
||||
}
|
||||
} {}
|
||||
do_test fkey-2.14.3.13 {
|
||||
execsql {
|
||||
CREATE TABLE b3(a, b REFERENCES b2 DEFERRABLE INITIALLY DEFERRED);
|
||||
DROP TABLE b2;
|
||||
}
|
||||
} {}
|
||||
|
||||
# Test that nothing goes wrong when dropping a table that refers to a view.
|
||||
# Or dropping a view that an existing FK (incorrectly) refers to. Or either
|
||||
# of the above scenarios with a virtual table.
|
||||
drop_all_tables
|
||||
do_test fkey-2.14.4.1 {
|
||||
execsql {
|
||||
CREATE TABLE t1(x REFERENCES v);
|
||||
CREATE VIEW v AS SELECT * FROM t1;
|
||||
}
|
||||
} {}
|
||||
do_test fkey-2.14.4.2 {
|
||||
execsql {
|
||||
DROP VIEW v;
|
||||
}
|
||||
} {}
|
||||
ifcapable vtab {
|
||||
register_echo_module db
|
||||
do_test fkey-2.14.4.3 {
|
||||
execsql { CREATE VIRTUAL TABLE v USING echo(t1) }
|
||||
} {}
|
||||
do_test fkey-2.14.4.2 {
|
||||
execsql {
|
||||
DROP TABLE v;
|
||||
}
|
||||
} {}
|
||||
}
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
# The following tests, fkey2-15.*, test that unnecessary FK related scans
|
||||
|
@ -101,6 +101,32 @@ do_malloc_test fkey_malloc-5 -sqlprep {
|
||||
UPDATE t1 SET x = 5;
|
||||
}
|
||||
|
||||
do_malloc_test fkey_malloc-6 -sqlprep {
|
||||
PRAGMA foreign_keys = 1;
|
||||
CREATE TABLE t1(
|
||||
x PRIMARY KEY,
|
||||
y REFERENCES t1 ON DELETE RESTRICT ON UPDATE SET DEFAULT
|
||||
);
|
||||
INSERT INTO t1 VALUES('abc', 'abc');
|
||||
INSERT INTO t1 VALUES('def', 'def');
|
||||
} -sqlbody {
|
||||
INSERT INTO t1 VALUES('ghi', 'ghi');
|
||||
DELETE FROM t1 WHERE rowid>1;
|
||||
UPDATE t1 SET x='jkl', y='jkl';
|
||||
}
|
||||
|
||||
do_malloc_test fkey_malloc-7 -sqlprep {
|
||||
PRAGMA foreign_keys = 1;
|
||||
CREATE TABLE x(a, b, PRIMARY KEY(a, b));
|
||||
CREATE TABLE y(c, d,
|
||||
FOREIGN KEY(d, c) REFERENCES x DEFERRABLE INITIALLY DEFERRED
|
||||
);
|
||||
CREATE TABLE z(e, f, FOREIGN KEY(e, f) REFERENCES x);
|
||||
} -sqlbody {
|
||||
DROP TABLE y;
|
||||
DROP TABLE x;
|
||||
}
|
||||
|
||||
finish_test
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user