]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
Fix handling of "DROP TABLE" commands when "PRAGMA defer_foreign_keys=1" is set.
authordan <dan@noemail.net>
Sat, 12 Oct 2013 15:12:43 +0000 (15:12 +0000)
committerdan <dan@noemail.net>
Sat, 12 Oct 2013 15:12:43 +0000 (15:12 +0000)
FossilOrigin-Name: 27001356ed8201529b3f31d4313f2010f1b4e1b1

manifest
manifest.uuid
src/fkey.c
test/fkey6.test

index 6be0e9f5fbbf8cb7c2fc6dccb82d34cd7505258a..10577d4ef527ed6f49951f2d08345db489db3f40 100644 (file)
--- a/manifest
+++ b/manifest
@@ -1,5 +1,5 @@
-C Add\stests\sthat\sdemonstrate\sthat\sPRAGMA\sdefer_foreign_keys\swill\sreset\sto\soff\nat\sthe\sconclusion\sof\sthe\snext\stransaction.
-D 2013-10-12T13:16:15.885
+C Fix\shandling\sof\s"DROP\sTABLE"\scommands\swhen\s"PRAGMA\sdefer_foreign_keys=1"\sis\sset.
+D 2013-10-12T15:12:43.761
 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f
 F Makefile.in e2d28ec95bd17ab4f3b6ee40b7102e9d7a0857b9
 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23
@@ -175,7 +175,7 @@ F src/date.c 593c744b2623971e45affd0bde347631bdfa4625
 F src/delete.c 45788c5e48734f2af4acd75a876466e5b9838e34
 F src/expr.c e7338ccffdc391c53ba2d51c5eb6a2f5299e040e
 F src/fault.c 160a0c015b6c2629d3899ed2daf63d75754a32bb
-F src/fkey.c be866cd8c4fa6cae98ba33109578fd1a3311ee5b
+F src/fkey.c 5dc10cbaa355753903cd2a64da040f948997ebf8
 F src/func.c 2c47b65e6e00e3e9374942f28254faf8adafe398
 F src/global.c 5caf4deab621abb45b4c607aad1bd21c20aac759
 F src/hash.c ac3470bbf1ca4ae4e306a8ecb0fdf1731810ffe4
@@ -463,7 +463,7 @@ F test/fkey2.test 06e0b4cc9e1b3271ae2ae6feeb19755468432111
 F test/fkey3.test 5ec899d12b13bcf1e9ef40eff7fb692fdb91392e
 F test/fkey4.test 86446017011273aad8f9a99c1a65019e7bd9ca9d
 F test/fkey5.test 2b8c761ad23bb6a95b9cf8366c9a982a80a439c2
-F test/fkey6.test aaf64e18e68fd9967e6accec65e2598ccefcb1e4
+F test/fkey6.test 18e8c024d39f68f8d4bb1177c992bcffdc273464
 F test/fkey7.test e31d0e71a41c1d29349a16448d6c420e2c53a8fc
 F test/fkey_malloc.test bb74c9cb8f8fceed03b58f8a7ef2df98520bbd51
 F test/format4.test 1f0cac8ff3895e9359ed87e41aaabee982a812eb
@@ -1123,7 +1123,7 @@ F tool/vdbe-compress.tcl f12c884766bd14277f4fcedcae07078011717381
 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4
 F tool/warnings.sh d1a6de74685f360ab718efda6265994b99bbea01
 F tool/win/sqlite.vsix 030f3eeaf2cb811a3692ab9c14d021a75ce41fff
-P 4b130f88fba216e088f61252bbcdde57ec7ee6a9
-R 99a9e83f60fa4dd81ccd94c036548c85
-U drh
-Z 4e218592d1ebb0a4d1a6f06c784de251
+P 67e28a11de97e97889f0c0f41c05605721c605c1
+R dc1f4dd0df343cdf7a68b757db650d93
+U dan
+Z abee286031badbf2a2b4e2d1bb40e0a3
index e1694f337c6d299d9929c66c1d781e99fbd27e55..2f25de0eb8ac20b4ce72c394d6a36c5c2a9d3c4b 100644 (file)
@@ -1 +1 @@
-67e28a11de97e97889f0c0f41c05605721c605c1
\ No newline at end of file
+27001356ed8201529b3f31d4313f2010f1b4e1b1
\ No newline at end of file
index 1947c2ee203f2c2e85a268ad3537a4d945cdc02d..5c49ded876ddc7e1ca3d8662d24cdcceae0e0089 100644 (file)
@@ -656,7 +656,7 @@ void sqlite3FkDropTable(Parse *pParse, SrcList *pName, Table *pTab){
       ** when this statement is run.  */
       FKey *p;
       for(p=pTab->pFKey; p; p=p->pNextFrom){
-        if( p->isDeferred ) break;
+        if( p->isDeferred || (db->flags & SQLITE_DeferFKs) ) break;
       }
       if( !p ) return;
       iSkip = sqlite3VdbeMakeLabel(v);
@@ -670,11 +670,18 @@ void sqlite3FkDropTable(Parse *pParse, SrcList *pName, Table *pTab){
     /* If the DELETE has generated immediate foreign key constraint 
     ** violations, halt the VDBE and return an error at this point, before
     ** any modifications to the schema are made. This is because statement
-    ** transactions are not able to rollback schema changes.  */
-    sqlite3VdbeAddOp2(v, OP_FkIfZero, 0, sqlite3VdbeCurrentAddr(v)+2);
-    sqlite3HaltConstraint(pParse, SQLITE_CONSTRAINT_FOREIGNKEY,
-        OE_Abort, "foreign key constraint failed", P4_STATIC
-    );
+    ** transactions are not able to rollback schema changes.  
+    **
+    ** If the SQLITE_DeferFKs flag is set, then this is not required, as
+    ** the statement transaction will not be rolled back even if FK
+    ** constraints are violated.
+    */
+    if( (db->flags & SQLITE_DeferFKs)==0 ){
+      sqlite3VdbeAddOp2(v, OP_FkIfZero, 0, sqlite3VdbeCurrentAddr(v)+2);
+      sqlite3HaltConstraint(pParse, SQLITE_CONSTRAINT_FOREIGNKEY,
+          OE_Abort, "foreign key constraint failed", P4_STATIC
+      );
+    }
 
     if( iSkip ){
       sqlite3VdbeResolveLabel(v, iSkip);
index 2ca364e4e3586c02fb6bdac9816d6aceb426f6cf..8f901164873686eb3d7666b8a24f451f293e4cd4 100644 (file)
@@ -121,5 +121,56 @@ do_test fkey6-1.22 {
   }
 } {}
 
+do_execsql_test fkey6-2.1 {
+  CREATE TABLE p1(a PRIMARY KEY);
+  INSERT INTO p1 VALUES('one'), ('two');
+  CREATE TABLE c1(x REFERENCES p1);
+  INSERT INTO c1 VALUES('two'), ('one');
+}
+
+do_execsql_test fkey6-2.2 {
+  BEGIN;
+    PRAGMA defer_foreign_keys = 1;
+    DELETE FROM p1;
+  ROLLBACK;
+  PRAGMA defer_foreign_keys;
+} {0}
+
+do_execsql_test fkey6-2.3 {
+  BEGIN;
+    PRAGMA defer_foreign_keys = 1;
+    DROP TABLE p1;
+    PRAGMA vdbe_trace = 0;
+  ROLLBACK;
+  PRAGMA defer_foreign_keys;
+} {0}
+
+do_execsql_test fkey6-2.4 {
+  BEGIN;
+    PRAGMA defer_foreign_keys = 1;
+    DELETE FROM p1;
+    DROP TABLE c1;
+  COMMIT;
+  PRAGMA defer_foreign_keys;
+} {0}
+
+do_execsql_test fkey6-2.5 {
+  DROP TABLE p1;
+  CREATE TABLE p1(a PRIMARY KEY);
+  INSERT INTO p1 VALUES('one'), ('two');
+  CREATE TABLE c1(x REFERENCES p1);
+  INSERT INTO c1 VALUES('two'), ('one');
+}
+
+do_execsql_test fkey6-2.6 {
+  BEGIN;
+    PRAGMA defer_foreign_keys = 1;
+    INSERT INTO c1 VALUES('three');
+    DROP TABLE c1;
+  COMMIT;
+  PRAGMA defer_foreign_keys;
+} {0}
+
 
 finish_test
+