aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authordan <dan@noemail.net>2018-05-17 14:26:27 +0000
committerdan <dan@noemail.net>2018-05-17 14:26:27 +0000
commit2e362f9775ba05e353276039acc788e592fea0e4 (patch)
treeb423e27a44841c7797e68a95d1bd2c14cffa8f16 /src
parent86fb6e173885b9ac170b14ce9a9d0ccf7cd34e50 (diff)
downloadsqlite-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.c41
-rw-r--r--src/select.c22
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