aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authordrh <drh@noemail.net>2015-08-20 23:21:34 +0000
committerdrh <drh@noemail.net>2015-08-20 23:21:34 +0000
commitd8b1bfc6bf2f9463c1dfc27e7c52e9207b291145 (patch)
tree36bc0fae80ab17a4ff16fdb17d0fc2dea604b7e0 /src
parent197d59ffc4fe46fb12dcf62bb248c102fc0d5ecf (diff)
downloadsqlite-d8b1bfc6bf2f9463c1dfc27e7c52e9207b291145.tar.gz
sqlite-d8b1bfc6bf2f9463c1dfc27e7c52e9207b291145.zip
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
Diffstat (limited to 'src')
-rw-r--r--src/build.c7
-rw-r--r--src/resolve.c9
-rw-r--r--src/vtab.c11
-rw-r--r--src/whereexpr.c2
4 files changed, 15 insertions, 14 deletions
diff --git a/src/build.c b/src/build.c
index 5f8bf8488..d6ceb2c88 100644
--- a/src/build.c
+++ b/src/build.c
@@ -355,7 +355,6 @@ Table *sqlite3LocateTable(
p = sqlite3FindTable(pParse->db, zName, zDbase);
if( p==0 ){
- const char *zMsg;
#ifndef SQLITE_OMIT_VIRTUAL_TABLE
/* If zName is the not the name of a table in the schema created using
** CREATE, then check to see if it is the name of an virtual table that
@@ -365,7 +364,7 @@ Table *sqlite3LocateTable(
return pMod->pEpoTab;
}
#endif
- zMsg = isView ? "no such view" : "no such table";
+ const char *zMsg = isView ? "no such view" : "no such table";
if( zDbase ){
sqlite3ErrorMsg(pParse, "%s: %s.%s", zMsg, zDbase, zName);
}else{
@@ -3803,13 +3802,15 @@ void sqlite3SrcListIndexedBy(Parse *pParse, SrcList *p, Token *pIndexedBy){
** table-valued-function.
*/
void sqlite3SrcListFuncArgs(Parse *pParse, SrcList *p, ExprList *pList){
- if( p && ALWAYS(p->nSrc>0) && pList ){
+ if( p && pList ){
struct SrcList_item *pItem = &p->a[p->nSrc-1];
assert( pItem->fg.notIndexed==0 );
assert( pItem->fg.isIndexedBy==0 );
assert( pItem->fg.isTabFunc==0 );
pItem->u1.pFuncArg = pList;
pItem->fg.isTabFunc = 1;
+ }else{
+ sqlite3ExprListDelete(pParse->db, pList);
}
}
diff --git a/src/resolve.c b/src/resolve.c
index 9799a136b..0908d4cd5 100644
--- a/src/resolve.c
+++ b/src/resolve.c
@@ -1451,11 +1451,10 @@ int sqlite3ResolveExprListNames(
NameContext *pNC, /* Namespace to resolve expressions in. */
ExprList *pList /* The expression list to be analyzed. */
){
- if( pList ){
- int i;
- for(i=0; i<pList->nExpr; i++){
- if( sqlite3ResolveExprNames(pNC, pList->a[i].pExpr) ) return WRC_Abort;
- }
+ assert( pList!=0 );
+ int i;
+ for(i=0; i<pList->nExpr; i++){
+ if( sqlite3ResolveExprNames(pNC, pList->a[i].pExpr) ) return WRC_Abort;
}
return WRC_Continue;
}
diff --git a/src/vtab.c b/src/vtab.c
index 8042e0e7b..1675ca2e3 100644
--- a/src/vtab.c
+++ b/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;
}
diff --git a/src/whereexpr.c b/src/whereexpr.c
index a0f7c822a..d6f94b3e1 100644
--- a/src/whereexpr.c
+++ b/src/whereexpr.c
@@ -1273,7 +1273,7 @@ void sqlite3WhereTabFuncArgs(
for(j=k=0; j<pArgs->nExpr; j++){
while( k<pTab->nCol && (pTab->aCol[k].colFlags & COLFLAG_HIDDEN)==0 ){ k++; }
if( k>=pTab->nCol ){
- sqlite3ErrorMsg(pParse, "too many arguments on %s - max %d",
+ sqlite3ErrorMsg(pParse, "too many arguments on %s() - max %d",
pTab->zName, j);
return;
}