From c275b4ea91e9980f83928f55e96ad46f07263a81 Mon Sep 17 00:00:00 2001 From: drh Date: Mon, 19 Jul 2004 17:25:24 +0000 Subject: [PATCH] Store schema cookies on the TEMP database. Ticket #807. (CVS 1817) FossilOrigin-Name: c6c13dc460094e6adea2b14849edf9f485238b99 --- manifest | 28 ++++++++++++------------ manifest.uuid | 2 +- src/build.c | 53 ++++++++++++++++++++++----------------------- src/main.c | 13 +++++------ src/vdbe.c | 11 ++++++++-- src/where.c | 4 ++-- test/attach2.test | 12 +++++----- test/join3.test | 8 +------ test/misc4.test | 15 +++++++++++-- test/tclsqlite.test | 3 ++- 10 files changed, 80 insertions(+), 69 deletions(-) diff --git a/manifest b/manifest index deb4ca78a8..ec4e19f896 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C use\s-lsqlite3\sin\s.pc\sfile\s(CVS\s1816) -D 2004-07-19T04:25:47 +C Store\sschema\scookies\son\sthe\sTEMP\sdatabase.\s\sTicket\s#807.\s(CVS\s1817) +D 2004-07-19T17:25:25 F Makefile.in 77d1219b6563476711a7a962e865979a6f314eb0 F Makefile.linux-gcc a9e5a0d309fa7c38e7c14d3ecf7690879d3a5457 F README f1de682fbbd94899d50aca13d387d1b3fd3be2dd @@ -29,7 +29,7 @@ F src/attach.c 5e37aaac0907edad5da8ba785b94f04fbb4003d7 F src/auth.c 60db23b98bb94c8b0178180faaf49dc116674217 F src/btree.c 3ed3c19e43bb243f502ee614f6ad0a52e53362a7 F src/btree.h 934d0ad30b5b419e9291a11da878be349df2277e -F src/build.c ecc10d4e5232a49f55304dd9b90739f2771e34ef +F src/build.c 1d9a72adb51a544131b51bd4101846f781f3266d F src/date.c d42ea73a0b16d5dff9d97e10dc0c05671471b753 F src/delete.c e81545e546f6bc87d7508a93a09ca70695265af3 F src/encode.c a876af473d1d636faa3dca51c7571f2e007eea37 @@ -39,7 +39,7 @@ F src/hash.c f0a2f22c2a7052d67053b5f4690ea3010bb3fb9f F src/hash.h 762d95f1e567664d1eafc1687de755626be962fb F src/insert.c d99ffe87e1e1397f4233afcd06841d52d6b17b18 F src/legacy.c ad23746f15f67e34577621b1875f639c94839e1f -F src/main.c 9cb3598be553c6e247e7ad7e9c41a9a0c38c7211 +F src/main.c 4f3c3f0f9e9aa6d6595d6fcb0d3cdd4d31191554 F src/md5.c 7ae1c39044b95de2f62e066f47bb1deb880a1070 F src/os.h d1780e0db95cad01f213d48da22ab490eb4fd345 F src/os_common.h fe9604754116bd2f2702d58f82d2d8b89998cb21 @@ -74,16 +74,16 @@ F src/update.c b66b1896c9da54678ba3eff2bf0b4d291a95986a F src/utf.c f03535db72bfa09e24202ccdd245f21d2fc65f0a F src/util.c 2aacc79b7bf5df5859813dafd3bf3258f67a5234 F src/vacuum.c b8546f4921719458cc537b9e736df52a8256399c -F src/vdbe.c efda404921668a4f1fbcc256dfca859d2eb5c66d +F src/vdbe.c a88514694be86eca792dd4d291e766f3c1831876 F src/vdbe.h 75b241c02431b9c0f16eaa9cdbb34146c6287f52 F src/vdbeInt.h 7160653a006b6d2c4a00d204112a095bdf842ab6 F src/vdbeapi.c c5c6d8f162a9581dde497b1a4034f9a0bf54c355 F src/vdbeaux.c 4de85e30ca4a83ea0a45eceb7e88ac7a48f4c237 F src/vdbemem.c bbf621377343bee046547712a144a94f387bb1eb -F src/where.c 2d346d4aaeae7b63545b85982c6c97d24b9898b5 +F src/where.c 504e1df3d7d9eb74175088e532d1d7ee17f50ac7 F test/all.test 3b692eb43583b52c99c344b2fa8934512d179016 F test/attach.test 3acdffccbf5f78b07746771b9490758718e28856 -F test/attach2.test 3cd1d4a69e0ec307d0b68a44a96c9c8e1e253d65 +F test/attach2.test b175333059e86c82dbf593fc922522ecb0f8aff8 F test/attach3.test 6d060986ff004ebb89e1876a331d96c6bb62269e F test/auth.test 23d1dbf2235635409fee36535a344edc7494aea2 F test/bigfile.test 62722ac4b420dfbcdceb137b8634e2cf2865fe27 @@ -125,7 +125,7 @@ F test/intpkey.test c8efd06db62b8b27216558ef439cc867d113cfec F test/ioerr.test 7d087bfd1a1a53442940e000df936e0df0c5b886 F test/join.test 9ef6aabaac9de51d5fc41e68d1f4355da05a84cd F test/join2.test c97e4c5aa65dea462145529e58212a709b4722b8 -F test/join3.test 920ba2d6dad3fe24593036e83db8bdfc9c44a798 +F test/join3.test 8d989e52413199065bd630b3d0a6b2329d173099 F test/lastinsert.test 31382f88b9b0270333ac9e4a17f2c2f4732da718 F test/laststmtchanges.test 417aa27eb2b5cdfafb46e390e2c9ddd0a20eba43 F test/limit.test 60d7f856ee7846f7130dee67f10f0e726cd70b5d @@ -139,7 +139,7 @@ F test/minmax.test 6513f9a1bb85fd35ff72b34b7b6634fad6b1e69c F test/misc1.test 72768ec8cabc952a4cfcddca43d566f9e0bce899 F test/misc2.test 703734f5817215ca54e364833b3bf5ff36fcc21e F test/misc3.test eb488314990bfc0959221a1acc465013238bf168 -F test/misc4.test f221d03868b4ae7f2028431034d3cf00cead7c26 +F test/misc4.test 9e4291bb174e4357459e0b080f7ca9c6733150c9 F test/misuse.test 2a64ce711419f2fd12806ed95af930fd4e7bb8f3 F test/notnull.test 7a08117a71e74b0321aaa937dbeb41a09d6eb1d0 F test/null.test c14d0f4739f21e929b8115b72bf0c765b6bb1721 @@ -162,7 +162,7 @@ F test/sort.test 30fb9ea782a78da849a562d53233ec62d421bf61 F test/subselect.test f0fea8cf9f386d416d64d152e3c65f9116d0f50f F test/table.test b6d07f04c4157d1f2a37fb7febe36b250d468e31 F test/tableapi.test b21ab097e87a5484bb61029e69e1a4e5c5e65ede -F test/tclsqlite.test 7a773d270a2c35af1d0295c18a9ee26859ddbf1f +F test/tclsqlite.test 0ef39b0228a32601432cec20208ec4b35e9b5cdb F test/temptable.test 63a16e3ad19adf073cfbcdf7624c92ac5236522c F test/tester.tcl f36cc22d0532725073ca78272d7834d56dceb6d9 F test/thread1.test 776c9e459b75ba905193b351926ac4019b049f35 @@ -236,7 +236,7 @@ F www/tclsqlite.tcl 19191cf2a1010eaeff74c51d83fd5f5a4d899075 F www/vdbe.tcl 59288db1ac5c0616296b26dce071c36cb611dfe9 F www/version3.tcl 092a01f5ef430d2c4acc0ae558d74c4bb89638a0 F www/whentouse.tcl a8335bce47cc2fddb07f19052cb0cb4d9129a8e4 -P 991b6108e7cac3837d39fd9a5adbd72b082a4983 -R 3f8e97ffe3ac63e9657b96b80fdf6afc -U dougcurrie -Z eba6b9812a93fa416bb50c87f38a7472 +P b36e6e4907716e048fb21903e234578596c7333d +R 27d8d1ff5e4a09c10df4c3b7ad31e5bc +U drh +Z 9bdf2c5059de01392d40fdc6b41ce812 diff --git a/manifest.uuid b/manifest.uuid index 6186b68d1c..56dd96ace6 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -b36e6e4907716e048fb21903e234578596c7333d \ No newline at end of file +c6c13dc460094e6adea2b14849edf9f485238b99 \ No newline at end of file diff --git a/src/build.c b/src/build.c index 8f2348d1b5..871b996759 100644 --- a/src/build.c +++ b/src/build.c @@ -23,7 +23,7 @@ ** ROLLBACK ** PRAGMA ** -** $Id: build.c,v 1.237 2004/06/29 08:59:35 danielk1977 Exp $ +** $Id: build.c,v 1.238 2004/07/19 17:25:25 drh Exp $ */ #include "sqliteInt.h" #include @@ -69,18 +69,16 @@ void sqlite3FinishCoding(Parse *pParse){ ** transaction on each used database and to verify the schema cookie ** on each used database. */ - if( pParse->cookieMask!=0 ){ + if( pParse->cookieGoto>0 ){ u32 mask; int iDb; - sqlite3VdbeChangeP2(v, pParse->cookieGoto, sqlite3VdbeCurrentAddr(v)); + sqlite3VdbeChangeP2(v, pParse->cookieGoto-1, sqlite3VdbeCurrentAddr(v)); for(iDb=0, mask=1; iDbnDb; mask<<=1, iDb++){ if( (mask & pParse->cookieMask)==0 ) continue; sqlite3VdbeAddOp(v, OP_Transaction, iDb, (mask & pParse->writeMask)!=0); - if( iDb!=1 ){ - sqlite3VdbeAddOp(v, OP_VerifyCookie, iDb, pParse->cookieValue[iDb]); - } + sqlite3VdbeAddOp(v, OP_VerifyCookie, iDb, pParse->cookieValue[iDb]); } - sqlite3VdbeAddOp(v, OP_Goto, 0, pParse->cookieGoto+1); + sqlite3VdbeAddOp(v, OP_Goto, 0, pParse->cookieGoto); } } @@ -101,6 +99,7 @@ void sqlite3FinishCoding(Parse *pParse){ pParse->nAgg = 0; pParse->nVar = 0; pParse->cookieMask = 0; + pParse->cookieGoto = 0; } /* @@ -1378,9 +1377,7 @@ void sqlite3EndTable(Parse *pParse, Token *pEnd, Select *pSelect){ } sqlite3VdbeOp3(v, OP_MakeRecord, 5, 0, "tttit", P3_STATIC); sqlite3VdbeAddOp(v, OP_PutIntKey, 0, 0); - if( p->iDb!=1 ){ - sqlite3ChangeCookie(db, v, p->iDb); - } + sqlite3ChangeCookie(db, v, p->iDb); sqlite3VdbeAddOp(v, OP_Close, 0, 0); sqlite3EndWriteOperation(pParse); @@ -2198,9 +2195,7 @@ void sqlite3CreateIndex( sqlite3VdbeAddOp(v, OP_Close, 1, 0); } if( pTblName!=0 ){ - if( !isTemp ){ - sqlite3ChangeCookie(db, v, iDb); - } + sqlite3ChangeCookie(db, v, iDb); sqlite3VdbeAddOp(v, OP_Close, 0, 0); sqlite3EndWriteOperation(pParse); } @@ -2300,9 +2295,7 @@ void sqlite3DropIndex(Parse *pParse, SrcList *pName){ sqlite3OpenMasterTable(v, pIndex->iDb); base = sqlite3VdbeAddOpList(v, ArraySize(dropIndex), dropIndex); sqlite3VdbeChangeP3(v, base+1, pIndex->zName, 0); - if( pIndex->iDb!=1 ){ - sqlite3ChangeCookie(db, v, pIndex->iDb); - } + sqlite3ChangeCookie(db, v, pIndex->iDb); sqlite3VdbeAddOp(v, OP_Close, 0, 0); sqlite3VdbeAddOp(v, OP_Destroy, pIndex->tnum, pIndex->iDb); sqlite3EndWriteOperation(pParse); @@ -2533,14 +2526,18 @@ void sqlite3RollbackTransaction(Parse *pParse){ ** the VDBE program. But this routine can be called after much other ** code has been generated. So here is what we do: ** -** The first time this routine is called, we code an OP_Gosub that +** The first time this routine is called, we code an OP_Goto that ** will jump to a subroutine at the end of the program. Then we ** record every database that needs its schema verified in the ** pParse->cookieMask field. Later, after all other code has been ** generated, the subroutine that does the cookie verifications and -** starts the transactions will be coded and the OP_Gosub P2 value +** starts the transactions will be coded and the OP_Goto P2 value ** will be made to point to that subroutine. The generation of the ** cookie verification subroutine code happens in sqlite3FinishCoding(). +** +** If iDb<0 then code the OP_Goto only - don't set flag to verify the +** schema on any databases. This can be used to position the OP_Goto +** early in the code, before we know if any database tables will be used. */ void sqlite3CodeVerifySchema(Parse *pParse, int iDb){ sqlite *db; @@ -2550,16 +2547,18 @@ void sqlite3CodeVerifySchema(Parse *pParse, int iDb){ v = sqlite3GetVdbe(pParse); if( v==0 ) return; /* This only happens if there was a prior error */ db = pParse->db; - assert( iDb>=0 && iDbnDb ); - assert( db->aDb[iDb].pBt!=0 || iDb==1 ); - assert( iDb<32 ); - if( pParse->cookieMask==0 ){ - pParse->cookieGoto = sqlite3VdbeAddOp(v, OP_Goto, 0, 0); + if( pParse->cookieGoto==0 ){ + pParse->cookieGoto = sqlite3VdbeAddOp(v, OP_Goto, 0, 0)+1; } - mask = 1<cookieMask & mask)==0 ){ - pParse->cookieMask |= mask; - pParse->cookieValue[iDb] = db->aDb[iDb].schema_cookie; + if( iDb>=0 ){ + assert( iDbnDb ); + assert( db->aDb[iDb].pBt!=0 || iDb==1 ); + assert( iDb<32 ); + mask = 1<cookieMask & mask)==0 ){ + pParse->cookieMask |= mask; + pParse->cookieValue[iDb] = db->aDb[iDb].schema_cookie; + } } } diff --git a/src/main.c b/src/main.c index 2beacd564b..2bf89a774f 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.244 2004/06/30 11:54:07 danielk1977 Exp $ +** $Id: main.c,v 1.245 2004/07/19 17:25:25 drh Exp $ */ #include "sqliteInt.h" #include "os.h" @@ -52,10 +52,10 @@ static void corruptSchema(InitData *pData, const char *zExtra){ ** ** Each callback contains the following information: ** -** argv[0] = "file-format" or "schema-cookie" or "table" or "index" -** argv[1] = table or index name or meta statement type. -** argv[2] = root page number for table or index. NULL for meta. -** argv[3] = SQL text for a CREATE TABLE or CREATE INDEX statement. +** argv[0] = "table" or "index" or "view" or "trigger" +** argv[1] = name of thing being created +** argv[2] = root page number for table or index. NULL for trigger or view. +** argv[3] = SQL text for the CREATE statement. ** argv[4] = "1" for temporary files, "0" for main database, "2" or more ** for auxiliary database files. ** @@ -922,7 +922,7 @@ int sqlite3_errcode(sqlite3 *db){ } /* -** Check schema cookies in all databases except TEMP. If any cookie is out +** Check schema cookies in all databases. If any cookie is out ** of date, return 0. If all schema cookies are current, return 1. */ static int schemaIsValid(sqlite *db){ @@ -934,7 +934,6 @@ static int schemaIsValid(sqlite *db){ for(iDb=0; allOk && iDbnDb; iDb++){ Btree *pBt; - if( iDb==1 ) continue; pBt = db->aDb[iDb].pBt; if( pBt==0 ) continue; rc = sqlite3BtreeCursor(pBt, MASTER_ROOT, 0, 0, 0, &curTemp); diff --git a/src/vdbe.c b/src/vdbe.c index 6561a5356b..b085fe7af1 100644 --- a/src/vdbe.c +++ b/src/vdbe.c @@ -43,7 +43,7 @@ ** in this file for details. If in doubt, do not deviate from existing ** commenting and indentation practices when changing or adding code. ** -** $Id: vdbe.c,v 1.401 2004/07/18 21:33:02 drh Exp $ +** $Id: vdbe.c,v 1.402 2004/07/19 17:25:25 drh Exp $ */ #include "sqliteInt.h" #include "os.h" @@ -2363,8 +2363,15 @@ case OP_SetCookie: { */ case OP_VerifyCookie: { int iMeta; + Btree *pBt; assert( pOp->p1>=0 && pOp->p1nDb ); - rc = sqlite3BtreeGetMeta(db->aDb[pOp->p1].pBt, 1, (u32 *)&iMeta); + pBt = db->aDb[pOp->p1].pBt; + if( pBt ){ + rc = sqlite3BtreeGetMeta(pBt, 1, (u32 *)&iMeta); + }else{ + rc = SQLITE_OK; + iMeta = 0; + } if( rc==SQLITE_OK && iMeta!=pOp->p2 ){ sqlite3SetString(&p->zErrMsg, "database schema has changed", (char*)0); rc = SQLITE_SCHEMA; diff --git a/src/where.c b/src/where.c index fef6974912..5d676d7c10 100644 --- a/src/where.c +++ b/src/where.c @@ -12,7 +12,7 @@ ** This module contains C code that generates VDBE code used to process ** the WHERE clause of SQL statements. ** -** $Id: where.c,v 1.108 2004/07/19 02:12:14 drh Exp $ +** $Id: where.c,v 1.109 2004/07/19 17:25:25 drh Exp $ */ #include "sqliteInt.h" @@ -695,7 +695,7 @@ WhereInfo *sqlite3WhereBegin( /* Open all tables in the pTabList and all indices used by those tables. */ - sqlite3CodeVerifySchema(pParse, 1); /* Inserts the cookie verifier Goto */ + sqlite3CodeVerifySchema(pParse, -1); /* Insert the cookie verifier Goto */ for(i=0; inSrc; i++){ Table *pTab; Index *pIx; diff --git a/test/attach2.test b/test/attach2.test index 566a292228..fac840c9b6 100644 --- a/test/attach2.test +++ b/test/attach2.test @@ -12,7 +12,7 @@ # focus of this script is testing the ATTACH and DETACH commands # and related functionality. # -# $Id: attach2.test,v 1.21 2004/06/21 18:14:47 drh Exp $ +# $Id: attach2.test,v 1.22 2004/07/19 17:25:25 drh Exp $ # set testdir [file dirname $argv0] @@ -177,7 +177,7 @@ do_test attach2-4.2 { # db2 - } {} -lock_status 4.2.1 db {main shared temp shared file2 unlocked} +lock_status 4.2.1 db {main shared temp unlocked file2 unlocked} lock_status 4.2.2 db2 {main unlocked temp unlocked file2 unlocked} do_test attach2-4.3 { @@ -185,7 +185,7 @@ do_test attach2-4.3 { execsql {SELECT * FROM t1} db2 } {} -lock_status 4.3.1 db {main shared temp shared file2 unlocked} +lock_status 4.3.1 db {main shared temp unlocked file2 unlocked} lock_status 4.3.2 db2 {main unlocked temp unlocked file2 unlocked} do_test attach2-4.4 { @@ -196,7 +196,7 @@ do_test attach2-4.4 { } db2 } {1 {database is locked}} -lock_status 4.4.1 db {main shared temp shared file2 unlocked} +lock_status 4.4.1 db {main shared temp unlocked file2 unlocked} lock_status 4.4.2 db2 {main unlocked temp unlocked file2 unlocked} do_test attach2-4.5 { @@ -208,7 +208,7 @@ do_test attach2-4.5 { # db2 - reserved(file2) } {} -lock_status 4.5.1 db {main shared temp shared file2 unlocked} +lock_status 4.5.1 db {main shared temp unlocked file2 unlocked} lock_status 4.5.2 db2 {main unlocked temp reserved file2 reserved} do_test attach2-4.6.1 { @@ -221,7 +221,7 @@ do_test attach2-4.6.1 { # db2 - reserved(file2) } {0 {}} -lock_status 4.6.1.1 db {main shared temp shared file2 shared} +lock_status 4.6.1.1 db {main shared temp unlocked file2 shared} lock_status 4.6.1.2 db2 {main unlocked temp reserved file2 reserved} do_test attach2-4.6.2 { diff --git a/test/join3.test b/test/join3.test index d5b19d5a2e..19bdf01cde 100644 --- a/test/join3.test +++ b/test/join3.test @@ -13,7 +13,7 @@ # This file implements tests for joins, including outer joins, where # there are a large number of tables involved in the join. # -# $Id: join3.test,v 1.1 2004/07/19 02:12:14 drh Exp $ +# $Id: join3.test,v 1.2 2004/07/19 17:25:25 drh Exp $ set testdir [file dirname $argv0] source $testdir/tester.tcl @@ -45,14 +45,8 @@ for {set N 1} {$N<=40} {incr N} { append sql " $sep t[expr {$i+1}].x==t$i.x+1" set sep AND } -#if {$N==32} {btree_breakpoint} -#if {$N==33} { -#explain $sql -#execsql {PRAGMA vdbe_trace=on} -#} execsql $sql } $result -#if {$N==33} exit } finish_test diff --git a/test/misc4.test b/test/misc4.test index 8f0b6f6af2..32d41644a8 100644 --- a/test/misc4.test +++ b/test/misc4.test @@ -13,7 +13,7 @@ # This file implements tests for miscellanous features that were # left out of other test files. # -# $Id: misc4.test,v 1.2 2004/07/19 00:39:46 drh Exp $ +# $Id: misc4.test,v 1.3 2004/07/19 17:25:25 drh Exp $ set testdir [file dirname $argv0] source $testdir/tester.tcl @@ -41,6 +41,17 @@ do_test misc4-1.1 { SELECT * FROM temp.t2; } } {1} -catch {sqlite3_finalize $stmt} + +# Drop the temporary table, then rerun the prepared statement to +# recreate it again. This recreates ticket #807. +# +do_test misc4-1.2 { + execsql {DROP TABLE t2} + sqlite3_reset $stmt + sqlite3_step $stmt +} {SQLITE_ERROR} +do_test misc4-1.3 { + sqlite3_finalize $stmt +} {SQLITE_SCHEMA} finish_test diff --git a/test/tclsqlite.test b/test/tclsqlite.test index 00f294b50d..7ef8fe1bb4 100644 --- a/test/tclsqlite.test +++ b/test/tclsqlite.test @@ -15,7 +15,7 @@ # interface is pretty well tested. This file contains some addition # tests for fringe issues that the main test suite does not cover. # -# $Id: tclsqlite.test,v 1.26 2004/06/29 12:39:08 drh Exp $ +# $Id: tclsqlite.test,v 1.27 2004/07/19 17:25:25 drh Exp $ set testdir [file dirname $argv0] source $testdir/tester.tcl @@ -133,6 +133,7 @@ do_test tcl-1.19 { if {[sqlite3 -tcl-uses-utf]} { + catch {unset ::result} do_test tcl-2.1 { execsql "CREATE TABLE t\u0123x(a int, b\u1235 float)" execsql "PRAGMA table_info(t\u0123x)"