| 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;
|
| }
|
|
|
|
|