diff options
author | drh <drh@noemail.net> | 2018-12-06 22:04:19 +0000 |
---|---|---|
committer | drh <drh@noemail.net> | 2018-12-06 22:04:19 +0000 |
commit | a83899754423bea16d4efeb4f39482b57d79c083 (patch) | |
tree | f333a44ec8dc2e4adb0623fc5b04e0dd92798dcf /src | |
parent | bb383df7c625daa4c7a0db4c7eed2296dc171bde (diff) | |
download | sqlite-a83899754423bea16d4efeb4f39482b57d79c083.tar.gz sqlite-a83899754423bea16d4efeb4f39482b57d79c083.zip |
Fix the sqlite3ExprDup() routine so that it makes complete duplications of
subqueries containing window functions.
FossilOrigin-Name: 940174543e87184a0278fcd02e8a096a11510174d9c1d65d21878819790ddaff
Diffstat (limited to 'src')
-rw-r--r-- | src/expr.c | 27 | ||||
-rw-r--r-- | src/window.c | 1 |
2 files changed, 28 insertions, 0 deletions
diff --git a/src/expr.c b/src/expr.c index fb44a7ef7..a6bb441d5 100644 --- a/src/expr.c +++ b/src/expr.c @@ -1330,6 +1330,32 @@ static With *withDup(sqlite3 *db, With *p){ # define withDup(x,y) 0 #endif +#ifndef SQLITE_OMIT_WINDOWFUNC +/* +** The gatherSelectWindows() procedure and its helper routine +** gatherSelectWindowsCallback() are used to scan all the expressions +** an a newly duplicated SELECT statement and gather all of the Window +** objects found there, assembling them onto the linked list at Select->pWin. +*/ +static int gatherSelectWindowsCallback(Walker *pWalker, Expr *pExpr){ + if( pExpr->op==TK_FUNCTION && pExpr->y.pWin!=0 ){ + assert( ExprHasProperty(pExpr, EP_WinFunc) ); + pExpr->y.pWin->pNextWin = pWalker->u.pSelect->pWin; + pWalker->u.pSelect->pWin = pExpr->y.pWin; + } + return WRC_Continue; +} +static void gatherSelectWindows(Select *p){ + Walker w; + w.xExprCallback = gatherSelectWindowsCallback; + w.xSelectCallback = 0; + w.u.pSelect = p; + sqlite3WalkSelectExpr(&w, p); + sqlite3WalkSelectFrom(&w, p); +} +#endif + + /* ** The following group of routines make deep copies of expressions, ** expression lists, ID lists, and select statements. The copies can @@ -1497,6 +1523,7 @@ Select *sqlite3SelectDup(sqlite3 *db, Select *pDup, int flags){ #ifndef SQLITE_OMIT_WINDOWFUNC pNew->pWin = 0; pNew->pWinDefn = sqlite3WindowListDup(db, p->pWinDefn); + if( p->pWin ) gatherSelectWindows(pNew); #endif pNew->selId = p->selId; *pp = pNew; diff --git a/src/window.c b/src/window.c index f5deae9a6..f3e274d6e 100644 --- a/src/window.c +++ b/src/window.c @@ -2133,6 +2133,7 @@ Window *sqlite3WindowDup(sqlite3 *db, Expr *pOwner, Window *p){ if( pNew ){ pNew->zName = sqlite3DbStrDup(db, p->zName); pNew->pFilter = sqlite3ExprDup(db, p->pFilter, 0); + pNew->pFunc = p->pFunc; pNew->pPartition = sqlite3ExprListDup(db, p->pPartition, 0); pNew->pOrderBy = sqlite3ExprListDup(db, p->pOrderBy, 0); pNew->eType = p->eType; |