ds@1952: /* ds@1952: ** 2006 June 10 ds@1952: ** ds@1952: ** The author disclaims copyright to this source code. In place of ds@1952: ** a legal notice, here is a blessing: ds@1952: ** ds@1952: ** May you do good and not evil. ds@1952: ** May you find forgiveness for yourself and forgive others. ds@1952: ** May you share freely, never taking more than you give. ds@1952: ** ds@1952: ************************************************************************* ds@1952: ** This file contains code used to help implement virtual tables. ds@1952: ** ds@1952: ** $Id$ ds@1952: */ ds@1952: #ifndef SQLITE_OMIT_VIRTUALTABLE ds@1952: #include "sqliteInt.h" ds@1952: ds@1952: static int createModule( ds@1952: sqlite3 *db, /* Database in which module is registered */ ds@1952: const char *zName, /* Name assigned to this module */ ds@1952: const sqlite3_module *pModule, /* The definition of the module */ ds@1952: void *pAux, /* Context pointer for xCreate/xConnect */ ds@1952: void (*xDestroy)(void *) /* Module destructor function */ ds@1952: ) { ds@1952: int rc, nName; ds@1952: Module *pMod; ds@1952: ds@1952: sqlite3_mutex_enter(db->mutex); ds@1952: nName = strlen(zName); ds@1952: pMod = (Module *)sqlite3DbMallocRaw(db, sizeof(Module) + nName + 1); ds@1952: if( pMod ){ ds@1952: char *zCopy = (char *)(&pMod[1]); ds@1952: memcpy(zCopy, zName, nName+1); ds@1952: pMod->zName = zCopy; ds@1952: pMod->pModule = pModule; ds@1952: pMod->pAux = pAux; ds@1952: pMod->xDestroy = xDestroy; ds@1952: pMod = (Module *)sqlite3HashInsert(&db->aModule, zCopy, nName, (void*)pMod); ds@1952: if( pMod && pMod->xDestroy ){ ds@1952: pMod->xDestroy(pMod->pAux); ds@1952: } ds@1952: sqlite3_free(pMod); ds@1952: sqlite3ResetInternalSchema(db, 0); ds@1952: } ds@1952: rc = sqlite3ApiExit(db, SQLITE_OK); ds@1952: sqlite3_mutex_leave(db->mutex); ds@1952: return rc; ds@1952: } ds@1952: ds@1952: ds@1952: /* ds@1952: ** External API function used to create a new virtual-table module. ds@1952: */ ds@1952: int sqlite3_create_module( ds@1952: sqlite3 *db, /* Database in which module is registered */ ds@1952: const char *zName, /* Name assigned to this module */ ds@1952: const sqlite3_module *pModule, /* The definition of the module */ ds@1952: void *pAux /* Context pointer for xCreate/xConnect */ ds@1952: ){ ds@1952: return createModule(db, zName, pModule, pAux, 0); ds@1952: } ds@1952: ds@1952: /* ds@1952: ** External API function used to create a new virtual-table module. ds@1952: */ ds@1952: int sqlite3_create_module_v2( ds@1952: sqlite3 *db, /* Database in which module is registered */ ds@1952: const char *zName, /* Name assigned to this module */ ds@1952: const sqlite3_module *pModule, /* The definition of the module */ ds@1952: void *pAux, /* Context pointer for xCreate/xConnect */ ds@1952: void (*xDestroy)(void *) /* Module destructor function */ ds@1952: ){ ds@1952: return createModule(db, zName, pModule, pAux, xDestroy); ds@1952: } ds@1952: ds@1952: /* ds@1952: ** Lock the virtual table so that it cannot be disconnected. ds@1952: ** Locks nest. Every lock should have a corresponding unlock. ds@1952: ** If an unlock is omitted, resources leaks will occur. ds@1952: ** ds@1952: ** If a disconnect is attempted while a virtual table is locked, ds@1952: ** the disconnect is deferred until all locks have been removed. ds@1952: */ ds@1952: void sqlite3VtabLock(sqlite3_vtab *pVtab){ ds@1952: pVtab->nRef++; ds@1952: } ds@1952: ds@1952: /* ds@1952: ** Unlock a virtual table. When the last lock is removed, ds@1952: ** disconnect the virtual table. ds@1952: */ ds@1952: void sqlite3VtabUnlock(sqlite3 *db, sqlite3_vtab *pVtab){ ds@1952: pVtab->nRef--; ds@1952: assert(db); ds@1952: assert(!sqlite3SafetyCheck(db)); ds@1952: if( pVtab->nRef==0 ){ ds@1952: if( db->magic==SQLITE_MAGIC_BUSY ){ ds@1952: sqlite3SafetyOff(db); ds@1952: pVtab->pModule->xDisconnect(pVtab); ds@1952: sqlite3SafetyOn(db); ds@1952: } else { ds@1952: pVtab->pModule->xDisconnect(pVtab); ds@1952: } ds@1952: } ds@1952: } ds@1952: ds@1952: /* ds@1952: ** Clear any and all virtual-table information from the Table record. ds@1952: ** This routine is called, for example, just before deleting the Table ds@1952: ** record. ds@1952: */ ds@1952: void sqlite3VtabClear(Table *p){ ds@1952: sqlite3_vtab *pVtab = p->pVtab; ds@1952: if( pVtab ){ ds@1952: assert( p->pMod && p->pMod->pModule ); ds@1952: sqlite3VtabUnlock(p->pSchema->db, pVtab); ds@1952: p->pVtab = 0; ds@1952: } ds@1952: if( p->azModuleArg ){ ds@1952: int i; ds@1952: for(i=0; inModuleArg; i++){ ds@1952: sqlite3_free(p->azModuleArg[i]); ds@1952: } ds@1952: sqlite3_free(p->azModuleArg); ds@1952: } ds@1952: } ds@1952: ds@1952: /* ds@1952: ** Add a new module argument to pTable->azModuleArg[]. ds@1952: ** The string is not copied - the pointer is stored. The ds@1952: ** string will be freed automatically when the table is ds@1952: ** deleted. ds@1952: */ ds@1952: static void addModuleArgument(sqlite3 *db, Table *pTable, char *zArg){ ds@1952: int i = pTable->nModuleArg++; ds@1952: int nBytes = sizeof(char *)*(1+pTable->nModuleArg); ds@1952: char **azModuleArg; ds@1952: azModuleArg = sqlite3DbRealloc(db, pTable->azModuleArg, nBytes); ds@1952: if( azModuleArg==0 ){ ds@1952: int j; ds@1952: for(j=0; jazModuleArg[j]); ds@1952: } ds@1952: sqlite3_free(zArg); ds@1952: sqlite3_free(pTable->azModuleArg); ds@1952: pTable->nModuleArg = 0; ds@1952: }else{ ds@1952: azModuleArg[i] = zArg; ds@1952: azModuleArg[i+1] = 0; ds@1952: } ds@1952: pTable->azModuleArg = azModuleArg; ds@1952: } ds@1952: ds@1952: /* ds@1952: ** The parser calls this routine when it first sees a CREATE VIRTUAL TABLE ds@1952: ** statement. The module name has been parsed, but the optional list ds@1952: ** of parameters that follow the module name are still pending. ds@1952: */ ds@1952: void sqlite3VtabBeginParse( ds@1952: Parse *pParse, /* Parsing context */ ds@1952: Token *pName1, /* Name of new table, or database name */ ds@1952: Token *pName2, /* Name of new table or NULL */ ds@1952: Token *pModuleName /* Name of the module for the virtual table */ ds@1952: ){ ds@1952: int iDb; /* The database the table is being created in */ ds@1952: Table *pTable; /* The new virtual table */ ds@1952: sqlite3 *db; /* Database connection */ ds@1952: ds@1952: if( pParse->db->flags & SQLITE_SharedCache ){ ds@1952: sqlite3ErrorMsg(pParse, "Cannot use virtual tables in shared-cache mode"); ds@1952: return; ds@1952: } ds@1952: ds@1952: sqlite3StartTable(pParse, pName1, pName2, 0, 0, 1, 0); ds@1952: pTable = pParse->pNewTable; ds@1952: if( pTable==0 || pParse->nErr ) return; ds@1952: assert( 0==pTable->pIndex ); ds@1952: ds@1952: db = pParse->db; ds@1952: iDb = sqlite3SchemaToIndex(db, pTable->pSchema); ds@1952: assert( iDb>=0 ); ds@1952: ds@1952: pTable->isVirtual = 1; ds@1952: pTable->nModuleArg = 0; ds@1952: addModuleArgument(db, pTable, sqlite3NameFromToken(db, pModuleName)); ds@1952: addModuleArgument(db, pTable, sqlite3DbStrDup(db, db->aDb[iDb].zName)); ds@1952: addModuleArgument(db, pTable, sqlite3DbStrDup(db, pTable->zName)); ds@1952: pParse->sNameToken.n = pModuleName->z + pModuleName->n - pName1->z; ds@1952: ds@1952: #ifndef SQLITE_OMIT_AUTHORIZATION ds@1952: /* Creating a virtual table invokes the authorization callback twice. ds@1952: ** The first invocation, to obtain permission to INSERT a row into the ds@1952: ** sqlite_master table, has already been made by sqlite3StartTable(). ds@1952: ** The second call, to obtain permission to create the table, is made now. ds@1952: */ ds@1952: if( pTable->azModuleArg ){ ds@1952: sqlite3AuthCheck(pParse, SQLITE_CREATE_VTABLE, pTable->zName, ds@1952: pTable->azModuleArg[0], pParse->db->aDb[iDb].zName); ds@1952: } ds@1952: #endif ds@1952: } ds@1952: ds@1952: /* ds@1952: ** This routine takes the module argument that has been accumulating ds@1952: ** in pParse->zArg[] and appends it to the list of arguments on the ds@1952: ** virtual table currently under construction in pParse->pTable. ds@1952: */ ds@1952: static void addArgumentToVtab(Parse *pParse){ ds@1952: if( pParse->sArg.z && pParse->pNewTable ){ ds@1952: const char *z = (const char*)pParse->sArg.z; ds@1952: int n = pParse->sArg.n; ds@1952: sqlite3 *db = pParse->db; ds@1952: addModuleArgument(db, pParse->pNewTable, sqlite3DbStrNDup(db, z, n)); ds@1952: } ds@1952: } ds@1952: ds@1952: /* ds@1952: ** The parser calls this routine after the CREATE VIRTUAL TABLE statement ds@1952: ** has been completely parsed. ds@1952: */ ds@1952: void sqlite3VtabFinishParse(Parse *pParse, Token *pEnd){ ds@1952: Table *pTab; /* The table being constructed */ ds@1952: sqlite3 *db; /* The database connection */ ds@1952: char *zModule; /* The module name of the table: USING modulename */ ds@1952: Module *pMod = 0; ds@1952: ds@1952: addArgumentToVtab(pParse); ds@1952: pParse->sArg.z = 0; ds@1952: ds@1952: /* Lookup the module name. */ ds@1952: pTab = pParse->pNewTable; ds@1952: if( pTab==0 ) return; ds@1952: db = pParse->db; ds@1952: if( pTab->nModuleArg<1 ) return; ds@1952: zModule = pTab->azModuleArg[0]; ds@1952: pMod = (Module *)sqlite3HashFind(&db->aModule, zModule, strlen(zModule)); ds@1952: pTab->pMod = pMod; ds@1952: ds@1952: /* If the CREATE VIRTUAL TABLE statement is being entered for the ds@1952: ** first time (in other words if the virtual table is actually being ds@1952: ** created now instead of just being read out of sqlite_master) then ds@1952: ** do additional initialization work and store the statement text ds@1952: ** in the sqlite_master table. ds@1952: */ ds@1952: if( !db->init.busy ){ ds@1952: char *zStmt; ds@1952: char *zWhere; ds@1952: int iDb; ds@1952: Vdbe *v; ds@1952: ds@1952: /* Compute the complete text of the CREATE VIRTUAL TABLE statement */ ds@1952: if( pEnd ){ ds@1952: pParse->sNameToken.n = pEnd->z - pParse->sNameToken.z + pEnd->n; ds@1952: } ds@1952: zStmt = sqlite3MPrintf(db, "CREATE VIRTUAL TABLE %T", &pParse->sNameToken); ds@1952: ds@1952: /* A slot for the record has already been allocated in the ds@1952: ** SQLITE_MASTER table. We just need to update that slot with all ds@1952: ** the information we've collected. ds@1952: ** ds@1952: ** The top of the stack is the rootpage allocated by sqlite3StartTable(). ds@1952: ** This value is always 0 and is ignored, a virtual table does not have a ds@1952: ** rootpage. The next entry on the stack is the rowid of the record ds@1952: ** in the sqlite_master table. ds@1952: */ ds@1952: iDb = sqlite3SchemaToIndex(db, pTab->pSchema); ds@1952: sqlite3NestedParse(pParse, ds@1952: "UPDATE %Q.%s " ds@1952: "SET type='table', name=%Q, tbl_name=%Q, rootpage=0, sql=%Q " ds@1952: "WHERE rowid=#1", ds@1952: db->aDb[iDb].zName, SCHEMA_TABLE(iDb), ds@1952: pTab->zName, ds@1952: pTab->zName, ds@1952: zStmt ds@1952: ); ds@1952: sqlite3_free(zStmt); ds@1952: v = sqlite3GetVdbe(pParse); ds@1952: sqlite3ChangeCookie(db, v, iDb); ds@1952: ds@1952: sqlite3VdbeAddOp(v, OP_Expire, 0, 0); ds@1952: zWhere = sqlite3MPrintf(db, "name='%q'", pTab->zName); ds@1952: sqlite3VdbeOp3(v, OP_ParseSchema, iDb, 1, zWhere, P3_DYNAMIC); ds@1952: sqlite3VdbeOp3(v, OP_VCreate, iDb, 0, pTab->zName, strlen(pTab->zName) + 1); ds@1952: } ds@1952: ds@1952: /* If we are rereading the sqlite_master table create the in-memory ds@1952: ** record of the table. If the module has already been registered, ds@1952: ** also call the xConnect method here. ds@1952: */ ds@1952: else { ds@1952: Table *pOld; ds@1952: Schema *pSchema = pTab->pSchema; ds@1952: const char *zName = pTab->zName; ds@1952: int nName = strlen(zName) + 1; ds@1952: pOld = sqlite3HashInsert(&pSchema->tblHash, zName, nName, pTab); ds@1952: if( pOld ){ ds@1952: db->mallocFailed = 1; ds@1952: assert( pTab==pOld ); /* Malloc must have failed inside HashInsert() */ ds@1952: return; ds@1952: } ds@1952: pSchema->db = pParse->db; ds@1952: pParse->pNewTable = 0; ds@1952: } ds@1952: } ds@1952: ds@1952: /* ds@1952: ** The parser calls this routine when it sees the first token ds@1952: ** of an argument to the module name in a CREATE VIRTUAL TABLE statement. ds@1952: */ ds@1952: void sqlite3VtabArgInit(Parse *pParse){ ds@1952: addArgumentToVtab(pParse); ds@1952: pParse->sArg.z = 0; ds@1952: pParse->sArg.n = 0; ds@1952: } ds@1952: ds@1952: /* ds@1952: ** The parser calls this routine for each token after the first token ds@1952: ** in an argument to the module name in a CREATE VIRTUAL TABLE statement. ds@1952: */ ds@1952: void sqlite3VtabArgExtend(Parse *pParse, Token *p){ ds@1952: Token *pArg = &pParse->sArg; ds@1952: if( pArg->z==0 ){ ds@1952: pArg->z = p->z; ds@1952: pArg->n = p->n; ds@1952: }else{ ds@1952: assert(pArg->z < p->z); ds@1952: pArg->n = (p->z + p->n - pArg->z); ds@1952: } ds@1952: } ds@1952: ds@1952: /* ds@1952: ** Invoke a virtual table constructor (either xCreate or xConnect). The ds@1952: ** pointer to the function to invoke is passed as the fourth parameter ds@1952: ** to this procedure. ds@1952: */ ds@1952: static int vtabCallConstructor( ds@1952: sqlite3 *db, ds@1952: Table *pTab, ds@1952: Module *pMod, ds@1952: int (*xConstruct)(sqlite3*,void*,int,const char*const*,sqlite3_vtab**,char**), ds@1952: char **pzErr ds@1952: ){ ds@1952: int rc; ds@1952: int rc2; ds@1952: sqlite3_vtab *pVtab = 0; ds@1952: const char *const*azArg = (const char *const*)pTab->azModuleArg; ds@1952: int nArg = pTab->nModuleArg; ds@1952: char *zErr = 0; ds@1952: char *zModuleName = sqlite3MPrintf(db, "%s", pTab->zName); ds@1952: ds@1952: if( !zModuleName ){ ds@1952: return SQLITE_NOMEM; ds@1952: } ds@1952: ds@1952: assert( !db->pVTab ); ds@1952: assert( xConstruct ); ds@1952: ds@1952: db->pVTab = pTab; ds@1952: rc = sqlite3SafetyOff(db); ds@1952: assert( rc==SQLITE_OK ); ds@1952: rc = xConstruct(db, pMod->pAux, nArg, azArg, &pVtab, &zErr); ds@1952: rc2 = sqlite3SafetyOn(db); ds@1952: if( rc==SQLITE_OK && pVtab ){ ds@1952: pVtab->pModule = pMod->pModule; ds@1952: pVtab->nRef = 1; ds@1952: pTab->pVtab = pVtab; ds@1952: } ds@1952: ds@1952: if( SQLITE_OK!=rc ){ ds@1952: if( zErr==0 ){ ds@1952: *pzErr = sqlite3MPrintf(db, "vtable constructor failed: %s", zModuleName); ds@1952: }else { ds@1952: *pzErr = sqlite3MPrintf(db, "%s", zErr); ds@1952: sqlite3_free(zErr); ds@1952: } ds@1952: }else if( db->pVTab ){ ds@1952: const char *zFormat = "vtable constructor did not declare schema: %s"; ds@1952: *pzErr = sqlite3MPrintf(db, zFormat, pTab->zName); ds@1952: rc = SQLITE_ERROR; ds@1952: } ds@1952: if( rc==SQLITE_OK ){ ds@1952: rc = rc2; ds@1952: } ds@1952: db->pVTab = 0; ds@1952: sqlite3_free(zModuleName); ds@1952: ds@1952: /* If everything went according to plan, loop through the columns ds@1952: ** of the table to see if any of them contain the token "hidden". ds@1952: ** If so, set the Column.isHidden flag and remove the token from ds@1952: ** the type string. ds@1952: */ ds@1952: if( rc==SQLITE_OK ){ ds@1952: int iCol; ds@1952: for(iCol=0; iColnCol; iCol++){ ds@1952: char *zType = pTab->aCol[iCol].zType; ds@1952: int nType; ds@1952: int i = 0; ds@1952: if( !zType ) continue; ds@1952: nType = strlen(zType); ds@1952: if( sqlite3StrNICmp("hidden", zType, 6) || (zType[6] && zType[6]!=' ') ){ ds@1952: for(i=0; i0 ){ ds@1952: assert(zType[i-1]==' '); ds@1952: zType[i-1] = '\0'; ds@1952: } ds@1952: pTab->aCol[iCol].isHidden = 1; ds@1952: } ds@1952: } ds@1952: } ds@1952: return rc; ds@1952: } ds@1952: ds@1952: /* ds@1952: ** This function is invoked by the parser to call the xConnect() method ds@1952: ** of the virtual table pTab. If an error occurs, an error code is returned ds@1952: ** and an error left in pParse. ds@1952: ** ds@1952: ** This call is a no-op if table pTab is not a virtual table. ds@1952: */ ds@1952: int sqlite3VtabCallConnect(Parse *pParse, Table *pTab){ ds@1952: Module *pMod; ds@1952: int rc = SQLITE_OK; ds@1952: ds@1952: if( !pTab || !pTab->isVirtual || pTab->pVtab ){ ds@1952: return SQLITE_OK; ds@1952: } ds@1952: ds@1952: pMod = pTab->pMod; ds@1952: if( !pMod ){ ds@1952: const char *zModule = pTab->azModuleArg[0]; ds@1952: sqlite3ErrorMsg(pParse, "no such module: %s", zModule); ds@1952: rc = SQLITE_ERROR; ds@1952: } else { ds@1952: char *zErr = 0; ds@1952: sqlite3 *db = pParse->db; ds@1952: rc = vtabCallConstructor(db, pTab, pMod, pMod->pModule->xConnect, &zErr); ds@1952: if( rc!=SQLITE_OK ){ ds@1952: sqlite3ErrorMsg(pParse, "%s", zErr); ds@1952: } ds@1952: sqlite3_free(zErr); ds@1952: } ds@1952: ds@1952: return rc; ds@1952: } ds@1952: ds@1952: /* ds@1952: ** Add the virtual table pVtab to the array sqlite3.aVTrans[]. ds@1952: */ ds@1952: static int addToVTrans(sqlite3 *db, sqlite3_vtab *pVtab){ ds@1952: const int ARRAY_INCR = 5; ds@1952: ds@1952: /* Grow the sqlite3.aVTrans array if required */ ds@1952: if( (db->nVTrans%ARRAY_INCR)==0 ){ ds@1952: sqlite3_vtab **aVTrans; ds@1952: int nBytes = sizeof(sqlite3_vtab *) * (db->nVTrans + ARRAY_INCR); ds@1952: aVTrans = sqlite3DbRealloc(db, (void *)db->aVTrans, nBytes); ds@1952: if( !aVTrans ){ ds@1952: return SQLITE_NOMEM; ds@1952: } ds@1952: memset(&aVTrans[db->nVTrans], 0, sizeof(sqlite3_vtab *)*ARRAY_INCR); ds@1952: db->aVTrans = aVTrans; ds@1952: } ds@1952: ds@1952: /* Add pVtab to the end of sqlite3.aVTrans */ ds@1952: db->aVTrans[db->nVTrans++] = pVtab; ds@1952: sqlite3VtabLock(pVtab); ds@1952: return SQLITE_OK; ds@1952: } ds@1952: ds@1952: /* ds@1952: ** This function is invoked by the vdbe to call the xCreate method ds@1952: ** of the virtual table named zTab in database iDb. ds@1952: ** ds@1952: ** If an error occurs, *pzErr is set to point an an English language ds@1952: ** description of the error and an SQLITE_XXX error code is returned. ds@1952: ** In this case the caller must call sqlite3_free() on *pzErr. ds@1952: */ ds@1952: int sqlite3VtabCallCreate(sqlite3 *db, int iDb, const char *zTab, char **pzErr){ ds@1952: int rc = SQLITE_OK; ds@1952: Table *pTab; ds@1952: Module *pMod; ds@1952: const char *zModule; ds@1952: ds@1952: pTab = sqlite3FindTable(db, zTab, db->aDb[iDb].zName); ds@1952: assert(pTab && pTab->isVirtual && !pTab->pVtab); ds@1952: pMod = pTab->pMod; ds@1952: zModule = pTab->azModuleArg[0]; ds@1952: ds@1952: /* If the module has been registered and includes a Create method, ds@1952: ** invoke it now. If the module has not been registered, return an ds@1952: ** error. Otherwise, do nothing. ds@1952: */ ds@1952: if( !pMod ){ ds@1952: *pzErr = sqlite3MPrintf(db, "no such module: %s", zModule); ds@1952: rc = SQLITE_ERROR; ds@1952: }else{ ds@1952: rc = vtabCallConstructor(db, pTab, pMod, pMod->pModule->xCreate, pzErr); ds@1952: } ds@1952: ds@1952: if( rc==SQLITE_OK && pTab->pVtab ){ ds@1952: rc = addToVTrans(db, pTab->pVtab); ds@1952: } ds@1952: ds@1952: return rc; ds@1952: } ds@1952: ds@1952: /* ds@1952: ** This function is used to set the schema of a virtual table. It is only ds@1952: ** valid to call this function from within the xCreate() or xConnect() of a ds@1952: ** virtual table module. ds@1952: */ ds@1952: int sqlite3_declare_vtab(sqlite3 *db, const char *zCreateTable){ ds@1952: Parse sParse; ds@1952: ds@1952: int rc = SQLITE_OK; ds@1952: Table *pTab; ds@1952: char *zErr = 0; ds@1952: ds@1952: sqlite3_mutex_enter(db->mutex); ds@1952: pTab = db->pVTab; ds@1952: if( !pTab ){ ds@1952: sqlite3Error(db, SQLITE_MISUSE, 0); ds@1952: sqlite3_mutex_leave(db->mutex); ds@1952: return SQLITE_MISUSE; ds@1952: } ds@1952: assert(pTab->isVirtual && pTab->nCol==0 && pTab->aCol==0); ds@1952: ds@1952: memset(&sParse, 0, sizeof(Parse)); ds@1952: sParse.declareVtab = 1; ds@1952: sParse.db = db; ds@1952: ds@1952: if( ds@1952: SQLITE_OK == sqlite3RunParser(&sParse, zCreateTable, &zErr) && ds@1952: sParse.pNewTable && ds@1952: !sParse.pNewTable->pSelect && ds@1952: !sParse.pNewTable->isVirtual ds@1952: ){ ds@1952: pTab->aCol = sParse.pNewTable->aCol; ds@1952: pTab->nCol = sParse.pNewTable->nCol; ds@1952: sParse.pNewTable->nCol = 0; ds@1952: sParse.pNewTable->aCol = 0; ds@1952: db->pVTab = 0; ds@1952: } else { ds@1952: sqlite3Error(db, SQLITE_ERROR, zErr); ds@1952: sqlite3_free(zErr); ds@1952: rc = SQLITE_ERROR; ds@1952: } ds@1952: sParse.declareVtab = 0; ds@1952: ds@1952: sqlite3_finalize((sqlite3_stmt*)sParse.pVdbe); ds@1952: sqlite3DeleteTable(sParse.pNewTable); ds@1952: sParse.pNewTable = 0; ds@1952: ds@1952: assert( (rc&0xff)==rc ); ds@1952: rc = sqlite3ApiExit(db, rc); ds@1952: sqlite3_mutex_leave(db->mutex); ds@1952: return rc; ds@1952: } ds@1952: ds@1952: /* ds@1952: ** This function is invoked by the vdbe to call the xDestroy method ds@1952: ** of the virtual table named zTab in database iDb. This occurs ds@1952: ** when a DROP TABLE is mentioned. ds@1952: ** ds@1952: ** This call is a no-op if zTab is not a virtual table. ds@1952: */ ds@1952: int sqlite3VtabCallDestroy(sqlite3 *db, int iDb, const char *zTab) ds@1952: { ds@1952: int rc = SQLITE_OK; ds@1952: Table *pTab; ds@1952: ds@1952: pTab = sqlite3FindTable(db, zTab, db->aDb[iDb].zName); ds@1952: assert(pTab); ds@1952: if( pTab->pVtab ){ ds@1952: int (*xDestroy)(sqlite3_vtab *pVTab) = pTab->pMod->pModule->xDestroy; ds@1952: rc = sqlite3SafetyOff(db); ds@1952: assert( rc==SQLITE_OK ); ds@1952: if( xDestroy ){ ds@1952: rc = xDestroy(pTab->pVtab); ds@1952: } ds@1952: sqlite3SafetyOn(db); ds@1952: if( rc==SQLITE_OK ){ ds@1952: pTab->pVtab = 0; ds@1952: } ds@1952: } ds@1952: ds@1952: return rc; ds@1952: } ds@1952: ds@1952: /* ds@1952: ** This function invokes either the xRollback or xCommit method ds@1952: ** of each of the virtual tables in the sqlite3.aVTrans array. The method ds@1952: ** called is identified by the second argument, "offset", which is ds@1952: ** the offset of the method to call in the sqlite3_module structure. ds@1952: ** ds@1952: ** The array is cleared after invoking the callbacks. ds@1952: */ ds@1952: static void callFinaliser(sqlite3 *db, int offset){ ds@1952: int i; ds@1952: if( db->aVTrans ){ ds@1952: for(i=0; inVTrans && db->aVTrans[i]; i++){ ds@1952: sqlite3_vtab *pVtab = db->aVTrans[i]; ds@1952: int (*x)(sqlite3_vtab *); ds@1952: x = *(int (**)(sqlite3_vtab *))((char *)pVtab->pModule + offset); ds@1952: if( x ) x(pVtab); ds@1952: sqlite3VtabUnlock(db, pVtab); ds@1952: } ds@1952: sqlite3_free(db->aVTrans); ds@1952: db->nVTrans = 0; ds@1952: db->aVTrans = 0; ds@1952: } ds@1952: } ds@1952: ds@1952: /* ds@1952: ** If argument rc2 is not SQLITE_OK, then return it and do nothing. ds@1952: ** Otherwise, invoke the xSync method of all virtual tables in the ds@1952: ** sqlite3.aVTrans array. Return the error code for the first error ds@1952: ** that occurs, or SQLITE_OK if all xSync operations are successful. ds@1952: */ ds@1952: int sqlite3VtabSync(sqlite3 *db, int rc2){ ds@1952: int i; ds@1952: int rc = SQLITE_OK; ds@1952: int rcsafety; ds@1952: sqlite3_vtab **aVTrans = db->aVTrans; ds@1952: if( rc2!=SQLITE_OK ) return rc2; ds@1952: ds@1952: rc = sqlite3SafetyOff(db); ds@1952: db->aVTrans = 0; ds@1952: for(i=0; rc==SQLITE_OK && inVTrans && aVTrans[i]; i++){ ds@1952: sqlite3_vtab *pVtab = aVTrans[i]; ds@1952: int (*x)(sqlite3_vtab *); ds@1952: x = pVtab->pModule->xSync; ds@1952: if( x ){ ds@1952: rc = x(pVtab); ds@1952: } ds@1952: } ds@1952: db->aVTrans = aVTrans; ds@1952: rcsafety = sqlite3SafetyOn(db); ds@1952: ds@1952: if( rc==SQLITE_OK ){ ds@1952: rc = rcsafety; ds@1952: } ds@1952: return rc; ds@1952: } ds@1952: ds@1952: /* ds@1952: ** Invoke the xRollback method of all virtual tables in the ds@1952: ** sqlite3.aVTrans array. Then clear the array itself. ds@1952: */ ds@1952: int sqlite3VtabRollback(sqlite3 *db){ ds@1952: callFinaliser(db, (int)(&((sqlite3_module *)0)->xRollback)); ds@1952: return SQLITE_OK; ds@1952: } ds@1952: ds@1952: /* ds@1952: ** Invoke the xCommit method of all virtual tables in the ds@1952: ** sqlite3.aVTrans array. Then clear the array itself. ds@1952: */ ds@1952: int sqlite3VtabCommit(sqlite3 *db){ ds@1952: callFinaliser(db, (int)(&((sqlite3_module *)0)->xCommit)); ds@1952: return SQLITE_OK; ds@1952: } ds@1952: ds@1952: /* ds@1952: ** If the virtual table pVtab supports the transaction interface ds@1952: ** (xBegin/xRollback/xCommit and optionally xSync) and a transaction is ds@1952: ** not currently open, invoke the xBegin method now. ds@1952: ** ds@1952: ** If the xBegin call is successful, place the sqlite3_vtab pointer ds@1952: ** in the sqlite3.aVTrans array. ds@1952: */ ds@1952: int sqlite3VtabBegin(sqlite3 *db, sqlite3_vtab *pVtab){ ds@1952: int rc = SQLITE_OK; ds@1952: const sqlite3_module *pModule; ds@1952: ds@1952: /* Special case: If db->aVTrans is NULL and db->nVTrans is greater ds@1952: ** than zero, then this function is being called from within a ds@1952: ** virtual module xSync() callback. It is illegal to write to ds@1952: ** virtual module tables in this case, so return SQLITE_LOCKED. ds@1952: */ ds@1952: if( 0==db->aVTrans && db->nVTrans>0 ){ ds@1952: return SQLITE_LOCKED; ds@1952: } ds@1952: if( !pVtab ){ ds@1952: return SQLITE_OK; ds@1952: } ds@1952: pModule = pVtab->pModule; ds@1952: ds@1952: if( pModule->xBegin ){ ds@1952: int i; ds@1952: ds@1952: ds@1952: /* If pVtab is already in the aVTrans array, return early */ ds@1952: for(i=0; (inVTrans) && 0!=db->aVTrans[i]; i++){ ds@1952: if( db->aVTrans[i]==pVtab ){ ds@1952: return SQLITE_OK; ds@1952: } ds@1952: } ds@1952: ds@1952: /* Invoke the xBegin method */ ds@1952: rc = pModule->xBegin(pVtab); ds@1952: if( rc!=SQLITE_OK ){ ds@1952: return rc; ds@1952: } ds@1952: ds@1952: rc = addToVTrans(db, pVtab); ds@1952: } ds@1952: return rc; ds@1952: } ds@1952: ds@1952: /* ds@1952: ** The first parameter (pDef) is a function implementation. The ds@1952: ** second parameter (pExpr) is the first argument to this function. ds@1952: ** If pExpr is a column in a virtual table, then let the virtual ds@1952: ** table implementation have an opportunity to overload the function. ds@1952: ** ds@1952: ** This routine is used to allow virtual table implementations to ds@1952: ** overload MATCH, LIKE, GLOB, and REGEXP operators. ds@1952: ** ds@1952: ** Return either the pDef argument (indicating no change) or a ds@1952: ** new FuncDef structure that is marked as ephemeral using the ds@1952: ** SQLITE_FUNC_EPHEM flag. ds@1952: */ ds@1952: FuncDef *sqlite3VtabOverloadFunction( ds@1952: sqlite3 *db, /* Database connection for reporting malloc problems */ ds@1952: FuncDef *pDef, /* Function to possibly overload */ ds@1952: int nArg, /* Number of arguments to the function */ ds@1952: Expr *pExpr /* First argument to the function */ ds@1952: ){ ds@1952: Table *pTab; ds@1952: sqlite3_vtab *pVtab; ds@1952: sqlite3_module *pMod; ds@1952: void (*xFunc)(sqlite3_context*,int,sqlite3_value**); ds@1952: void *pArg; ds@1952: FuncDef *pNew; ds@1952: int rc = 0; ds@1952: char *zLowerName; ds@1952: unsigned char *z; ds@1952: ds@1952: ds@1952: /* Check to see the left operand is a column in a virtual table */ ds@1952: if( pExpr==0 ) return pDef; ds@1952: if( pExpr->op!=TK_COLUMN ) return pDef; ds@1952: pTab = pExpr->pTab; ds@1952: if( pTab==0 ) return pDef; ds@1952: if( !pTab->isVirtual ) return pDef; ds@1952: pVtab = pTab->pVtab; ds@1952: assert( pVtab!=0 ); ds@1952: assert( pVtab->pModule!=0 ); ds@1952: pMod = (sqlite3_module *)pVtab->pModule; ds@1952: if( pMod->xFindFunction==0 ) return pDef; ds@1952: ds@1952: /* Call the xFindFunction method on the virtual table implementation ds@1952: ** to see if the implementation wants to overload this function ds@1952: */ ds@1952: zLowerName = sqlite3DbStrDup(db, pDef->zName); ds@1952: if( zLowerName ){ ds@1952: for(z=(unsigned char*)zLowerName; *z; z++){ ds@1952: *z = sqlite3UpperToLower[*z]; ds@1952: } ds@1952: rc = pMod->xFindFunction(pVtab, nArg, zLowerName, &xFunc, &pArg); ds@1952: sqlite3_free(zLowerName); ds@1952: } ds@1952: if( rc==0 ){ ds@1952: return pDef; ds@1952: } ds@1952: ds@1952: /* Create a new ephemeral function definition for the overloaded ds@1952: ** function */ ds@1952: pNew = sqlite3DbMallocZero(db, sizeof(*pNew) + strlen(pDef->zName) ); ds@1952: if( pNew==0 ){ ds@1952: return pDef; ds@1952: } ds@1952: *pNew = *pDef; ds@1952: memcpy(pNew->zName, pDef->zName, strlen(pDef->zName)+1); ds@1952: pNew->xFunc = xFunc; ds@1952: pNew->pUserData = pArg; ds@1952: pNew->flags |= SQLITE_FUNC_EPHEM; ds@1952: return pNew; ds@1952: } ds@1952: ds@1952: #endif /* SQLITE_OMIT_VIRTUALTABLE */