diff --git a/manifest b/manifest index 2a787c7558..3fcfca4c46 100644 --- 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 diff --git a/manifest.uuid b/manifest.uuid index bc45157ffe..6ded43767c 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -26676538ee63311393b52c8479c324469bf71f65 \ No newline at end of file +1f43219a7402af7255743466731dba2afb31d12b \ No newline at end of file diff --git a/src/build.c b/src/build.c index d9194a2645..0d1cb496b5 100644 --- a/src/build.c +++ b/src/build.c @@ -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 @@ -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); diff --git a/src/main.c b/src/main.c index 4bcf33fa38..3d83bc1b28 100644 --- a/src/main.c +++ b/src/main.c @@ -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 && iDbnDb ); - assert( iDb>=0 && iDb!=1 && iDbnDb ); - - /* 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 && inDb; 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; diff --git a/test/attach3.test b/test/attach3.test index 0a78638caf..96ecd98f84 100644 --- a/test/attach3.test +++ b/test/attach3.test @@ -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 diff --git a/test/trigger1.test b/test/trigger1.test index 7556a13cbc..80bd313465 100644 --- a/test/trigger1.test +++ b/test/trigger1.test @@ -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