diff options
author | drh <drh@noemail.net> | 2019-12-25 23:54:21 +0000 |
---|---|---|
committer | drh <drh@noemail.net> | 2019-12-25 23:54:21 +0000 |
commit | a9ebfe20309d5aeec90337099a27e68454d16ff6 (patch) | |
tree | 7951f0603588b693977a4b054ab8eec965e92362 /src/select.c | |
parent | b44fec68a53b88612d1d0954eecaa638674764a4 (diff) | |
download | sqlite-a9ebfe20309d5aeec90337099a27e68454d16ff6.tar.gz sqlite-a9ebfe20309d5aeec90337099a27e68454d16ff6.zip |
When the sqlite3WindowRewrite() routine detects and error, have it convert
the SELECT statement into just "SELECT null" so that it does not leave the
parse tree in a goofy state that can cause problems with subsequent code
before the stack has a chance to unwind and report the error.
Ticket [d87336c81c7d0873]
FossilOrigin-Name: fa58aad48a788802b13a819e49f9b8787f713bbe395c46c7295e821c52c81738
Diffstat (limited to 'src/select.c')
-rw-r--r-- | src/select.c | 27 |
1 files changed, 23 insertions, 4 deletions
diff --git a/src/select.c b/src/select.c index 6fff2883e..60744e825 100644 --- a/src/select.c +++ b/src/select.c @@ -84,7 +84,10 @@ struct SortCtx { /* ** Delete all the content of a Select structure. Deallocate the structure -** itself only if bFree is true. +** itself depending on the value of bFree +** +** If bFree==1, call sqlite3DbFree() on the p object. +** If bFree==0, Leave the first Select object unfreed */ static void clearSelect(sqlite3 *db, Select *p, int bFree){ while( p ){ @@ -189,6 +192,20 @@ void sqlite3SelectDelete(sqlite3 *db, Select *p){ } /* +** Delete all the substructure for p, but keep p allocated. Redefine +** p to be a single SELECT where every column of the result set has a +** value of NULL. +*/ +void sqlite3SelectReset(Parse *pParse, Select *p){ + if( ALWAYS(p) ){ + clearSelect(pParse->db, p, 0); + memset(&p->iLimit, 0, sizeof(Select) - offsetof(Select,iLimit)); + p->pEList = sqlite3ExprListAppend(pParse, 0, + sqlite3ExprAlloc(pParse->db,TK_NULL,0,0)); + } +} + +/* ** Return a pointer to the right-most SELECT statement in a compound. */ static Select *findRightmost(Select *p){ @@ -2711,9 +2728,9 @@ static int multiSelect( ** it is that we currently need. */ assert( unionTab==dest.iSDParm || dest.eDest!=priorOp ); - if( dest.eDest!=priorOp ){ + assert( p->pEList || db->mallocFailed ); + if( dest.eDest!=priorOp && db->mallocFailed==0 ){ int iCont, iBreak, iStart; - assert( p->pEList ); iBreak = sqlite3VdbeMakeLabel(pParse); iCont = sqlite3VdbeMakeLabel(pParse); computeLimitRegisters(pParse, p, iBreak); @@ -5738,7 +5755,9 @@ int sqlite3Select( } #ifndef SQLITE_OMIT_WINDOWFUNC - if( sqlite3WindowRewrite(pParse, p) ){ + rc = sqlite3WindowRewrite(pParse, p); + if( rc ){ + assert( pParse->nErr>0 ); goto select_end; } #if SELECTTRACE_ENABLED |