diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/expr.c | 38 | ||||
-rw-r--r-- | src/parse.y | 9 | ||||
-rw-r--r-- | src/sqliteInt.h | 1 | ||||
-rw-r--r-- | src/treeview.c | 6 |
4 files changed, 54 insertions, 0 deletions
diff --git a/src/expr.c b/src/expr.c index f7290262e..07b6dfcef 100644 --- a/src/expr.c +++ b/src/expr.c @@ -1182,6 +1182,44 @@ Expr *sqlite3ExprFunction( } /* +** Attach an ORDER BY clause to a function call. +** +** functionname( arguments ORDER BY sortlist ) +** \_____________________/ \______/ +** pExpr pOrderBy +** +** The ORDER BY clause is inserted into a new Expr node of type TK_ORDER +** and added to the Expr.pLeft field of the parent TK_FUNCTION node. +*/ +void sqlite3ExprAddFunctionOrderBy( + Parse *pParse, /* Parsing context */ + Expr *pExpr, /* The function call to which ORDER BY is to be added */ + ExprList *pOrderBy /* The ORDER BY clause to add */ +){ + Expr *pOB; + sqlite3 *db = pParse->db; + if( pOrderBy==0 ){ + assert( db->mallocFailed ); + return; + } + if( pExpr==0 ){ + assert( db->mallocFailed ); + sqlite3ExprListDelete(db, pOrderBy); + return; + } + assert( pExpr->op==TK_FUNCTION ); + assert( pExpr->pLeft==0 ); + pOB = sqlite3ExprAlloc(db, TK_ORDER, 0, 0); + if( pOB==0 ){ + sqlite3ExprListDelete(db, pOrderBy); + return; + } + pOB->x.pList = pOrderBy; + assert( ExprUseXList(pOB) ); + pExpr->pLeft = pOB; +} + +/* ** Check to see if a function is usable according to current access ** rules: ** diff --git a/src/parse.y b/src/parse.y index 867b62aa7..19491192e 100644 --- a/src/parse.y +++ b/src/parse.y @@ -1144,6 +1144,10 @@ expr(A) ::= CAST LP expr(E) AS typetoken(T) RP. { expr(A) ::= idj(X) LP distinct(D) exprlist(Y) RP. { A = sqlite3ExprFunction(pParse, Y, &X, D); } +expr(A) ::= idj(X) LP distinct(D) exprlist(Y) ORDER BY sortlist(O) RP. { + A = sqlite3ExprFunction(pParse, Y, &X, D); + sqlite3ExprAddFunctionOrderBy(pParse, A, O); +} expr(A) ::= idj(X) LP STAR RP. { A = sqlite3ExprFunction(pParse, 0, &X, 0); } @@ -1153,6 +1157,11 @@ expr(A) ::= idj(X) LP distinct(D) exprlist(Y) RP filter_over(Z). { A = sqlite3ExprFunction(pParse, Y, &X, D); sqlite3WindowAttach(pParse, A, Z); } +expr(A) ::= idj(X) LP distinct(D) exprlist(Y) ORDER BY sortlist(O) RP filter_over(Z). { + A = sqlite3ExprFunction(pParse, Y, &X, D); + sqlite3WindowAttach(pParse, A, Z); + sqlite3ExprAddFunctionOrderBy(pParse, A, O); +} expr(A) ::= idj(X) LP STAR RP filter_over(Z). { A = sqlite3ExprFunction(pParse, 0, &X, 0); sqlite3WindowAttach(pParse, A, Z); diff --git a/src/sqliteInt.h b/src/sqliteInt.h index bee53b6c7..16da1db4c 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -4786,6 +4786,7 @@ void sqlite3PExprAddSelect(Parse*, Expr*, Select*); Expr *sqlite3ExprAnd(Parse*,Expr*, Expr*); Expr *sqlite3ExprSimplifiedAndOr(Expr*); Expr *sqlite3ExprFunction(Parse*,ExprList*, const Token*, int); +void sqlite3ExprAddFunctionOrderBy(Parse*,Expr*,ExprList*); void sqlite3ExprFunctionUsable(Parse*,const Expr*,const FuncDef*); void sqlite3ExprAssignVarNumber(Parse*, Expr*, u32); void sqlite3ExprDelete(sqlite3*, Expr*); diff --git a/src/treeview.c b/src/treeview.c index d55adab38..6852a61dd 100644 --- a/src/treeview.c +++ b/src/treeview.c @@ -709,6 +709,12 @@ void sqlite3TreeViewExpr(TreeView *pView, const Expr *pExpr, u8 moreToFollow){ } if( pFarg ){ sqlite3TreeViewExprList(pView, pFarg, pWin!=0, 0); + if( pExpr->pLeft ){ + Expr *pOB = pExpr->pLeft; + assert( pOB->op==TK_ORDER ); + assert( ExprUseXList(pOB) ); + sqlite3TreeViewExprList(pView, pOB->x.pList, pWin!=0, "ORDERBY"); + } } #ifndef SQLITE_OMIT_WINDOWFUNC if( pWin ){ |