aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authordanielk1977 <danielk1977@noemail.net>2007-04-16 15:06:25 +0000
committerdanielk1977 <danielk1977@noemail.net>2007-04-16 15:06:25 +0000
commita04a34ff1ada3cd122b336c4b781ea600fd96f55 (patch)
tree020741d15ee3daed7165662dbbfcaf3c2290022d /src
parent86a88114fa4a7c298836e4ef391416f9cf149f81 (diff)
downloadsqlite-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.c23
-rw-r--r--src/callback.c4
-rw-r--r--src/delete.c4
-rw-r--r--src/main.c5
-rw-r--r--src/select.c6
-rw-r--r--src/sqliteInt.h17
-rw-r--r--src/tokenize.c4
-rw-r--r--src/vdbe.c4
-rw-r--r--src/vtab.c21
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;