diff --git a/manifest b/manifest index 2825452d94..3ee559c472 100644 --- a/manifest +++ b/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 diff --git a/manifest.uuid b/manifest.uuid index abb017cba7..071d942203 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -b733e939f785111eac987fe4a25ccfa512e4f0b4 \ No newline at end of file +0a0a17d87c990a811a2755b9d9d4141b611b49db \ No newline at end of file diff --git a/src/fkey.c b/src/fkey.c index 7e95969018..7ec256d7bc 100644 --- a/src/fkey.c +++ b/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); } diff --git a/test/fkey2.test b/test/fkey2.test index b377c726e2..1ae9cce88a 100644 --- a/test/fkey2.test +++ b/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 diff --git a/test/fkey_malloc.test b/test/fkey_malloc.test index 3ab188ad1d..05a2a4f474 100644 --- a/test/fkey_malloc.test +++ b/test/fkey_malloc.test @@ -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