1
0
mirror of https://github.com/sqlite/sqlite.git synced 2025-08-10 01:02:56 +03:00

Remove Window objects from the corresponding Select.pWin list when they are deleted, as they are, for example, when the ORDER BY clause is optimized out.

FossilOrigin-Name: fd7316cda0fdfe86985f41a97dff3beba188606ec9bc6fef38a686a6976a6e01
This commit is contained in:
dan
2019-07-22 16:33:02 +00:00
8 changed files with 77 additions and 33 deletions

View File

@@ -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,16 +1300,15 @@ int sqlite3ResolveOrderGroupBy(
#ifndef SQLITE_OMIT_WINDOWFUNC
/*
** Walker callback for resolveRemoveWindows().
** 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;
@@ -1314,16 +1318,18 @@ 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.
*/
static void resolveRemoveWindows(Select *pSelect, Expr *pExpr){
Walker sWalker;
memset(&sWalker, 0, sizeof(Walker));
sWalker.xExprCallback = resolveRemoveWindowsCb;
sWalker.u.pSelect = pSelect;
sqlite3WalkExpr(&sWalker, pExpr);
static void windowRemoveExprFromSelect(Select *pSelect, Expr *pExpr){
if( pSelect->pWin ){
Walker sWalker;
memset(&sWalker, 0, sizeof(Walker));
sWalker.xExprCallback = resolveRemoveWindowsCb;
sWalker.u.pSelect = pSelect;
sqlite3WalkExpr(&sWalker, pExpr);
}
}
#else
# define resolveRemoveWindows(x,y)
#endif
# define windowRemoveExprFromSelect(a, b)
#endif /* SQLITE_OMIT_WINDOWFUNC */
/*
** pOrderBy is an ORDER BY or GROUP BY clause in SELECT statement pSelect.
@@ -1394,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. */
resolveRemoveWindows(pSelect, pE);
windowRemoveExprFromSelect(pSelect, pE);
pItem->u.x.iOrderByCol = j+1;
}
}