Skip to content

Commit

Permalink
Make sure any window definitions in an ORDER BY clause are removed from
Browse files Browse the repository at this point in the history
the SELECT statement if the ORDER BY clause gets optimized out.
  • Loading branch information
D. Richard Hipp committed Jul 20, 2019
1 parent 3feab07 commit 1e31356
Show file tree
Hide file tree
Showing 3 changed files with 34 additions and 11 deletions.
40 changes: 29 additions & 11 deletions src/resolve.c
Original file line number Diff line number Diff line change
Expand Up @@ -1295,7 +1295,8 @@ int sqlite3ResolveOrderGroupBy(

#ifndef SQLITE_OMIT_WINDOWFUNC
/*
** Walker callback for resolveRemoveWindows().
** Walker callback for sqlite3WindowRemoveExprFromSelect() and
** sqlite3WindowRemoveExprListFromSelect()
*/
static int resolveRemoveWindowsCb(Walker *pWalker, Expr *pExpr){
if( ExprHasProperty(pExpr, EP_WinFunc) ){
Expand All @@ -1314,16 +1315,33 @@ 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);
void sqlite3WindowRemoveExprFromSelect(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

/*
** 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);
}
}
}
#endif /* SQLITE_OMIT_WINDOWFUNC */

/*
** pOrderBy is an ORDER BY or GROUP BY clause in SELECT statement pSelect.
Expand Down Expand Up @@ -1394,7 +1412,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);
sqlite3WindowRemoveExprFromSelect(pSelect, pE);
pItem->u.x.iOrderByCol = j+1;
}
}
Expand Down
1 change: 1 addition & 0 deletions src/select.c
Original file line number Diff line number Diff line change
Expand Up @@ -5661,6 +5661,7 @@ 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;
Expand Down
4 changes: 4 additions & 0 deletions src/sqliteInt.h
Original file line number Diff line number Diff line change
Expand Up @@ -3627,10 +3627,14 @@ 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

/*
Expand Down

0 comments on commit 1e31356

Please sign in to comment.