1
0
mirror of https://github.com/sqlite/sqlite.git synced 2025-11-12 13:01:09 +03:00

Make sure any window definitions in an ORDER BY clause are removed from

the SELECT statement if the ORDER BY clause gets optimized out.

FossilOrigin-Name: 23b119671f0be3c6b72cf2dc5f7707a0626766db7aa56529ab00d33d1a0a1bee
This commit is contained in:
drh
2019-07-20 21:12:31 +00:00
parent 7fc296aa66
commit fd15e18d7f
5 changed files with 46 additions and 20 deletions

View File

@@ -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) ){
@@ -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.
@@ -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;
}
}

View File

@@ -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;

View File

@@ -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
/*