Store schema cookies on the TEMP database. Ticket #807. (CVS 1817)

FossilOrigin-Name: c6c13dc460094e6adea2b14849edf9f485238b99
This commit is contained in:
drh 2004-07-19 17:25:24 +00:00
parent 27438cf186
commit c275b4ea91
10 changed files with 80 additions and 69 deletions

View File

@ -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

View File

@ -1 +1 @@
b36e6e4907716e048fb21903e234578596c7333d
c6c13dc460094e6adea2b14849edf9f485238b99

View File

@ -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 <ctype.h>
@ -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; iDb<db->nDb; 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 && iDb<db->nDb );
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<<iDb;
if( (pParse->cookieMask & mask)==0 ){
pParse->cookieMask |= mask;
pParse->cookieValue[iDb] = db->aDb[iDb].schema_cookie;
if( iDb>=0 ){
assert( iDb<db->nDb );
assert( db->aDb[iDb].pBt!=0 || iDb==1 );
assert( iDb<32 );
mask = 1<<iDb;
if( (pParse->cookieMask & mask)==0 ){
pParse->cookieMask |= mask;
pParse->cookieValue[iDb] = db->aDb[iDb].schema_cookie;
}
}
}

View 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.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 && iDb<db->nDb; 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);

View File

@ -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->p1<db->nDb );
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;

View File

@ -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; i<pTabList->nSrc; i++){
Table *pTab;
Index *pIx;

View File

@ -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 {

View File

@ -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

View File

@ -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

View File

@ -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)"