webengine/webkitutils/SqliteSymbian/vtab.c
changeset 0 dd21522fd290
equal deleted inserted replaced
-1:000000000000 0:dd21522fd290
       
     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 ** $Id: vtab.c,v 1.31 2006/09/02 20:57:52 drh Exp $
       
    15 */
       
    16 #ifndef SQLITE_OMIT_VIRTUALTABLE
       
    17 #include "sqliteInt.h"
       
    18 
       
    19 /*
       
    20 ** External API function used to create a new virtual-table module.
       
    21 */
       
    22 int sqlite3_create_module(
       
    23   sqlite3 *db,                    /* Database in which module is registered */
       
    24   const char *zName,              /* Name assigned to this module */
       
    25   const sqlite3_module *pModule,  /* The definition of the module */
       
    26   void *pAux                      /* Context pointer for xCreate/xConnect */
       
    27 ){
       
    28   int nName = strlen(zName);
       
    29   Module *pMod = (Module *)sqliteMallocRaw(sizeof(Module) + nName + 1);
       
    30   if( pMod ){
       
    31     char *zCopy = (char *)(&pMod[1]);
       
    32     strcpy(zCopy, zName);
       
    33     pMod->zName = zCopy;
       
    34     pMod->pModule = pModule;
       
    35     pMod->pAux = pAux;
       
    36     pMod = (Module *)sqlite3HashInsert(&db->aModule, zCopy, nName, (void*)pMod);
       
    37     sqliteFree(pMod);
       
    38     sqlite3ResetInternalSchema(db, 0);
       
    39   }
       
    40   return sqlite3ApiExit(db, SQLITE_OK);
       
    41 }
       
    42 
       
    43 /*
       
    44 ** Lock the virtual table so that it cannot be disconnected.
       
    45 ** Locks nest.  Every lock should have a corresponding unlock.
       
    46 ** If an unlock is omitted, resources leaks will occur.  
       
    47 **
       
    48 ** If a disconnect is attempted while a virtual table is locked,
       
    49 ** the disconnect is deferred until all locks have been removed.
       
    50 */
       
    51 void sqlite3VtabLock(sqlite3_vtab *pVtab){
       
    52   pVtab->nRef++;
       
    53 }
       
    54 
       
    55 /*
       
    56 ** Unlock a virtual table.  When the last lock is removed,
       
    57 ** disconnect the virtual table.
       
    58 */
       
    59 void sqlite3VtabUnlock(sqlite3_vtab *pVtab){
       
    60   pVtab->nRef--;
       
    61   if( pVtab->nRef==0 ){
       
    62     pVtab->pModule->xDisconnect(pVtab);
       
    63   }
       
    64 }
       
    65 
       
    66 /*
       
    67 ** Clear any and all virtual-table information from the Table record.
       
    68 ** This routine is called, for example, just before deleting the Table
       
    69 ** record.
       
    70 */
       
    71 void sqlite3VtabClear(Table *p){
       
    72   sqlite3_vtab *pVtab = p->pVtab;
       
    73   if( pVtab ){
       
    74     assert( p->pMod && p->pMod->pModule );
       
    75     sqlite3VtabUnlock(pVtab);
       
    76     p->pVtab = 0;
       
    77   }
       
    78   if( p->azModuleArg ){
       
    79     int i;
       
    80     for(i=0; i<p->nModuleArg; i++){
       
    81       sqliteFree(p->azModuleArg[i]);
       
    82     }
       
    83     sqliteFree(p->azModuleArg);
       
    84   }
       
    85 }
       
    86 
       
    87 /*
       
    88 ** Add a new module argument to pTable->azModuleArg[].
       
    89 ** The string is not copied - the pointer is stored.  The
       
    90 ** string will be freed automatically when the table is
       
    91 ** deleted.
       
    92 */
       
    93 static void addModuleArgument(Table *pTable, char *zArg){
       
    94   int i = pTable->nModuleArg++;
       
    95   int nBytes = sizeof(char *)*(1+pTable->nModuleArg);
       
    96   char **azModuleArg;
       
    97   azModuleArg = sqliteRealloc(pTable->azModuleArg, nBytes);
       
    98   if( azModuleArg==0 ){
       
    99     int j;
       
   100     for(j=0; j<i; j++){
       
   101       sqliteFree(pTable->azModuleArg[j]);
       
   102     }
       
   103     sqliteFree(zArg);
       
   104     sqliteFree(pTable->azModuleArg);
       
   105     pTable->nModuleArg = 0;
       
   106   }else{
       
   107     azModuleArg[i] = zArg;
       
   108     azModuleArg[i+1] = 0;
       
   109   }
       
   110   pTable->azModuleArg = azModuleArg;
       
   111 }
       
   112 
       
   113 /*
       
   114 ** The parser calls this routine when it first sees a CREATE VIRTUAL TABLE
       
   115 ** statement.  The module name has been parsed, but the optional list
       
   116 ** of parameters that follow the module name are still pending.
       
   117 */
       
   118 void sqlite3VtabBeginParse(
       
   119   Parse *pParse,        /* Parsing context */
       
   120   Token *pName1,        /* Name of new table, or database name */
       
   121   Token *pName2,        /* Name of new table or NULL */
       
   122   Token *pModuleName    /* Name of the module for the virtual table */
       
   123 ){
       
   124   int iDb;              /* The database the table is being created in */
       
   125   Table *pTable;        /* The new virtual table */
       
   126 
       
   127   sqlite3StartTable(pParse, pName1, pName2, 0, 0, 1, 0);
       
   128   pTable = pParse->pNewTable;
       
   129   if( pTable==0 || pParse->nErr ) return;
       
   130   assert( 0==pTable->pIndex );
       
   131 
       
   132   iDb = sqlite3SchemaToIndex(pParse->db, pTable->pSchema);
       
   133   assert( iDb>=0 );
       
   134 
       
   135   pTable->isVirtual = 1;
       
   136   pTable->nModuleArg = 0;
       
   137   addModuleArgument(pTable, sqlite3NameFromToken(pModuleName));
       
   138   addModuleArgument(pTable, sqlite3StrDup(pParse->db->aDb[iDb].zName));
       
   139   addModuleArgument(pTable, sqlite3StrDup(pTable->zName));
       
   140   pParse->sNameToken.n = pModuleName->z + pModuleName->n - pName1->z;
       
   141 
       
   142 #ifndef SQLITE_OMIT_AUTHORIZATION
       
   143   /* Creating a virtual table invokes the authorization callback twice.
       
   144   ** The first invocation, to obtain permission to INSERT a row into the
       
   145   ** sqlite_master table, has already been made by sqlite3StartTable().
       
   146   ** The second call, to obtain permission to create the table, is made now.
       
   147   */
       
   148   if( pTable->azModuleArg ){
       
   149     sqlite3AuthCheck(pParse, SQLITE_CREATE_VTABLE, pTable->zName, 
       
   150             pTable->azModuleArg[0], pParse->db->aDb[iDb].zName);
       
   151   }
       
   152 #endif
       
   153 }
       
   154 
       
   155 /*
       
   156 ** This routine takes the module argument that has been accumulating
       
   157 ** in pParse->zArg[] and appends it to the list of arguments on the
       
   158 ** virtual table currently under construction in pParse->pTable.
       
   159 */
       
   160 static void addArgumentToVtab(Parse *pParse){
       
   161   if( pParse->sArg.z && pParse->pNewTable ){
       
   162     const char *z = (const char*)pParse->sArg.z;
       
   163     int n = pParse->sArg.n;
       
   164     addModuleArgument(pParse->pNewTable, sqliteStrNDup(z, n));
       
   165   }
       
   166 }
       
   167 
       
   168 /*
       
   169 ** The parser calls this routine after the CREATE VIRTUAL TABLE statement
       
   170 ** has been completely parsed.
       
   171 */
       
   172 void sqlite3VtabFinishParse(Parse *pParse, Token *pEnd){
       
   173   Table *pTab;        /* The table being constructed */
       
   174   sqlite3 *db;        /* The database connection */
       
   175   char *zModule;      /* The module name of the table: USING modulename */
       
   176   Module *pMod = 0;
       
   177 
       
   178   addArgumentToVtab(pParse);
       
   179   pParse->sArg.z = 0;
       
   180 
       
   181   /* Lookup the module name. */
       
   182   pTab = pParse->pNewTable;
       
   183   if( pTab==0 ) return;
       
   184   db = pParse->db;
       
   185   if( pTab->nModuleArg<1 ) return;
       
   186   zModule = pTab->azModuleArg[0];
       
   187   pMod = (Module *)sqlite3HashFind(&db->aModule, zModule, strlen(zModule));
       
   188   pTab->pMod = pMod;
       
   189   
       
   190   /* If the CREATE VIRTUAL TABLE statement is being entered for the
       
   191   ** first time (in other words if the virtual table is actually being
       
   192   ** created now instead of just being read out of sqlite_master) then
       
   193   ** do additional initialization work and store the statement text
       
   194   ** in the sqlite_master table.
       
   195   */
       
   196   if( !db->init.busy ){
       
   197     char *zStmt;
       
   198     char *zWhere;
       
   199     int iDb;
       
   200     Vdbe *v;
       
   201 
       
   202     /* Compute the complete text of the CREATE VIRTUAL TABLE statement */
       
   203     if( pEnd ){
       
   204       pParse->sNameToken.n = pEnd->z - pParse->sNameToken.z + pEnd->n;
       
   205     }
       
   206     zStmt = sqlite3MPrintf("CREATE VIRTUAL TABLE %T", &pParse->sNameToken);
       
   207 
       
   208     /* A slot for the record has already been allocated in the 
       
   209     ** SQLITE_MASTER table.  We just need to update that slot with all
       
   210     ** the information we've collected.  
       
   211     **
       
   212     ** The top of the stack is the rootpage allocated by sqlite3StartTable().
       
   213     ** This value is always 0 and is ignored, a virtual table does not have a
       
   214     ** rootpage. The next entry on the stack is the rowid of the record
       
   215     ** in the sqlite_master table.
       
   216     */
       
   217     iDb = sqlite3SchemaToIndex(db, pTab->pSchema);
       
   218     sqlite3NestedParse(pParse,
       
   219       "UPDATE %Q.%s "
       
   220          "SET type='table', name=%Q, tbl_name=%Q, rootpage=0, sql=%Q "
       
   221        "WHERE rowid=#1",
       
   222       db->aDb[iDb].zName, SCHEMA_TABLE(iDb),
       
   223       pTab->zName,
       
   224       pTab->zName,
       
   225       zStmt
       
   226     );
       
   227     sqliteFree(zStmt);
       
   228     v = sqlite3GetVdbe(pParse);
       
   229     sqlite3ChangeCookie(db, v, iDb);
       
   230 
       
   231     sqlite3VdbeAddOp(v, OP_Expire, 0, 0);
       
   232     zWhere = sqlite3MPrintf("name='%q'", pTab->zName);
       
   233     sqlite3VdbeOp3(v, OP_ParseSchema, iDb, 0, zWhere, P3_DYNAMIC);
       
   234     sqlite3VdbeOp3(v, OP_VCreate, iDb, 0, pTab->zName, strlen(pTab->zName) + 1);
       
   235   }
       
   236 
       
   237   /* If we are rereading the sqlite_master table create the in-memory
       
   238   ** record of the table. If the module has already been registered,
       
   239   ** also call the xConnect method here.
       
   240   */
       
   241   else {
       
   242     Table *pOld;
       
   243     Schema *pSchema = pTab->pSchema;
       
   244     const char *zName = pTab->zName;
       
   245     int nName = strlen(zName) + 1;
       
   246     pOld = sqlite3HashInsert(&pSchema->tblHash, zName, nName, pTab);
       
   247     if( pOld ){
       
   248       assert( pTab==pOld );  /* Malloc must have failed inside HashInsert() */
       
   249       return;
       
   250     }
       
   251     pParse->pNewTable = 0;
       
   252   }
       
   253 }
       
   254 
       
   255 /*
       
   256 ** The parser calls this routine when it sees the first token
       
   257 ** of an argument to the module name in a CREATE VIRTUAL TABLE statement.
       
   258 */
       
   259 void sqlite3VtabArgInit(Parse *pParse){
       
   260   addArgumentToVtab(pParse);
       
   261   pParse->sArg.z = 0;
       
   262   pParse->sArg.n = 0;
       
   263 }
       
   264 
       
   265 /*
       
   266 ** The parser calls this routine for each token after the first token
       
   267 ** in an argument to the module name in a CREATE VIRTUAL TABLE statement.
       
   268 */
       
   269 void sqlite3VtabArgExtend(Parse *pParse, Token *p){
       
   270   Token *pArg = &pParse->sArg;
       
   271   if( pArg->z==0 ){
       
   272     pArg->z = p->z;
       
   273     pArg->n = p->n;
       
   274   }else{
       
   275     assert(pArg->z < p->z);
       
   276     pArg->n = (p->z + p->n - pArg->z);
       
   277   }
       
   278 }
       
   279 
       
   280 /*
       
   281 ** Invoke a virtual table constructor (either xCreate or xConnect). The
       
   282 ** pointer to the function to invoke is passed as the fourth parameter
       
   283 ** to this procedure.
       
   284 */
       
   285 static int vtabCallConstructor(
       
   286   sqlite3 *db, 
       
   287   Table *pTab,
       
   288   Module *pMod,
       
   289   int (*xConstruct)(sqlite3*, void *, int, char **, sqlite3_vtab **),
       
   290   char **pzErr
       
   291 ){
       
   292   int rc;
       
   293   int rc2;
       
   294   char **azArg = pTab->azModuleArg;
       
   295   int nArg = pTab->nModuleArg;
       
   296   char *zErr = sqlite3MPrintf("vtable constructor failed: %s", pTab->zName);
       
   297 
       
   298   assert( !db->pVTab );
       
   299   assert( xConstruct );
       
   300 
       
   301   db->pVTab = pTab;
       
   302   rc = sqlite3SafetyOff(db);
       
   303   assert( rc==SQLITE_OK );
       
   304   rc = xConstruct(db, pMod->pAux, nArg, azArg, &pTab->pVtab);
       
   305   rc2 = sqlite3SafetyOn(db);
       
   306   if( rc==SQLITE_OK && pTab->pVtab ){
       
   307     pTab->pVtab->pModule = pMod->pModule;
       
   308     pTab->pVtab->nRef = 1;
       
   309   }
       
   310 
       
   311   if( SQLITE_OK!=rc ){
       
   312     *pzErr = zErr;
       
   313     zErr = 0;
       
   314   } else if( db->pVTab ){
       
   315     const char *zFormat = "vtable constructor did not declare schema: %s";
       
   316     *pzErr = sqlite3MPrintf(zFormat, pTab->zName);
       
   317     rc = SQLITE_ERROR;
       
   318   } 
       
   319   if( rc==SQLITE_OK ){
       
   320     rc = rc2;
       
   321   }
       
   322   db->pVTab = 0;
       
   323   sqliteFree(zErr);
       
   324   return rc;
       
   325 }
       
   326 
       
   327 /*
       
   328 ** This function is invoked by the parser to call the xConnect() method
       
   329 ** of the virtual table pTab. If an error occurs, an error code is returned 
       
   330 ** and an error left in pParse.
       
   331 **
       
   332 ** This call is a no-op if table pTab is not a virtual table.
       
   333 */
       
   334 int sqlite3VtabCallConnect(Parse *pParse, Table *pTab){
       
   335   Module *pMod;
       
   336   const char *zModule;
       
   337   int rc = SQLITE_OK;
       
   338 
       
   339   if( !pTab || !pTab->isVirtual || pTab->pVtab ){
       
   340     return SQLITE_OK;
       
   341   }
       
   342 
       
   343   pMod = pTab->pMod;
       
   344   zModule = pTab->azModuleArg[0];
       
   345   if( !pMod ){
       
   346     const char *zModule = pTab->azModuleArg[0];
       
   347     sqlite3ErrorMsg(pParse, "no such module: %s", zModule);
       
   348     rc = SQLITE_ERROR;
       
   349   } else {
       
   350     char *zErr = 0;
       
   351     sqlite3 *db = pParse->db;
       
   352     rc = vtabCallConstructor(db, pTab, pMod, pMod->pModule->xConnect, &zErr);
       
   353     if( rc!=SQLITE_OK ){
       
   354       sqlite3ErrorMsg(pParse, "%s", zErr);
       
   355     }
       
   356     sqliteFree(zErr);
       
   357   }
       
   358 
       
   359   return rc;
       
   360 }
       
   361 
       
   362 /*
       
   363 ** Add the virtual table pVtab to the array sqlite3.aVTrans[].
       
   364 */
       
   365 static int addToVTrans(sqlite3 *db, sqlite3_vtab *pVtab){
       
   366   const int ARRAY_INCR = 5;
       
   367 
       
   368   /* Grow the sqlite3.aVTrans array if required */
       
   369   if( (db->nVTrans%ARRAY_INCR)==0 ){
       
   370     sqlite3_vtab **aVTrans;
       
   371     int nBytes = sizeof(sqlite3_vtab *) * (db->nVTrans + ARRAY_INCR);
       
   372     aVTrans = sqliteRealloc((void *)db->aVTrans, nBytes);
       
   373     if( !aVTrans ){
       
   374       return SQLITE_NOMEM;
       
   375     }
       
   376     memset(&aVTrans[db->nVTrans], 0, sizeof(sqlite3_vtab *)*ARRAY_INCR);
       
   377     db->aVTrans = aVTrans;
       
   378   }
       
   379 
       
   380   /* Add pVtab to the end of sqlite3.aVTrans */
       
   381   db->aVTrans[db->nVTrans++] = pVtab;
       
   382   sqlite3VtabLock(pVtab);
       
   383   return SQLITE_OK;
       
   384 }
       
   385 
       
   386 /*
       
   387 ** This function is invoked by the vdbe to call the xCreate method
       
   388 ** of the virtual table named zTab in database iDb. 
       
   389 **
       
   390 ** If an error occurs, *pzErr is set to point an an English language
       
   391 ** description of the error and an SQLITE_XXX error code is returned.
       
   392 ** In this case the caller must call sqliteFree() on *pzErr.
       
   393 */
       
   394 int sqlite3VtabCallCreate(sqlite3 *db, int iDb, const char *zTab, char **pzErr){
       
   395   int rc = SQLITE_OK;
       
   396   Table *pTab;
       
   397   Module *pMod;
       
   398   const char *zModule;
       
   399 
       
   400   pTab = sqlite3FindTable(db, zTab, db->aDb[iDb].zName);
       
   401   assert(pTab && pTab->isVirtual && !pTab->pVtab);
       
   402   pMod = pTab->pMod;
       
   403   zModule = pTab->azModuleArg[0];
       
   404 
       
   405   /* If the module has been registered and includes a Create method, 
       
   406   ** invoke it now. If the module has not been registered, return an 
       
   407   ** error. Otherwise, do nothing.
       
   408   */
       
   409   if( !pMod ){
       
   410     *pzErr = sqlite3MPrintf("no such module: %s", zModule);
       
   411     rc = SQLITE_ERROR;
       
   412   }else{
       
   413     rc = vtabCallConstructor(db, pTab, pMod, pMod->pModule->xCreate, pzErr);
       
   414   }
       
   415 
       
   416   if( rc==SQLITE_OK && pTab->pVtab ){
       
   417       rc = addToVTrans(db, pTab->pVtab);
       
   418   }
       
   419 
       
   420   return rc;
       
   421 }
       
   422 
       
   423 /*
       
   424 ** This function is used to set the schema of a virtual table.  It is only
       
   425 ** valid to call this function from within the xCreate() or xConnect() of a
       
   426 ** virtual table module.
       
   427 */
       
   428 int sqlite3_declare_vtab(sqlite3 *db, const char *zCreateTable){
       
   429   Parse sParse;
       
   430 
       
   431   int rc = SQLITE_OK;
       
   432   Table *pTab = db->pVTab;
       
   433   char *zErr = 0;
       
   434 
       
   435   if( !pTab ){
       
   436     sqlite3Error(db, SQLITE_MISUSE, 0);
       
   437     return SQLITE_MISUSE;
       
   438   }
       
   439   assert(pTab->isVirtual && pTab->nCol==0 && pTab->aCol==0);
       
   440 
       
   441   memset(&sParse, 0, sizeof(Parse));
       
   442   sParse.declareVtab = 1;
       
   443   sParse.db = db;
       
   444 
       
   445   if( 
       
   446       SQLITE_OK == sqlite3RunParser(&sParse, zCreateTable, &zErr) && 
       
   447       sParse.pNewTable && 
       
   448       !sParse.pNewTable->pSelect && 
       
   449       !sParse.pNewTable->isVirtual 
       
   450   ){
       
   451     pTab->aCol = sParse.pNewTable->aCol;
       
   452     pTab->nCol = sParse.pNewTable->nCol;
       
   453     sParse.pNewTable->nCol = 0;
       
   454     sParse.pNewTable->aCol = 0;
       
   455   } else {
       
   456     sqlite3Error(db, SQLITE_ERROR, zErr);
       
   457     sqliteFree(zErr);
       
   458     rc = SQLITE_ERROR;
       
   459   }
       
   460   sParse.declareVtab = 0;
       
   461 
       
   462   sqlite3_finalize((sqlite3_stmt*)sParse.pVdbe);
       
   463   sqlite3DeleteTable(0, sParse.pNewTable);
       
   464   sParse.pNewTable = 0;
       
   465   db->pVTab = 0;
       
   466 
       
   467   return rc;
       
   468 }
       
   469 
       
   470 /*
       
   471 ** This function is invoked by the vdbe to call the xDestroy method
       
   472 ** of the virtual table named zTab in database iDb. This occurs
       
   473 ** when a DROP TABLE is mentioned.
       
   474 **
       
   475 ** This call is a no-op if zTab is not a virtual table.
       
   476 */
       
   477 int sqlite3VtabCallDestroy(sqlite3 *db, int iDb, const char *zTab)
       
   478 {
       
   479   int rc = SQLITE_OK;
       
   480   Table *pTab;
       
   481 
       
   482   pTab = sqlite3FindTable(db, zTab, db->aDb[iDb].zName);
       
   483   assert(pTab);
       
   484   if( pTab->pVtab ){
       
   485     int (*xDestroy)(sqlite3_vtab *pVTab) = pTab->pMod->pModule->xDestroy;
       
   486     rc = sqlite3SafetyOff(db);
       
   487     assert( rc==SQLITE_OK );
       
   488     if( xDestroy ){
       
   489       rc = xDestroy(pTab->pVtab);
       
   490     }
       
   491     sqlite3SafetyOn(db);
       
   492     if( rc==SQLITE_OK ){
       
   493       pTab->pVtab = 0;
       
   494     }
       
   495   }
       
   496 
       
   497   return rc;
       
   498 }
       
   499 
       
   500 /*
       
   501 ** This function invokes either the xRollback or xCommit method
       
   502 ** of each of the virtual tables in the sqlite3.aVTrans array. The method
       
   503 ** called is identified by the second argument, "offset", which is
       
   504 ** the offset of the method to call in the sqlite3_module structure.
       
   505 **
       
   506 ** The array is cleared after invoking the callbacks. 
       
   507 */
       
   508 static void callFinaliser(sqlite3 *db, int offset){
       
   509   int i;
       
   510   for(i=0; i<db->nVTrans && db->aVTrans[i]; i++){
       
   511     sqlite3_vtab *pVtab = db->aVTrans[i];
       
   512     int (*x)(sqlite3_vtab *);
       
   513     x = *(int (**)(sqlite3_vtab *))((char *)pVtab->pModule + offset);
       
   514     if( x ) x(pVtab);
       
   515     sqlite3VtabUnlock(pVtab);
       
   516   }
       
   517   sqliteFree(db->aVTrans);
       
   518   db->nVTrans = 0;
       
   519   db->aVTrans = 0;
       
   520 }
       
   521 
       
   522 /*
       
   523 ** If argument rc2 is not SQLITE_OK, then return it and do nothing. 
       
   524 ** Otherwise, invoke the xSync method of all virtual tables in the 
       
   525 ** sqlite3.aVTrans array. Return the error code for the first error 
       
   526 ** that occurs, or SQLITE_OK if all xSync operations are successful.
       
   527 */
       
   528 int sqlite3VtabSync(sqlite3 *db, int rc2){
       
   529   int i;
       
   530   int rc = SQLITE_OK;
       
   531   int rcsafety;
       
   532   sqlite3_vtab **aVTrans = db->aVTrans;
       
   533   if( rc2!=SQLITE_OK ) return rc2;
       
   534 
       
   535   rc = sqlite3SafetyOff(db);
       
   536   db->aVTrans = 0;
       
   537   for(i=0; rc==SQLITE_OK && i<db->nVTrans && aVTrans[i]; i++){
       
   538     sqlite3_vtab *pVtab = aVTrans[i];
       
   539     int (*x)(sqlite3_vtab *);
       
   540     x = pVtab->pModule->xSync;
       
   541     if( x ){
       
   542       rc = x(pVtab);
       
   543     }
       
   544   }
       
   545   db->aVTrans = aVTrans;
       
   546   rcsafety = sqlite3SafetyOn(db);
       
   547 
       
   548   if( rc==SQLITE_OK ){
       
   549     rc = rcsafety;
       
   550   }
       
   551   return rc;
       
   552 }
       
   553 
       
   554 /*
       
   555 ** Invoke the xRollback method of all virtual tables in the 
       
   556 ** sqlite3.aVTrans array. Then clear the array itself.
       
   557 */
       
   558 int sqlite3VtabRollback(sqlite3 *db){
       
   559   callFinaliser(db, (int)(&((sqlite3_module *)0)->xRollback));
       
   560   return SQLITE_OK;
       
   561 }
       
   562 
       
   563 /*
       
   564 ** Invoke the xCommit method of all virtual tables in the 
       
   565 ** sqlite3.aVTrans array. Then clear the array itself.
       
   566 */
       
   567 int sqlite3VtabCommit(sqlite3 *db){
       
   568   callFinaliser(db, (int)(&((sqlite3_module *)0)->xCommit));
       
   569   return SQLITE_OK;
       
   570 }
       
   571 
       
   572 /*
       
   573 ** If the virtual table pVtab supports the transaction interface
       
   574 ** (xBegin/xRollback/xCommit and optionally xSync) and a transaction is
       
   575 ** not currently open, invoke the xBegin method now.
       
   576 **
       
   577 ** If the xBegin call is successful, place the sqlite3_vtab pointer
       
   578 ** in the sqlite3.aVTrans array.
       
   579 */
       
   580 int sqlite3VtabBegin(sqlite3 *db, sqlite3_vtab *pVtab){
       
   581   int rc = SQLITE_OK;
       
   582   const sqlite3_module *pModule;
       
   583 
       
   584   /* Special case: If db->aVTrans is NULL and db->nVTrans is greater
       
   585   ** than zero, then this function is being called from within a
       
   586   ** virtual module xSync() callback. It is illegal to write to 
       
   587   ** virtual module tables in this case, so return SQLITE_LOCKED.
       
   588   */
       
   589   if( 0==db->aVTrans && db->nVTrans>0 ){
       
   590     return SQLITE_LOCKED;
       
   591   }
       
   592   if( !pVtab ){
       
   593     return SQLITE_OK;
       
   594   } 
       
   595   pModule = pVtab->pModule;
       
   596 
       
   597   if( pModule->xBegin ){
       
   598     int i;
       
   599 
       
   600 
       
   601     /* If pVtab is already in the aVTrans array, return early */
       
   602     for(i=0; (i<db->nVTrans) && 0!=db->aVTrans[i]; i++){
       
   603       if( db->aVTrans[i]==pVtab ){
       
   604         return SQLITE_OK;
       
   605       }
       
   606     }
       
   607 
       
   608     /* Invoke the xBegin method */
       
   609     rc = pModule->xBegin(pVtab);
       
   610     if( rc!=SQLITE_OK ){
       
   611       return rc;
       
   612     }
       
   613 
       
   614     rc = addToVTrans(db, pVtab);
       
   615   }
       
   616   return rc;
       
   617 }
       
   618 
       
   619 /*
       
   620 ** The first parameter (pDef) is a function implementation.  The
       
   621 ** second parameter (pExpr) is the first argument to this function.
       
   622 ** If pExpr is a column in a virtual table, then let the virtual
       
   623 ** table implementation have an opportunity to overload the function.
       
   624 **
       
   625 ** This routine is used to allow virtual table implementations to
       
   626 ** overload MATCH, LIKE, GLOB, and REGEXP operators.
       
   627 **
       
   628 ** Return either the pDef argument (indicating no change) or a 
       
   629 ** new FuncDef structure that is marked as ephemeral using the
       
   630 ** SQLITE_FUNC_EPHEM flag.
       
   631 */
       
   632 FuncDef *sqlite3VtabOverloadFunction(
       
   633   FuncDef *pDef,  /* Function to possibly overload */
       
   634   int nArg,       /* Number of arguments to the function */
       
   635   Expr *pExpr     /* First argument to the function */
       
   636 ){
       
   637   Table *pTab;
       
   638   sqlite3_vtab *pVtab;
       
   639   sqlite3_module *pMod;
       
   640   void (*xFunc)(sqlite3_context*,int,sqlite3_value**);
       
   641   void *pArg;
       
   642   FuncDef *pNew;
       
   643 
       
   644   /* Check to see the left operand is a column in a virtual table */
       
   645   if( pExpr==0 ) return pDef;
       
   646   if( pExpr->op!=TK_COLUMN ) return pDef;
       
   647   pTab = pExpr->pTab;
       
   648   if( pTab==0 ) return pDef;
       
   649   if( !pTab->isVirtual ) return pDef;
       
   650   pVtab = pTab->pVtab;
       
   651   assert( pVtab!=0 );
       
   652   assert( pVtab->pModule!=0 );
       
   653   pMod = (sqlite3_module *)pVtab->pModule;
       
   654   if( pMod->xFindFunction==0 ) return pDef;
       
   655  
       
   656   /* Call the xFuncFunction method on the virtual table implementation
       
   657   ** to see if the implementation wants to overload this function */
       
   658   if( pMod->xFindFunction(pVtab, nArg, pDef->zName, &xFunc, &pArg)==0 ){
       
   659     return pDef;
       
   660   }
       
   661 
       
   662   /* Create a new ephemeral function definition for the overloaded
       
   663   ** function */
       
   664   pNew = sqliteMalloc( sizeof(*pNew) + strlen(pDef->zName) );
       
   665   if( pNew==0 ){
       
   666     return pDef;
       
   667   }
       
   668   *pNew = *pDef;
       
   669   strcpy(pNew->zName, pDef->zName);
       
   670   pNew->xFunc = xFunc;
       
   671   pNew->pUserData = pArg;
       
   672   pNew->flags |= SQLITE_FUNC_EPHEM;
       
   673   return pNew;
       
   674 }
       
   675 
       
   676 #endif /* SQLITE_OMIT_VIRTUALTABLE */