aboutsummaryrefslogtreecommitdiff
path: root/src/expr.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/expr.c')
-rw-r--r--src/expr.c33
1 files changed, 33 insertions, 0 deletions
diff --git a/src/expr.c b/src/expr.c
index 91eb44b8e..54e9ced00 100644
--- a/src/expr.c
+++ b/src/expr.c
@@ -772,6 +772,7 @@ Expr *sqlite3ExprAlloc(
memset(pNew, 0, sizeof(Expr));
pNew->op = (u8)op;
pNew->iAgg = -1;
+ pNew->pWin = 0;
if( pToken ){
if( nExtra==0 ){
pNew->flags |= EP_IntValue|EP_Leaf;
@@ -861,6 +862,7 @@ Expr *sqlite3PExpr(
memset(p, 0, sizeof(Expr));
p->op = op & TKFLG_MASK;
p->iAgg = -1;
+ p->pWin = 0;
}
sqlite3ExprAttachSubtrees(pParse->db, p, pLeft, pRight);
}
@@ -1063,6 +1065,9 @@ static SQLITE_NOINLINE void sqlite3ExprDeleteNN(sqlite3 *db, Expr *p){
}else{
sqlite3ExprListDelete(db, p->x.pList);
}
+ if( !ExprHasProperty(p, EP_Reduced) ){
+ sqlite3WindowDelete(db, p->pWin);
+ }
}
if( ExprHasProperty(p, EP_MemToken) ) sqlite3DbFree(db, p->u.zToken);
if( !ExprHasProperty(p, EP_Static) ){
@@ -1177,6 +1182,24 @@ static int dupedExprSize(Expr *p, int flags){
return nByte;
}
+static Window *winDup(sqlite3 *db, Window *p){
+ Window *pNew = 0;
+ if( p ){
+ pNew = sqlite3DbMallocZero(db, sizeof(Window));
+ if( pNew ){
+ pNew->pFilter = sqlite3ExprDup(db, p->pFilter, 0);
+ pNew->pPartition = sqlite3ExprListDup(db, p->pPartition, 0);
+ pNew->pOrderBy = sqlite3ExprListDup(db, p->pOrderBy, 0);
+ pNew->eType = p->eType;
+ pNew->eEnd = p->eEnd;
+ pNew->eStart = p->eStart;
+ pNew->pStart = sqlite3ExprDup(db, pNew->pStart, 0);
+ pNew->pEnd = sqlite3ExprDup(db, pNew->pEnd, 0);
+ }
+ }
+ return pNew;
+}
+
/*
** This function is similar to sqlite3ExprDup(), except that if pzBuffer
** is not NULL then *pzBuffer is assumed to point to a buffer large enough
@@ -1263,6 +1286,11 @@ static Expr *exprDup(sqlite3 *db, Expr *p, int dupFlags, u8 **pzBuffer){
*pzBuffer = zAlloc;
}
}else{
+ if( ExprHasProperty(p, EP_Reduced|EP_TokenOnly) ){
+ pNew->pWin = 0;
+ }else{
+ pNew->pWin = winDup(db, p->pWin);
+ }
if( !ExprHasProperty(p, EP_TokenOnly|EP_Leaf) ){
if( pNew->op==TK_SELECT_COLUMN ){
pNew->pLeft = p->pLeft;
@@ -1469,6 +1497,7 @@ Select *sqlite3SelectDup(sqlite3 *db, Select *pDup, int flags){
pNew->addrOpenEphm[1] = -1;
pNew->nSelectRow = p->nSelectRow;
pNew->pWith = withDup(db, p->pWith);
+ pNew->pWin = 0;
sqlite3SelectSetName(pNew, p->zSelName);
*pp = pNew;
pp = &pNew->pPrior;
@@ -3778,6 +3807,10 @@ expr_code_doover:
u8 enc = ENC(db); /* The text encoding used by this database */
CollSeq *pColl = 0; /* A collating sequence */
+ if( !ExprHasProperty(pExpr, EP_TokenOnly|EP_Reduced) && pExpr->pWin ){
+ return pExpr->pWin->regResult;
+ }
+
if( ConstFactorOk(pParse) && sqlite3ExprIsConstantNotJoin(pExpr) ){
/* SQL functions can be expensive. So try to move constant functions
** out of the inner loop, even if that means an extra OP_Copy. */