aboutsummaryrefslogtreecommitdiff
path: root/src/expr.c
diff options
context:
space:
mode:
authordrh <drh@noemail.net>2020-01-01 21:14:30 +0000
committerdrh <drh@noemail.net>2020-01-01 21:14:30 +0000
commitfc705da15d0af088db099aa5c8c2b26fa63fe951 (patch)
tree777ca07bab0645f28dca461242945c2691c514fe /src/expr.c
parent4ea562ee7007f184b53faa4a2bbdbfa70d0dbe9c (diff)
downloadsqlite-fc705da15d0af088db099aa5c8c2b26fa63fe951.tar.gz
sqlite-fc705da15d0af088db099aa5c8c2b26fa63fe951.zip
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
Diffstat (limited to 'src/expr.c')
-rw-r--r--src/expr.c15
1 files changed, 12 insertions, 3 deletions
diff --git a/src/expr.c b/src/expr.c
index 1c03cf634..b441b9a4f 100644
--- a/src/expr.c
+++ b/src/expr.c
@@ -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 ){