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:
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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
|
||||
|
||||
/*
|
||||
|
||||
Reference in New Issue
Block a user