Annotation of embedaddon/sqlite3/src/vtab.c, revision 1.1

1.1     ! misho       1: /*
        !             2: ** 2006 June 10
        !             3: **
        !             4: ** The author disclaims copyright to this source code.  In place of
        !             5: ** a legal notice, here is a blessing:
        !             6: **
        !             7: **    May you do good and not evil.
        !             8: **    May you find forgiveness for yourself and forgive others.
        !             9: **    May you share freely, never taking more than you give.
        !            10: **
        !            11: *************************************************************************
        !            12: ** This file contains code used to help implement virtual tables.
        !            13: */
        !            14: #ifndef SQLITE_OMIT_VIRTUALTABLE
        !            15: #include "sqliteInt.h"
        !            16: 
        !            17: /*
        !            18: ** Before a virtual table xCreate() or xConnect() method is invoked, the
        !            19: ** sqlite3.pVtabCtx member variable is set to point to an instance of
        !            20: ** this struct allocated on the stack. It is used by the implementation of 
        !            21: ** the sqlite3_declare_vtab() and sqlite3_vtab_config() APIs, both of which
        !            22: ** are invoked only from within xCreate and xConnect methods.
        !            23: */
        !            24: struct VtabCtx {
        !            25:   Table *pTab;
        !            26:   VTable *pVTable;
        !            27: };
        !            28: 
        !            29: /*
        !            30: ** The actual function that does the work of creating a new module.
        !            31: ** This function implements the sqlite3_create_module() and
        !            32: ** sqlite3_create_module_v2() interfaces.
        !            33: */
        !            34: static int createModule(
        !            35:   sqlite3 *db,                    /* Database in which module is registered */
        !            36:   const char *zName,              /* Name assigned to this module */
        !            37:   const sqlite3_module *pModule,  /* The definition of the module */
        !            38:   void *pAux,                     /* Context pointer for xCreate/xConnect */
        !            39:   void (*xDestroy)(void *)        /* Module destructor function */
        !            40: ){
        !            41:   int rc, nName;
        !            42:   Module *pMod;
        !            43: 
        !            44:   sqlite3_mutex_enter(db->mutex);
        !            45:   nName = sqlite3Strlen30(zName);
        !            46:   pMod = (Module *)sqlite3DbMallocRaw(db, sizeof(Module) + nName + 1);
        !            47:   if( pMod ){
        !            48:     Module *pDel;
        !            49:     char *zCopy = (char *)(&pMod[1]);
        !            50:     memcpy(zCopy, zName, nName+1);
        !            51:     pMod->zName = zCopy;
        !            52:     pMod->pModule = pModule;
        !            53:     pMod->pAux = pAux;
        !            54:     pMod->xDestroy = xDestroy;
        !            55:     pDel = (Module *)sqlite3HashInsert(&db->aModule, zCopy, nName, (void*)pMod);
        !            56:     if( pDel && pDel->xDestroy ){
        !            57:       sqlite3ResetInternalSchema(db, -1);
        !            58:       pDel->xDestroy(pDel->pAux);
        !            59:     }
        !            60:     sqlite3DbFree(db, pDel);
        !            61:     if( pDel==pMod ){
        !            62:       db->mallocFailed = 1;
        !            63:     }
        !            64:   }else if( xDestroy ){
        !            65:     xDestroy(pAux);
        !            66:   }
        !            67:   rc = sqlite3ApiExit(db, SQLITE_OK);
        !            68:   sqlite3_mutex_leave(db->mutex);
        !            69:   return rc;
        !            70: }
        !            71: 
        !            72: 
        !            73: /*
        !            74: ** External API function used to create a new virtual-table module.
        !            75: */
        !            76: int sqlite3_create_module(
        !            77:   sqlite3 *db,                    /* Database in which module is registered */
        !            78:   const char *zName,              /* Name assigned to this module */
        !            79:   const sqlite3_module *pModule,  /* The definition of the module */
        !            80:   void *pAux                      /* Context pointer for xCreate/xConnect */
        !            81: ){
        !            82:   return createModule(db, zName, pModule, pAux, 0);
        !            83: }
        !            84: 
        !            85: /*
        !            86: ** External API function used to create a new virtual-table module.
        !            87: */
        !            88: int sqlite3_create_module_v2(
        !            89:   sqlite3 *db,                    /* Database in which module is registered */
        !            90:   const char *zName,              /* Name assigned to this module */
        !            91:   const sqlite3_module *pModule,  /* The definition of the module */
        !            92:   void *pAux,                     /* Context pointer for xCreate/xConnect */
        !            93:   void (*xDestroy)(void *)        /* Module destructor function */
        !            94: ){
        !            95:   return createModule(db, zName, pModule, pAux, xDestroy);
        !            96: }
        !            97: 
        !            98: /*
        !            99: ** Lock the virtual table so that it cannot be disconnected.
        !           100: ** Locks nest.  Every lock should have a corresponding unlock.
        !           101: ** If an unlock is omitted, resources leaks will occur.  
        !           102: **
        !           103: ** If a disconnect is attempted while a virtual table is locked,
        !           104: ** the disconnect is deferred until all locks have been removed.
        !           105: */
        !           106: void sqlite3VtabLock(VTable *pVTab){
        !           107:   pVTab->nRef++;
        !           108: }
        !           109: 
        !           110: 
        !           111: /*
        !           112: ** pTab is a pointer to a Table structure representing a virtual-table.
        !           113: ** Return a pointer to the VTable object used by connection db to access 
        !           114: ** this virtual-table, if one has been created, or NULL otherwise.
        !           115: */
        !           116: VTable *sqlite3GetVTable(sqlite3 *db, Table *pTab){
        !           117:   VTable *pVtab;
        !           118:   assert( IsVirtual(pTab) );
        !           119:   for(pVtab=pTab->pVTable; pVtab && pVtab->db!=db; pVtab=pVtab->pNext);
        !           120:   return pVtab;
        !           121: }
        !           122: 
        !           123: /*
        !           124: ** Decrement the ref-count on a virtual table object. When the ref-count
        !           125: ** reaches zero, call the xDisconnect() method to delete the object.
        !           126: */
        !           127: void sqlite3VtabUnlock(VTable *pVTab){
        !           128:   sqlite3 *db = pVTab->db;
        !           129: 
        !           130:   assert( db );
        !           131:   assert( pVTab->nRef>0 );
        !           132:   assert( sqlite3SafetyCheckOk(db) );
        !           133: 
        !           134:   pVTab->nRef--;
        !           135:   if( pVTab->nRef==0 ){
        !           136:     sqlite3_vtab *p = pVTab->pVtab;
        !           137:     if( p ){
        !           138:       p->pModule->xDisconnect(p);
        !           139:     }
        !           140:     sqlite3DbFree(db, pVTab);
        !           141:   }
        !           142: }
        !           143: 
        !           144: /*
        !           145: ** Table p is a virtual table. This function moves all elements in the
        !           146: ** p->pVTable list to the sqlite3.pDisconnect lists of their associated
        !           147: ** database connections to be disconnected at the next opportunity. 
        !           148: ** Except, if argument db is not NULL, then the entry associated with
        !           149: ** connection db is left in the p->pVTable list.
        !           150: */
        !           151: static VTable *vtabDisconnectAll(sqlite3 *db, Table *p){
        !           152:   VTable *pRet = 0;
        !           153:   VTable *pVTable = p->pVTable;
        !           154:   p->pVTable = 0;
        !           155: 
        !           156:   /* Assert that the mutex (if any) associated with the BtShared database 
        !           157:   ** that contains table p is held by the caller. See header comments 
        !           158:   ** above function sqlite3VtabUnlockList() for an explanation of why
        !           159:   ** this makes it safe to access the sqlite3.pDisconnect list of any
        !           160:   ** database connection that may have an entry in the p->pVTable list.
        !           161:   */
        !           162:   assert( db==0 || sqlite3SchemaMutexHeld(db, 0, p->pSchema) );
        !           163: 
        !           164:   while( pVTable ){
        !           165:     sqlite3 *db2 = pVTable->db;
        !           166:     VTable *pNext = pVTable->pNext;
        !           167:     assert( db2 );
        !           168:     if( db2==db ){
        !           169:       pRet = pVTable;
        !           170:       p->pVTable = pRet;
        !           171:       pRet->pNext = 0;
        !           172:     }else{
        !           173:       pVTable->pNext = db2->pDisconnect;
        !           174:       db2->pDisconnect = pVTable;
        !           175:     }
        !           176:     pVTable = pNext;
        !           177:   }
        !           178: 
        !           179:   assert( !db || pRet );
        !           180:   return pRet;
        !           181: }
        !           182: 
        !           183: 
        !           184: /*
        !           185: ** Disconnect all the virtual table objects in the sqlite3.pDisconnect list.
        !           186: **
        !           187: ** This function may only be called when the mutexes associated with all
        !           188: ** shared b-tree databases opened using connection db are held by the 
        !           189: ** caller. This is done to protect the sqlite3.pDisconnect list. The
        !           190: ** sqlite3.pDisconnect list is accessed only as follows:
        !           191: **
        !           192: **   1) By this function. In this case, all BtShared mutexes and the mutex
        !           193: **      associated with the database handle itself must be held.
        !           194: **
        !           195: **   2) By function vtabDisconnectAll(), when it adds a VTable entry to
        !           196: **      the sqlite3.pDisconnect list. In this case either the BtShared mutex
        !           197: **      associated with the database the virtual table is stored in is held
        !           198: **      or, if the virtual table is stored in a non-sharable database, then
        !           199: **      the database handle mutex is held.
        !           200: **
        !           201: ** As a result, a sqlite3.pDisconnect cannot be accessed simultaneously 
        !           202: ** by multiple threads. It is thread-safe.
        !           203: */
        !           204: void sqlite3VtabUnlockList(sqlite3 *db){
        !           205:   VTable *p = db->pDisconnect;
        !           206:   db->pDisconnect = 0;
        !           207: 
        !           208:   assert( sqlite3BtreeHoldsAllMutexes(db) );
        !           209:   assert( sqlite3_mutex_held(db->mutex) );
        !           210: 
        !           211:   if( p ){
        !           212:     sqlite3ExpirePreparedStatements(db);
        !           213:     do {
        !           214:       VTable *pNext = p->pNext;
        !           215:       sqlite3VtabUnlock(p);
        !           216:       p = pNext;
        !           217:     }while( p );
        !           218:   }
        !           219: }
        !           220: 
        !           221: /*
        !           222: ** Clear any and all virtual-table information from the Table record.
        !           223: ** This routine is called, for example, just before deleting the Table
        !           224: ** record.
        !           225: **
        !           226: ** Since it is a virtual-table, the Table structure contains a pointer
        !           227: ** to the head of a linked list of VTable structures. Each VTable 
        !           228: ** structure is associated with a single sqlite3* user of the schema.
        !           229: ** The reference count of the VTable structure associated with database 
        !           230: ** connection db is decremented immediately (which may lead to the 
        !           231: ** structure being xDisconnected and free). Any other VTable structures
        !           232: ** in the list are moved to the sqlite3.pDisconnect list of the associated 
        !           233: ** database connection.
        !           234: */
        !           235: void sqlite3VtabClear(sqlite3 *db, Table *p){
        !           236:   if( !db || db->pnBytesFreed==0 ) vtabDisconnectAll(0, p);
        !           237:   if( p->azModuleArg ){
        !           238:     int i;
        !           239:     for(i=0; i<p->nModuleArg; i++){
        !           240:       sqlite3DbFree(db, p->azModuleArg[i]);
        !           241:     }
        !           242:     sqlite3DbFree(db, p->azModuleArg);
        !           243:   }
        !           244: }
        !           245: 
        !           246: /*
        !           247: ** Add a new module argument to pTable->azModuleArg[].
        !           248: ** The string is not copied - the pointer is stored.  The
        !           249: ** string will be freed automatically when the table is
        !           250: ** deleted.
        !           251: */
        !           252: static void addModuleArgument(sqlite3 *db, Table *pTable, char *zArg){
        !           253:   int i = pTable->nModuleArg++;
        !           254:   int nBytes = sizeof(char *)*(1+pTable->nModuleArg);
        !           255:   char **azModuleArg;
        !           256:   azModuleArg = sqlite3DbRealloc(db, pTable->azModuleArg, nBytes);
        !           257:   if( azModuleArg==0 ){
        !           258:     int j;
        !           259:     for(j=0; j<i; j++){
        !           260:       sqlite3DbFree(db, pTable->azModuleArg[j]);
        !           261:     }
        !           262:     sqlite3DbFree(db, zArg);
        !           263:     sqlite3DbFree(db, pTable->azModuleArg);
        !           264:     pTable->nModuleArg = 0;
        !           265:   }else{
        !           266:     azModuleArg[i] = zArg;
        !           267:     azModuleArg[i+1] = 0;
        !           268:   }
        !           269:   pTable->azModuleArg = azModuleArg;
        !           270: }
        !           271: 
        !           272: /*
        !           273: ** The parser calls this routine when it first sees a CREATE VIRTUAL TABLE
        !           274: ** statement.  The module name has been parsed, but the optional list
        !           275: ** of parameters that follow the module name are still pending.
        !           276: */
        !           277: void sqlite3VtabBeginParse(
        !           278:   Parse *pParse,        /* Parsing context */
        !           279:   Token *pName1,        /* Name of new table, or database name */
        !           280:   Token *pName2,        /* Name of new table or NULL */
        !           281:   Token *pModuleName    /* Name of the module for the virtual table */
        !           282: ){
        !           283:   int iDb;              /* The database the table is being created in */
        !           284:   Table *pTable;        /* The new virtual table */
        !           285:   sqlite3 *db;          /* Database connection */
        !           286: 
        !           287:   sqlite3StartTable(pParse, pName1, pName2, 0, 0, 1, 0);
        !           288:   pTable = pParse->pNewTable;
        !           289:   if( pTable==0 ) return;
        !           290:   assert( 0==pTable->pIndex );
        !           291: 
        !           292:   db = pParse->db;
        !           293:   iDb = sqlite3SchemaToIndex(db, pTable->pSchema);
        !           294:   assert( iDb>=0 );
        !           295: 
        !           296:   pTable->tabFlags |= TF_Virtual;
        !           297:   pTable->nModuleArg = 0;
        !           298:   addModuleArgument(db, pTable, sqlite3NameFromToken(db, pModuleName));
        !           299:   addModuleArgument(db, pTable, sqlite3DbStrDup(db, db->aDb[iDb].zName));
        !           300:   addModuleArgument(db, pTable, sqlite3DbStrDup(db, pTable->zName));
        !           301:   pParse->sNameToken.n = (int)(&pModuleName->z[pModuleName->n] - pName1->z);
        !           302: 
        !           303: #ifndef SQLITE_OMIT_AUTHORIZATION
        !           304:   /* Creating a virtual table invokes the authorization callback twice.
        !           305:   ** The first invocation, to obtain permission to INSERT a row into the
        !           306:   ** sqlite_master table, has already been made by sqlite3StartTable().
        !           307:   ** The second call, to obtain permission to create the table, is made now.
        !           308:   */
        !           309:   if( pTable->azModuleArg ){
        !           310:     sqlite3AuthCheck(pParse, SQLITE_CREATE_VTABLE, pTable->zName, 
        !           311:             pTable->azModuleArg[0], pParse->db->aDb[iDb].zName);
        !           312:   }
        !           313: #endif
        !           314: }
        !           315: 
        !           316: /*
        !           317: ** This routine takes the module argument that has been accumulating
        !           318: ** in pParse->zArg[] and appends it to the list of arguments on the
        !           319: ** virtual table currently under construction in pParse->pTable.
        !           320: */
        !           321: static void addArgumentToVtab(Parse *pParse){
        !           322:   if( pParse->sArg.z && ALWAYS(pParse->pNewTable) ){
        !           323:     const char *z = (const char*)pParse->sArg.z;
        !           324:     int n = pParse->sArg.n;
        !           325:     sqlite3 *db = pParse->db;
        !           326:     addModuleArgument(db, pParse->pNewTable, sqlite3DbStrNDup(db, z, n));
        !           327:   }
        !           328: }
        !           329: 
        !           330: /*
        !           331: ** The parser calls this routine after the CREATE VIRTUAL TABLE statement
        !           332: ** has been completely parsed.
        !           333: */
        !           334: void sqlite3VtabFinishParse(Parse *pParse, Token *pEnd){
        !           335:   Table *pTab = pParse->pNewTable;  /* The table being constructed */
        !           336:   sqlite3 *db = pParse->db;         /* The database connection */
        !           337: 
        !           338:   if( pTab==0 ) return;
        !           339:   addArgumentToVtab(pParse);
        !           340:   pParse->sArg.z = 0;
        !           341:   if( pTab->nModuleArg<1 ) return;
        !           342:   
        !           343:   /* If the CREATE VIRTUAL TABLE statement is being entered for the
        !           344:   ** first time (in other words if the virtual table is actually being
        !           345:   ** created now instead of just being read out of sqlite_master) then
        !           346:   ** do additional initialization work and store the statement text
        !           347:   ** in the sqlite_master table.
        !           348:   */
        !           349:   if( !db->init.busy ){
        !           350:     char *zStmt;
        !           351:     char *zWhere;
        !           352:     int iDb;
        !           353:     Vdbe *v;
        !           354: 
        !           355:     /* Compute the complete text of the CREATE VIRTUAL TABLE statement */
        !           356:     if( pEnd ){
        !           357:       pParse->sNameToken.n = (int)(pEnd->z - pParse->sNameToken.z) + pEnd->n;
        !           358:     }
        !           359:     zStmt = sqlite3MPrintf(db, "CREATE VIRTUAL TABLE %T", &pParse->sNameToken);
        !           360: 
        !           361:     /* A slot for the record has already been allocated in the 
        !           362:     ** SQLITE_MASTER table.  We just need to update that slot with all
        !           363:     ** the information we've collected.  
        !           364:     **
        !           365:     ** The VM register number pParse->regRowid holds the rowid of an
        !           366:     ** entry in the sqlite_master table tht was created for this vtab
        !           367:     ** by sqlite3StartTable().
        !           368:     */
        !           369:     iDb = sqlite3SchemaToIndex(db, pTab->pSchema);
        !           370:     sqlite3NestedParse(pParse,
        !           371:       "UPDATE %Q.%s "
        !           372:          "SET type='table', name=%Q, tbl_name=%Q, rootpage=0, sql=%Q "
        !           373:        "WHERE rowid=#%d",
        !           374:       db->aDb[iDb].zName, SCHEMA_TABLE(iDb),
        !           375:       pTab->zName,
        !           376:       pTab->zName,
        !           377:       zStmt,
        !           378:       pParse->regRowid
        !           379:     );
        !           380:     sqlite3DbFree(db, zStmt);
        !           381:     v = sqlite3GetVdbe(pParse);
        !           382:     sqlite3ChangeCookie(pParse, iDb);
        !           383: 
        !           384:     sqlite3VdbeAddOp2(v, OP_Expire, 0, 0);
        !           385:     zWhere = sqlite3MPrintf(db, "name='%q' AND type='table'", pTab->zName);
        !           386:     sqlite3VdbeAddParseSchemaOp(v, iDb, zWhere);
        !           387:     sqlite3VdbeAddOp4(v, OP_VCreate, iDb, 0, 0, 
        !           388:                          pTab->zName, sqlite3Strlen30(pTab->zName) + 1);
        !           389:   }
        !           390: 
        !           391:   /* If we are rereading the sqlite_master table create the in-memory
        !           392:   ** record of the table. The xConnect() method is not called until
        !           393:   ** the first time the virtual table is used in an SQL statement. This
        !           394:   ** allows a schema that contains virtual tables to be loaded before
        !           395:   ** the required virtual table implementations are registered.  */
        !           396:   else {
        !           397:     Table *pOld;
        !           398:     Schema *pSchema = pTab->pSchema;
        !           399:     const char *zName = pTab->zName;
        !           400:     int nName = sqlite3Strlen30(zName);
        !           401:     assert( sqlite3SchemaMutexHeld(db, 0, pSchema) );
        !           402:     pOld = sqlite3HashInsert(&pSchema->tblHash, zName, nName, pTab);
        !           403:     if( pOld ){
        !           404:       db->mallocFailed = 1;
        !           405:       assert( pTab==pOld );  /* Malloc must have failed inside HashInsert() */
        !           406:       return;
        !           407:     }
        !           408:     pParse->pNewTable = 0;
        !           409:   }
        !           410: }
        !           411: 
        !           412: /*
        !           413: ** The parser calls this routine when it sees the first token
        !           414: ** of an argument to the module name in a CREATE VIRTUAL TABLE statement.
        !           415: */
        !           416: void sqlite3VtabArgInit(Parse *pParse){
        !           417:   addArgumentToVtab(pParse);
        !           418:   pParse->sArg.z = 0;
        !           419:   pParse->sArg.n = 0;
        !           420: }
        !           421: 
        !           422: /*
        !           423: ** The parser calls this routine for each token after the first token
        !           424: ** in an argument to the module name in a CREATE VIRTUAL TABLE statement.
        !           425: */
        !           426: void sqlite3VtabArgExtend(Parse *pParse, Token *p){
        !           427:   Token *pArg = &pParse->sArg;
        !           428:   if( pArg->z==0 ){
        !           429:     pArg->z = p->z;
        !           430:     pArg->n = p->n;
        !           431:   }else{
        !           432:     assert(pArg->z < p->z);
        !           433:     pArg->n = (int)(&p->z[p->n] - pArg->z);
        !           434:   }
        !           435: }
        !           436: 
        !           437: /*
        !           438: ** Invoke a virtual table constructor (either xCreate or xConnect). The
        !           439: ** pointer to the function to invoke is passed as the fourth parameter
        !           440: ** to this procedure.
        !           441: */
        !           442: static int vtabCallConstructor(
        !           443:   sqlite3 *db, 
        !           444:   Table *pTab,
        !           445:   Module *pMod,
        !           446:   int (*xConstruct)(sqlite3*,void*,int,const char*const*,sqlite3_vtab**,char**),
        !           447:   char **pzErr
        !           448: ){
        !           449:   VtabCtx sCtx;
        !           450:   VTable *pVTable;
        !           451:   int rc;
        !           452:   const char *const*azArg = (const char *const*)pTab->azModuleArg;
        !           453:   int nArg = pTab->nModuleArg;
        !           454:   char *zErr = 0;
        !           455:   char *zModuleName = sqlite3MPrintf(db, "%s", pTab->zName);
        !           456: 
        !           457:   if( !zModuleName ){
        !           458:     return SQLITE_NOMEM;
        !           459:   }
        !           460: 
        !           461:   pVTable = sqlite3DbMallocZero(db, sizeof(VTable));
        !           462:   if( !pVTable ){
        !           463:     sqlite3DbFree(db, zModuleName);
        !           464:     return SQLITE_NOMEM;
        !           465:   }
        !           466:   pVTable->db = db;
        !           467:   pVTable->pMod = pMod;
        !           468: 
        !           469:   /* Invoke the virtual table constructor */
        !           470:   assert( &db->pVtabCtx );
        !           471:   assert( xConstruct );
        !           472:   sCtx.pTab = pTab;
        !           473:   sCtx.pVTable = pVTable;
        !           474:   db->pVtabCtx = &sCtx;
        !           475:   rc = xConstruct(db, pMod->pAux, nArg, azArg, &pVTable->pVtab, &zErr);
        !           476:   db->pVtabCtx = 0;
        !           477:   if( rc==SQLITE_NOMEM ) db->mallocFailed = 1;
        !           478: 
        !           479:   if( SQLITE_OK!=rc ){
        !           480:     if( zErr==0 ){
        !           481:       *pzErr = sqlite3MPrintf(db, "vtable constructor failed: %s", zModuleName);
        !           482:     }else {
        !           483:       *pzErr = sqlite3MPrintf(db, "%s", zErr);
        !           484:       sqlite3_free(zErr);
        !           485:     }
        !           486:     sqlite3DbFree(db, pVTable);
        !           487:   }else if( ALWAYS(pVTable->pVtab) ){
        !           488:     /* Justification of ALWAYS():  A correct vtab constructor must allocate
        !           489:     ** the sqlite3_vtab object if successful.  */
        !           490:     pVTable->pVtab->pModule = pMod->pModule;
        !           491:     pVTable->nRef = 1;
        !           492:     if( sCtx.pTab ){
        !           493:       const char *zFormat = "vtable constructor did not declare schema: %s";
        !           494:       *pzErr = sqlite3MPrintf(db, zFormat, pTab->zName);
        !           495:       sqlite3VtabUnlock(pVTable);
        !           496:       rc = SQLITE_ERROR;
        !           497:     }else{
        !           498:       int iCol;
        !           499:       /* If everything went according to plan, link the new VTable structure
        !           500:       ** into the linked list headed by pTab->pVTable. Then loop through the 
        !           501:       ** columns of the table to see if any of them contain the token "hidden".
        !           502:       ** If so, set the Column.isHidden flag and remove the token from
        !           503:       ** the type string.  */
        !           504:       pVTable->pNext = pTab->pVTable;
        !           505:       pTab->pVTable = pVTable;
        !           506: 
        !           507:       for(iCol=0; iCol<pTab->nCol; iCol++){
        !           508:         char *zType = pTab->aCol[iCol].zType;
        !           509:         int nType;
        !           510:         int i = 0;
        !           511:         if( !zType ) continue;
        !           512:         nType = sqlite3Strlen30(zType);
        !           513:         if( sqlite3StrNICmp("hidden", zType, 6)||(zType[6] && zType[6]!=' ') ){
        !           514:           for(i=0; i<nType; i++){
        !           515:             if( (0==sqlite3StrNICmp(" hidden", &zType[i], 7))
        !           516:              && (zType[i+7]=='\0' || zType[i+7]==' ')
        !           517:             ){
        !           518:               i++;
        !           519:               break;
        !           520:             }
        !           521:           }
        !           522:         }
        !           523:         if( i<nType ){
        !           524:           int j;
        !           525:           int nDel = 6 + (zType[i+6] ? 1 : 0);
        !           526:           for(j=i; (j+nDel)<=nType; j++){
        !           527:             zType[j] = zType[j+nDel];
        !           528:           }
        !           529:           if( zType[i]=='\0' && i>0 ){
        !           530:             assert(zType[i-1]==' ');
        !           531:             zType[i-1] = '\0';
        !           532:           }
        !           533:           pTab->aCol[iCol].isHidden = 1;
        !           534:         }
        !           535:       }
        !           536:     }
        !           537:   }
        !           538: 
        !           539:   sqlite3DbFree(db, zModuleName);
        !           540:   return rc;
        !           541: }
        !           542: 
        !           543: /*
        !           544: ** This function is invoked by the parser to call the xConnect() method
        !           545: ** of the virtual table pTab. If an error occurs, an error code is returned 
        !           546: ** and an error left in pParse.
        !           547: **
        !           548: ** This call is a no-op if table pTab is not a virtual table.
        !           549: */
        !           550: int sqlite3VtabCallConnect(Parse *pParse, Table *pTab){
        !           551:   sqlite3 *db = pParse->db;
        !           552:   const char *zMod;
        !           553:   Module *pMod;
        !           554:   int rc;
        !           555: 
        !           556:   assert( pTab );
        !           557:   if( (pTab->tabFlags & TF_Virtual)==0 || sqlite3GetVTable(db, pTab) ){
        !           558:     return SQLITE_OK;
        !           559:   }
        !           560: 
        !           561:   /* Locate the required virtual table module */
        !           562:   zMod = pTab->azModuleArg[0];
        !           563:   pMod = (Module*)sqlite3HashFind(&db->aModule, zMod, sqlite3Strlen30(zMod));
        !           564: 
        !           565:   if( !pMod ){
        !           566:     const char *zModule = pTab->azModuleArg[0];
        !           567:     sqlite3ErrorMsg(pParse, "no such module: %s", zModule);
        !           568:     rc = SQLITE_ERROR;
        !           569:   }else{
        !           570:     char *zErr = 0;
        !           571:     rc = vtabCallConstructor(db, pTab, pMod, pMod->pModule->xConnect, &zErr);
        !           572:     if( rc!=SQLITE_OK ){
        !           573:       sqlite3ErrorMsg(pParse, "%s", zErr);
        !           574:     }
        !           575:     sqlite3DbFree(db, zErr);
        !           576:   }
        !           577: 
        !           578:   return rc;
        !           579: }
        !           580: /*
        !           581: ** Grow the db->aVTrans[] array so that there is room for at least one
        !           582: ** more v-table. Return SQLITE_NOMEM if a malloc fails, or SQLITE_OK otherwise.
        !           583: */
        !           584: static int growVTrans(sqlite3 *db){
        !           585:   const int ARRAY_INCR = 5;
        !           586: 
        !           587:   /* Grow the sqlite3.aVTrans array if required */
        !           588:   if( (db->nVTrans%ARRAY_INCR)==0 ){
        !           589:     VTable **aVTrans;
        !           590:     int nBytes = sizeof(sqlite3_vtab *) * (db->nVTrans + ARRAY_INCR);
        !           591:     aVTrans = sqlite3DbRealloc(db, (void *)db->aVTrans, nBytes);
        !           592:     if( !aVTrans ){
        !           593:       return SQLITE_NOMEM;
        !           594:     }
        !           595:     memset(&aVTrans[db->nVTrans], 0, sizeof(sqlite3_vtab *)*ARRAY_INCR);
        !           596:     db->aVTrans = aVTrans;
        !           597:   }
        !           598: 
        !           599:   return SQLITE_OK;
        !           600: }
        !           601: 
        !           602: /*
        !           603: ** Add the virtual table pVTab to the array sqlite3.aVTrans[]. Space should
        !           604: ** have already been reserved using growVTrans().
        !           605: */
        !           606: static void addToVTrans(sqlite3 *db, VTable *pVTab){
        !           607:   /* Add pVtab to the end of sqlite3.aVTrans */
        !           608:   db->aVTrans[db->nVTrans++] = pVTab;
        !           609:   sqlite3VtabLock(pVTab);
        !           610: }
        !           611: 
        !           612: /*
        !           613: ** This function is invoked by the vdbe to call the xCreate method
        !           614: ** of the virtual table named zTab in database iDb. 
        !           615: **
        !           616: ** If an error occurs, *pzErr is set to point an an English language
        !           617: ** description of the error and an SQLITE_XXX error code is returned.
        !           618: ** In this case the caller must call sqlite3DbFree(db, ) on *pzErr.
        !           619: */
        !           620: int sqlite3VtabCallCreate(sqlite3 *db, int iDb, const char *zTab, char **pzErr){
        !           621:   int rc = SQLITE_OK;
        !           622:   Table *pTab;
        !           623:   Module *pMod;
        !           624:   const char *zMod;
        !           625: 
        !           626:   pTab = sqlite3FindTable(db, zTab, db->aDb[iDb].zName);
        !           627:   assert( pTab && (pTab->tabFlags & TF_Virtual)!=0 && !pTab->pVTable );
        !           628: 
        !           629:   /* Locate the required virtual table module */
        !           630:   zMod = pTab->azModuleArg[0];
        !           631:   pMod = (Module*)sqlite3HashFind(&db->aModule, zMod, sqlite3Strlen30(zMod));
        !           632: 
        !           633:   /* If the module has been registered and includes a Create method, 
        !           634:   ** invoke it now. If the module has not been registered, return an 
        !           635:   ** error. Otherwise, do nothing.
        !           636:   */
        !           637:   if( !pMod ){
        !           638:     *pzErr = sqlite3MPrintf(db, "no such module: %s", zMod);
        !           639:     rc = SQLITE_ERROR;
        !           640:   }else{
        !           641:     rc = vtabCallConstructor(db, pTab, pMod, pMod->pModule->xCreate, pzErr);
        !           642:   }
        !           643: 
        !           644:   /* Justification of ALWAYS():  The xConstructor method is required to
        !           645:   ** create a valid sqlite3_vtab if it returns SQLITE_OK. */
        !           646:   if( rc==SQLITE_OK && ALWAYS(sqlite3GetVTable(db, pTab)) ){
        !           647:     rc = growVTrans(db);
        !           648:     if( rc==SQLITE_OK ){
        !           649:       addToVTrans(db, sqlite3GetVTable(db, pTab));
        !           650:     }
        !           651:   }
        !           652: 
        !           653:   return rc;
        !           654: }
        !           655: 
        !           656: /*
        !           657: ** This function is used to set the schema of a virtual table.  It is only
        !           658: ** valid to call this function from within the xCreate() or xConnect() of a
        !           659: ** virtual table module.
        !           660: */
        !           661: int sqlite3_declare_vtab(sqlite3 *db, const char *zCreateTable){
        !           662:   Parse *pParse;
        !           663: 
        !           664:   int rc = SQLITE_OK;
        !           665:   Table *pTab;
        !           666:   char *zErr = 0;
        !           667: 
        !           668:   sqlite3_mutex_enter(db->mutex);
        !           669:   if( !db->pVtabCtx || !(pTab = db->pVtabCtx->pTab) ){
        !           670:     sqlite3Error(db, SQLITE_MISUSE, 0);
        !           671:     sqlite3_mutex_leave(db->mutex);
        !           672:     return SQLITE_MISUSE_BKPT;
        !           673:   }
        !           674:   assert( (pTab->tabFlags & TF_Virtual)!=0 );
        !           675: 
        !           676:   pParse = sqlite3StackAllocZero(db, sizeof(*pParse));
        !           677:   if( pParse==0 ){
        !           678:     rc = SQLITE_NOMEM;
        !           679:   }else{
        !           680:     pParse->declareVtab = 1;
        !           681:     pParse->db = db;
        !           682:     pParse->nQueryLoop = 1;
        !           683:   
        !           684:     if( SQLITE_OK==sqlite3RunParser(pParse, zCreateTable, &zErr) 
        !           685:      && pParse->pNewTable
        !           686:      && !db->mallocFailed
        !           687:      && !pParse->pNewTable->pSelect
        !           688:      && (pParse->pNewTable->tabFlags & TF_Virtual)==0
        !           689:     ){
        !           690:       if( !pTab->aCol ){
        !           691:         pTab->aCol = pParse->pNewTable->aCol;
        !           692:         pTab->nCol = pParse->pNewTable->nCol;
        !           693:         pParse->pNewTable->nCol = 0;
        !           694:         pParse->pNewTable->aCol = 0;
        !           695:       }
        !           696:       db->pVtabCtx->pTab = 0;
        !           697:     }else{
        !           698:       sqlite3Error(db, SQLITE_ERROR, (zErr ? "%s" : 0), zErr);
        !           699:       sqlite3DbFree(db, zErr);
        !           700:       rc = SQLITE_ERROR;
        !           701:     }
        !           702:     pParse->declareVtab = 0;
        !           703:   
        !           704:     if( pParse->pVdbe ){
        !           705:       sqlite3VdbeFinalize(pParse->pVdbe);
        !           706:     }
        !           707:     sqlite3DeleteTable(db, pParse->pNewTable);
        !           708:     sqlite3StackFree(db, pParse);
        !           709:   }
        !           710: 
        !           711:   assert( (rc&0xff)==rc );
        !           712:   rc = sqlite3ApiExit(db, rc);
        !           713:   sqlite3_mutex_leave(db->mutex);
        !           714:   return rc;
        !           715: }
        !           716: 
        !           717: /*
        !           718: ** This function is invoked by the vdbe to call the xDestroy method
        !           719: ** of the virtual table named zTab in database iDb. This occurs
        !           720: ** when a DROP TABLE is mentioned.
        !           721: **
        !           722: ** This call is a no-op if zTab is not a virtual table.
        !           723: */
        !           724: int sqlite3VtabCallDestroy(sqlite3 *db, int iDb, const char *zTab){
        !           725:   int rc = SQLITE_OK;
        !           726:   Table *pTab;
        !           727: 
        !           728:   pTab = sqlite3FindTable(db, zTab, db->aDb[iDb].zName);
        !           729:   if( ALWAYS(pTab!=0 && pTab->pVTable!=0) ){
        !           730:     VTable *p = vtabDisconnectAll(db, pTab);
        !           731: 
        !           732:     assert( rc==SQLITE_OK );
        !           733:     rc = p->pMod->pModule->xDestroy(p->pVtab);
        !           734: 
        !           735:     /* Remove the sqlite3_vtab* from the aVTrans[] array, if applicable */
        !           736:     if( rc==SQLITE_OK ){
        !           737:       assert( pTab->pVTable==p && p->pNext==0 );
        !           738:       p->pVtab = 0;
        !           739:       pTab->pVTable = 0;
        !           740:       sqlite3VtabUnlock(p);
        !           741:     }
        !           742:   }
        !           743: 
        !           744:   return rc;
        !           745: }
        !           746: 
        !           747: /*
        !           748: ** This function invokes either the xRollback or xCommit method
        !           749: ** of each of the virtual tables in the sqlite3.aVTrans array. The method
        !           750: ** called is identified by the second argument, "offset", which is
        !           751: ** the offset of the method to call in the sqlite3_module structure.
        !           752: **
        !           753: ** The array is cleared after invoking the callbacks. 
        !           754: */
        !           755: static void callFinaliser(sqlite3 *db, int offset){
        !           756:   int i;
        !           757:   if( db->aVTrans ){
        !           758:     for(i=0; i<db->nVTrans; i++){
        !           759:       VTable *pVTab = db->aVTrans[i];
        !           760:       sqlite3_vtab *p = pVTab->pVtab;
        !           761:       if( p ){
        !           762:         int (*x)(sqlite3_vtab *);
        !           763:         x = *(int (**)(sqlite3_vtab *))((char *)p->pModule + offset);
        !           764:         if( x ) x(p);
        !           765:       }
        !           766:       pVTab->iSavepoint = 0;
        !           767:       sqlite3VtabUnlock(pVTab);
        !           768:     }
        !           769:     sqlite3DbFree(db, db->aVTrans);
        !           770:     db->nVTrans = 0;
        !           771:     db->aVTrans = 0;
        !           772:   }
        !           773: }
        !           774: 
        !           775: /*
        !           776: ** Invoke the xSync method of all virtual tables in the sqlite3.aVTrans
        !           777: ** array. Return the error code for the first error that occurs, or
        !           778: ** SQLITE_OK if all xSync operations are successful.
        !           779: **
        !           780: ** Set *pzErrmsg to point to a buffer that should be released using 
        !           781: ** sqlite3DbFree() containing an error message, if one is available.
        !           782: */
        !           783: int sqlite3VtabSync(sqlite3 *db, char **pzErrmsg){
        !           784:   int i;
        !           785:   int rc = SQLITE_OK;
        !           786:   VTable **aVTrans = db->aVTrans;
        !           787: 
        !           788:   db->aVTrans = 0;
        !           789:   for(i=0; rc==SQLITE_OK && i<db->nVTrans; i++){
        !           790:     int (*x)(sqlite3_vtab *);
        !           791:     sqlite3_vtab *pVtab = aVTrans[i]->pVtab;
        !           792:     if( pVtab && (x = pVtab->pModule->xSync)!=0 ){
        !           793:       rc = x(pVtab);
        !           794:       sqlite3DbFree(db, *pzErrmsg);
        !           795:       *pzErrmsg = sqlite3DbStrDup(db, pVtab->zErrMsg);
        !           796:       sqlite3_free(pVtab->zErrMsg);
        !           797:     }
        !           798:   }
        !           799:   db->aVTrans = aVTrans;
        !           800:   return rc;
        !           801: }
        !           802: 
        !           803: /*
        !           804: ** Invoke the xRollback method of all virtual tables in the 
        !           805: ** sqlite3.aVTrans array. Then clear the array itself.
        !           806: */
        !           807: int sqlite3VtabRollback(sqlite3 *db){
        !           808:   callFinaliser(db, offsetof(sqlite3_module,xRollback));
        !           809:   return SQLITE_OK;
        !           810: }
        !           811: 
        !           812: /*
        !           813: ** Invoke the xCommit method of all virtual tables in the 
        !           814: ** sqlite3.aVTrans array. Then clear the array itself.
        !           815: */
        !           816: int sqlite3VtabCommit(sqlite3 *db){
        !           817:   callFinaliser(db, offsetof(sqlite3_module,xCommit));
        !           818:   return SQLITE_OK;
        !           819: }
        !           820: 
        !           821: /*
        !           822: ** If the virtual table pVtab supports the transaction interface
        !           823: ** (xBegin/xRollback/xCommit and optionally xSync) and a transaction is
        !           824: ** not currently open, invoke the xBegin method now.
        !           825: **
        !           826: ** If the xBegin call is successful, place the sqlite3_vtab pointer
        !           827: ** in the sqlite3.aVTrans array.
        !           828: */
        !           829: int sqlite3VtabBegin(sqlite3 *db, VTable *pVTab){
        !           830:   int rc = SQLITE_OK;
        !           831:   const sqlite3_module *pModule;
        !           832: 
        !           833:   /* Special case: If db->aVTrans is NULL and db->nVTrans is greater
        !           834:   ** than zero, then this function is being called from within a
        !           835:   ** virtual module xSync() callback. It is illegal to write to 
        !           836:   ** virtual module tables in this case, so return SQLITE_LOCKED.
        !           837:   */
        !           838:   if( sqlite3VtabInSync(db) ){
        !           839:     return SQLITE_LOCKED;
        !           840:   }
        !           841:   if( !pVTab ){
        !           842:     return SQLITE_OK;
        !           843:   } 
        !           844:   pModule = pVTab->pVtab->pModule;
        !           845: 
        !           846:   if( pModule->xBegin ){
        !           847:     int i;
        !           848: 
        !           849:     /* If pVtab is already in the aVTrans array, return early */
        !           850:     for(i=0; i<db->nVTrans; i++){
        !           851:       if( db->aVTrans[i]==pVTab ){
        !           852:         return SQLITE_OK;
        !           853:       }
        !           854:     }
        !           855: 
        !           856:     /* Invoke the xBegin method. If successful, add the vtab to the 
        !           857:     ** sqlite3.aVTrans[] array. */
        !           858:     rc = growVTrans(db);
        !           859:     if( rc==SQLITE_OK ){
        !           860:       rc = pModule->xBegin(pVTab->pVtab);
        !           861:       if( rc==SQLITE_OK ){
        !           862:         addToVTrans(db, pVTab);
        !           863:       }
        !           864:     }
        !           865:   }
        !           866:   return rc;
        !           867: }
        !           868: 
        !           869: /*
        !           870: ** Invoke either the xSavepoint, xRollbackTo or xRelease method of all
        !           871: ** virtual tables that currently have an open transaction. Pass iSavepoint
        !           872: ** as the second argument to the virtual table method invoked.
        !           873: **
        !           874: ** If op is SAVEPOINT_BEGIN, the xSavepoint method is invoked. If it is
        !           875: ** SAVEPOINT_ROLLBACK, the xRollbackTo method. Otherwise, if op is 
        !           876: ** SAVEPOINT_RELEASE, then the xRelease method of each virtual table with
        !           877: ** an open transaction is invoked.
        !           878: **
        !           879: ** If any virtual table method returns an error code other than SQLITE_OK, 
        !           880: ** processing is abandoned and the error returned to the caller of this
        !           881: ** function immediately. If all calls to virtual table methods are successful,
        !           882: ** SQLITE_OK is returned.
        !           883: */
        !           884: int sqlite3VtabSavepoint(sqlite3 *db, int op, int iSavepoint){
        !           885:   int rc = SQLITE_OK;
        !           886: 
        !           887:   assert( op==SAVEPOINT_RELEASE||op==SAVEPOINT_ROLLBACK||op==SAVEPOINT_BEGIN );
        !           888:   assert( iSavepoint>=0 );
        !           889:   if( db->aVTrans ){
        !           890:     int i;
        !           891:     for(i=0; rc==SQLITE_OK && i<db->nVTrans; i++){
        !           892:       VTable *pVTab = db->aVTrans[i];
        !           893:       const sqlite3_module *pMod = pVTab->pMod->pModule;
        !           894:       if( pVTab->pVtab && pMod->iVersion>=2 ){
        !           895:         int (*xMethod)(sqlite3_vtab *, int);
        !           896:         switch( op ){
        !           897:           case SAVEPOINT_BEGIN:
        !           898:             xMethod = pMod->xSavepoint;
        !           899:             pVTab->iSavepoint = iSavepoint+1;
        !           900:             break;
        !           901:           case SAVEPOINT_ROLLBACK:
        !           902:             xMethod = pMod->xRollbackTo;
        !           903:             break;
        !           904:           default:
        !           905:             xMethod = pMod->xRelease;
        !           906:             break;
        !           907:         }
        !           908:         if( xMethod && pVTab->iSavepoint>iSavepoint ){
        !           909:           rc = xMethod(pVTab->pVtab, iSavepoint);
        !           910:         }
        !           911:       }
        !           912:     }
        !           913:   }
        !           914:   return rc;
        !           915: }
        !           916: 
        !           917: /*
        !           918: ** The first parameter (pDef) is a function implementation.  The
        !           919: ** second parameter (pExpr) is the first argument to this function.
        !           920: ** If pExpr is a column in a virtual table, then let the virtual
        !           921: ** table implementation have an opportunity to overload the function.
        !           922: **
        !           923: ** This routine is used to allow virtual table implementations to
        !           924: ** overload MATCH, LIKE, GLOB, and REGEXP operators.
        !           925: **
        !           926: ** Return either the pDef argument (indicating no change) or a 
        !           927: ** new FuncDef structure that is marked as ephemeral using the
        !           928: ** SQLITE_FUNC_EPHEM flag.
        !           929: */
        !           930: FuncDef *sqlite3VtabOverloadFunction(
        !           931:   sqlite3 *db,    /* Database connection for reporting malloc problems */
        !           932:   FuncDef *pDef,  /* Function to possibly overload */
        !           933:   int nArg,       /* Number of arguments to the function */
        !           934:   Expr *pExpr     /* First argument to the function */
        !           935: ){
        !           936:   Table *pTab;
        !           937:   sqlite3_vtab *pVtab;
        !           938:   sqlite3_module *pMod;
        !           939:   void (*xFunc)(sqlite3_context*,int,sqlite3_value**) = 0;
        !           940:   void *pArg = 0;
        !           941:   FuncDef *pNew;
        !           942:   int rc = 0;
        !           943:   char *zLowerName;
        !           944:   unsigned char *z;
        !           945: 
        !           946: 
        !           947:   /* Check to see the left operand is a column in a virtual table */
        !           948:   if( NEVER(pExpr==0) ) return pDef;
        !           949:   if( pExpr->op!=TK_COLUMN ) return pDef;
        !           950:   pTab = pExpr->pTab;
        !           951:   if( NEVER(pTab==0) ) return pDef;
        !           952:   if( (pTab->tabFlags & TF_Virtual)==0 ) return pDef;
        !           953:   pVtab = sqlite3GetVTable(db, pTab)->pVtab;
        !           954:   assert( pVtab!=0 );
        !           955:   assert( pVtab->pModule!=0 );
        !           956:   pMod = (sqlite3_module *)pVtab->pModule;
        !           957:   if( pMod->xFindFunction==0 ) return pDef;
        !           958:  
        !           959:   /* Call the xFindFunction method on the virtual table implementation
        !           960:   ** to see if the implementation wants to overload this function 
        !           961:   */
        !           962:   zLowerName = sqlite3DbStrDup(db, pDef->zName);
        !           963:   if( zLowerName ){
        !           964:     for(z=(unsigned char*)zLowerName; *z; z++){
        !           965:       *z = sqlite3UpperToLower[*z];
        !           966:     }
        !           967:     rc = pMod->xFindFunction(pVtab, nArg, zLowerName, &xFunc, &pArg);
        !           968:     sqlite3DbFree(db, zLowerName);
        !           969:   }
        !           970:   if( rc==0 ){
        !           971:     return pDef;
        !           972:   }
        !           973: 
        !           974:   /* Create a new ephemeral function definition for the overloaded
        !           975:   ** function */
        !           976:   pNew = sqlite3DbMallocZero(db, sizeof(*pNew)
        !           977:                              + sqlite3Strlen30(pDef->zName) + 1);
        !           978:   if( pNew==0 ){
        !           979:     return pDef;
        !           980:   }
        !           981:   *pNew = *pDef;
        !           982:   pNew->zName = (char *)&pNew[1];
        !           983:   memcpy(pNew->zName, pDef->zName, sqlite3Strlen30(pDef->zName)+1);
        !           984:   pNew->xFunc = xFunc;
        !           985:   pNew->pUserData = pArg;
        !           986:   pNew->flags |= SQLITE_FUNC_EPHEM;
        !           987:   return pNew;
        !           988: }
        !           989: 
        !           990: /*
        !           991: ** Make sure virtual table pTab is contained in the pParse->apVirtualLock[]
        !           992: ** array so that an OP_VBegin will get generated for it.  Add pTab to the
        !           993: ** array if it is missing.  If pTab is already in the array, this routine
        !           994: ** is a no-op.
        !           995: */
        !           996: void sqlite3VtabMakeWritable(Parse *pParse, Table *pTab){
        !           997:   Parse *pToplevel = sqlite3ParseToplevel(pParse);
        !           998:   int i, n;
        !           999:   Table **apVtabLock;
        !          1000: 
        !          1001:   assert( IsVirtual(pTab) );
        !          1002:   for(i=0; i<pToplevel->nVtabLock; i++){
        !          1003:     if( pTab==pToplevel->apVtabLock[i] ) return;
        !          1004:   }
        !          1005:   n = (pToplevel->nVtabLock+1)*sizeof(pToplevel->apVtabLock[0]);
        !          1006:   apVtabLock = sqlite3_realloc(pToplevel->apVtabLock, n);
        !          1007:   if( apVtabLock ){
        !          1008:     pToplevel->apVtabLock = apVtabLock;
        !          1009:     pToplevel->apVtabLock[pToplevel->nVtabLock++] = pTab;
        !          1010:   }else{
        !          1011:     pToplevel->db->mallocFailed = 1;
        !          1012:   }
        !          1013: }
        !          1014: 
        !          1015: /*
        !          1016: ** Return the ON CONFLICT resolution mode in effect for the virtual
        !          1017: ** table update operation currently in progress.
        !          1018: **
        !          1019: ** The results of this routine are undefined unless it is called from
        !          1020: ** within an xUpdate method.
        !          1021: */
        !          1022: int sqlite3_vtab_on_conflict(sqlite3 *db){
        !          1023:   static const unsigned char aMap[] = { 
        !          1024:     SQLITE_ROLLBACK, SQLITE_ABORT, SQLITE_FAIL, SQLITE_IGNORE, SQLITE_REPLACE 
        !          1025:   };
        !          1026:   assert( OE_Rollback==1 && OE_Abort==2 && OE_Fail==3 );
        !          1027:   assert( OE_Ignore==4 && OE_Replace==5 );
        !          1028:   assert( db->vtabOnConflict>=1 && db->vtabOnConflict<=5 );
        !          1029:   return (int)aMap[db->vtabOnConflict-1];
        !          1030: }
        !          1031: 
        !          1032: /*
        !          1033: ** Call from within the xCreate() or xConnect() methods to provide 
        !          1034: ** the SQLite core with additional information about the behavior
        !          1035: ** of the virtual table being implemented.
        !          1036: */
        !          1037: int sqlite3_vtab_config(sqlite3 *db, int op, ...){
        !          1038:   va_list ap;
        !          1039:   int rc = SQLITE_OK;
        !          1040: 
        !          1041:   sqlite3_mutex_enter(db->mutex);
        !          1042: 
        !          1043:   va_start(ap, op);
        !          1044:   switch( op ){
        !          1045:     case SQLITE_VTAB_CONSTRAINT_SUPPORT: {
        !          1046:       VtabCtx *p = db->pVtabCtx;
        !          1047:       if( !p ){
        !          1048:         rc = SQLITE_MISUSE_BKPT;
        !          1049:       }else{
        !          1050:         assert( p->pTab==0 || (p->pTab->tabFlags & TF_Virtual)!=0 );
        !          1051:         p->pVTable->bConstraint = (u8)va_arg(ap, int);
        !          1052:       }
        !          1053:       break;
        !          1054:     }
        !          1055:     default:
        !          1056:       rc = SQLITE_MISUSE_BKPT;
        !          1057:       break;
        !          1058:   }
        !          1059:   va_end(ap);
        !          1060: 
        !          1061:   if( rc!=SQLITE_OK ) sqlite3Error(db, rc, 0);
        !          1062:   sqlite3_mutex_leave(db->mutex);
        !          1063:   return rc;
        !          1064: }
        !          1065: 
        !          1066: #endif /* SQLITE_OMIT_VIRTUALTABLE */

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>