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:
11
src/vtab.c
11
src/vtab.c
@@ -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;
|
||||
}
|
||||
|
Reference in New Issue
Block a user