aboutsummaryrefslogtreecommitdiff
path: root/src/resolve.c
diff options
context:
space:
mode:
authordan <dan@noemail.net>2019-07-22 16:33:02 +0000
committerdan <dan@noemail.net>2019-07-22 16:33:02 +0000
commit7f6f12bdd35c55d9f98b6eefbe2d40c4a85aab87 (patch)
treec90be8f5173dfe1513abdfe7ae4a356f4f82bd9c /src/resolve.c
parent1e60261cfbc34cdad2625241ba6e5bedfb2e6716 (diff)
parent75b0821e999cb14d4081a6ff8090e28e49e5bc7e (diff)
downloadsqlite-7f6f12bdd35c55d9f98b6eefbe2d40c4a85aab87.tar.gz
sqlite-7f6f12bdd35c55d9f98b6eefbe2d40c4a85aab87.zip
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
Diffstat (limited to 'src/resolve.c')
-rw-r--r--src/resolve.c42
1 files changed, 24 insertions, 18 deletions
diff --git a/src/resolve.c b/src/resolve.c
index be6430deb..48d8fcb9b 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,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;
}
}