From: dan Date: Mon, 28 Sep 2009 18:52:11 +0000 (+0000) Subject: Ignore foreign key mismatch errors while compiling DROP TABLE commands. X-Git-Tag: fts3-refactor~141 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=f0662567faf5057b0e6e985e2fbfde6731ab4251;p=thirdparty%2Fsqlite.git Ignore foreign key mismatch errors while compiling DROP TABLE commands. FossilOrigin-Name: 5b4d46374a8e808246a1813c12c36c4a75371898 --- diff --git a/manifest b/manifest index 5ef6c818da..a50bfe89c2 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sthe\sDROP\sTABLE\scommand\sso\sthat\sit\scannot\sbe\sused\sto\sbypass\sforeign\skey\sconstraints\s(if\sforeign\skey\ssupport\sis\senabled). -D 2009-09-28T14:49:02 +C Ignore\sforeign\skey\smismatch\serrors\swhile\scompiling\sDROP\sTABLE\scommands. +D 2009-09-28T18:52:12 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 8c5deb1775c5051327ebe9fc2fc54ef57890c83d +F src/fkey.c e31715c14bd9fbe398551aceb5c5454755bdfa52 F src/func.c e536218d193b8d326aab91120bc4c6f28aa2b606 F src/global.c 271952d199a8cc59d4ce840b3bbbfd2f30c8ba32 F src/hash.c ebcaa921ffd9d86f7ea5ae16a0a29d1c871130a7 @@ -330,7 +330,7 @@ F test/expr.test 9f521ae22f00e074959f72ce2e55d46b9ed23f68 F test/filectrl.test 8923a6dc7630f31c8a9dd3d3d740aa0922df7bf8 F test/filefmt.test 84e3d0fe9f12d0d2ac852465c6f8450aea0d6f43 F test/fkey1.test 01c7de578e11747e720c2d9aeef27f239853c4da -F test/fkey2.test d26f490838bb067d654f4daae3aa90a8a8c8b562 +F test/fkey2.test a041806ef603f8dbae139ad99e57ed1e6cadebf2 F test/fkey3.test 4d8d87a72e0dee5b5411cf10dc05ad9edebbeac8 F test/fkey_malloc.test da912d000bb6ceb1cd11b655de1989762fa71ceb F test/format4.test 1f0cac8ff3895e9359ed87e41aaabee982a812eb @@ -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 9e503e2d0428c9e8df878c7c6594790232cca4e0 -R a460411e3ababe633f79d4b6b7ec5ee3 +P 8353808c9e70412fdee31bfda7810e948f1c7485 +R d0e9896e0ec532c989c7902d96591d81 U dan -Z e4a35317c102426902fe4c436cf5658b +Z c982a4c0e50b77ad87726fbdb4e6d971 diff --git a/manifest.uuid b/manifest.uuid index cdfb7dc2be..bc5950d77f 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -8353808c9e70412fdee31bfda7810e948f1c7485 \ No newline at end of file +5b4d46374a8e808246a1813c12c36c4a75371898 \ No newline at end of file diff --git a/src/fkey.c b/src/fkey.c index 706e054e26..04077d7df2 100644 --- a/src/fkey.c +++ b/src/fkey.c @@ -259,7 +259,9 @@ static int locateFkeyIndex( } if( pParse && !pIdx ){ - sqlite3ErrorMsg(pParse, "foreign key mismatch"); + if( !pParse->disableTriggers ){ + sqlite3ErrorMsg(pParse, "foreign key mismatch"); + } sqlite3DbFree(pParse->db, aiCol); return 1; } @@ -679,6 +681,7 @@ void sqlite3FkCheck( FKey *pFKey; /* Used to iterate through FKs */ int iDb; /* Index of database containing pTab */ const char *zDb; /* Name of database containing pTab */ + int isIgnoreErrors = pParse->disableTriggers; assert( ( pChanges && (regOld==0)!=(regNew==0)) /* UPDATE operation */ || (!pChanges && !regOld && regNew) /* INSERT operation */ @@ -706,8 +709,15 @@ void sqlite3FkCheck( ** on the parent key columns in the parent table. If either of these ** schema items cannot be located, set an error in pParse and return ** early. */ - pTo = sqlite3LocateTable(pParse, 0, pFKey->zTo, zDb); - if( !pTo || locateFkeyIndex(pParse, pTo, pFKey, &pIdx, &aiFree) ) return; + if( pParse->disableTriggers ){ + pTo = sqlite3FindTable(db, pFKey->zTo, zDb); + }else{ + pTo = sqlite3LocateTable(pParse, 0, pFKey->zTo, zDb); + } + if( !pTo || locateFkeyIndex(pParse, pTo, pFKey, &pIdx, &aiFree) ){ + if( !isIgnoreErrors || db->mallocFailed ) return; + continue; + } assert( pFKey->nCol==1 || (aiFree && pIdx) ); /* If the key does not overlap with the pChanges list, skip this FK. */ @@ -759,10 +769,13 @@ void sqlite3FkCheck( assert( regOld==0 && regNew!=0 ); /* Inserting a single row into a parent table cannot cause an immediate ** foreign key violation. So do nothing in this case. */ - return; + continue; } - if( locateFkeyIndex(pParse, pTab, pFKey, &pIdx, &aiCol) ) return; + if( locateFkeyIndex(pParse, pTab, pFKey, &pIdx, &aiCol) ){ + if( !isIgnoreErrors || db->mallocFailed ) return; + continue; + } assert( aiCol || pFKey->nCol==1 ); /* Check if this update statement has modified any of the child key @@ -826,7 +839,7 @@ u32 sqlite3FkOldmask( } for(p=sqlite3FkReferences(pTab); p; p=p->pNextTo){ Index *pIdx = 0; - locateFkeyIndex(0, pTab, p, &pIdx, 0); + locateFkeyIndex(pParse, pTab, p, &pIdx, 0); if( pIdx ){ for(i=0; inColumn; i++) mask |= COLUMN_MASK(pIdx->aiColumn[i]); } diff --git a/test/fkey2.test b/test/fkey2.test index 3f341a75ba..375b4da8a7 100644 --- a/test/fkey2.test +++ b/test/fkey2.test @@ -87,18 +87,6 @@ proc drop_all_tables {{db db}} { execsql { PRAGMA foreign_keys = on } -if 0 { -execsql { - CREATE TABLE t1(a PRIMARY KEY, b REFERENCES t1); - INSERT INTO t1 VALUES('aaa', 'aaa'); -} -puts XXX -explain { UPDATE t1 SET a = 'bbb' } -execsql { PRAGMA vdbe_trace = 1 } -execsql { UPDATE t1 SET a = 'bbb' } -exit -} - set FkeySimpleSchema { PRAGMA foreign_keys = on; CREATE TABLE t1(a PRIMARY KEY, b); @@ -876,6 +864,60 @@ do_test fkey2-14.2.2.7 { execsql { INSERT INTO t3 VALUES(1, NULL, 1) } } {} +do_test fkey-2.14.3.1 { + drop_all_tables + execsql { + CREATE TABLE t1(a, b REFERENCES nosuchtable); + DROP TABLE t1; + } +} {} +do_test fkey-2.14.3.2 { + execsql { + CREATE TABLE t1(a PRIMARY KEY, b); + INSERT INTO t1 VALUES('a', 1); + CREATE TABLE t2(x REFERENCES t1); + INSERT INTO t2 VALUES('a'); + } +} {} +do_test fkey-2.14.3.3 { + catchsql { DROP TABLE t1 } +} {1 {foreign key constraint failed}} +do_test fkey-2.14.3.4 { + execsql { + DELETE FROM t2; + DROP TABLE t1; + } +} {} +do_test fkey-2.14.3.4 { + catchsql { INSERT INTO t2 VALUES('x') } +} {1 {no such table: main.t1}} +do_test fkey-2.14.3.5 { + execsql { + CREATE TABLE t1(x PRIMARY KEY); + INSERT INTO t1 VALUES('x'); + } + execsql { INSERT INTO t2 VALUES('x') } +} {} +do_test fkey-2.14.3.6 { + catchsql { DROP TABLE t1 } +} {1 {foreign key constraint failed}} +do_test fkey-2.14.3.7 { + execsql { + DROP TABLE t2; + DROP TABLE t1; + } +} {} +do_test fkey-2.14.3.8 { + execsql { + CREATE TABLE pp(x, y, PRIMARY KEY(x, y)); + CREATE TABLE cc(a, b, FOREIGN KEY(a, b) REFERENCES pp(x, z)); + } + catchsql { INSERT INTO cc VALUES(1, 2) } +} {1 {foreign key mismatch}} +do_test fkey-2.14.3.9 { + execsql { DROP TABLE cc } +} {} + #------------------------------------------------------------------------- # The following tests, fkey2-15.*, test that unnecessary FK related scans # and lookups are avoided when the constraint counters are zero.