/ Check-in [02b77a58]
Login

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Overview
Comment:Fix a memory leak that occurs when an out-of-memory error occurs while preparing a statement that has multiple virtual table updates within triggers. Other virtual table changes to support full-coverage testing. (CVS 6661)
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1:02b77a582c65e0eb45eb1a9abbdeef11f52d7ce6
User & Date: drh 2009-05-20 20:10:47
Context
2009-05-21
04:42
Add conditional 'extern "C"' block to sqlite3async.h. Ticket #3866. (CVS 6662) check-in: e4d1b117 user: danielk1977 tags: trunk
2009-05-20
20:10
Fix a memory leak that occurs when an out-of-memory error occurs while preparing a statement that has multiple virtual table updates within triggers. Other virtual table changes to support full-coverage testing. (CVS 6661) check-in: 02b77a58 user: drh tags: trunk
16:22
Remove unused, undocumented, and untested error reporting logic from the xFindFunction interface in virtual tables. (CVS 6660) check-in: 55d6ced2 user: drh tags: trunk
Changes
Hide Diffs Side-by-Side Diffs Ignore Whitespace Patch

Changes to src/vtab.c.

     7      7   **    May you do good and not evil.
     8      8   **    May you find forgiveness for yourself and forgive others.
     9      9   **    May you share freely, never taking more than you give.
    10     10   **
    11     11   *************************************************************************
    12     12   ** This file contains code used to help implement virtual tables.
    13     13   **
    14         -** $Id: vtab.c,v 1.88 2009/05/20 16:22:02 drh Exp $
           14  +** $Id: vtab.c,v 1.89 2009/05/20 20:10:47 drh Exp $
    15     15   */
    16     16   #ifndef SQLITE_OMIT_VIRTUALTABLE
    17     17   #include "sqliteInt.h"
    18     18   
    19     19   /*
    20     20   ** The actual function that does the work of creating a new module.
    21     21   ** This function implements the sqlite3_create_module() and
................................................................................
   103    103   */
   104    104   void sqlite3VtabUnlock(sqlite3 *db, sqlite3_vtab *pVtab){
   105    105     assert( pVtab->nRef>0 );
   106    106     pVtab->nRef--;
   107    107     assert(db);
   108    108     assert( sqlite3SafetyCheckOk(db) );
   109    109     if( pVtab->nRef==0 ){
          110  +#ifdef SQLITE_DEBUG
   110    111       if( db->magic==SQLITE_MAGIC_BUSY ){
   111    112         (void)sqlite3SafetyOff(db);
   112    113         pVtab->pModule->xDisconnect(pVtab);
   113    114         (void)sqlite3SafetyOn(db);
   114         -    } else {
          115  +    } else 
          116  +#endif
          117  +    {
   115    118         pVtab->pModule->xDisconnect(pVtab);
   116    119       }
   117    120     }
   118    121   }
   119    122   
   120    123   /*
   121    124   ** Clear any and all virtual-table information from the Table record.
................................................................................
   184    187     if( pParse->db->flags & SQLITE_SharedCache ){
   185    188       sqlite3ErrorMsg(pParse, "Cannot use virtual tables in shared-cache mode");
   186    189       return;
   187    190     }
   188    191   
   189    192     sqlite3StartTable(pParse, pName1, pName2, 0, 0, 1, 0);
   190    193     pTable = pParse->pNewTable;
   191         -  if( pTable==0 || pParse->nErr ) return;
          194  +  if( pTable==0 ) return;
   192    195     assert( 0==pTable->pIndex );
   193    196   
   194    197     db = pParse->db;
   195    198     iDb = sqlite3SchemaToIndex(db, pTable->pSchema);
   196    199     assert( iDb>=0 );
   197    200   
   198    201     pTable->tabFlags |= TF_Virtual;
................................................................................
   217    220   
   218    221   /*
   219    222   ** This routine takes the module argument that has been accumulating
   220    223   ** in pParse->zArg[] and appends it to the list of arguments on the
   221    224   ** virtual table currently under construction in pParse->pTable.
   222    225   */
   223    226   static void addArgumentToVtab(Parse *pParse){
   224         -  if( pParse->sArg.z && pParse->pNewTable ){
          227  +  if( pParse->sArg.z && ALWAYS(pParse->pNewTable) ){
   225    228       const char *z = (const char*)pParse->sArg.z;
   226    229       int n = pParse->sArg.n;
   227    230       sqlite3 *db = pParse->db;
   228    231       addModuleArgument(db, pParse->pNewTable, sqlite3DbStrNDup(db, z, n));
   229    232     }
   230    233   }
   231    234   
................................................................................
   374    377   
   375    378     db->pVTab = pTab;
   376    379     rc = sqlite3SafetyOff(db);
   377    380     assert( rc==SQLITE_OK );
   378    381     rc = xConstruct(db, pMod->pAux, nArg, azArg, &pVtab, &zErr);
   379    382     rc2 = sqlite3SafetyOn(db);
   380    383     if( rc==SQLITE_NOMEM ) db->mallocFailed = 1;
   381         -  if( rc==SQLITE_OK && pVtab ){
          384  +  /* Justification of ALWAYS():  A correct vtab constructor must allocate
          385  +  ** the sqlite3_vtab object if successful. */
          386  +  if( rc==SQLITE_OK && ALWAYS(pVtab) ){
   382    387       pVtab->pModule = pMod->pModule;
   383    388       pVtab->nRef = 1;
   384    389       pTab->pVtab = pVtab;
   385    390     }
   386    391   
   387    392     if( SQLITE_OK!=rc ){
   388    393       if( zErr==0 ){
................................................................................
   449    454   **
   450    455   ** This call is a no-op if table pTab is not a virtual table.
   451    456   */
   452    457   int sqlite3VtabCallConnect(Parse *pParse, Table *pTab){
   453    458     Module *pMod;
   454    459     int rc = SQLITE_OK;
   455    460   
   456         -  if( !pTab || (pTab->tabFlags & TF_Virtual)==0 || pTab->pVtab ){
          461  +  assert( pTab );
          462  +  if( (pTab->tabFlags & TF_Virtual)==0 || pTab->pVtab ){
   457    463       return SQLITE_OK;
   458    464     }
   459    465   
   460    466     pMod = pTab->pMod;
   461    467     if( !pMod ){
   462    468       const char *zModule = pTab->azModuleArg[0];
   463    469       sqlite3ErrorMsg(pParse, "no such module: %s", zModule);
................................................................................
   525    531     if( !pMod ){
   526    532       *pzErr = sqlite3MPrintf(db, "no such module: %s", zModule);
   527    533       rc = SQLITE_ERROR;
   528    534     }else{
   529    535       rc = vtabCallConstructor(db, pTab, pMod, pMod->pModule->xCreate, pzErr);
   530    536     }
   531    537   
   532         -  if( rc==SQLITE_OK && pTab->pVtab ){
          538  +  /* Justification of ALWAYS():  The xConstructor method is required to
          539  +  ** create a valid sqlite3_vtab if it returns SQLITE_OK. */
          540  +  if( rc==SQLITE_OK && ALWAYS(pTab->pVtab) ){
   533    541         rc = addToVTrans(db, pTab->pVtab);
   534    542     }
   535    543   
   536    544     return rc;
   537    545   }
   538    546   
   539    547   /*
................................................................................
   594    602   /*
   595    603   ** This function is invoked by the vdbe to call the xDestroy method
   596    604   ** of the virtual table named zTab in database iDb. This occurs
   597    605   ** when a DROP TABLE is mentioned.
   598    606   **
   599    607   ** This call is a no-op if zTab is not a virtual table.
   600    608   */
   601         -int sqlite3VtabCallDestroy(sqlite3 *db, int iDb, const char *zTab)
   602         -{
          609  +int sqlite3VtabCallDestroy(sqlite3 *db, int iDb, const char *zTab){
   603    610     int rc = SQLITE_OK;
   604    611     Table *pTab;
   605    612   
   606    613     pTab = sqlite3FindTable(db, zTab, db->aDb[iDb].zName);
   607         -  assert(pTab);
   608         -  if( pTab->pVtab ){
          614  +  if( ALWAYS(pTab!=0 && pTab->pVtab!=0) ){
   609    615       int (*xDestroy)(sqlite3_vtab *pVTab) = pTab->pMod->pModule->xDestroy;
   610    616       rc = sqlite3SafetyOff(db);
   611    617       assert( rc==SQLITE_OK );
   612         -    if( xDestroy ){
   613         -      rc = xDestroy(pTab->pVtab);
   614         -    }
          618  +    rc = xDestroy(pTab->pVtab);
   615    619       (void)sqlite3SafetyOn(db);
   616    620       if( rc==SQLITE_OK ){
   617    621         int i;
   618    622         for(i=0; i<db->nVTrans; i++){
   619    623           if( db->aVTrans[i]==pTab->pVtab ){
   620    624             db->aVTrans[i] = db->aVTrans[--db->nVTrans];
   621    625             break;
................................................................................
   635    639   ** the offset of the method to call in the sqlite3_module structure.
   636    640   **
   637    641   ** The array is cleared after invoking the callbacks. 
   638    642   */
   639    643   static void callFinaliser(sqlite3 *db, int offset){
   640    644     int i;
   641    645     if( db->aVTrans ){
   642         -    for(i=0; i<db->nVTrans && db->aVTrans[i]; i++){
          646  +    for(i=0; i<db->nVTrans; i++){
   643    647         sqlite3_vtab *pVtab = db->aVTrans[i];
   644    648         int (*x)(sqlite3_vtab *);
          649  +
          650  +      assert( pVtab!=0 );
   645    651         x = *(int (**)(sqlite3_vtab *))((char *)pVtab->pModule + offset);
   646    652         if( x ) x(pVtab);
   647    653         sqlite3VtabUnlock(db, pVtab);
   648    654       }
   649    655       sqlite3DbFree(db, db->aVTrans);
   650    656       db->nVTrans = 0;
   651    657       db->aVTrans = 0;
................................................................................
   664    670     int i;
   665    671     int rc = SQLITE_OK;
   666    672     int rcsafety;
   667    673     sqlite3_vtab **aVTrans = db->aVTrans;
   668    674   
   669    675     rc = sqlite3SafetyOff(db);
   670    676     db->aVTrans = 0;
   671         -  for(i=0; rc==SQLITE_OK && i<db->nVTrans && aVTrans[i]; i++){
          677  +  for(i=0; rc==SQLITE_OK && i<db->nVTrans; i++){
   672    678       sqlite3_vtab *pVtab = aVTrans[i];
   673    679       int (*x)(sqlite3_vtab *);
          680  +    assert( pVtab!=0 );
   674    681       x = pVtab->pModule->xSync;
   675    682       if( x ){
   676    683         rc = x(pVtab);
   677    684         sqlite3DbFree(db, *pzErrmsg);
   678    685         *pzErrmsg = pVtab->zErrMsg;
   679    686         pVtab->zErrMsg = 0;
   680    687       }
................................................................................
   717    724   int sqlite3VtabBegin(sqlite3 *db, sqlite3_vtab *pVtab){
   718    725     int rc = SQLITE_OK;
   719    726     const sqlite3_module *pModule;
   720    727   
   721    728     /* Special case: If db->aVTrans is NULL and db->nVTrans is greater
   722    729     ** than zero, then this function is being called from within a
   723    730     ** virtual module xSync() callback. It is illegal to write to 
   724         -  ** virtual module tables in this case, so return SQLITE_MISUSE.
          731  +  ** virtual module tables in this case, so return SQLITE_LOCKED.
   725    732     */
   726    733     if( sqlite3VtabInSync(db) ){
   727    734       return SQLITE_LOCKED;
   728    735     }
   729    736     if( !pVtab ){
   730    737       return SQLITE_OK;
   731    738     } 
................................................................................
   732    739     pModule = pVtab->pModule;
   733    740   
   734    741     if( pModule->xBegin ){
   735    742       int i;
   736    743   
   737    744   
   738    745       /* If pVtab is already in the aVTrans array, return early */
   739         -    for(i=0; (i<db->nVTrans) && 0!=db->aVTrans[i]; i++){
          746  +    for(i=0; i<db->nVTrans; i++){
   740    747         if( db->aVTrans[i]==pVtab ){
   741    748           return SQLITE_OK;
   742    749         }
   743    750       }
   744    751   
   745    752       /* Invoke the xBegin method */
   746    753       rc = pModule->xBegin(pVtab);
................................................................................
   778    785     FuncDef *pNew;
   779    786     int rc = 0;
   780    787     char *zLowerName;
   781    788     unsigned char *z;
   782    789   
   783    790   
   784    791     /* Check to see the left operand is a column in a virtual table */
   785         -  if( pExpr==0 ) return pDef;
          792  +  if( NEVER(pExpr==0) ) return pDef;
   786    793     if( pExpr->op!=TK_COLUMN ) return pDef;
   787    794     pTab = pExpr->pTab;
   788         -  if( pTab==0 ) return pDef;
          795  +  if( NEVER(pTab==0) ) return pDef;
   789    796     if( (pTab->tabFlags & TF_Virtual)==0 ) return pDef;
   790    797     pVtab = pTab->pVtab;
   791    798     assert( pVtab!=0 );
   792    799     assert( pVtab->pModule!=0 );
   793    800     pMod = (sqlite3_module *)pVtab->pModule;
   794    801     if( pMod->xFindFunction==0 ) return pDef;
   795    802    
................................................................................
   828    835   ** Make sure virtual table pTab is contained in the pParse->apVirtualLock[]
   829    836   ** array so that an OP_VBegin will get generated for it.  Add pTab to the
   830    837   ** array if it is missing.  If pTab is already in the array, this routine
   831    838   ** is a no-op.
   832    839   */
   833    840   void sqlite3VtabMakeWritable(Parse *pParse, Table *pTab){
   834    841     int i, n;
          842  +  Table **apVtabLock;
          843  +
   835    844     assert( IsVirtual(pTab) );
   836    845     for(i=0; i<pParse->nVtabLock; i++){
   837    846       if( pTab==pParse->apVtabLock[i] ) return;
   838    847     }
   839    848     n = (pParse->nVtabLock+1)*sizeof(pParse->apVtabLock[0]);
   840         -  pParse->apVtabLock = sqlite3_realloc(pParse->apVtabLock, n);
   841         -  if( pParse->apVtabLock ){
          849  +  apVtabLock = sqlite3_realloc(pParse->apVtabLock, n);
          850  +  if( apVtabLock ){
          851  +    pParse->apVtabLock = apVtabLock;
   842    852       pParse->apVtabLock[pParse->nVtabLock++] = pTab;
   843    853     }else{
   844    854       pParse->db->mallocFailed = 1;
   845    855     }
   846    856   }
   847    857   
   848    858   #endif /* SQLITE_OMIT_VIRTUALTABLE */