Index: third_party/sqlite/src/src/vtab.c |
diff --git a/third_party/sqlite/src/src/vtab.c b/third_party/sqlite/src/src/vtab.c |
index 117f36183bfb9d2ebc668d03220656ae1f0d63a2..b052de23a5ff5c7b32511ab5faed98dbb4efcc07 100644 |
--- a/third_party/sqlite/src/src/vtab.c |
+++ b/third_party/sqlite/src/src/vtab.c |
@@ -10,8 +10,6 @@ |
** |
************************************************************************* |
** This file contains code used to help implement virtual tables. |
-** |
-** $Id: vtab.c,v 1.94 2009/08/08 18:01:08 drh Exp $ |
*/ |
#ifndef SQLITE_OMIT_VIRTUALTABLE |
#include "sqliteInt.h" |
@@ -50,7 +48,7 @@ static int createModule( |
if( pDel==pMod ){ |
db->mallocFailed = 1; |
} |
- sqlite3ResetInternalSchema(db, 0); |
+ sqlite3ResetInternalSchema(db, -1); |
}else if( xDestroy ){ |
xDestroy(pAux); |
} |
@@ -125,16 +123,7 @@ void sqlite3VtabUnlock(VTable *pVTab){ |
if( pVTab->nRef==0 ){ |
sqlite3_vtab *p = pVTab->pVtab; |
if( p ){ |
-#ifdef SQLITE_DEBUG |
- if( pVTab->db->magic==SQLITE_MAGIC_BUSY ){ |
- (void)sqlite3SafetyOff(db); |
- p->pModule->xDisconnect(p); |
- (void)sqlite3SafetyOn(db); |
- } else |
-#endif |
- { |
- p->pModule->xDisconnect(p); |
- } |
+ p->pModule->xDisconnect(p); |
} |
sqlite3DbFree(db, pVTab); |
} |
@@ -156,10 +145,9 @@ static VTable *vtabDisconnectAll(sqlite3 *db, Table *p){ |
** that contains table p is held by the caller. See header comments |
** above function sqlite3VtabUnlockList() for an explanation of why |
** this makes it safe to access the sqlite3.pDisconnect list of any |
- ** database connection that may have an entry in the p->pVTable list. */ |
- assert( db==0 || |
- sqlite3BtreeHoldsMutex(db->aDb[sqlite3SchemaToIndex(db, p->pSchema)].pBt) |
- ); |
+ ** database connection that may have an entry in the p->pVTable list. |
+ */ |
+ assert( db==0 || sqlite3SchemaMutexHeld(db, 0, p->pSchema) ); |
while( pVTable ){ |
sqlite3 *db2 = pVTable->db; |
@@ -232,14 +220,14 @@ void sqlite3VtabUnlockList(sqlite3 *db){ |
** in the list are moved to the sqlite3.pDisconnect list of the associated |
** database connection. |
*/ |
-void sqlite3VtabClear(Table *p){ |
- vtabDisconnectAll(0, p); |
+void sqlite3VtabClear(sqlite3 *db, Table *p){ |
+ if( !db || db->pnBytesFreed==0 ) vtabDisconnectAll(0, p); |
if( p->azModuleArg ){ |
int i; |
for(i=0; i<p->nModuleArg; i++){ |
- sqlite3DbFree(p->dbMem, p->azModuleArg[i]); |
+ sqlite3DbFree(db, p->azModuleArg[i]); |
} |
- sqlite3DbFree(p->dbMem, p->azModuleArg); |
+ sqlite3DbFree(db, p->azModuleArg); |
} |
} |
@@ -382,8 +370,8 @@ void sqlite3VtabFinishParse(Parse *pParse, Token *pEnd){ |
sqlite3ChangeCookie(pParse, iDb); |
sqlite3VdbeAddOp2(v, OP_Expire, 0, 0); |
- zWhere = sqlite3MPrintf(db, "name='%q'", pTab->zName); |
- sqlite3VdbeAddOp4(v, OP_ParseSchema, iDb, 1, 0, zWhere, P4_DYNAMIC); |
+ zWhere = sqlite3MPrintf(db, "name='%q' AND type='table'", pTab->zName); |
+ sqlite3VdbeAddOp4(v, OP_ParseSchema, iDb, 0, 0, zWhere, P4_DYNAMIC); |
sqlite3VdbeAddOp4(v, OP_VCreate, iDb, 0, 0, |
pTab->zName, sqlite3Strlen30(pTab->zName) + 1); |
} |
@@ -398,13 +386,13 @@ void sqlite3VtabFinishParse(Parse *pParse, Token *pEnd){ |
Schema *pSchema = pTab->pSchema; |
const char *zName = pTab->zName; |
int nName = sqlite3Strlen30(zName); |
+ assert( sqlite3SchemaMutexHeld(db, 0, pSchema) ); |
pOld = sqlite3HashInsert(&pSchema->tblHash, zName, nName, pTab); |
if( pOld ){ |
db->mallocFailed = 1; |
assert( pTab==pOld ); /* Malloc must have failed inside HashInsert() */ |
return; |
} |
- pSchema->db = pParse->db; |
pParse->pNewTable = 0; |
} |
} |
@@ -470,9 +458,7 @@ static int vtabCallConstructor( |
db->pVTab = pTab; |
/* Invoke the virtual table constructor */ |
- (void)sqlite3SafetyOff(db); |
rc = xConstruct(db, pMod->pAux, nArg, azArg, &pVTable->pVtab, &zErr); |
- (void)sqlite3SafetyOn(db); |
if( rc==SQLITE_NOMEM ) db->mallocFailed = 1; |
if( SQLITE_OK!=rc ){ |
@@ -480,7 +466,7 @@ static int vtabCallConstructor( |
*pzErr = sqlite3MPrintf(db, "vtable constructor failed: %s", zModuleName); |
}else { |
*pzErr = sqlite3MPrintf(db, "%s", zErr); |
- sqlite3DbFree(db, zErr); |
+ sqlite3_free(zErr); |
} |
sqlite3DbFree(db, pVTable); |
}else if( ALWAYS(pVTable->pVtab) ){ |
@@ -660,7 +646,7 @@ int sqlite3_declare_vtab(sqlite3 *db, const char *zCreateTable){ |
if( !pTab ){ |
sqlite3Error(db, SQLITE_MISUSE, 0); |
sqlite3_mutex_leave(db->mutex); |
- return SQLITE_MISUSE; |
+ return SQLITE_MISUSE_BKPT; |
} |
assert( (pTab->tabFlags & TF_Virtual)!=0 ); |
@@ -670,12 +656,13 @@ int sqlite3_declare_vtab(sqlite3 *db, const char *zCreateTable){ |
}else{ |
pParse->declareVtab = 1; |
pParse->db = db; |
+ pParse->nQueryLoop = 1; |
- if( |
- SQLITE_OK == sqlite3RunParser(pParse, zCreateTable, &zErr) && |
- pParse->pNewTable && |
- !pParse->pNewTable->pSelect && |
- (pParse->pNewTable->tabFlags & TF_Virtual)==0 |
+ if( SQLITE_OK==sqlite3RunParser(pParse, zCreateTable, &zErr) |
+ && pParse->pNewTable |
+ && !db->mallocFailed |
+ && !pParse->pNewTable->pSelect |
+ && (pParse->pNewTable->tabFlags & TF_Virtual)==0 |
){ |
if( !pTab->aCol ){ |
pTab->aCol = pParse->pNewTable->aCol; |
@@ -684,8 +671,8 @@ int sqlite3_declare_vtab(sqlite3 *db, const char *zCreateTable){ |
pParse->pNewTable->aCol = 0; |
} |
db->pVTab = 0; |
- } else { |
- sqlite3Error(db, SQLITE_ERROR, zErr); |
+ }else{ |
+ sqlite3Error(db, SQLITE_ERROR, (zErr ? "%s" : 0), zErr); |
sqlite3DbFree(db, zErr); |
rc = SQLITE_ERROR; |
} |
@@ -694,7 +681,7 @@ int sqlite3_declare_vtab(sqlite3 *db, const char *zCreateTable){ |
if( pParse->pVdbe ){ |
sqlite3VdbeFinalize(pParse->pVdbe); |
} |
- sqlite3DeleteTable(pParse->pNewTable); |
+ sqlite3DeleteTable(db, pParse->pNewTable); |
sqlite3StackFree(db, pParse); |
} |
@@ -719,10 +706,8 @@ int sqlite3VtabCallDestroy(sqlite3 *db, int iDb, const char *zTab){ |
if( ALWAYS(pTab!=0 && pTab->pVTable!=0) ){ |
VTable *p = vtabDisconnectAll(db, pTab); |
- rc = sqlite3SafetyOff(db); |
assert( rc==SQLITE_OK ); |
rc = p->pMod->pModule->xDestroy(p->pVtab); |
- (void)sqlite3SafetyOn(db); |
/* Remove the sqlite3_vtab* from the aVTrans[] array, if applicable */ |
if( rc==SQLITE_OK ){ |
@@ -774,10 +759,8 @@ static void callFinaliser(sqlite3 *db, int offset){ |
int sqlite3VtabSync(sqlite3 *db, char **pzErrmsg){ |
int i; |
int rc = SQLITE_OK; |
- int rcsafety; |
VTable **aVTrans = db->aVTrans; |
- rc = sqlite3SafetyOff(db); |
db->aVTrans = 0; |
for(i=0; rc==SQLITE_OK && i<db->nVTrans; i++){ |
int (*x)(sqlite3_vtab *); |
@@ -785,16 +768,11 @@ int sqlite3VtabSync(sqlite3 *db, char **pzErrmsg){ |
if( pVtab && (x = pVtab->pModule->xSync)!=0 ){ |
rc = x(pVtab); |
sqlite3DbFree(db, *pzErrmsg); |
- *pzErrmsg = pVtab->zErrMsg; |
- pVtab->zErrMsg = 0; |
+ *pzErrmsg = sqlite3DbStrDup(db, pVtab->zErrMsg); |
+ sqlite3_free(pVtab->zErrMsg); |
} |
} |
db->aVTrans = aVTrans; |
- rcsafety = sqlite3SafetyOn(db); |
- |
- if( rc==SQLITE_OK ){ |
- rc = rcsafety; |
- } |
return rc; |
} |