diff options
author | drh <drh@noemail.net> | 2009-03-24 15:08:09 +0000 |
---|---|---|
committer | drh <drh@noemail.net> | 2009-03-24 15:08:09 +0000 |
commit | d9da78a2c89341d2507ff43c1732821c80ca1664 (patch) | |
tree | 56a14f20c1d1acc86755290f55d943013f9d8e42 /src | |
parent | 4be64691468e95abb6ddc33ea89333b4a63e2e08 (diff) | |
download | sqlite-d9da78a2c89341d2507ff43c1732821c80ca1664.tar.gz sqlite-d9da78a2c89341d2507ff43c1732821c80ca1664.zip |
Changes to insure that lookaside memory allocations are never used to hold
schema content.
Ticket #3743. (CVS 6377)
FossilOrigin-Name: ea74d8dc62f5784089aa8ef098e97c505a79b176
Diffstat (limited to 'src')
-rw-r--r-- | src/alter.c | 4 | ||||
-rw-r--r-- | src/build.c | 13 | ||||
-rw-r--r-- | src/callback.c | 3 | ||||
-rw-r--r-- | src/expr.c | 50 | ||||
-rw-r--r-- | src/malloc.c | 5 | ||||
-rw-r--r-- | src/parse.y | 17 | ||||
-rw-r--r-- | src/prepare.c | 21 | ||||
-rw-r--r-- | src/select.c | 6 | ||||
-rw-r--r-- | src/sqliteInt.h | 15 | ||||
-rw-r--r-- | src/tclsqlite.c | 17 | ||||
-rw-r--r-- | src/tokenize.c | 22 | ||||
-rw-r--r-- | src/vdbeblob.c | 8 | ||||
-rw-r--r-- | src/vtab.c | 5 |
13 files changed, 102 insertions, 84 deletions
diff --git a/src/alter.c b/src/alter.c index 2a1b18ea1..d89b4339b 100644 --- a/src/alter.c +++ b/src/alter.c @@ -12,7 +12,7 @@ ** This file contains C code routines that used to generate VDBE code ** that implements the ALTER TABLE command. ** -** $Id: alter.c,v 1.54 2009/02/28 10:47:42 danielk1977 Exp $ +** $Id: alter.c,v 1.55 2009/03/24 15:08:10 drh Exp $ */ #include "sqliteInt.h" @@ -593,7 +593,7 @@ void sqlite3AlterBeginAddColumn(Parse *pParse, SrcList *pSrc){ if( !pNew ) goto exit_begin_add_column; pParse->pNewTable = pNew; pNew->nRef = 1; - pNew->db = db; + pNew->dbMem = pTab->dbMem; pNew->nCol = pTab->nCol; assert( pNew->nCol>0 ); nAlloc = (((pNew->nCol-1)/8)*8)+8; diff --git a/src/build.c b/src/build.c index e9fcb27b6..f226334dd 100644 --- a/src/build.c +++ b/src/build.c @@ -22,7 +22,7 @@ ** COMMIT ** ROLLBACK ** -** $Id: build.c,v 1.525 2009/03/21 16:19:26 drh Exp $ +** $Id: build.c,v 1.526 2009/03/24 15:08:10 drh Exp $ */ #include "sqliteInt.h" @@ -339,7 +339,7 @@ Index *sqlite3FindIndex(sqlite3 *db, const char *zName, const char *zDb){ ** Reclaim the memory used by an index */ static void freeIndex(Index *p){ - sqlite3 *db = p->pTable->db; + sqlite3 *db = p->pTable->dbMem; sqlite3DbFree(db, p->zColAff); sqlite3DbFree(db, p); } @@ -467,7 +467,7 @@ void sqlite3CommitInternalChanges(sqlite3 *db){ static void sqliteResetColumnNames(Table *pTable){ int i; Column *pCol; - sqlite3 *db = pTable->db; + sqlite3 *db = pTable->dbMem; assert( pTable!=0 ); if( (pCol = pTable->aCol)!=0 ){ for(i=0; i<pTable->nCol; i++, pCol++){ @@ -498,7 +498,7 @@ void sqlite3DeleteTable(Table *pTable){ sqlite3 *db; if( pTable==0 ) return; - db = pTable->db; + db = pTable->dbMem; /* Do not delete the table until the reference count reaches zero. */ pTable->nRef--; @@ -836,7 +836,7 @@ void sqlite3StartTable( pTable->iPKey = -1; pTable->pSchema = db->aDb[iDb].pSchema; pTable->nRef = 1; - pTable->db = db; + pTable->dbMem = db->lookaside.bEnabled ? db : 0; if( pParse->pNewTable ) sqlite3DeleteTable(pParse->pNewTable); pParse->pNewTable = pTable; @@ -1855,9 +1855,11 @@ int sqlite3ViewGetColumnNames(Parse *pParse, Table *pTable){ assert( pTable->pSelect ); pSel = sqlite3SelectDup(db, pTable->pSelect, 0); if( pSel ){ + int enableLookaside = db->lookaside.bEnabled; n = pParse->nTab; sqlite3SrcListAssignCursors(pParse, pSel->pSrc); pTable->nCol = -1; + db->lookaside.bEnabled = 0; #ifndef SQLITE_OMIT_AUTHORIZATION xAuth = db->xAuth; db->xAuth = 0; @@ -1866,6 +1868,7 @@ int sqlite3ViewGetColumnNames(Parse *pParse, Table *pTable){ #else pSelTab = sqlite3ResultSetOfSelect(pParse, pSel); #endif + db->lookaside.bEnabled = enableLookaside; pParse->nTab = n; if( pSelTab ){ assert( pTable->aCol==0 ); diff --git a/src/callback.c b/src/callback.c index ca41c08f4..c4a5280d2 100644 --- a/src/callback.c +++ b/src/callback.c @@ -13,7 +13,7 @@ ** This file contains functions used to access the internal hash tables ** of user defined functions and collation sequences. ** -** $Id: callback.c,v 1.36 2009/03/05 04:20:32 shane Exp $ +** $Id: callback.c,v 1.37 2009/03/24 15:08:10 drh Exp $ */ #include "sqliteInt.h" @@ -423,6 +423,7 @@ void sqlite3SchemaFree(void *p){ sqlite3HashInit(&pSchema->tblHash, 0); for(pElem=sqliteHashFirst(&temp1); pElem; pElem=sqliteHashNext(pElem)){ Table *pTab = sqliteHashData(pElem); + assert( pTab->dbMem==0 ); sqlite3DeleteTable(pTab); } sqlite3HashClear(&temp1); diff --git a/src/expr.c b/src/expr.c index edea9224d..01e151e83 100644 --- a/src/expr.c +++ b/src/expr.c @@ -12,7 +12,7 @@ ** This file contains routines used for analyzing expressions and ** for generating VDBE code that evaluates expressions in SQLite. ** -** $Id: expr.c,v 1.421 2009/03/23 04:33:32 danielk1977 Exp $ +** $Id: expr.c,v 1.422 2009/03/24 15:08:10 drh Exp $ */ #include "sqliteInt.h" @@ -404,8 +404,22 @@ Expr *sqlite3Expr( pNew->iAgg = -1; pNew->span.z = (u8*)""; if( pToken ){ + int c; assert( pToken->dyn==0 ); - pNew->span = pNew->token = *pToken; + pNew->span = *pToken; + + /* The pToken->z value is constant and must not change. But + ** this expression might be passed to sqlite3DequoteExpr() which + ** will attempt to modify pNew->token.z. Hence, if the token + ** is quoted, make a copy now so that DequoteExpr() will change + ** the copy rather than the original (read-only) text. + */ + if( pToken->n>=2 + && ((c = pToken->z[0])=='\'' || c=='"' || c=='[' || c=='`') ){ + sqlite3TokenCopy(db, &pNew->token, pToken); + }else{ + pNew->token = *pToken; + } }else if( pLeft ){ if( pRight ){ if( pRight->span.dyn==0 && pLeft->span.dyn==0 ){ @@ -511,16 +525,15 @@ Expr *sqlite3ExprFunction(Parse *pParse, ExprList *pList, Token *pToken){ assert( pToken ); pNew = sqlite3DbMallocZero(db, sizeof(Expr) ); if( pNew==0 ){ - sqlite3ExprListDelete(db, pList); /* Avoid leaking memory when malloc fails */ + sqlite3ExprListDelete(db, pList); /* Avoid memory leak when malloc fails */ return 0; } pNew->op = TK_FUNCTION; pNew->x.pList = pList; assert( !ExprHasProperty(pNew, EP_xIsSelect) ); assert( pToken->dyn==0 ); - pNew->token = *pToken; - pNew->span = pNew->token; - + pNew->span = *pToken; + sqlite3TokenCopy(db, &pNew->token, pToken); sqlite3ExprSetHeight(pParse, pNew); return pNew; } @@ -645,27 +658,10 @@ void sqlite3ExprDelete(sqlite3 *db, Expr *p){ ** If so, remove the quotation marks. */ void sqlite3DequoteExpr(sqlite3 *db, Expr *p){ - if( ExprHasAnyProperty(p, EP_Dequoted) ){ - return; + if( !ExprHasAnyProperty(p, EP_Dequoted) ){ + ExprSetProperty(p, EP_Dequoted); + sqlite3Dequote((char*)p->token.z); } - ExprSetProperty(p, EP_Dequoted); - - /* If p->token.dyn==0 and none of EP_Reduced, EP_TokenOnly, or - ** EP_SpanOnly are set, that means that the p->token.z string points - ** back to the original SQL statement text. In that case, we need - ** to make a copy before modifying the string, otherwise we would - ** corrupt the original SQL statement text. - */ - testcase( p->token.dyn==0 && ExprHasProperty(p, EP_Reduced) ); - testcase( p->token.dyn==0 && ExprHasProperty(p, EP_TokenOnly) ); - testcase( p->token.dyn==0 && ExprHasProperty(p, EP_SpanOnly) ); - if( p->token.dyn==0 - && !ExprHasAnyProperty(p, EP_Reduced|EP_TokenOnly|EP_SpanOnly) - ){ - sqlite3TokenCopy(db, &p->token, &p->token); - } - - sqlite3Dequote((char*)p->token.z); } /* @@ -876,7 +872,7 @@ static Expr *exprDup(sqlite3 *db, Expr *p, int flags, u8 **pzBuffer){ Expr *sqlite3ExprDup(sqlite3 *db, Expr *p, int flags){ return exprDup(db, p, flags, 0); } -void sqlite3TokenCopy(sqlite3 *db, Token *pTo, Token *pFrom){ +void sqlite3TokenCopy(sqlite3 *db, Token *pTo, const Token *pFrom){ if( pTo->dyn ) sqlite3DbFree(db, (char*)pTo->z); if( pFrom->z ){ pTo->n = pFrom->n; diff --git a/src/malloc.c b/src/malloc.c index a995e2c0f..92e56394e 100644 --- a/src/malloc.c +++ b/src/malloc.c @@ -12,7 +12,7 @@ ** ** Memory allocation functions used throughout sqlite. ** -** $Id: malloc.c,v 1.60 2009/03/23 17:49:15 drh Exp $ +** $Id: malloc.c,v 1.61 2009/03/24 15:08:10 drh Exp $ */ #include "sqliteInt.h" #include <stdarg.h> @@ -565,10 +565,10 @@ void *sqlite3DbMallocZero(sqlite3 *db, int n){ */ void *sqlite3DbMallocRaw(sqlite3 *db, int n){ void *p; + assert( db==0 || sqlite3_mutex_held(db->mutex) ); #ifndef SQLITE_OMIT_LOOKASIDE if( db ){ LookasideSlot *pBuf; - assert( sqlite3_mutex_held(db->mutex) ); if( db->mallocFailed ){ return 0; } @@ -600,6 +600,7 @@ void *sqlite3DbMallocRaw(sqlite3 *db, int n){ */ void *sqlite3DbRealloc(sqlite3 *db, void *p, int n){ void *pNew = 0; + assert( db!=0 ); assert( sqlite3_mutex_held(db->mutex) ); if( db->mallocFailed==0 ){ if( p==0 ){ diff --git a/src/parse.y b/src/parse.y index 63c68ac68..1f14b4168 100644 --- a/src/parse.y +++ b/src/parse.y @@ -14,7 +14,7 @@ ** the parser. Lemon will also generate a header file containing ** numeric codes for all of the tokens. ** -** @(#) $Id: parse.y,v 1.271 2009/03/22 20:36:19 drh Exp $ +** @(#) $Id: parse.y,v 1.272 2009/03/24 15:08:10 drh Exp $ */ // All token codes are small integers with #defines that begin with "TK_" @@ -133,9 +133,13 @@ cmd ::= ROLLBACK trans_opt TO savepoint_opt nm(X). { ///////////////////// The CREATE TABLE statement //////////////////////////// // cmd ::= create_table create_table_args. -create_table ::= CREATE temp(T) TABLE ifnotexists(E) nm(Y) dbnm(Z). { +create_table ::= createkw temp(T) TABLE ifnotexists(E) nm(Y) dbnm(Z). { sqlite3StartTable(pParse,&Y,&Z,T,0,0,E); } +createkw(A) ::= CREATE(X). { + pParse->db->lookaside.bEnabled = 0; + A = X; +} %type ifnotexists {int} ifnotexists(A) ::= . {A = 0;} ifnotexists(A) ::= IF NOT EXISTS. {A = 1;} @@ -365,7 +369,7 @@ ifexists(A) ::= . {A = 0;} ///////////////////// The CREATE VIEW statement ///////////////////////////// // %ifndef SQLITE_OMIT_VIEW -cmd ::= CREATE(X) temp(T) VIEW ifnotexists(E) nm(Y) dbnm(Z) AS select(S). { +cmd ::= createkw(X) temp(T) VIEW ifnotexists(E) nm(Y) dbnm(Z) AS select(S). { sqlite3CreateView(pParse, &X, &Y, &Z, S, T, E); } cmd ::= DROP VIEW ifexists(E) fullname(X). { @@ -941,7 +945,7 @@ nexprlist(A) ::= expr(Y). ///////////////////////////// The CREATE INDEX command /////////////////////// // -cmd ::= CREATE(S) uniqueflag(U) INDEX ifnotexists(NE) nm(X) dbnm(D) +cmd ::= createkw(S) uniqueflag(U) INDEX ifnotexists(NE) nm(X) dbnm(D) ON nm(Y) LP idxlist(Z) RP(E). { sqlite3CreateIndex(pParse, &X, &D, sqlite3SrcListAppend(pParse->db,0,&Y,0), Z, U, @@ -1024,7 +1028,7 @@ plus_opt ::= . %ifndef SQLITE_OMIT_TRIGGER -cmd ::= CREATE trigger_decl(A) BEGIN trigger_cmd_list(S) END(Z). { +cmd ::= createkw trigger_decl(A) BEGIN trigger_cmd_list(S) END(Z). { Token all; all.z = A.z; all.n = (int)(Z.z - A.z) + Z.n; @@ -1170,6 +1174,7 @@ cmd ::= ALTER TABLE add_column_fullname ADD kwcolumn_opt column(Y). { sqlite3AlterFinishAddColumn(pParse, &Y); } add_column_fullname ::= fullname(X). { + pParse->db->lookaside.bEnabled = 0; sqlite3AlterBeginAddColumn(pParse, X); } kwcolumn_opt ::= . @@ -1180,7 +1185,7 @@ kwcolumn_opt ::= COLUMNKW. %ifndef SQLITE_OMIT_VIRTUALTABLE cmd ::= create_vtab. {sqlite3VtabFinishParse(pParse,0);} cmd ::= create_vtab LP vtabarglist RP(X). {sqlite3VtabFinishParse(pParse,&X);} -create_vtab ::= CREATE VIRTUAL TABLE nm(X) dbnm(Y) USING nm(Z). { +create_vtab ::= createkw VIRTUAL TABLE nm(X) dbnm(Y) USING nm(Z). { sqlite3VtabBeginParse(pParse, &X, &Y, &Z); } vtabarglist ::= vtabarg. diff --git a/src/prepare.c b/src/prepare.c index 1f5853817..dc576959f 100644 --- a/src/prepare.c +++ b/src/prepare.c @@ -13,7 +13,7 @@ ** interface, and routines that contribute to loading the database schema ** from disk. ** -** $Id: prepare.c,v 1.113 2009/03/24 04:46:08 danielk1977 Exp $ +** $Id: prepare.c,v 1.114 2009/03/24 15:08:10 drh Exp $ */ #include "sqliteInt.h" @@ -74,33 +74,14 @@ int sqlite3InitCallback(void *pInit, int argc, char **argv, char **NotUsed){ ** But because db->init.busy is set to 1, no VDBE code is generated ** or executed. All the parser does is build the internal data ** structures that describe the table, index, or view. - ** - ** While the CREATE XXX statement is being processed, the lookaside - ** buffer is disabled. One reason for this is that when running in - ** shared cache mode, the objects allocated for the in-memory schema - ** might be freed from within a call made on a different database - ** connection to db (e.g. if the second connection executes a DROP - ** TABLE statement). If the objects that make up the Table structure - ** are allocated from within db's lookaside buffer, then db->mutex - ** would have to be obtained before they could be freed. This would - ** open the door to deadlock in a multi-threaded application. - ** - ** Another reason to disable the lookaside buffer is that lookaside - ** gives the greatest performance boost when it is used to allocate - ** and free small transient objects. The schema objects, which tend - ** to have long lifetimes, are better allocated from the heap. */ char *zErr; int rc; - u8 lookasideEnabled; assert( db->init.busy ); db->init.iDb = iDb; db->init.newTnum = atoi(argv[1]); - lookasideEnabled = db->lookaside.bEnabled; - db->lookaside.bEnabled = 0; rc = sqlite3_exec(db, argv[2], 0, 0, &zErr); db->init.iDb = 0; - db->lookaside.bEnabled = lookasideEnabled; assert( rc!=SQLITE_OK || zErr==0 ); if( SQLITE_OK!=rc ){ pData->rc = rc; diff --git a/src/select.c b/src/select.c index 6c5c232e7..86c0c8c9f 100644 --- a/src/select.c +++ b/src/select.c @@ -12,7 +12,7 @@ ** This file contains C code routines that are called by the parser ** to handle SELECT statements in SQLite. ** -** $Id: select.c,v 1.504 2009/02/25 08:56:47 danielk1977 Exp $ +** $Id: select.c,v 1.505 2009/03/24 15:08:10 drh Exp $ */ #include "sqliteInt.h" @@ -1284,7 +1284,7 @@ Table *sqlite3ResultSetOfSelect(Parse *pParse, Select *pSelect){ if( pTab==0 ){ return 0; } - pTab->db = db; + pTab->dbMem = db->lookaside.bEnabled ? db : 0; pTab->nRef = 1; pTab->zName = 0; selectColumnsFromExprList(pParse, pSelect->pEList, &pTab->nCol, &pTab->aCol); @@ -3080,7 +3080,7 @@ static int selectExpander(Walker *pWalker, Select *p){ sqlite3WalkSelect(pWalker, pSel); pFrom->pTab = pTab = sqlite3DbMallocZero(db, sizeof(Table)); if( pTab==0 ) return WRC_Abort; - pTab->db = db; + pTab->dbMem = db->lookaside.bEnabled ? db : 0; pTab->nRef = 1; pTab->zName = sqlite3MPrintf(db, "sqlite_subquery_%p_", (void*)pTab); while( pSel->pPrior ){ pSel = pSel->pPrior; } diff --git a/src/sqliteInt.h b/src/sqliteInt.h index 67836d1b0..bb79aaa7c 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -11,7 +11,7 @@ ************************************************************************* ** Internal interface definitions for SQLite. ** -** @(#) $Id: sqliteInt.h,v 1.845 2009/03/23 04:33:33 danielk1977 Exp $ +** @(#) $Id: sqliteInt.h,v 1.846 2009/03/24 15:08:10 drh Exp $ */ #ifndef _SQLITEINT_H_ #define _SQLITEINT_H_ @@ -686,10 +686,17 @@ struct Schema { ** lookaside malloc subsystem. Each available memory allocation in ** the lookaside subsystem is stored on a linked list of LookasideSlot ** objects. +** +** Lookaside allocations are only allowed for objects that are associated +** with a particular database connection. Hence, schema information cannot +** be stored in lookaside because in shared cache mode the schema information +** is shared by multiple database connections. Therefore, while parsing +** schema information, the Lookaside.bEnabled flag is cleared so that +** lookaside allocations are not used to construct the schema objects. */ struct Lookaside { u16 sz; /* Size of each buffer in bytes */ - u8 bEnabled; /* True if use lookaside. False to ignore it */ + u8 bEnabled; /* False to disable new lookaside allocations */ u8 bMalloced; /* True if pStart obtained from sqlite3_malloc() */ int nOut; /* Number of buffers currently checked out */ int mxOut; /* Highwater mark for nOut */ @@ -1105,7 +1112,7 @@ struct CollSeq { ** of a SELECT statement. */ struct Table { - sqlite3 *db; /* Associated database connection. Might be NULL. */ + sqlite3 *dbMem; /* DB connection used for lookaside allocations. */ char *zName; /* Name of the table or view */ int iPKey; /* If not negative, use aCol[iPKey] as the primary key */ int nCol; /* Number of columns in this table */ @@ -2466,7 +2473,7 @@ void sqlite3CompleteInsertion(Parse*, Table*, int, int, int*, int, int, int); int sqlite3OpenTableAndIndices(Parse*, Table*, int, int); void sqlite3BeginWriteOperation(Parse*, int, int); Expr *sqlite3ExprDup(sqlite3*,Expr*,int); -void sqlite3TokenCopy(sqlite3*,Token*, Token*); +void sqlite3TokenCopy(sqlite3*,Token*,const Token*); ExprList *sqlite3ExprListDup(sqlite3*,ExprList*,int); SrcList *sqlite3SrcListDup(sqlite3*,SrcList*,int); IdList *sqlite3IdListDup(sqlite3*,IdList*); diff --git a/src/tclsqlite.c b/src/tclsqlite.c index a429662d8..8959e6074 100644 --- a/src/tclsqlite.c +++ b/src/tclsqlite.c @@ -12,7 +12,7 @@ ** A TCL Interface to SQLite. Append this file to sqlite3.c and ** compile the whole thing to build a TCL-enabled version of SQLite. ** -** $Id: tclsqlite.c,v 1.238 2009/03/16 13:19:36 danielk1977 Exp $ +** $Id: tclsqlite.c,v 1.239 2009/03/24 15:08:10 drh Exp $ */ #include "tcl.h" #include <errno.h> @@ -2593,8 +2593,21 @@ static int DbMain(void *cd, Tcl_Interp *interp, int objc,Tcl_Obj *const*objv){ int i; const char *zFile; const char *zVfs = 0; - int flags = SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE | SQLITE_OPEN_NOMUTEX; + int flags; Tcl_DString translatedFilename; + + /* In normal use, each TCL interpreter runs in a single thread. So + ** by default, we can turn of mutexing on SQLite database connections. + ** However, for testing purposes it is useful to have mutexes turned + ** on. So, by default, mutexes default off. But if compiled with + ** SQLITE_TCL_DEFAULT_FULLMUTEX then mutexes default on. + */ +#ifdef SQLITE_TCL_DEFAULT_FULLMUTEX + flags = SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE | SQLITE_OPEN_FULLMUTEX; +#else + flags = SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE | SQLITE_OPEN_NOMUTEX; +#endif + if( objc==2 ){ zArg = Tcl_GetStringFromObj(objv[1], 0); if( strcmp(zArg,"-version")==0 ){ diff --git a/src/tokenize.c b/src/tokenize.c index afc3dd639..60313aef4 100644 --- a/src/tokenize.c +++ b/src/tokenize.c @@ -15,7 +15,7 @@ ** individual tokens and sends those tokens one-by-one over to the ** parser for analysis. ** -** $Id: tokenize.c,v 1.153 2009/01/20 16:53:41 danielk1977 Exp $ +** $Id: tokenize.c,v 1.154 2009/03/24 15:08:10 drh Exp $ */ #include "sqliteInt.h" #include <stdlib.h> @@ -381,14 +381,17 @@ int sqlite3GetToken(const unsigned char *z, int *tokenType){ ** error message. */ int sqlite3RunParser(Parse *pParse, const char *zSql, char **pzErrMsg){ - int nErr = 0; - int i; - void *pEngine; - int tokenType; - int lastTokenParsed = -1; - sqlite3 *db = pParse->db; - int mxSqlLen = db->aLimit[SQLITE_LIMIT_SQL_LENGTH]; + int nErr = 0; /* Number of errors encountered */ + int i; /* Loop counter */ + void *pEngine; /* The LEMON-generated LALR(1) parser */ + int tokenType; /* type of the next token */ + int lastTokenParsed = -1; /* type of the previous token */ + int enableLookaside; /* Saved value of db->lookaside.bEnabled */ + sqlite3 *db = pParse->db; /* The database connection */ + int mxSqlLen; /* Max length of an SQL string */ + + mxSqlLen = db->aLimit[SQLITE_LIMIT_SQL_LENGTH]; if( db->activeVdbeCnt==0 ){ db->u1.isInterrupted = 0; } @@ -408,6 +411,8 @@ int sqlite3RunParser(Parse *pParse, const char *zSql, char **pzErrMsg){ assert( pParse->nVarExpr==0 ); assert( pParse->nVarExprAlloc==0 ); assert( pParse->apVarExpr==0 ); + enableLookaside = db->lookaside.bEnabled; + if( db->lookaside.pStart ) db->lookaside.bEnabled = 1; while( !db->mallocFailed && zSql[i]!=0 ){ assert( i>=0 ); pParse->sLastToken.z = (u8*)&zSql[i]; @@ -462,6 +467,7 @@ abort_parse: ); #endif /* YYDEBUG */ sqlite3ParserFree(pEngine, sqlite3_free); + db->lookaside.bEnabled = enableLookaside; if( db->mallocFailed ){ pParse->rc = SQLITE_NOMEM; } diff --git a/src/vdbeblob.c b/src/vdbeblob.c index 82844675b..de051e1ee 100644 --- a/src/vdbeblob.c +++ b/src/vdbeblob.c @@ -12,7 +12,7 @@ ** ** This file contains code used to implement incremental BLOB I/O. ** -** $Id: vdbeblob.c,v 1.30 2009/03/19 18:51:07 danielk1977 Exp $ +** $Id: vdbeblob.c,v 1.31 2009/03/24 15:08:10 drh Exp $ */ #include "sqliteInt.h" @@ -264,9 +264,13 @@ blob_open_out: int sqlite3_blob_close(sqlite3_blob *pBlob){ Incrblob *p = (Incrblob *)pBlob; int rc; + sqlite3 *db; + db = p->db; + sqlite3_mutex_enter(db->mutex); rc = sqlite3_finalize(p->pStmt); - sqlite3DbFree(p->db, p); + sqlite3DbFree(db, p); + sqlite3_mutex_leave(db->mutex); return rc; } diff --git a/src/vtab.c b/src/vtab.c index a5865d893..bfa88e9db 100644 --- a/src/vtab.c +++ b/src/vtab.c @@ -11,7 +11,7 @@ ************************************************************************* ** This file contains code used to help implement virtual tables. ** -** $Id: vtab.c,v 1.83 2009/03/19 18:51:07 danielk1977 Exp $ +** $Id: vtab.c,v 1.84 2009/03/24 15:08:10 drh Exp $ */ #ifndef SQLITE_OMIT_VIRTUALTABLE #include "sqliteInt.h" @@ -118,7 +118,8 @@ void sqlite3VtabUnlock(sqlite3 *db, sqlite3_vtab *pVtab){ */ void sqlite3VtabClear(Table *p){ sqlite3_vtab *pVtab = p->pVtab; - sqlite3 *db = p->db; + Schema *pSchema = p->pSchema; + sqlite3 *db = pSchema ? pSchema->db : 0; if( pVtab ){ assert( p->pMod && p->pMod->pModule ); sqlite3VtabUnlock(db, pVtab); |