diff --git a/manifest b/manifest index b8a242e0e5..c241e31be5 100644 --- a/manifest +++ b/manifest @@ -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 diff --git a/manifest.uuid b/manifest.uuid index d8f8de95b4..948d54bf70 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -70bcff024b44d1b40afac6eba959fa89fb993147 \ No newline at end of file +36693a5cb72b4363010f9ab0866e1f7865f65275 \ No newline at end of file diff --git a/src/sqlite.h.in b/src/sqlite.h.in index a1fbf7e825..1d559db5ac 100644 --- a/src/sqlite.h.in +++ b/src/sqlite.h.in @@ -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 */ }; diff --git a/src/vtab.c b/src/vtab.c index 9207fc485b..bb4634a46a 100644 --- a/src/vtab.c +++ b/src/vtab.c @@ -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;