/ Check-in [e2c6771d]
Login

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

Overview
Comment:Read the sqlite3_vtab.zErrMsg after each call to a virtual table method and transfer any error into the database connection. Fix the fts2.test and fts3.test scripts to that they return silently rather than failing the test sequence if the appropriate FTS implementation is unavailable. (CVS 5463)
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1: e2c6771d44f1b4fee16ef90e91c3498be2a7d2b1
User & Date: drh 2008-07-23 18:17:32
Context
2008-07-23
18:25
Clarify in the documentation that the database connection pointer to sqlite3_next_stmt() must not be NULL. Ticket #3244. (CVS 5464) check-in: a7d64e86 user: drh tags: trunk
18:17
Read the sqlite3_vtab.zErrMsg after each call to a virtual table method and transfer any error into the database connection. Fix the fts2.test and fts3.test scripts to that they return silently rather than failing the test sequence if the appropriate FTS implementation is unavailable. (CVS 5463) check-in: e2c6771d user: drh tags: trunk
15:40
Update requirements derivation information in sqlite.h.in. (CVS 5462) check-in: d6202907 user: drh tags: trunk
Changes
Hide Diffs Side-by-Side Diffs Ignore Whitespace Patch

Changes to src/sqliteInt.h.

     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   ** Internal interface definitions for SQLite.
    13     13   **
    14         -** @(#) $Id: sqliteInt.h,v 1.742 2008/07/12 14:52:20 drh Exp $
           14  +** @(#) $Id: sqliteInt.h,v 1.743 2008/07/23 18:17:32 drh Exp $
    15     15   */
    16     16   #ifndef _SQLITEINT_H_
    17     17   #define _SQLITEINT_H_
    18     18   
    19     19   /*
    20     20   ** Include the configuration header output by 'configure' if we're using the
    21     21   ** autoconf-based build
................................................................................
  2211   2211   #endif
  2212   2212   
  2213   2213   #ifdef SQLITE_OMIT_VIRTUALTABLE
  2214   2214   #  define sqlite3VtabClear(X)
  2215   2215   #  define sqlite3VtabSync(X,Y) (Y)
  2216   2216   #  define sqlite3VtabRollback(X)
  2217   2217   #  define sqlite3VtabCommit(X)
         2218  +#  define sqlite3VtabTransferError(A,B,C)
  2218   2219   #else
  2219   2220      void sqlite3VtabClear(Table*);
  2220   2221      int sqlite3VtabSync(sqlite3 *db, int rc);
  2221   2222      int sqlite3VtabRollback(sqlite3 *db);
  2222   2223      int sqlite3VtabCommit(sqlite3 *db);
         2224  +   void sqlite3VtabTransferError(sqlite3 *db, int, sqlite3_vtab*);
  2223   2225   #endif
  2224   2226   void sqlite3VtabMakeWritable(Parse*,Table*);
  2225   2227   void sqlite3VtabLock(sqlite3_vtab*);
  2226   2228   void sqlite3VtabUnlock(sqlite3*, sqlite3_vtab*);
  2227   2229   void sqlite3VtabBeginParse(Parse*, Token*, Token*, Token*);
  2228   2230   void sqlite3VtabFinishParse(Parse*, Token*);
  2229   2231   void sqlite3VtabArgInit(Parse*);

Changes to src/test8.c.

     9      9   **    May you share freely, never taking more than you give.
    10     10   **
    11     11   *************************************************************************
    12     12   ** Code for testing the virtual table interfaces.  This code
    13     13   ** is not included in the SQLite library.  It is used for automated
    14     14   ** testing of the SQLite library.
    15     15   **
    16         -** $Id: test8.c,v 1.67 2008/07/07 14:50:14 drh Exp $
           16  +** $Id: test8.c,v 1.68 2008/07/23 18:17:32 drh Exp $
    17     17   */
    18     18   #include "sqliteInt.h"
    19     19   #include "tcl.h"
    20     20   #include <stdlib.h>
    21     21   #include <string.h>
    22     22   
    23     23   #ifndef SQLITE_OMIT_VIRTUALTABLE
................................................................................
   983    983         sqlite3_finalize(pStmt);
   984    984       }
   985    985     }
   986    986   
   987    987     if( pRowid && rc==SQLITE_OK ){
   988    988       *pRowid = sqlite3_last_insert_rowid(db);
   989    989     }
          990  +  if( rc!=SQLITE_OK ){
          991  +    tab->zErrMsg = sqlite3_mprintf("echo-vtab-error: %s", sqlite3_errmsg(db));
          992  +  }
   990    993   
   991    994     return rc;
   992    995   }
   993    996   
   994    997   /*
   995    998   ** xBegin, xSync, xCommit and xRollback callbacks for echo module
   996    999   ** virtual tables. Do nothing other than add the name of the callback

Changes to src/vdbe.c.

    39     39   **
    40     40   ** Various scripts scan this source file in order to generate HTML
    41     41   ** documentation, headers files, or other derived files.  The formatting
    42     42   ** of the code in this file is, therefore, important.  See other comments
    43     43   ** in this file for details.  If in doubt, do not deviate from existing
    44     44   ** commenting and indentation practices when changing or adding code.
    45     45   **
    46         -** $Id: vdbe.c,v 1.761 2008/07/11 21:02:54 drh Exp $
           46  +** $Id: vdbe.c,v 1.762 2008/07/23 18:17:32 drh Exp $
    47     47   */
    48     48   #include "sqliteInt.h"
    49     49   #include <ctype.h>
    50     50   #include "vdbeInt.h"
    51     51   
    52     52   /*
    53     53   ** The following global variable is incremented every time a cursor
................................................................................
  4617   4617   
  4618   4618     sqlite3_vtab *pVtab = pOp->p4.pVtab;
  4619   4619     sqlite3_module *pModule = (sqlite3_module *)pVtab->pModule;
  4620   4620   
  4621   4621     assert(pVtab && pModule);
  4622   4622     if( sqlite3SafetyOff(db) ) goto abort_due_to_misuse;
  4623   4623     rc = pModule->xOpen(pVtab, &pVtabCursor);
         4624  +  sqlite3VtabTransferError(db, rc, pVtab);
  4624   4625     if( sqlite3SafetyOn(db) ) goto abort_due_to_misuse;
  4625   4626     if( SQLITE_OK==rc ){
  4626   4627       /* Initialize sqlite3_vtab_cursor base class */
  4627   4628       pVtabCursor->pVtab = pVtab;
  4628   4629   
  4629   4630       /* Initialise vdbe cursor object */
  4630   4631       pCur = allocateCursor(p, pOp->p1, &pOp[-1], -1, 0);
................................................................................
  4661   4662   */
  4662   4663   case OP_VFilter: {   /* jump */
  4663   4664     int nArg;
  4664   4665     int iQuery;
  4665   4666     const sqlite3_module *pModule;
  4666   4667     Mem *pQuery = &p->aMem[pOp->p3];
  4667   4668     Mem *pArgc = &pQuery[1];
         4669  +  sqlite3_vtab_cursor *pVtabCursor;
         4670  +  sqlite3_vtab *pVtab;
  4668   4671   
  4669   4672     Cursor *pCur = p->apCsr[pOp->p1];
  4670   4673   
  4671   4674     REGISTER_TRACE(pOp->p3, pQuery);
  4672   4675     assert( pCur->pVtabCursor );
  4673         -  pModule = pCur->pVtabCursor->pVtab->pModule;
         4676  +  pVtabCursor = pCur->pVtabCursor;
         4677  +  pVtab = pVtabCursor->pVtab;
         4678  +  pModule = pVtab->pModule;
  4674   4679   
  4675   4680     /* Grab the index number and argc parameters */
  4676   4681     assert( (pQuery->flags&MEM_Int)!=0 && pArgc->flags==MEM_Int );
  4677   4682     nArg = pArgc->u.i;
  4678   4683     iQuery = pQuery->u.i;
  4679   4684   
  4680   4685     /* Invoke the xFilter method */
................................................................................
  4685   4690       for(i = 0; i<nArg; i++){
  4686   4691         apArg[i] = &pArgc[i+1];
  4687   4692         storeTypeInfo(apArg[i], 0);
  4688   4693       }
  4689   4694   
  4690   4695       if( sqlite3SafetyOff(db) ) goto abort_due_to_misuse;
  4691   4696       p->inVtabMethod = 1;
  4692         -    rc = pModule->xFilter(pCur->pVtabCursor, iQuery, pOp->p4.z, nArg, apArg);
         4697  +    rc = pModule->xFilter(pVtabCursor, iQuery, pOp->p4.z, nArg, apArg);
  4693   4698       p->inVtabMethod = 0;
  4694   4699       if( rc==SQLITE_OK ){
  4695         -      res = pModule->xEof(pCur->pVtabCursor);
         4700  +      res = pModule->xEof(pVtabCursor);
  4696   4701       }
  4697   4702       if( sqlite3SafetyOn(db) ) goto abort_due_to_misuse;
  4698   4703   
  4699   4704       if( res ){
  4700   4705         pc = pOp->p2 - 1;
  4701   4706       }
  4702   4707     }
................................................................................
  4843   4848   
  4844   4849     Stringify(pName, encoding);
  4845   4850   
  4846   4851     if( sqlite3SafetyOff(db) ) goto abort_due_to_misuse;
  4847   4852     sqlite3VtabLock(pVtab);
  4848   4853     rc = pVtab->pModule->xRename(pVtab, pName->z);
  4849   4854     sqlite3VtabUnlock(db, pVtab);
         4855  +  sqlite3VtabTransferError(db, rc, pVtab);
  4850   4856     if( sqlite3SafetyOn(db) ) goto abort_due_to_misuse;
  4851   4857   
  4852   4858     break;
  4853   4859   }
  4854   4860   #endif
  4855   4861   
  4856   4862   #ifndef SQLITE_OMIT_VIRTUALTABLE
................................................................................
  4895   4901         apArg[i] = pX;
  4896   4902         pX++;
  4897   4903       }
  4898   4904       if( sqlite3SafetyOff(db) ) goto abort_due_to_misuse;
  4899   4905       sqlite3VtabLock(pVtab);
  4900   4906       rc = pModule->xUpdate(pVtab, nArg, apArg, &rowid);
  4901   4907       sqlite3VtabUnlock(db, pVtab);
         4908  +    sqlite3VtabTransferError(db, rc, pVtab);
  4902   4909       if( sqlite3SafetyOn(db) ) goto abort_due_to_misuse;
  4903   4910       if( pOp->p1 && rc==SQLITE_OK ){
  4904   4911         assert( nArg>1 && apArg[0] && (apArg[0]->flags&MEM_Null) );
  4905   4912         db->lastRowid = rowid;
  4906   4913       }
  4907   4914       p->nChange++;
  4908   4915     }

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.70 2008/06/23 17:44:19 danielk1977 Exp $
           14  +** $Id: vtab.c,v 1.71 2008/07/23 18:17:32 drh Exp $
    15     15   */
    16     16   #ifndef SQLITE_OMIT_VIRTUALTABLE
    17     17   #include "sqliteInt.h"
    18     18   
    19     19   static int createModule(
    20     20     sqlite3 *db,                    /* Database in which module is registered */
    21     21     const char *zName,              /* Name assigned to this module */
................................................................................
   722    722         if( db->aVTrans[i]==pVtab ){
   723    723           return SQLITE_OK;
   724    724         }
   725    725       }
   726    726   
   727    727       /* Invoke the xBegin method */
   728    728       rc = pModule->xBegin(pVtab);
          729  +    sqlite3VtabTransferError(db, rc, pVtab);
   729    730       if( rc!=SQLITE_OK ){
   730    731         return rc;
   731    732       }
   732    733   
   733    734       rc = addToVTrans(db, pVtab);
   734    735     }
   735    736     return rc;
................................................................................
   783    784     zLowerName = sqlite3DbStrDup(db, pDef->zName);
   784    785     if( zLowerName ){
   785    786       for(z=(unsigned char*)zLowerName; *z; z++){
   786    787         *z = sqlite3UpperToLower[*z];
   787    788       }
   788    789       rc = pMod->xFindFunction(pVtab, nArg, zLowerName, &xFunc, &pArg);
   789    790       sqlite3_free(zLowerName);
          791  +    sqlite3VtabTransferError(db, rc, pVtab);
   790    792     }
   791    793     if( rc==0 ){
   792    794       return pDef;
   793    795     }
   794    796   
   795    797     /* Create a new ephemeral function definition for the overloaded
   796    798     ** function */
................................................................................
   822    824     pParse->apVtabLock = sqlite3_realloc(pParse->apVtabLock, n);
   823    825     if( pParse->apVtabLock ){
   824    826       pParse->apVtabLock[pParse->nVtabLock++] = pTab;
   825    827     }else{
   826    828       pParse->db->mallocFailed = 1;
   827    829     }
   828    830   }
          831  +
          832  +/*
          833  +** Transfer a virtual table error into the database connection.
          834  +*/
          835  +void sqlite3VtabTransferError(sqlite3 *db, int rc, sqlite3_vtab *pVtab){
          836  +  if( pVtab->zErrMsg ){
          837  +    sqlite3Error(db, rc, "%s", pVtab->zErrMsg);
          838  +    sqlite3_free(pVtab->zErrMsg);
          839  +    pVtab->zErrMsg = 0;
          840  +  }
          841  +}
   829    842   
   830    843   #endif /* SQLITE_OMIT_VIRTUALTABLE */

Changes to test/fts2.test.

            1  +# 2008 July 22
     1      2   #
     2      3   #    May you do good and not evil.
     3      4   #    May you find forgiveness for yourself and forgive others.
     4      5   #    May you share freely, never taking more than you give.
     5      6   #
     6      7   #***********************************************************************
     7      8   # This file runs all tests.
     8      9   #
     9         -# $Id: fts2.test,v 1.1 2008/07/22 22:57:54 shess Exp $
           10  +# $Id: fts2.test,v 1.2 2008/07/23 18:17:32 drh Exp $
    10     11   
    11     12   proc lshift {lvar} {
    12     13     upvar $lvar l
    13     14     set ret [lindex $l 0]
    14     15     set l [lrange $l 1 end]
    15     16     return $ret
    16     17   }
................................................................................
    29     30     }
    30     31   }
    31     32   
    32     33   set testdir [file dirname $argv0]
    33     34   source $testdir/tester.tcl
    34     35   # If SQLITE_ENABLE_FTS2 is defined, omit this file.
    35     36   ifcapable !fts2 {
    36         -  puts stderr "this build does not include FTS2 capability"
    37         -  exit 1
           37  +  return
    38     38   }
    39     39   rename finish_test really_finish_test
    40     40   proc finish_test {} {}
    41     41   set ISQUICK 1
    42     42   
    43     43   set EXCLUDE {
    44     44     fts2.test

Changes to test/fts3.test.

            1  +# 2007 November 23
     1      2   #
     2      3   #    May you do good and not evil.
     3      4   #    May you find forgiveness for yourself and forgive others.
     4      5   #    May you share freely, never taking more than you give.
     5      6   #
     6      7   #***********************************************************************
     7      8   # This file runs all tests.
     8      9   #
     9         -# $Id: fts3.test,v 1.1 2007/11/23 17:31:19 drh Exp $
           10  +# $Id: fts3.test,v 1.2 2008/07/23 18:17:32 drh Exp $
    10     11   
    11     12   proc lshift {lvar} {
    12     13     upvar $lvar l
    13     14     set ret [lindex $l 0]
    14     15     set l [lrange $l 1 end]
    15     16     return $ret
    16     17   }
................................................................................
    29     30     }
    30     31   }
    31     32   
    32     33   set testdir [file dirname $argv0]
    33     34   source $testdir/tester.tcl
    34     35   # If SQLITE_ENABLE_FTS3 is defined, omit this file.
    35     36   ifcapable !fts3 {
    36         -  puts stderr "this build does not include FTS3 capability"
    37         -  exit 1
           37  +  return
    38     38   }
    39     39   rename finish_test really_finish_test
    40     40   proc finish_test {} {}
    41     41   set ISQUICK 1
    42     42   
    43     43   set EXCLUDE {
    44     44     fts3.test