diff options
author | danielk1977 <danielk1977@noemail.net> | 2007-04-16 15:06:25 +0000 |
---|---|---|
committer | danielk1977 <danielk1977@noemail.net> | 2007-04-16 15:06:25 +0000 |
commit | a04a34ff1ada3cd122b336c4b781ea600fd96f55 (patch) | |
tree | 020741d15ee3daed7165662dbbfcaf3c2290022d /src | |
parent | 86a88114fa4a7c298836e4ef391416f9cf149f81 (diff) | |
download | sqlite-a04a34ff1ada3cd122b336c4b781ea600fd96f55.tar.gz sqlite-a04a34ff1ada3cd122b336c4b781ea600fd96f55.zip |
Ensure sqlite3_finalize() can be called from within the xDisconnect() method of virtual tables. (CVS 3845)
FossilOrigin-Name: 8d6c3bfc4dfdd380a2915d778e256d3e49d22d72
Diffstat (limited to 'src')
-rw-r--r-- | src/build.c | 23 | ||||
-rw-r--r-- | src/callback.c | 4 | ||||
-rw-r--r-- | src/delete.c | 4 | ||||
-rw-r--r-- | src/main.c | 5 | ||||
-rw-r--r-- | src/select.c | 6 | ||||
-rw-r--r-- | src/sqliteInt.h | 17 | ||||
-rw-r--r-- | src/tokenize.c | 4 | ||||
-rw-r--r-- | src/vdbe.c | 4 | ||||
-rw-r--r-- | src/vtab.c | 21 |
9 files changed, 51 insertions, 37 deletions
diff --git a/src/build.c b/src/build.c index 0557482ef..a5f92c9a0 100644 --- a/src/build.c +++ b/src/build.c @@ -22,7 +22,7 @@ ** COMMIT ** ROLLBACK ** -** $Id: build.c,v 1.419 2007/04/05 11:25:58 drh Exp $ +** $Id: build.c,v 1.420 2007/04/16 15:06:25 danielk1977 Exp $ */ #include "sqliteInt.h" #include <ctype.h> @@ -478,18 +478,11 @@ static void sqliteResetColumnNames(Table *pTable){ ** foreign keys from the sqlite.aFKey hash table. But it does destroy ** memory structures of the indices and foreign keys associated with ** the table. -** -** Indices associated with the table are unlinked from the "db" -** data structure if db!=NULL. If db==NULL, indices attached to -** the table are deleted, but it is assumed they have already been -** unlinked. */ -void sqlite3DeleteTable(sqlite3 *db, Table *pTable){ +void sqlite3DeleteTable(Table *pTable){ Index *pIndex, *pNext; FKey *pFKey, *pNextFKey; - db = 0; - if( pTable==0 ) return; /* Do not delete the table until the reference count reaches zero. */ @@ -509,7 +502,7 @@ void sqlite3DeleteTable(sqlite3 *db, Table *pTable){ #ifndef SQLITE_OMIT_FOREIGN_KEY /* Delete all foreign keys associated with this table. The keys - ** should have already been unlinked from the db->aFKey hash table + ** should have already been unlinked from the pSchema->aFKey hash table */ for(pFKey=pTable->pFKey; pFKey; pFKey=pNextFKey){ pNextFKey = pFKey->pNextFrom; @@ -561,7 +554,7 @@ void sqlite3UnlinkAndDeleteTable(sqlite3 *db, int iDb, const char *zTabName){ } } #endif - sqlite3DeleteTable(db, p); + sqlite3DeleteTable(p); } db->flags |= SQLITE_InternChanges; } @@ -810,7 +803,7 @@ void sqlite3StartTable( pTable->iPKey = -1; pTable->pSchema = db->aDb[iDb].pSchema; pTable->nRef = 1; - if( pParse->pNewTable ) sqlite3DeleteTable(db, pParse->pNewTable); + if( pParse->pNewTable ) sqlite3DeleteTable(pParse->pNewTable); pParse->pNewTable = pTable; /* If this is the magic sqlite_sequence table used by autoincrement, @@ -1484,7 +1477,7 @@ void sqlite3EndTable( p->aCol = pSelTab->aCol; pSelTab->nCol = 0; pSelTab->aCol = 0; - sqlite3DeleteTable(0, pSelTab); + sqlite3DeleteTable(pSelTab); } } @@ -1712,7 +1705,7 @@ int sqlite3ViewGetColumnNames(Parse *pParse, Table *pTable){ pTable->aCol = pSelTab->aCol; pSelTab->nCol = 0; pSelTab->aCol = 0; - sqlite3DeleteTable(0, pSelTab); + sqlite3DeleteTable(pSelTab); pTable->pSchema->flags |= DB_UnresetViews; }else{ pTable->nCol = 0; @@ -2959,7 +2952,7 @@ void sqlite3SrcListDelete(SrcList *pList){ sqliteFree(pItem->zDatabase); sqliteFree(pItem->zName); sqliteFree(pItem->zAlias); - sqlite3DeleteTable(0, pItem->pTab); + sqlite3DeleteTable(pItem->pTab); sqlite3SelectDelete(pItem->pSelect); sqlite3ExprDelete(pItem->pOn); sqlite3IdListDelete(pItem->pUsing); diff --git a/src/callback.c b/src/callback.c index 96985ba85..87f5b2472 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.16 2007/02/02 12:44:37 drh Exp $ +** $Id: callback.c,v 1.17 2007/04/16 15:06:25 danielk1977 Exp $ */ #include "sqliteInt.h" @@ -344,7 +344,7 @@ void sqlite3SchemaFree(void *p){ sqlite3HashInit(&pSchema->tblHash, SQLITE_HASH_STRING, 0); for(pElem=sqliteHashFirst(&temp1); pElem; pElem=sqliteHashNext(pElem)){ Table *pTab = sqliteHashData(pElem); - sqlite3DeleteTable(0, pTab); + sqlite3DeleteTable(pTab); } sqlite3HashClear(&temp1); pSchema->pSeqTab = 0; diff --git a/src/delete.c b/src/delete.c index 3022f5eb6..b30452624 100644 --- a/src/delete.c +++ b/src/delete.c @@ -12,7 +12,7 @@ ** This file contains C code routines that are called by the parser ** in order to generate code for DELETE FROM statements. ** -** $Id: delete.c,v 1.128 2007/02/07 01:06:53 drh Exp $ +** $Id: delete.c,v 1.129 2007/04/16 15:06:25 danielk1977 Exp $ */ #include "sqliteInt.h" @@ -27,7 +27,7 @@ Table *sqlite3SrcListLookup(Parse *pParse, SrcList *pSrc){ struct SrcList_item *pItem; for(i=0, pItem=pSrc->a; i<pSrc->nSrc; i++, pItem++){ pTab = sqlite3LocateTable(pParse, pItem->zName, pItem->zDatabase); - sqlite3DeleteTable(pParse->db, pItem->pTab); + sqlite3DeleteTable(pItem->pTab); pItem->pTab = pTab; if( pTab ){ pTab->nRef++; diff --git a/src/main.c b/src/main.c index cf92e14cb..12fd3e8c5 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.368 2007/04/02 16:40:38 drh Exp $ +** $Id: main.c,v 1.369 2007/04/16 15:06:25 danielk1977 Exp $ */ #include "sqliteInt.h" #include "os.h" @@ -127,8 +127,9 @@ int sqlite3_close(sqlite3 *db){ } #endif - /* If there are any outstanding VMs, return SQLITE_BUSY. */ sqlite3ResetInternalSchema(db, 0); + + /* If there are any outstanding VMs, return SQLITE_BUSY. */ if( db->pVdbe ){ sqlite3Error(db, SQLITE_BUSY, "Unable to close due to unfinalised statements"); diff --git a/src/select.c b/src/select.c index bc0c0ff52..d74873783 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.336 2007/04/13 16:06:33 drh Exp $ +** $Id: select.c,v 1.337 2007/04/16 15:06:25 danielk1977 Exp $ */ #include "sqliteInt.h" @@ -1097,7 +1097,7 @@ Table *sqlite3ResultSetOfSelect(Parse *pParse, char *zTabName, Select *pSelect){ sqlite3Dequote(zName); if( sqlite3MallocFailed() ){ sqliteFree(zName); - sqlite3DeleteTable(0, pTab); + sqlite3DeleteTable(pTab); return 0; } @@ -2216,7 +2216,7 @@ static int flattenSubquery( int nSubSrc = pSubSrc->nSrc; int jointype = pSubitem->jointype; - sqlite3DeleteTable(0, pSubitem->pTab); + sqlite3DeleteTable(pSubitem->pTab); sqliteFree(pSubitem->zDatabase); sqliteFree(pSubitem->zName); sqliteFree(pSubitem->zAlias); diff --git a/src/sqliteInt.h b/src/sqliteInt.h index 981af8045..039d22f95 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -11,7 +11,7 @@ ************************************************************************* ** Internal interface definitions for SQLite. ** -** @(#) $Id: sqliteInt.h,v 1.551 2007/04/12 03:54:39 drh Exp $ +** @(#) $Id: sqliteInt.h,v 1.552 2007/04/16 15:06:25 danielk1977 Exp $ */ #ifndef _SQLITEINT_H_ #define _SQLITEINT_H_ @@ -381,6 +381,14 @@ struct Db { /* ** An instance of the following structure stores a database schema. +** +** If there are no virtual tables configured in this schema, the +** Schema.db variable is set to NULL. After the first virtual table +** has been added, it is set to point to the database connection +** used to create the connection. Once a virtual table has been +** added to the Schema structure and the Schema.db variable populated, +** only that database connection may use the Schema to prepare +** statements. */ struct Schema { int schema_cookie; /* Database schema version number for this file */ @@ -393,6 +401,9 @@ struct Schema { u8 enc; /* Text encoding used by this database */ u16 flags; /* Flags associated with this schema */ int cache_size; /* Number of pages to use in the cache */ +#ifndef SQLITE_OMIT_VIRTUALTABLE + sqlite3 *db; /* "Owner" connection. See comment above */ +#endif }; /* @@ -1632,7 +1643,7 @@ void sqlite3CreateView(Parse*,Token*,Token*,Token*,Select*,int,int); #endif void sqlite3DropTable(Parse*, SrcList*, int, int); -void sqlite3DeleteTable(sqlite3*, Table*); +void sqlite3DeleteTable(Table*); void sqlite3Insert(Parse*, SrcList*, ExprList*, Select*, IdList*, int); void *sqlite3ArrayAllocate(void*,int,int,int*,int*,int*); IdList *sqlite3IdListAppend(IdList*, Token*); @@ -1890,7 +1901,7 @@ int sqlite3OpenTempDatabase(Parse *); int sqlite3VtabCommit(sqlite3 *db); #endif void sqlite3VtabLock(sqlite3_vtab*); -void sqlite3VtabUnlock(sqlite3_vtab*); +void sqlite3VtabUnlock(sqlite3*, sqlite3_vtab*); void sqlite3VtabBeginParse(Parse*, Token*, Token*, Token*); void sqlite3VtabFinishParse(Parse*, Token*); void sqlite3VtabArgInit(Parse*); diff --git a/src/tokenize.c b/src/tokenize.c index 691f8d731..4e915bdf8 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.125 2007/01/26 19:31:01 drh Exp $ +** $Id: tokenize.c,v 1.126 2007/04/16 15:06:25 danielk1977 Exp $ */ #include "sqliteInt.h" #include "os.h" @@ -495,7 +495,7 @@ abort_parse: ** structure built up in pParse->pNewTable. The calling code (see vtab.c) ** will take responsibility for freeing the Table structure. */ - sqlite3DeleteTable(pParse->db, pParse->pNewTable); + sqlite3DeleteTable(pParse->pNewTable); } sqlite3DeleteTrigger(pParse->pNewTrigger); diff --git a/src/vdbe.c b/src/vdbe.c index 0a23cd91f..e63d00e7c 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.598 2007/03/30 18:42:56 drh Exp $ +** $Id: vdbe.c,v 1.599 2007/04/16 15:06:25 danielk1977 Exp $ */ #include "sqliteInt.h" #include "os.h" @@ -4881,7 +4881,7 @@ case OP_VUpdate: { /* no-push */ if( sqlite3SafetyOff(db) ) goto abort_due_to_misuse; sqlite3VtabLock(pVtab); rc = pModule->xUpdate(pVtab, nArg, apArg, &rowid); - sqlite3VtabUnlock(pVtab); + sqlite3VtabUnlock(db, pVtab); if( sqlite3SafetyOn(db) ) goto abort_due_to_misuse; if( pOp->p1 && rc==SQLITE_OK ){ assert( nArg>1 && apArg[0] && (apArg[0]->flags&MEM_Null) ); diff --git a/src/vtab.c b/src/vtab.c index c08752aeb..480937aee 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.39 2007/01/09 14:01:14 drh Exp $ +** $Id: vtab.c,v 1.40 2007/04/16 15:06:26 danielk1977 Exp $ */ #ifndef SQLITE_OMIT_VIRTUALTABLE #include "sqliteInt.h" @@ -56,10 +56,18 @@ void sqlite3VtabLock(sqlite3_vtab *pVtab){ ** Unlock a virtual table. When the last lock is removed, ** disconnect the virtual table. */ -void sqlite3VtabUnlock(sqlite3_vtab *pVtab){ +void sqlite3VtabUnlock(sqlite3 *db, sqlite3_vtab *pVtab){ pVtab->nRef--; + assert(db); + assert(!sqlite3SafetyCheck(db)); if( pVtab->nRef==0 ){ - pVtab->pModule->xDisconnect(pVtab); + if( db->magic==SQLITE_MAGIC_BUSY ){ + sqlite3SafetyOff(db); + pVtab->pModule->xDisconnect(pVtab); + sqlite3SafetyOn(db); + } else { + pVtab->pModule->xDisconnect(pVtab); + } } } @@ -72,7 +80,7 @@ void sqlite3VtabClear(Table *p){ sqlite3_vtab *pVtab = p->pVtab; if( pVtab ){ assert( p->pMod && p->pMod->pModule ); - sqlite3VtabUnlock(pVtab); + sqlite3VtabUnlock(p->pSchema->db, pVtab); p->pVtab = 0; } if( p->azModuleArg ){ @@ -248,6 +256,7 @@ void sqlite3VtabFinishParse(Parse *pParse, Token *pEnd){ assert( pTab==pOld ); /* Malloc must have failed inside HashInsert() */ return; } + pSchema->db = pParse->db; pParse->pNewTable = 0; } } @@ -465,7 +474,7 @@ int sqlite3_declare_vtab(sqlite3 *db, const char *zCreateTable){ sParse.declareVtab = 0; sqlite3_finalize((sqlite3_stmt*)sParse.pVdbe); - sqlite3DeleteTable(0, sParse.pNewTable); + sqlite3DeleteTable(sParse.pNewTable); sParse.pNewTable = 0; db->pVTab = 0; @@ -518,7 +527,7 @@ static void callFinaliser(sqlite3 *db, int offset){ int (*x)(sqlite3_vtab *); x = *(int (**)(sqlite3_vtab *))((char *)pVtab->pModule + offset); if( x ) x(pVtab); - sqlite3VtabUnlock(pVtab); + sqlite3VtabUnlock(db, pVtab); } sqliteFree(db->aVTrans); db->nVTrans = 0; |