diff options
author | dan <dan@noemail.net> | 2019-07-22 16:20:03 +0000 |
---|---|---|
committer | dan <dan@noemail.net> | 2019-07-22 16:20:03 +0000 |
commit | 75b0821e999cb14d4081a6ff8090e28e49e5bc7e (patch) | |
tree | 778d751b5c8ac70cb3800d06990a15b9dde08a8b /src | |
parent | fd15e18d7fe9bea571c52324a6eae25f3e2b4ebc (diff) | |
download | sqlite-75b0821e999cb14d4081a6ff8090e28e49e5bc7e.tar.gz sqlite-75b0821e999cb14d4081a6ff8090e28e49e5bc7e.zip |
Remove Window objects from the corresponding Select.pWin list when they are deleted.
FossilOrigin-Name: d23f33168222dfa40a67dc7de58057418151989e81429e4af47617e86db04667
Diffstat (limited to 'src')
-rw-r--r-- | src/expr.c | 13 | ||||
-rw-r--r-- | src/resolve.c | 46 | ||||
-rw-r--r-- | src/select.c | 2 | ||||
-rw-r--r-- | src/sqliteInt.h | 5 | ||||
-rw-r--r-- | src/window.c | 4 |
5 files changed, 33 insertions, 37 deletions
diff --git a/src/expr.c b/src/expr.c index 56b3148ed..571e9e494 100644 --- a/src/expr.c +++ b/src/expr.c @@ -1326,10 +1326,17 @@ static With *withDup(sqlite3 *db, With *p){ */ static int gatherSelectWindowsCallback(Walker *pWalker, Expr *pExpr){ if( pExpr->op==TK_FUNCTION && ExprHasProperty(pExpr, EP_WinFunc) ){ - assert( pExpr->y.pWin ); + Select *pSelect = pWalker->u.pSelect; + Window *pWin = pExpr->y.pWin; + assert( pWin ); assert( IsWindowFunc(pExpr) ); - pExpr->y.pWin->pNextWin = pWalker->u.pSelect->pWin; - pWalker->u.pSelect->pWin = pExpr->y.pWin; + if( pSelect->pWin ){ + *pSelect->pWin->ppThis = pSelect->pWin->pNextWin; + pSelect->pWin->ppThis = &pWin->pNextWin; + } + pWin->pNextWin = pSelect->pWin; + pWin->ppThis = &pSelect->pWin; + pSelect->pWin = pWin; } return WRC_Continue; } diff --git a/src/resolve.c b/src/resolve.c index cf3d9c339..2fd98ef0b 100644 --- a/src/resolve.c +++ b/src/resolve.c @@ -901,6 +901,7 @@ static int resolveExprStep(Walker *pWalker, Expr *pExpr){ #ifndef SQLITE_OMIT_WINDOWFUNC if( pWin ){ Select *pSel = pNC->pWinSelect; + assert( pWin==pExpr->y.pWin ); if( IN_RENAME_OBJECT==0 ){ sqlite3WindowUpdate(pParse, pSel->pWinDefn, pWin, pDef); } @@ -910,8 +911,12 @@ static int resolveExprStep(Walker *pWalker, Expr *pExpr){ if( 0==pSel->pWin || 0==sqlite3WindowCompare(pParse, pSel->pWin, pWin, 0) ){ - pExpr->y.pWin->pNextWin = pSel->pWin; - pSel->pWin = pExpr->y.pWin; + pWin->pNextWin = pSel->pWin; + if( pSel->pWin ){ + pSel->pWin->ppThis = &pWin->pNextWin; + } + pSel->pWin = pWin; + pWin->ppThis = &pSel->pWin; } pNC->ncFlags |= NC_HasWin; }else @@ -1295,17 +1300,15 @@ int sqlite3ResolveOrderGroupBy( #ifndef SQLITE_OMIT_WINDOWFUNC /* -** Walker callback for sqlite3WindowRemoveExprFromSelect() and -** sqlite3WindowRemoveExprListFromSelect() +** Walker callback for windowRemoveExprFromSelect(). */ static int resolveRemoveWindowsCb(Walker *pWalker, Expr *pExpr){ if( ExprHasProperty(pExpr, EP_WinFunc) ){ - Window **pp; - for(pp=&pWalker->u.pSelect->pWin; *pp; pp=&(*pp)->pNextWin){ - if( *pp==pExpr->y.pWin ){ - *pp = (*pp)->pNextWin; - break; - } + Window *pWin = pExpr->y.pWin; + if( pWin->ppThis ){ + *pWin->ppThis = pWin->pNextWin; + if( pWin->pNextWin ) pWin->pNextWin->ppThis = pWin->ppThis; + pWin->ppThis = 0; } } return WRC_Continue; @@ -1315,7 +1318,7 @@ static int resolveRemoveWindowsCb(Walker *pWalker, Expr *pExpr){ ** Remove any Window objects owned by the expression pExpr from the ** Select.pWin list of Select object pSelect. */ -void sqlite3WindowRemoveExprFromSelect(Select *pSelect, Expr *pExpr){ +static void windowRemoveExprFromSelect(Select *pSelect, Expr *pExpr){ if( pSelect->pWin ){ Walker sWalker; memset(&sWalker, 0, sizeof(Walker)); @@ -1324,23 +1327,8 @@ void sqlite3WindowRemoveExprFromSelect(Select *pSelect, Expr *pExpr){ sqlite3WalkExpr(&sWalker, pExpr); } } - -/* -** Remove any Window objects owned by the expression list from the -** Select.pWin list of Select object pSelect. -*/ -void sqlite3WindowRemoveExprListFromSelect(Select *pSelect, ExprList *pList){ - if( pList && pSelect->pWin ){ - int i; - Walker sWalker; - memset(&sWalker, 0, sizeof(Walker)); - sWalker.xExprCallback = resolveRemoveWindowsCb; - sWalker.u.pSelect = pSelect; - for(i=0; i<pList->nExpr; i++){ - sqlite3WalkExpr(&sWalker, pList->a[i].pExpr); - } - } -} +#else +# define windowRemoveExprFromSelect(a, b) #endif /* SQLITE_OMIT_WINDOWFUNC */ /* @@ -1412,7 +1400,7 @@ static int resolveOrderGroupBy( /* Since this expresion is being changed into a reference ** to an identical expression in the result set, remove all Window ** objects belonging to the expression from the Select.pWin list. */ - sqlite3WindowRemoveExprFromSelect(pSelect, pE); + windowRemoveExprFromSelect(pSelect, pE); pItem->u.x.iOrderByCol = j+1; } } diff --git a/src/select.c b/src/select.c index 824583c8f..6e0eeb2f4 100644 --- a/src/select.c +++ b/src/select.c @@ -102,6 +102,7 @@ static void clearSelect(sqlite3 *db, Select *p, int bFree){ } #endif if( OK_IF_ALWAYS_TRUE(p->pWith) ) sqlite3WithDelete(db, p->pWith); + assert( p->pWin==0 ); if( bFree ) sqlite3DbFreeNN(db, p); p = pPrior; bFree = 1; @@ -5661,7 +5662,6 @@ int sqlite3Select( pDest->eDest==SRT_DistQueue || pDest->eDest==SRT_Fifo); /* If ORDER BY makes no difference in the output then neither does ** DISTINCT so it can be removed too. */ - sqlite3WindowRemoveExprListFromSelect(p, p->pOrderBy); sqlite3ExprListDelete(db, p->pOrderBy); p->pOrderBy = 0; p->selFlags &= ~SF_Distinct; diff --git a/src/sqliteInt.h b/src/sqliteInt.h index 0d3e19efc..e55eadea6 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -3594,6 +3594,7 @@ struct Window { u8 eExclude; /* TK_NO, TK_CURRENT, TK_TIES, TK_GROUP, or 0 */ Expr *pStart; /* Expression for "<expr> PRECEDING" */ Expr *pEnd; /* Expression for "<expr> FOLLOWING" */ + Window **ppThis; /* Pointer to this object in Select.pWin list */ Window *pNextWin; /* Next window function belonging to this SELECT */ Expr *pFilter; /* The FILTER expression */ FuncDef *pFunc; /* The function */ @@ -3627,14 +3628,10 @@ Window *sqlite3WindowListDup(sqlite3 *db, Window *p); void sqlite3WindowFunctions(void); void sqlite3WindowChain(Parse*, Window*, Window*); Window *sqlite3WindowAssemble(Parse*, Window*, ExprList*, ExprList*, Token*); -void sqlite3WindowRemoveExprFromSelect(Select*,Expr*); -void sqlite3WindowRemoveExprListFromSelect(Select*,ExprList*); #else # define sqlite3WindowDelete(a,b) # define sqlite3WindowFunctions() # define sqlite3WindowAttach(a,b,c) -# define sqlite3WindowRemoveExprFromSelect(Select*,Expr*); -# define sqlite3WindowRemoveExprListFromSelect(Select*,ExprList*); #endif /* diff --git a/src/window.c b/src/window.c index d769b0bb7..f94370a49 100644 --- a/src/window.c +++ b/src/window.c @@ -1022,6 +1022,10 @@ int sqlite3WindowRewrite(Parse *pParse, Select *p){ */ void sqlite3WindowDelete(sqlite3 *db, Window *p){ if( p ){ + if( p->ppThis ){ + *p->ppThis = p->pNextWin; + if( p->pNextWin ) p->pNextWin->ppThis = p->ppThis; + } sqlite3ExprDelete(db, p->pFilter); sqlite3ExprListDelete(db, p->pPartition); sqlite3ExprListDelete(db, p->pOrderBy); |