]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
Fix for #764. When reloading the schema, load the temp schema last. (CVS 1628)
authordanielk1977 <danielk1977@noemail.net>
Sat, 19 Jun 2004 02:22:10 +0000 (02:22 +0000)
committerdanielk1977 <danielk1977@noemail.net>
Sat, 19 Jun 2004 02:22:10 +0000 (02:22 +0000)
FossilOrigin-Name: 1f43219a7402af7255743466731dba2afb31d12b

manifest
manifest.uuid
src/build.c
src/main.c
test/attach3.test
test/trigger1.test

index 2a787c755825be697fec34a782a3ffc05c1d2f72..3fcfca4c463af191d1a900b0cb2f68cce118eebd 100644 (file)
--- a/manifest
+++ b/manifest
@@ -1,5 +1,5 @@
-C fix\sdependencies\sfor\stestfixture\sin\sMakefile.in\s(CVS\s1627)
-D 2004-06-19T02:19:39
+C Fix\sfor\s#764.\sWhen\sreloading\sthe\sschema,\sload\sthe\stemp\sschema\slast.\s(CVS\s1628)
+D 2004-06-19T02:22:10
 F Makefile.in d69d53c543518c1572ee0a8e8723d7e00bdb2266
 F Makefile.linux-gcc a9e5a0d309fa7c38e7c14d3ecf7690879d3a5457
 F README f1de682fbbd94899d50aca13d387d1b3fd3be2dd
@@ -28,7 +28,7 @@ F src/attach.c 93b8ecec4a8d7b4e9f2479e2327d90c9d01765e8
 F src/auth.c 204e1e9c45e64315589bc8b62cba5d9de29b6a3c
 F src/btree.c 0cf8a52a57a7eb13d50719114ee1fa353e89d7d3
 F src/btree.h 32f96abef464cf8765b23ca669acfe90d191fcc5
-F src/build.c 44057a0aba7c57fb7a32ee4addd2e981fcb9de60
+F src/build.c 239bd93949db1ddc277f26c27e0d613ff5fe16c7
 F src/date.c 65b483caeb0e4dd663667d2f927caa058168ebff
 F src/delete.c a5191011b7429dff939df631b8bdcc1714b8d7aa
 F src/encode.c a876af473d1d636faa3dca51c7571f2e007eea37
@@ -38,7 +38,7 @@ F src/hash.c 440c2f8cb373ee1b4e13a0988489c7cd95d55b6f
 F src/hash.h 762d95f1e567664d1eafc1687de755626be962fb
 F src/insert.c 1428887f4a7515a7d34e82aaeb76297c79ba378b
 F src/legacy.c ad23746f15f67e34577621b1875f639c94839e1f
-F src/main.c bbb19c7ad47bbb433a5467a39347ddd49eb5eefe
+F src/main.c da53b961729954bd4c4408ee339f2e2b690feb98
 F src/md5.c d77a389955759c8329bb357e3d71bac3d6eb710b
 F src/os.h 1cb5f0293a30288451fe3c0c73815cf208212ed1
 F src/os_common.h ba1b7306e16e2091718f2c48db0fe6c1d7a31bb8
@@ -81,7 +81,7 @@ F src/where.c 6507074d8ce3f78e7a4cd33f667f11e62020553e
 F test/all.test 569a92a8ee88f5300c057cc4a8f50fbbc69a3242
 F test/attach.test 3acdffccbf5f78b07746771b9490758718e28856
 F test/attach2.test a05150eb43cf852599dcc491351c67a060337e4b
-F test/attach3.test 0ac01a2baf600768e36a8ef6e0a5d4d652b93e74
+F test/attach3.test c4cc0b806783ce3d860af6b80c947f93ffb14270
 F test/auth.test a211eab0542ec024b578d771b09242dd9bb1aba3
 F test/bigfile.test a1101b46528ad7282fb9b323d25da18672a3bd0a
 F test/bigrow.test 8ab252dba108f12ad64e337b0f2ff31a807ac578
@@ -160,7 +160,7 @@ F test/thread1.test 776c9e459b75ba905193b351926ac4019b049f35
 F test/threadtest1.c f5c7d628d5b23a1418816351b3cd8fe06e146250
 F test/threadtest2.c d94ca4114fd1504f7e0ae724bcd83d4b40931d86
 F test/trans.test 29645b344d2b9b6792793562b12340177ddd8f96
-F test/trigger1.test b45ef390959f736e5a4b7463c857939c48a7c6bb
+F test/trigger1.test dc015c410161f1a6109fd52638dfac852e2a34de
 F test/trigger2.test 0767ab30cb5a2c8402c8524f3d566b410b6f5263
 F test/trigger3.test 70931be83fa3f563f7a5ca9e88b86f476af73948
 F test/trigger4.test 97c11d3cf43d752b172809bb82536372ee5e399c
@@ -225,7 +225,7 @@ F www/tclsqlite.tcl 19191cf2a1010eaeff74c51d83fd5f5a4d899075
 F www/vdbe.tcl 59288db1ac5c0616296b26dce071c36cb611dfe9
 F www/version3.tcl af528563442e3039928f9018327a18157e53a44f
 F www/whentouse.tcl a8335bce47cc2fddb07f19052cb0cb4d9129a8e4
-P d705d051bed2b92b6c3bbcc75fe5b056633b9c31
-R 98029011cfa4c6389636b174deced918
-U dougcurrie
-Z d0a7909e9532f0b290607d1238c66326
+P 26676538ee63311393b52c8479c324469bf71f65
+R 00e7c262ba02f91646c321e006cada67
+U danielk1977
+Z 9439357e77e5edc00904308c8fb4c430
index bc45157ffeb92b76eab491231cacee1c53b8b528..6ded43767c670a493be36444d439856e6f1f1568 100644 (file)
@@ -1 +1 @@
-26676538ee63311393b52c8479c324469bf71f65
\ No newline at end of file
+1f43219a7402af7255743466731dba2afb31d12b
\ No newline at end of file
index d9194a264528a7fc48dbc269bb6f1b522c80ac96..0d1cb496b50fda2a4e4b3c75e15612bb043b21c0 100644 (file)
@@ -23,7 +23,7 @@
 **     ROLLBACK
 **     PRAGMA
 **
-** $Id: build.c,v 1.222 2004/06/18 06:02:35 danielk1977 Exp $
+** $Id: build.c,v 1.223 2004/06/19 02:22:10 danielk1977 Exp $
 */
 #include "sqliteInt.h"
 #include <ctype.h>
@@ -656,16 +656,15 @@ void sqlite3StartTable(
   */
   if( !db->init.busy && (v = sqlite3GetVdbe(pParse))!=0 ){
     sqlite3BeginWriteOperation(pParse, 0, iDb);
-    if( !isTemp ){
-      /* Every time a new table is created the file-format
-      ** and encoding meta-values are set in the database, in
-      ** case this is the first table created.
-      */
-      sqlite3VdbeAddOp(v, OP_Integer, db->file_format, 0);
-      sqlite3VdbeAddOp(v, OP_SetCookie, iDb, 1);
-      sqlite3VdbeAddOp(v, OP_Integer, db->enc, 0);
-      sqlite3VdbeAddOp(v, OP_SetCookie, iDb, 4);
-    }
+    /* Every time a new table is created the file-format
+    ** and encoding meta-values are set in the database, in
+    ** case this is the first table created.
+    */
+    sqlite3VdbeAddOp(v, OP_Integer, db->file_format, 0);
+    sqlite3VdbeAddOp(v, OP_SetCookie, iDb, 1);
+    sqlite3VdbeAddOp(v, OP_Integer, db->enc, 0);
+    sqlite3VdbeAddOp(v, OP_SetCookie, iDb, 4);
+
     sqlite3OpenMasterTable(v, iDb);
     sqlite3VdbeAddOp(v, OP_NewRecno, 0, 0);
     sqlite3VdbeAddOp(v, OP_Dup, 0, 0);
index 4bcf33fa387fe024f6e3597c02c0a733dfaeffd1..3d83bc1b2874df9beee25e1a23a91f2449d1c098 100644 (file)
@@ -14,7 +14,7 @@
 ** other files are for internal use by SQLite and should not be
 ** accessed by users of the library.
 **
-** $Id: main.c,v 1.226 2004/06/18 17:10:17 drh Exp $
+** $Id: main.c,v 1.227 2004/06/19 02:22:11 danielk1977 Exp $
 */
 #include "sqliteInt.h"
 #include "os.h"
@@ -142,10 +142,12 @@ static int sqlite3InitOne(sqlite *db, int iDb, char **pzErrMsg){
   BtCursor *curMain;
   int size;
   Table *pTab;
-  char *azArg[6];
+  char const *azArg[6];
   char zDbNum[30];
   int meta[10];
   InitData initData;
+  char const *zMasterSchema;
+  char const *zMasterName;
 
   /*
   ** The master database table has a structure like this
@@ -169,42 +171,36 @@ static int sqlite3InitOne(sqlite *db, int iDb, char **pzErrMsg){
      ")"
   ;
 
-  /* The following SQL will read the schema from the master tables.
-  */
-  static char init_script1[] = 
-     "SELECT type, name, rootpage, sql, 1 FROM sqlite_temp_master";
-  static char init_script2[] = 
-     "SELECT type, name, rootpage, sql, 0 FROM sqlite_master";
-
-  assert( iDb>=0 && iDb!=1 && iDb<db->nDb );
+  assert( iDb>=0 && iDb<db->nDb );
 
-  /* Construct the schema tables: sqlite_master and sqlite_temp_master
+  /* zMasterSchema and zInitScript are set to point at the master schema
+  ** and initialisation script appropriate for the database being
+  ** initialised. zMasterName is the name of the master table.
   */
+  if( iDb==1 ){
+    zMasterSchema = temp_master_schema;
+    zMasterName = TEMP_MASTER_NAME;
+  }else{
+    zMasterSchema = master_schema;
+    zMasterName = MASTER_NAME;
+  }
+
+  /* Construct the schema tables.  */
   sqlite3SafetyOff(db);
   azArg[0] = "table";
-  azArg[1] = MASTER_NAME;
+  azArg[1] = zMasterName;
   azArg[2] = "1";
-  azArg[3] = master_schema;
+  azArg[3] = zMasterSchema;
   sprintf(zDbNum, "%d", iDb);
   azArg[4] = zDbNum;
   azArg[5] = 0;
   initData.db = db;
   initData.pzErrMsg = pzErrMsg;
-  sqlite3InitCallback(&initData, 5, azArg, 0);
-  pTab = sqlite3FindTable(db, MASTER_NAME, "main");
+  sqlite3InitCallback(&initData, 5, (char **)azArg, 0);
+  pTab = sqlite3FindTable(db, zMasterName, db->aDb[iDb].zName);
   if( pTab ){
     pTab->readOnly = 1;
   }
-  if( iDb==0 ){
-    azArg[1] = TEMP_MASTER_NAME;
-    azArg[3] = temp_master_schema;
-    azArg[4] = "1";
-    sqlite3InitCallback(&initData, 5, azArg, 0);
-    pTab = sqlite3FindTable(db, TEMP_MASTER_NAME, "temp");
-    if( pTab ){
-      pTab->readOnly = 1;
-    }
-  }
   sqlite3SafetyOn(db);
 
   /* Create a cursor to hold the database open
@@ -307,23 +303,13 @@ static int sqlite3InitOne(sqlite *db, int iDb, char **pzErrMsg){
     /* For an empty database, there is nothing to read */
     rc = SQLITE_OK;
   }else{
+    char *zSql = 0;
     sqlite3SafetyOff(db);
-    if( iDb==0 ){
-      /* This SQL statement tries to read the temp.* schema from the
-      ** sqlite_temp_master table. It might return SQLITE_EMPTY. 
-      */
-      rc = sqlite3_exec(db, init_script1, sqlite3InitCallback, &initData, 0);
-      if( rc==SQLITE_OK || rc==SQLITE_EMPTY ){
-        rc = sqlite3_exec(db, init_script2, sqlite3InitCallback, &initData, 0);
-      }
-    }else{
-      char *zSql = 0;
-      sqlite3SetString(&zSql, 
-         "SELECT type, name, rootpage, sql, ", zDbNum, " FROM \"",
-         db->aDb[iDb].zName, "\".sqlite_master", (char*)0);
-      rc = sqlite3_exec(db, zSql, sqlite3InitCallback, &initData, 0);
-      sqliteFree(zSql);
-    }
+    sqlite3SetString(&zSql, 
+        "SELECT type, name, rootpage, sql, ", zDbNum, " FROM \"",
+        db->aDb[iDb].zName, "\".", zMasterName, (char*)0);
+    rc = sqlite3_exec(db, zSql, sqlite3InitCallback, &initData, 0);
+    sqliteFree(zSql);
     sqlite3SafetyOn(db);
     sqlite3BtreeCloseCursor(curMain);
   }
@@ -334,9 +320,6 @@ static int sqlite3InitOne(sqlite *db, int iDb, char **pzErrMsg){
   }
   if( rc==SQLITE_OK ){
     DbSetProperty(db, iDb, DB_SchemaLoaded);
-    if( iDb==0 ){
-      DbSetProperty(db, 1, DB_SchemaLoaded);
-    }
   }else{
     sqlite3ResetInternalSchema(db, iDb);
   }
@@ -360,13 +343,24 @@ int sqlite3Init(sqlite *db, char **pzErrMsg){
   rc = SQLITE_OK;
   db->init.busy = 1;
   for(i=0; rc==SQLITE_OK && i<db->nDb; i++){
-    if( DbHasProperty(db, i, DB_SchemaLoaded) ) continue;
-    assert( i!=1 );  /* Should have been initialized together with 0 */
+    if( DbHasProperty(db, i, DB_SchemaLoaded) || i==1 ) continue;
     rc = sqlite3InitOne(db, i, pzErrMsg);
     if( rc ){
       sqlite3ResetInternalSchema(db, i);
     }
   }
+
+  /* Once all the other databases have been initialised, load the schema
+  ** for the TEMP database. This is loaded last, as the TEMP database
+  ** schema may contain references to objects in other databases.
+  */
+  if( rc==SQLITE_OK && db->nDb>1 && !DbHasProperty(db, 1, DB_SchemaLoaded) ){
+    rc = sqlite3InitOne(db, 1, pzErrMsg);
+    if( rc ){
+      sqlite3ResetInternalSchema(db, 1);
+    }
+  }
+
   db->init.busy = 0;
   if( rc==SQLITE_OK ){
     db->flags |= SQLITE_Initialized;
index 0a78638cafd6ab65b763ceb2dea5191eec70d942..96ecd98f848604469275be1e2a71abbd5a4d957d 100644 (file)
@@ -12,7 +12,7 @@
 # focus of this script is testing the ATTACH and DETACH commands
 # and schema changes to attached databases.
 #
-# $Id: attach3.test,v 1.7 2004/06/19 00:16:31 drh Exp $
+# $Id: attach3.test,v 1.8 2004/06/19 02:22:11 danielk1977 Exp $
 #
 
 
@@ -212,6 +212,14 @@ do_test attach3-9.2 {
   }
 } {0}
 
+# Make sure the aux.sqlite_master table is read-only
+do_test attach3-10.0 {
+  catchsql {
+    INSERT INTO aux.sqlite_master VALUES(1, 2, 3, 4, 5);
+  }
+} {1 {table sqlite_master may not be modified}}
+
+
 finish_test
 
 
index 7556a13cbc354d93c1277e54eb30497d48e253f7..80bd313465527edcfb3df51c73d3388b08c0c1f7 100644 (file)
@@ -412,5 +412,106 @@ do_test trigger-9.2 {
   }
 } {1 2 1 3 99 99 1 3}
 
+execsql {
+  DROP TABLE t2;
+  DROP TABLE t3;
+  DROP TABLE t4;
+}
+
+# Ticket #764. At one stage TEMP triggers would fail to re-install when the
+# schema was reloaded. The following tests ensure that TEMP triggers are
+# correctly re-installed.
+#
+# Also verify that references within trigger programs are resolved at
+# statement compile time, not trigger installation time. This means, for
+# example, that you can drop and re-create tables referenced by triggers. 
+do_test trigger-10.0 {
+  file delete -force test2.db
+  file delete -force test2.db-journal
+  execsql {
+    ATTACH 'test2.db' AS aux;
+  }
+} {}
+do_test trigger-10.1 {
+  execsql {
+    CREATE TABLE main.t4(a, b, c);
+    CREATE TABLE temp.t4(a, b, c);
+    CREATE TABLE aux.t4(a, b, c);
+    CREATE TABLE insert_log(db, a, b, c);
+  }
+} {}
+do_test trigger-10.2 {
+  execsql {
+    CREATE TEMP TRIGGER trig1 AFTER INSERT ON main.t4 BEGIN 
+      INSERT INTO insert_log VALUES('main', new.a, new.b, new.c);
+    END;
+    CREATE TEMP TRIGGER trig2 AFTER INSERT ON temp.t4 BEGIN 
+      INSERT INTO insert_log VALUES('temp', new.a, new.b, new.c);
+    END;
+    CREATE TEMP TRIGGER trig3 AFTER INSERT ON aux.t4 BEGIN 
+      INSERT INTO insert_log VALUES('aux', new.a, new.b, new.c);
+    END;
+  }
+} {}
+do_test trigger-10.3 {
+  execsql {
+    INSERT INTO main.t4 VALUES(1, 2, 3);
+    INSERT INTO temp.t4 VALUES(4, 5, 6);
+    INSERT INTO aux.t4  VALUES(7, 8, 9);
+  }
+} {}
+do_test trigger-10.4 {
+  execsql {
+    SELECT * FROM insert_log;
+  }
+} {main 1 2 3 temp 4 5 6 aux 7 8 9}
+do_test trigger-10.5 {
+  execsql {
+    BEGIN;
+    INSERT INTO main.t4 VALUES(1, 2, 3);
+    INSERT INTO temp.t4 VALUES(4, 5, 6);
+    INSERT INTO aux.t4  VALUES(7, 8, 9);
+    ROLLBACK;
+  }
+} {}
+do_test trigger-10.6 {
+  execsql {
+    SELECT * FROM insert_log;
+  }
+} {main 1 2 3 temp 4 5 6 aux 7 8 9}
+do_test trigger-10.7 {
+  execsql {
+    DELETE FROM insert_log;
+    INSERT INTO main.t4 VALUES(11, 12, 13);
+    INSERT INTO temp.t4 VALUES(14, 15, 16);
+    INSERT INTO aux.t4  VALUES(17, 18, 19);
+  }
+} {}
+do_test trigger-10.8 {
+  execsql {
+    SELECT * FROM insert_log;
+  }
+} {main 11 12 13 temp 14 15 16 aux 17 18 19}
+do_test trigger-10.8 {
+# Drop and re-create the insert_log table in a different database. Note
+# that we can change the column names because the trigger programs don't
+# use them explicitly.
+  execsql {
+    DROP TABLE insert_log;
+    CREATE TABLE aux.insert_log(db, d, e, f);
+  }
+} {}
+do_test trigger-10.10 {
+  execsql {
+    INSERT INTO main.t4 VALUES(21, 22, 23);
+    INSERT INTO temp.t4 VALUES(24, 25, 26);
+    INSERT INTO aux.t4  VALUES(27, 28, 29);
+  }
+} {}
+do_test trigger-10.11 {
+  execsql {
+    SELECT * FROM insert_log;
+  }
+} {main 21 22 23 temp 24 25 26 aux 27 28 29}
 
 finish_test