diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/alter.c | 2 | ||||
-rw-r--r-- | src/select.c | 22 | ||||
-rw-r--r-- | src/sqliteInt.h | 2 |
3 files changed, 17 insertions, 9 deletions
diff --git a/src/alter.c b/src/alter.c index de0dd4e4d..24b0960a2 100644 --- a/src/alter.c +++ b/src/alter.c @@ -811,7 +811,7 @@ static void renameWalkWith(Walker *pWalker, Select *pSelect){ ** fails if the Select objects on it have already been expanded and ** resolved. */ pCopy = sqlite3WithDup(pParse->db, pWith); - sqlite3WithPush(pParse, pCopy, 1); + pCopy = sqlite3WithPush(pParse, pCopy, 1); } for(i=0; i<pWith->nCte; i++){ Select *p = pWith->a[i].pSelect; diff --git a/src/select.c b/src/select.c index 589c8532d..660b8302e 100644 --- a/src/select.c +++ b/src/select.c @@ -5093,21 +5093,29 @@ static struct Cte *searchWith( ** be freed along with the Parse object. In other cases, when ** bFree==0, the With object will be freed along with the SELECT ** statement with which it is associated. +** +** This routine returns a copy of pWith. Or, if bFree is true and +** the pWith object is destroyed immediately due to an OOM condition, +** then this routine return NULL. +** +** If bFree is true, do not continue to use the pWith pointer after +** calling this routine, Instead, use only the return value. */ -void sqlite3WithPush(Parse *pParse, With *pWith, u8 bFree){ +With *sqlite3WithPush(Parse *pParse, With *pWith, u8 bFree){ if( pWith ){ + if( bFree ){ + pWith = (With*)sqlite3ParserAddCleanup(pParse, + (void(*)(sqlite3*,void*))sqlite3WithDelete, + pWith); + if( pWith==0 ) return 0; + } if( pParse->nErr==0 ){ assert( pParse->pWith!=pWith ); pWith->pOuter = pParse->pWith; pParse->pWith = pWith; } - if( bFree ){ - sqlite3ParserAddCleanup(pParse, - (void(*)(sqlite3*,void*))sqlite3WithDelete, - pWith); - testcase( pParse->earlyCleanup ); - } } + return pWith; } /* diff --git a/src/sqliteInt.h b/src/sqliteInt.h index ad857ab03..4e99be384 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -4987,7 +4987,7 @@ const char *sqlite3JournalModename(int); void sqlite3CteDelete(sqlite3*,Cte*); With *sqlite3WithAdd(Parse*,With*,Cte*); void sqlite3WithDelete(sqlite3*,With*); - void sqlite3WithPush(Parse*, With*, u8); + With *sqlite3WithPush(Parse*, With*, u8); #else # define sqlite3CteNew(P,T,E,S) ((void*)0) # define sqlite3CteDelete(D,C) |