@@ -252,6 +252,7 @@ func validateGroupBy(ctx *sql.Context, a *Analyzer, n sql.Node, scope *plan.Scop
252252
253253 var err error
254254 var project * plan.Project
255+ var orderBy * plan.Sort
255256 transform .Inspect (n , func (n sql.Node ) bool {
256257 switch n := n .(type ) {
257258 case * plan.GroupBy :
@@ -307,20 +308,36 @@ func validateGroupBy(ctx *sql.Context, a *Analyzer, n sql.Node, scope *plan.Scop
307308 return true
308309 }
309310
310- selectExprs := getSelectExprs (project , n .SelectDeps , groupBys )
311+ selectExprs , orderByExprs := getSelectAndOrderByExprs (project , orderBy , n .SelectDeps , groupBys )
311312
312313 for i , expr := range selectExprs {
313314 if valid , col := expressionReferencesOnlyGroupBys (groupBys , expr , noGroupBy ); ! valid {
314315 if noGroupBy {
315316 err = sql .ErrNonAggregatedColumnWithoutGroupBy .New (i + 1 , col )
316317 } else {
317- err = analyzererrors .ErrValidationGroupBy .New (i + 1 )
318+ err = analyzererrors .ErrValidationGroupBy .New (i + 1 , col )
318319 }
319320 return false
320321 }
321322 }
323+ // According to MySQL documentation, we should still be validating ORDER BY expressions when there's not an
324+ // explicit GROUP BY in the query ("If a query has aggregate functions and no GROUP BY clause, it cannot
325+ // have nonaggregated columns in the select list, HAVING condition, or ORDER BY list with
326+ // ONLY_FULL_GROUP_BY enabled"). But when testing queries in MySQL, it doesn't seem like they actually
327+ // validate ORDER BY expressions in aggregate queries without an explicit GROUP BY
328+ if ! noGroupBy {
329+ for i , expr := range orderByExprs {
330+ if valid , col := expressionReferencesOnlyGroupBys (groupBys , expr , noGroupBy ); ! valid {
331+ err = analyzererrors .ErrValidationGroupByOrderBy .New (i + 1 , col )
332+ return false
333+ }
334+ }
335+ }
322336 case * plan.Project :
323337 project = n
338+ orderBy = nil
339+ case * plan.Sort :
340+ orderBy = n
324341 }
325342 return true
326343 })
@@ -351,42 +368,56 @@ func getEqualsDependencies(expr sql.Expression) []sql.Expression {
351368
352369// getSelectExprs transforms the projection expressions from a Project node such that it uses the appropriate select
353370// dependency expressions.
354- func getSelectExprs (project * plan.Project , selectDeps []sql.Expression , groupBys map [string ]bool ) []sql.Expression {
355- if project == nil {
356- return selectDeps
371+ func getSelectAndOrderByExprs (project * plan.Project , orderBy * plan. Sort , selectDeps []sql.Expression , groupBys map [string ]bool ) ( []sql.Expression , []sql. Expression ) {
372+ if project == nil && orderBy == nil {
373+ return selectDeps , nil
357374 } else {
358375 sd := make (map [string ]sql.Expression , len (selectDeps ))
359376 for _ , dep := range selectDeps {
360377 sd [strings .ToLower (dep .String ())] = dep
361378 }
362379
363380 selectExprs := make ([]sql.Expression , 0 )
381+ orderByExprs := make ([]sql.Expression , 0 )
364382
365383 for _ , expr := range project .Projections {
366384 if ! project .AliasDeps [strings .ToLower (expr .String ())] {
367- resolvedExpr , _ , _ := transform .Expr (expr , func (expr sql.Expression ) (sql.Expression , transform.TreeIdentity , error ) {
368- if groupBys [strings .ToLower (expr .String ())] {
369- return expr , transform .SameTree , nil
370- }
371- switch expr := expr .(type ) {
372- case * expression.Alias :
373- if dep , ok := sd [strings .ToLower (expr .Child .String ())]; ok {
374- return dep , transform .NewTree , nil
375- }
376- case * expression.GetField :
377- if dep , ok := sd [strings .ToLower (expr .String ())]; ok {
378- return dep , transform .NewTree , nil
379- }
380- }
381- return expr , transform .SameTree , nil
382- })
385+ resolvedExpr := resolveExpr (expr , sd , groupBys )
383386 selectExprs = append (selectExprs , resolvedExpr )
384387 }
385388 }
386- return selectExprs
389+
390+ if orderBy != nil {
391+ for _ , expr := range orderBy .Expressions () {
392+ resolvedExpr := resolveExpr (expr , sd , groupBys )
393+ orderByExprs = append (orderByExprs , resolvedExpr )
394+ }
395+ }
396+
397+ return selectExprs , orderByExprs
387398 }
388399}
389400
401+ func resolveExpr (expr sql.Expression , selectDeps map [string ]sql.Expression , groupBys map [string ]bool ) sql.Expression {
402+ resolvedExpr , _ , _ := transform .Expr (expr , func (expr sql.Expression ) (sql.Expression , transform.TreeIdentity , error ) {
403+ if groupBys [strings .ToLower (expr .String ())] {
404+ return expr , transform .SameTree , nil
405+ }
406+ switch expr := expr .(type ) {
407+ case * expression.Alias :
408+ if dep , ok := selectDeps [strings .ToLower (expr .Child .String ())]; ok {
409+ return dep , transform .NewTree , nil
410+ }
411+ case * expression.GetField :
412+ if dep , ok := selectDeps [strings .ToLower (expr .String ())]; ok {
413+ return dep , transform .NewTree , nil
414+ }
415+ }
416+ return expr , transform .SameTree , nil
417+ })
418+ return resolvedExpr
419+ }
420+
390421// expressionReferencesOnlyGroupBys validates that an expression is dependent on only group by expressions
391422func expressionReferencesOnlyGroupBys (groupBys map [string ]bool , expr sql.Expression , noGroupBy bool ) (bool , string ) {
392423 var col string
0 commit comments