1
0
mirror of https://github.com/sqlite/sqlite.git synced 2025-08-08 14:02:16 +03:00

Fix corner-case memory management issues in table-valued functions. Change

virtual table handling so that if xDestroy is missing the table is
eponymous only even if xCreate is present.

FossilOrigin-Name: 774e6a14b124bbae4da0e188b62aee9ffb8c3745
This commit is contained in:
drh
2015-08-20 23:21:34 +00:00
parent 197d59ffc4
commit d8b1bfc6bf
8 changed files with 37 additions and 33 deletions

View File

@@ -699,7 +699,7 @@ int sqlite3VtabCallCreate(sqlite3 *db, int iDb, const char *zTab, char **pzErr){
** invoke it now. If the module has not been registered, return an
** error. Otherwise, do nothing.
*/
if( pMod==0 || pMod->pModule->xCreate==0 ){
if( pMod==0 || pMod->pModule->xCreate==0 || pMod->pModule->xDestroy==0 ){
*pzErr = sqlite3MPrintf(db, "no such module: %s", zMod);
rc = SQLITE_ERROR;
}else{
@@ -810,7 +810,8 @@ int sqlite3VtabCallDestroy(sqlite3 *db, int iDb, const char *zTab){
}
p = vtabDisconnectAll(db, pTab);
xDestroy = p->pMod->pModule->xDestroy;
rc = xDestroy ? xDestroy(p->pVtab) : SQLITE_OK;
assert( xDestroy!=0 ); /* Checked before the virtual table is created */
rc = xDestroy(p->pVtab);
/* Remove the sqlite3_vtab* from the aVTrans[] array, if applicable */
if( rc==SQLITE_OK ){
assert( pTab->pVTable==p && p->pNext==0 );
@@ -1123,9 +1124,9 @@ int sqlite3VtabEponymousTableInit(Parse *pParse, Module *pMod){
pTab->tabFlags |= TF_Virtual;
pTab->nModuleArg = 0;
pTab->iPKey = -1;
addModuleArgument(db, pTab, pTab->zName);
addModuleArgument(db, pTab, sqlite3DbStrDup(db, pTab->zName));
addModuleArgument(db, pTab, 0);
addModuleArgument(db, pTab, pTab->zName);
addModuleArgument(db, pTab, sqlite3DbStrDup(db, pTab->zName));
rc = vtabCallConstructor(db, pTab, pMod, pModule->xConnect, &zErr);
if( rc ){
sqlite3ErrorMsg(pParse, "%s", zErr);
@@ -1144,7 +1145,7 @@ void sqlite3VtabEponymousTableClear(sqlite3 *db, Module *pMod){
Table *pTab = pMod->pEpoTab;
if( (pTab = pMod->pEpoTab)!=0 ){
sqlite3DeleteColumnNames(db, pTab);
sqlite3DbFree(db, pTab->azModuleArg);
sqlite3VtabClear(db, pTab);
sqlite3DbFree(db, pTab);
pMod->pEpoTab = 0;
}