diff options
author | dan <dan@noemail.net> | 2018-05-17 14:26:27 +0000 |
---|---|---|
committer | dan <dan@noemail.net> | 2018-05-17 14:26:27 +0000 |
commit | 2e362f9775ba05e353276039acc788e592fea0e4 (patch) | |
tree | b423e27a44841c7797e68a95d1bd2c14cffa8f16 /src | |
parent | 86fb6e173885b9ac170b14ce9a9d0ccf7cd34e50 (diff) | |
download | sqlite-2e362f9775ba05e353276039acc788e592fea0e4.tar.gz sqlite-2e362f9775ba05e353276039acc788e592fea0e4.zip |
Handle multiple window-functions in a single query.
FossilOrigin-Name: 35af0b750e70dcf0f343b115f4bbd0860a7e8064be204d4dfba1a43c22ff07b1
Diffstat (limited to 'src')
-rw-r--r-- | src/expr.c | 41 | ||||
-rw-r--r-- | src/select.c | 22 |
2 files changed, 34 insertions, 29 deletions
diff --git a/src/expr.c b/src/expr.c index a1407a85f..faaca6c86 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); } @@ -1180,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 @@ -1266,6 +1286,7 @@ static Expr *exprDup(sqlite3 *db, Expr *p, int dupFlags, u8 **pzBuffer){ *pzBuffer = zAlloc; } }else{ + pNew->pWin = winDup(db, p->pWin); if( !ExprHasProperty(p, EP_TokenOnly|EP_Leaf) ){ if( pNew->op==TK_SELECT_COLUMN ){ pNew->pLeft = p->pLeft; @@ -1308,24 +1329,6 @@ static With *withDup(sqlite3 *db, With *p){ # define withDup(x,y) 0 #endif -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; -} - /* ** The following group of routines make deep copies of expressions, ** expression lists, ID lists, and select statements. The copies can @@ -1490,7 +1493,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 = winDup(db, p->pWin); + pNew->pWin = 0; sqlite3SelectSetName(pNew, p->zSelName); *pp = pNew; pp = &pNew->pPrior; diff --git a/src/select.c b/src/select.c index 2b5a3dc54..93e55b680 100644 --- a/src/select.c +++ b/src/select.c @@ -5418,6 +5418,17 @@ static int selectWindowRewriteExprCb(Walker *pWalker, Expr *pExpr){ int rc = WRC_Continue; switch( pExpr->op ){ + + case TK_FUNCTION: + if( pExpr->pWin==0 ){ + break; + }else if( pExpr->pWin==p->pWin ){ + rc = WRC_Prune; + pExpr->pWin->pOwner = pExpr; + break; + } + /* Fall through. */ + case TK_COLUMN: { Expr *pDup = sqlite3ExprDup(pParse->db, pExpr, 0); p->pSub = sqlite3ExprListAppend(pParse, p->pSub, pDup); @@ -5436,13 +5447,6 @@ static int selectWindowRewriteExprCb(Walker *pWalker, Expr *pExpr){ break; } - case TK_FUNCTION: - if( pExpr->pWin ){ - rc = WRC_Prune; - pExpr->pWin->pOwner = pExpr; - } - break; - default: /* no-op */ break; } @@ -5530,9 +5534,6 @@ static int selectWindowRewrite(Parse *pParse, Select *p){ ExprList *pSublist = 0; /* Expression list for sub-query */ Window *pWin = p->pWin; - /* TODO: This is of course temporary requirements */ - assert( pWin->pNextWin==0 ); - p->pSrc = 0; p->pWhere = 0; p->pGroupBy = 0; @@ -5581,6 +5582,7 @@ static int selectWindowRewrite(Parse *pParse, Select *p){ }else{ pSub->selFlags |= SF_Expanded; } + pWin->pNextWin = 0; } #if SELECTTRACE_ENABLED |