Add a new zErrMsg field to the sqlite3_vtab structure to support returning

error messages from virtual table constructors.  This change means that
virtual table implementations compiled as loadable extensions for version
3.3.7 will need to be recompile for version 3.3.8 and will not be usable
by both versions at one.  The virtual table mechanism is still considered
experimental so we feel justified in breaking backwards compatibility
in this way.  Additional interface changes might occurs in the future. (CVS 3401)

FossilOrigin-Name: 36693a5cb72b4363010f9ab0866e1f7865f65275
This commit is contained in:
drh 2006-09-10 17:08:29 +00:00
parent a2a9d18869
commit fe1368ee08
4 changed files with 37 additions and 16 deletions

View File

@ -1,5 +1,5 @@
C Add\ssome\ssimple\stest\scases\sfor\sthe\sOR\sand\sNOT\slogic\sof\sthe\sfts1\smodule.\nFix\slots\sof\sbugs\sdiscovered\swhile\sdeveloping\sthese\stest\scases.\s(CVS\s3400)
D 2006-09-10T03:34:06
C Add\sa\snew\szErrMsg\sfield\sto\sthe\ssqlite3_vtab\sstructure\sto\ssupport\sreturning\nerror\smessages\sfrom\svirtual\stable\sconstructors.\s\sThis\schange\smeans\sthat\nvirtual\stable\simplementations\scompiled\sas\sloadable\sextensions\sfor\sversion\n3.3.7\swill\sneed\sto\sbe\srecompile\sfor\sversion\s3.3.8\sand\swill\snot\sbe\susable\nby\sboth\sversions\sat\sone.\s\sThe\svirtual\stable\smechanism\sis\sstill\sconsidered\nexperimental\sso\swe\sfeel\sjustified\sin\sbreaking\sbackwards\scompatibility\nin\sthis\sway.\s\sAdditional\sinterface\schanges\smight\soccurs\sin\sthe\sfuture.\s(CVS\s3401)
D 2006-09-10T17:08:30
F Makefile.in cabd42d34340f49260bc2a7668c38eba8d4cfd99
F Makefile.linux-gcc 2d8574d1ba75f129aba2019f0b959db380a90935
F README 9c4e2d6706bdcc3efdd773ce752a8cdab4f90028
@ -86,7 +86,7 @@ F src/random.c d40f8d356cecbd351ccfab6eaedd7ec1b54f5261
F src/select.c 0d4724930a1f34c747105ed1802fa4af0d8eb519
F src/server.c 087b92a39d883e3fa113cae259d64e4c7438bc96
F src/shell.c 233f7766e532a204bed465249ffc584424ed1757
F src/sqlite.h.in 84ac26ca94a84dd603fb57a27d862f51bfd9f687
F src/sqlite.h.in 364f2aac46a3f2435ff30ccae1f34b53d667b0af
F src/sqlite3ext.h 11a046b3519c4b9b7709e6d6a95c3a36366f684a
F src/sqliteInt.h 259adce944cc3b28da1fa3df9beb9ba86017a45d
F src/table.c d8817f43a6c6bf139487db161760b9e1e02da3f1
@ -119,7 +119,7 @@ F src/vdbeapi.c 81f531d7dc5c898131b02ef85f6c6144ab2892cf
F src/vdbeaux.c 9fab61427a0741c9c123e8ff16e349b1f90397be
F src/vdbefifo.c 9efb94c8c3f4c979ebd0028219483f88e57584f5
F src/vdbemem.c 26623176bf1c616aa478da958fac49502491a921
F src/vtab.c 7fc0624c2bb6156c3d99e2ce706f2a5b54094e36
F src/vtab.c c68946eda1e9259582836d3fec39272fd3647b4d
F src/where.c 75a89957fcb8c068bec55caa4e9d2ed5fa0b0724
F tclinstaller.tcl 046e3624671962dc50f0481d7c25b38ef803eb42
F test/aggerror.test a867e273ef9e3d7919f03ef4f0e8c0d2767944f2
@ -397,7 +397,7 @@ F www/tclsqlite.tcl bb0d1357328a42b1993d78573e587c6dcbc964b9
F www/vdbe.tcl 87a31ace769f20d3627a64fa1fade7fed47b90d0
F www/version3.tcl 890248cf7b70e60c383b0e84d77d5132b3ead42b
F www/whentouse.tcl 97e2b5cd296f7d8057e11f44427dea8a4c2db513
P ae50265791d1a7500aa3c405a78a9bca8ff0cc08
R 102c1a21ff09d0f20e46f405978da02e
P 70bcff024b44d1b40afac6eba959fa89fb993147
R 49ee6571b74bcd7a8b8e06a293fd1796
U drh
Z f515ac19d2cdc367f4c6838848ae4bb1
Z e7e707b3d9d576052a0534936bdcea9b

View File

@ -1 +1 @@
70bcff024b44d1b40afac6eba959fa89fb993147
36693a5cb72b4363010f9ab0866e1f7865f65275

View File

@ -12,7 +12,7 @@
** This header file defines the interface that the SQLite library
** presents to client programs.
**
** @(#) $Id: sqlite.h.in,v 1.189 2006/08/24 14:59:46 drh Exp $
** @(#) $Id: sqlite.h.in,v 1.190 2006/09/10 17:08:30 drh Exp $
*/
#ifndef _SQLITE3_H_
#define _SQLITE3_H_
@ -1705,10 +1705,21 @@ int sqlite3_create_module(
** be taylored to the specific needs of the module implementation. The
** purpose of this superclass is to define certain fields that are common
** to all module implementations.
**
** Virtual tables methods can set an error message by assigning a
** string obtained from sqlite3_mprintf() to zErrMsg. The method should
** take care that any prior string is freed by a call to sqlite3_free()
** prior to assigning a new string to zErrMsg. After the error message
** is delivered up to the client application, the string will be automatically
** freed by sqlite3_free() and the zErrMsg field will be zeroed. Note
** that sqlite3_mprintf() and sqlite3_free() are used on the zErrMsg field
** since virtual tables are commonly implemented in loadable extensions which
** do not have access to sqlite3MPrintf() or sqlite3Free().
*/
struct sqlite3_vtab {
const sqlite3_module *pModule; /* The module for this virtual table */
int nRef; /* Used internally */
char *zErrMsg; /* Error message text */
/* Virtual table implementations will typically add additional fields */
};

View File

@ -11,7 +11,7 @@
*************************************************************************
** This file contains code used to help implement virtual tables.
**
** $Id: vtab.c,v 1.31 2006/09/02 20:57:52 drh Exp $
** $Id: vtab.c,v 1.32 2006/09/10 17:08:30 drh Exp $
*/
#ifndef SQLITE_OMIT_VIRTUALTABLE
#include "sqliteInt.h"
@ -59,6 +59,8 @@ void sqlite3VtabLock(sqlite3_vtab *pVtab){
void sqlite3VtabUnlock(sqlite3_vtab *pVtab){
pVtab->nRef--;
if( pVtab->nRef==0 ){
sqlite3_free(pVtab->zErrMsg);
pVtab->zErrMsg = 0;
pVtab->pModule->xDisconnect(pVtab);
}
}
@ -291,6 +293,7 @@ static int vtabCallConstructor(
){
int rc;
int rc2;
sqlite3_vtab *pVtab;
char **azArg = pTab->azModuleArg;
int nArg = pTab->nModuleArg;
char *zErr = sqlite3MPrintf("vtable constructor failed: %s", pTab->zName);
@ -303,15 +306,22 @@ static int vtabCallConstructor(
assert( rc==SQLITE_OK );
rc = xConstruct(db, pMod->pAux, nArg, azArg, &pTab->pVtab);
rc2 = sqlite3SafetyOn(db);
if( rc==SQLITE_OK && pTab->pVtab ){
pTab->pVtab->pModule = pMod->pModule;
pTab->pVtab->nRef = 1;
pVtab = pTab->pVtab;
if( rc==SQLITE_OK && pVtab ){
pVtab->pModule = pMod->pModule;
pVtab->nRef = 1;
}
if( SQLITE_OK!=rc ){
*pzErr = zErr;
zErr = 0;
} else if( db->pVTab ){
if( pVtab && pVtab->zErrMsg ){
*pzErr = sqlite3MPrintf("%s", pVtab->zErrMsg);
sqlite3_free(pVtab->zErrMsg);
pVtab->zErrMsg = 0;
}else{
*pzErr = zErr;
zErr = 0;
}
}else if( db->pVTab ){
const char *zFormat = "vtable constructor did not declare schema: %s";
*pzErr = sqlite3MPrintf(zFormat, pTab->zName);
rc = SQLITE_ERROR;