@@ -235,6 +235,8 @@ func validateDeleteFrom(ctx *sql.Context, a *Analyzer, n sql.Node, scope *plan.S
235235 }
236236}
237237
238+ // validateGroupBy makes sure that all selected expressions are functionally dependent on group by expressions when
239+ // ONLY_FULL_GROUP_BY mode is on https://dev.mysql.com/doc/refman/8.4/en/group-by-functional-dependence.html
238240func validateGroupBy (ctx * sql.Context , a * Analyzer , n sql.Node , scope * plan.Scope , sel RuleSelector , qFlags * sql.QueryFlags ) (sql.Node , transform.TreeIdentity , error ) {
239241 if ! FlagIsSet (qFlags , sql .QFlagAggregation ) {
240242 return n , transform .SameTree , nil
@@ -250,13 +252,11 @@ func validateGroupBy(ctx *sql.Context, a *Analyzer, n sql.Node, scope *plan.Scop
250252
251253 var err error
252254 var project * plan.Project
253- var having * plan.Having
254255 transform .Inspect (n , func (n sql.Node ) bool {
255- // Allow the parser use the GroupBy node to eval the aggregation functions
256- // for sql statements that don't make use of the GROUP BY expression.
257256 switch n := n .(type ) {
258257 case * plan.GroupBy :
259-
258+ // Allow the parser use the GroupBy node to eval the aggregation functions for sql statements that don't
259+ // make use of the GROUP BY expression.
260260 if len (n .GroupByExprs ) == 0 {
261261 return true
262262 }
@@ -273,9 +273,6 @@ func validateGroupBy(ctx *sql.Context, a *Analyzer, n sql.Node, scope *plan.Scop
273273 isJoin := false
274274 exprs := make ([]sql.Expression , 0 )
275275 exprs = append (exprs , n .GroupByExprs ... )
276- if having != nil {
277- exprs = append (exprs , getEqualsDependencies (having .Cond )... )
278- }
279276 possibleJoin := n .Child
280277 if filter , ok := n .Child .(* plan.Filter ); ok {
281278 possibleJoin = filter .Child
@@ -319,15 +316,14 @@ func validateGroupBy(ctx *sql.Context, a *Analyzer, n sql.Node, scope *plan.Scop
319316 }
320317 case * plan.Project :
321318 project = n
322- case * plan.Having :
323- having = n
324319 }
325320 return true
326321 })
327322
328323 return n , transform .SameTree , err
329324}
330325
326+ // getEqualsDependencies looks for Equals expressions and gets any non-literal arguments
331327func getEqualsDependencies (expr sql.Expression ) []sql.Expression {
332328 exprs := make ([]sql.Expression , 0 )
333329 sql .Inspect (expr , func (expr sql.Expression ) bool {
@@ -348,6 +344,8 @@ func getEqualsDependencies(expr sql.Expression) []sql.Expression {
348344 return exprs
349345}
350346
347+ // getSelectExprs transforms the projection expressions from a Project node such that it uses the appropriate select
348+ // dependency expressions.
351349func getSelectExprs (project * plan.Project , selectDeps []sql.Expression , groupBys map [string ]bool ) []sql.Expression {
352350 if project == nil {
353351 return selectDeps
@@ -384,6 +382,7 @@ func getSelectExprs(project *plan.Project, selectDeps []sql.Expression, groupBys
384382 }
385383}
386384
385+ // expressionReferencesOnlyGroupBys validates that an expression is dependent on only group by expressions
387386func expressionReferencesOnlyGroupBys (groupBys map [string ]bool , expr sql.Expression ) bool {
388387 valid := true
389388 sql .Inspect (expr , func (expr sql.Expression ) bool {
0 commit comments