]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
Fix the ALTER TABLE RENAME command so that it converts FOREIGN KEY constraints
authordrh <drh@noemail.net>
Mon, 15 Feb 2010 18:03:20 +0000 (18:03 +0000)
committerdrh <drh@noemail.net>
Mon, 15 Feb 2010 18:03:20 +0000 (18:03 +0000)
in ATTACH-ed and in TEMP tables as well as in the main database.
Ticket [13336e9c3c8c3f].

FossilOrigin-Name: ab197d0aaf18016ac2dd3674f49bea5f1556451c

manifest
manifest.uuid
src/alter.c
test/fkey2.test
test/tester.tcl

index dfea442e14f63de5c7b46e71a80366162f24994c..ff847cc77c359b20c19c0f192dbfd2bbadb74565 100644 (file)
--- a/manifest
+++ b/manifest
@@ -1,8 +1,8 @@
 -----BEGIN PGP SIGNED MESSAGE-----
 Hash: SHA1
 
-C When\screating\sa\strigger\son\sa\smain\sdatabase\stable\swhen\sthere\sis\sa\sTEMP\stable\nwith\sthe\ssame\sname,\smake\ssure\sthe\strigger\sis\sbound\sto\sthe\smain\stable.\nTicket\s[985771e11612].
-D 2010-02-15T16:54:55
+C Fix\sthe\sALTER\sTABLE\sRENAME\scommand\sso\sthat\sit\sconverts\sFOREIGN\sKEY\sconstraints\nin\sATTACH-ed\sand\sin\sTEMP\stables\sas\swell\sas\sin\sthe\smain\sdatabase.\nTicket\s[13336e9c3c8c3f].
+D 2010-02-15T18:03:20
 F Makefile.arm-wince-mingw32ce-gcc fcd5e9cd67fe88836360bb4f9ef4cb7f8e2fb5a0
 F Makefile.in c5827ead754ab32b9585487177c93bb00b9497b3
 F Makefile.linux-gcc d53183f4aa6a9192d249731c90dbdffbd2c68654
@@ -104,7 +104,7 @@ F spec.template 86a4a43b99ebb3e75e6b9a735d5fd293a24e90ca
 F sqlite.pc.in 42b7bf0d02e08b9e77734a47798d1a55a9e0716b
 F sqlite3.1 6be1ad09113570e1fc8dcaff84c9b0b337db5ffc
 F sqlite3.pc.in ae6f59a76e862f5c561eb32a380228a02afc3cad
-F src/alter.c 92ba938565d7cc6bfe92aad6cc90c00800ff21d3
+F src/alter.c e6f4d11b1c0b23642fc46bac9abe0753c4294e05
 F src/analyze.c 55155f05ee9ab4ce33b7a4d19c449053f8935200
 F src/attach.c a6b5e97c84c46c731aad064c413e40e12cb718b7
 F src/auth.c 523da7fb4979469955d822ff9298352d6b31de34
@@ -341,7 +341,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 add654160d1b066f7b866d63d4435954ccbcab7d
+F test/fkey2.test e71f5baf9bb42cdba4700d73cba6f4d82fd6b925
 F test/fkey3.test 42f88d6048d8dc079e2a8cf7baad1cc1483a7620
 F test/fkey_malloc.test a5ede29bd2f6e56dea78c3d43fb86dd696c068c8
 F test/format4.test 1f0cac8ff3895e9359ed87e41aaabee982a812eb
@@ -596,7 +596,7 @@ F test/tclsqlite.test bf4227eb236a4c097aa7974a2bf7d3225acf34be
 F test/tempdb.test 1bf52da28a9c24e29717362a87722dff08feb72b
 F test/temptable.test f42121a0d29a62f00f93274464164177ab1cc24a
 F test/temptrigger.test b0273db072ce5f37cf19140ceb1f0d524bbe9f05
-F test/tester.tcl f38dd7ca63d81197c853989dbd39dfa3582c9ce7
+F test/tester.tcl e1f581c7a2648a0aaa51135c4d2e7be68f4b9292
 F test/thread001.test a3e6a7254d1cb057836cb3145b60c10bf5b7e60f
 F test/thread002.test afd20095e6e845b405df4f2c920cb93301ca69db
 F test/thread003.test b824d4f52b870ae39fc5bae4d8070eca73085dca
@@ -790,14 +790,14 @@ F tool/speedtest2.tcl ee2149167303ba8e95af97873c575c3e0fab58ff
 F tool/speedtest8.c 2902c46588c40b55661e471d7a86e4dd71a18224
 F tool/speedtest8inst1.c 293327bc76823f473684d589a8160bde1f52c14e
 F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f
-P c727601eecd85a26dbd4fc36823d77bec34da3c3
-R 45004b2e132c529777330e8469a3dee0
+P ec914af32675e472694270d46f3ba2214eb2fe90
+R b63197d6039614d907827a453eecec99
 U drh
-Z b2e9d944fd601fa751cf2872dbab1f73
+Z 49dfd565a21afaa90179ba63716c3b3a
 -----BEGIN PGP SIGNATURE-----
 Version: GnuPG v1.4.6 (GNU/Linux)
 
-iD8DBQFLeXxioxKgR168RlERAlHrAJ4+sjtvvNq54HhErGM+S2FPfikqFwCfQzkv
-9UxvOxpkUFkuGCjFzxJh+7w=
-=TAZV
+iD8DBQFLeYxroxKgR168RlERAp42AJ9eXZoQAtGar3vAWWJ+ElAji3XDgACfTqUL
+/luMg2NSLMumM1Iu2R9tVWU=
+=ahs6
 -----END PGP SIGNATURE-----
index 2601e3cb661c0fa5437e3935bccc854361b5a44a..2f6721b605c0c859195af27c5fada0657d520d66 100644 (file)
@@ -1 +1 @@
-ec914af32675e472694270d46f3ba2214eb2fe90
\ No newline at end of file
+ab197d0aaf18016ac2dd3674f49bea5f1556451c
\ No newline at end of file
index c4117cf7ef58023d465c6d13786e055c75cf2740..694b243bd3d5eb6257a5a35abf09adc8a1c81e0a 100644 (file)
@@ -479,9 +479,9 @@ void sqlite3AlterRenameTable(
     ** for which the renamed table is the parent table.  */
     if( (zWhere=whereForeignKeys(pParse, pTab))!=0 ){
       sqlite3NestedParse(pParse, 
-          "UPDATE sqlite_master SET "
+          "UPDATE \"%w\".%s SET "
               "sql = sqlite_rename_parent(sql, %Q, %Q) "
-              "WHERE %s;", zTabName, zName, zWhere);
+              "WHERE %s;", zDb, SCHEMA_TABLE(iDb), zTabName, zName, zWhere);
       sqlite3DbFree(db, zWhere);
     }
   }
index dc6529be13c1800690a2f925045c6b7280c1b7db..10a624ef0a445d4b5526108dc8be1936a585e0b4 100644 (file)
@@ -1003,6 +1003,169 @@ ifcapable altertable {
   do_test fkey2-14.2.2.7 {
     execsql { INSERT INTO t3 VALUES(1, NULL, 1) }
   } {}
+
+  # Repeat for TEMP tables
+  #
+  drop_all_tables
+  do_test fkey2-14.1tmp.1 {
+    # Adding a column with a REFERENCES clause is not supported.
+    execsql { 
+      CREATE TEMP TABLE t1(a PRIMARY KEY);
+      CREATE TEMP TABLE t2(a, b);
+    }
+    catchsql { ALTER TABLE t2 ADD COLUMN c REFERENCES t1 }
+  } {0 {}}
+  do_test fkey2-14.1tmp.2 {
+    catchsql { ALTER TABLE t2 ADD COLUMN d DEFAULT NULL REFERENCES t1 }
+  } {0 {}}
+  do_test fkey2-14.1tmp.3 {
+    catchsql { ALTER TABLE t2 ADD COLUMN e REFERENCES t1 DEFAULT NULL}
+  } {0 {}}
+  do_test fkey2-14.1tmp.4 {
+    catchsql { ALTER TABLE t2 ADD COLUMN f REFERENCES t1 DEFAULT 'text'}
+  } {1 {Cannot add a REFERENCES column with non-NULL default value}}
+  do_test fkey2-14.1tmp.5 {
+    catchsql { ALTER TABLE t2 ADD COLUMN g DEFAULT CURRENT_TIME REFERENCES t1 }
+  } {1 {Cannot add a REFERENCES column with non-NULL default value}}
+  do_test fkey2-14.1tmp.6 {
+    execsql { 
+      PRAGMA foreign_keys = off;
+      ALTER TABLE t2 ADD COLUMN h DEFAULT 'text' REFERENCES t1;
+      PRAGMA foreign_keys = on;
+      SELECT sql FROM sqlite_temp_master WHERE name='t2';
+    }
+  } {{CREATE TABLE t2(a, b, c REFERENCES t1, d DEFAULT NULL REFERENCES t1, e REFERENCES t1 DEFAULT NULL, h DEFAULT 'text' REFERENCES t1)}}
+
+  do_test fkey2-14.2tmp.1.1 {
+    test_rename_parent {CREATE TABLE t1(a REFERENCES t2)} t2 t3
+  } {{CREATE TABLE t1(a REFERENCES "t3")}}
+  do_test fkey2-14.2tmp.1.2 {
+    test_rename_parent {CREATE TABLE t1(a REFERENCES t2)} t4 t3
+  } {{CREATE TABLE t1(a REFERENCES t2)}}
+  do_test fkey2-14.2tmp.1.3 {
+    test_rename_parent {CREATE TABLE t1(a REFERENCES "t2")} t2 t3
+  } {{CREATE TABLE t1(a REFERENCES "t3")}}
+  
+  # Test ALTER TABLE RENAME TABLE a bit.
+  #
+  do_test fkey2-14.2tmp.2.1 {
+    drop_all_tables
+    execsql {
+      CREATE TEMP TABLE t1(a PRIMARY KEY, b REFERENCES t1);
+      CREATE TEMP TABLE t2(a PRIMARY KEY, b REFERENCES t1, c REFERENCES t2);
+      CREATE TEMP TABLE t3(a REFERENCES t1, b REFERENCES t2, c REFERENCES t1);
+    }
+    execsql { SELECT sql FROM sqlite_temp_master WHERE type = 'table'}
+  } [list \
+    {CREATE TABLE t1(a PRIMARY KEY, b REFERENCES t1)}                     \
+    {CREATE TABLE t2(a PRIMARY KEY, b REFERENCES t1, c REFERENCES t2)}    \
+    {CREATE TABLE t3(a REFERENCES t1, b REFERENCES t2, c REFERENCES t1)}  \
+  ]
+  do_test fkey2-14.2tmp.2.2 {
+    execsql { ALTER TABLE t1 RENAME TO t4 }
+    execsql { SELECT sql FROM sqlite_temp_master WHERE type = 'table'}
+  } [list \
+    {CREATE TABLE "t4"(a PRIMARY KEY, b REFERENCES "t4")}                    \
+    {CREATE TABLE t2(a PRIMARY KEY, b REFERENCES "t4", c REFERENCES t2)}     \
+    {CREATE TABLE t3(a REFERENCES "t4", b REFERENCES t2, c REFERENCES "t4")} \
+  ]
+  do_test fkey2-14.2tmp.2.3 {
+    catchsql { INSERT INTO t3 VALUES(1, 2, 3) }
+  } {1 {foreign key constraint failed}}
+  do_test fkey2-14.2tmp.2.4 {
+    execsql { INSERT INTO t4 VALUES(1, NULL) }
+  } {}
+  do_test fkey2-14.2tmp.2.5 {
+    catchsql { UPDATE t4 SET b = 5 }
+  } {1 {foreign key constraint failed}}
+  do_test fkey2-14.2tmp.2.6 {
+    catchsql { UPDATE t4 SET b = 1 }
+  } {0 {}}
+  do_test fkey2-14.2tmp.2.7 {
+    execsql { INSERT INTO t3 VALUES(1, NULL, 1) }
+  } {}
+
+  # Repeat for ATTACH-ed tables
+  #
+  drop_all_tables
+  do_test fkey2-14.1aux.1 {
+    # Adding a column with a REFERENCES clause is not supported.
+    execsql { 
+      ATTACH ':memory:' AS aux;
+      CREATE TABLE aux.t1(a PRIMARY KEY);
+      CREATE TABLE aux.t2(a, b);
+    }
+    catchsql { ALTER TABLE t2 ADD COLUMN c REFERENCES t1 }
+  } {0 {}}
+  do_test fkey2-14.1aux.2 {
+    catchsql { ALTER TABLE t2 ADD COLUMN d DEFAULT NULL REFERENCES t1 }
+  } {0 {}}
+  do_test fkey2-14.1aux.3 {
+    catchsql { ALTER TABLE t2 ADD COLUMN e REFERENCES t1 DEFAULT NULL}
+  } {0 {}}
+  do_test fkey2-14.1aux.4 {
+    catchsql { ALTER TABLE t2 ADD COLUMN f REFERENCES t1 DEFAULT 'text'}
+  } {1 {Cannot add a REFERENCES column with non-NULL default value}}
+  do_test fkey2-14.1aux.5 {
+    catchsql { ALTER TABLE t2 ADD COLUMN g DEFAULT CURRENT_TIME REFERENCES t1 }
+  } {1 {Cannot add a REFERENCES column with non-NULL default value}}
+  do_test fkey2-14.1aux.6 {
+    execsql { 
+      PRAGMA foreign_keys = off;
+      ALTER TABLE t2 ADD COLUMN h DEFAULT 'text' REFERENCES t1;
+      PRAGMA foreign_keys = on;
+      SELECT sql FROM aux.sqlite_master WHERE name='t2';
+    }
+  } {{CREATE TABLE t2(a, b, c REFERENCES t1, d DEFAULT NULL REFERENCES t1, e REFERENCES t1 DEFAULT NULL, h DEFAULT 'text' REFERENCES t1)}}
+
+  do_test fkey2-14.2aux.1.1 {
+    test_rename_parent {CREATE TABLE t1(a REFERENCES t2)} t2 t3
+  } {{CREATE TABLE t1(a REFERENCES "t3")}}
+  do_test fkey2-14.2aux.1.2 {
+    test_rename_parent {CREATE TABLE t1(a REFERENCES t2)} t4 t3
+  } {{CREATE TABLE t1(a REFERENCES t2)}}
+  do_test fkey2-14.2aux.1.3 {
+    test_rename_parent {CREATE TABLE t1(a REFERENCES "t2")} t2 t3
+  } {{CREATE TABLE t1(a REFERENCES "t3")}}
+  
+  # Test ALTER TABLE RENAME TABLE a bit.
+  #
+  do_test fkey2-14.2aux.2.1 {
+    drop_all_tables
+    execsql {
+      CREATE TABLE aux.t1(a PRIMARY KEY, b REFERENCES t1);
+      CREATE TABLE aux.t2(a PRIMARY KEY, b REFERENCES t1, c REFERENCES t2);
+      CREATE TABLE aux.t3(a REFERENCES t1, b REFERENCES t2, c REFERENCES t1);
+    }
+    execsql { SELECT sql FROM aux.sqlite_master WHERE type = 'table'}
+  } [list \
+    {CREATE TABLE t1(a PRIMARY KEY, b REFERENCES t1)}                     \
+    {CREATE TABLE t2(a PRIMARY KEY, b REFERENCES t1, c REFERENCES t2)}    \
+    {CREATE TABLE t3(a REFERENCES t1, b REFERENCES t2, c REFERENCES t1)}  \
+  ]
+  do_test fkey2-14.2aux.2.2 {
+    execsql { ALTER TABLE t1 RENAME TO t4 }
+    execsql { SELECT sql FROM aux.sqlite_master WHERE type = 'table'}
+  } [list \
+    {CREATE TABLE "t4"(a PRIMARY KEY, b REFERENCES "t4")}                    \
+    {CREATE TABLE t2(a PRIMARY KEY, b REFERENCES "t4", c REFERENCES t2)}     \
+    {CREATE TABLE t3(a REFERENCES "t4", b REFERENCES t2, c REFERENCES "t4")} \
+  ]
+  do_test fkey2-14.2aux.2.3 {
+    catchsql { INSERT INTO t3 VALUES(1, 2, 3) }
+  } {1 {foreign key constraint failed}}
+  do_test fkey2-14.2aux.2.4 {
+    execsql { INSERT INTO t4 VALUES(1, NULL) }
+  } {}
+  do_test fkey2-14.2aux.2.5 {
+    catchsql { UPDATE t4 SET b = 5 }
+  } {1 {foreign key constraint failed}}
+  do_test fkey2-14.2aux.2.6 {
+    catchsql { UPDATE t4 SET b = 1 }
+  } {0 {}}
+  do_test fkey2-14.2aux.2.7 {
+    execsql { INSERT INTO t3 VALUES(1, NULL, 1) }
+  } {}
 }
 
 do_test fkey-2.14.3.1 {
index 136e1161599e1992fab75964bf696f2737e1ae3b..8fe877ec01d0e64f4e19dd32b25367b9258b0b7f 100644 (file)
@@ -964,11 +964,18 @@ proc drop_all_tables {{db db}} {
     set pk [$db one "PRAGMA foreign_keys"]
     $db eval "PRAGMA foreign_keys = OFF"
   }
-  foreach {t type} [$db eval {
-    SELECT name, type FROM sqlite_master 
-    WHERE type IN('table', 'view') AND name NOT like 'sqlite_%'
-  }] {
-    $db eval "DROP $type $t"
+  foreach {idx name file} [db eval {PRAGMA database_list}] {
+    if {$idx==1} {
+      set master sqlite_temp_master
+    } else {
+      set master $name.sqlite_master
+    }
+    foreach {t type} [$db eval "
+      SELECT name, type FROM $master
+      WHERE type IN('table', 'view') AND name NOT like 'sqlite_%'
+    "] {
+      $db eval "DROP $type $t"
+    }
   }
   ifcapable trigger&&foreignkey {
     $db eval "PRAGMA foreign_keys = $pk"