1
0
mirror of https://github.com/sqlite/sqlite.git synced 2025-11-12 13:01:09 +03:00

When generating code for a subquery, make a copy of the Select object and

generate the code out of the copy, in case the code generator makes
modifications to expression and the Select object needs to be reused.

FossilOrigin-Name: 4edddcc0bc8d71e9b8abac67bc3766f1d9143dddd1f59264859ce65e5aa9b8c6
This commit is contained in:
drh
2020-01-01 21:14:30 +00:00
parent 4ea562ee70
commit fc705da15d
4 changed files with 34 additions and 12 deletions

View File

@@ -2933,6 +2933,8 @@ int sqlite3CodeSubselect(Parse *pParse, Expr *pExpr){
SelectDest dest; /* How to deal with SELECT result */
int nReg; /* Registers to allocate */
Expr *pLimit; /* New limit expression */
Select *pCopy; /* Copy of pSel */
int rc; /* return value from subroutine call */
Vdbe *v = pParse->pVdbe;
assert( v!=0 );
@@ -3016,9 +3018,16 @@ int sqlite3CodeSubselect(Parse *pParse, Expr *pExpr){
pSel->pLimit = sqlite3PExpr(pParse, TK_LIMIT, pLimit, 0);
}
pSel->iLimit = 0;
if( sqlite3Select(pParse, pSel, &dest) ){
return 0;
}
/* pSel might be reused. So generate code using a copy of pSel, so that
** if the code generator modifies the underlying structure of the SELECT
** (for example in whereIndexExprTrans()) the original in pSel will be
** unchanged. */
pCopy = sqlite3SelectDup(pParse->db, pSel, 0);
rc = sqlite3Select(pParse, pCopy, &dest);
sqlite3SelectDelete(pParse->db, pCopy);
if( rc ) return 0;
pExpr->iTable = rReg = dest.iSDParm;
ExprSetVVAProperty(pExpr, EP_NoReduce);
if( addrOnce ){