-
Notifications
You must be signed in to change notification settings - Fork 5.8k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
plan: fix a bug when 'only_full_group_by' is set in sql_mode #6734
Changes from 3 commits
977b7cb
d13d11e
00f4ef3
3d71d75
a0c7e94
f96eeba
62fe5fc
6515cb4
2e0fa4c
baea970
4a04f0d
1224876
4921233
e6b8d7f
e0d9b9c
8b4e13d
eb23718
375aeab
26af262
35c0ef3
b2122f3
7f9a3ef
b5589a4
2e081e0
a11a30c
ac564c1
35ac5bf
93274e0
c87e4b9
38c0858
2c9317d
e46c082
d961c65
3ba0eeb
883ba84
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -1286,6 +1286,14 @@ func checkExprInGroupBy(p LogicalPlan, expr ast.ExprNode, offset int, loc string | |
} | ||
|
||
func (b *planBuilder) checkOnlyFullGroupBy(p LogicalPlan, fields []*ast.SelectField, orderBy *ast.OrderByClause, gby *ast.GroupByClause, from ast.ResultSetNode, where ast.ExprNode) { | ||
if gby != nil { | ||
b.checkOnlyFullGroupByWithGroupClause(p, fields, orderBy, gby, from, where) | ||
return | ||
} | ||
b.checkOnlyFullGroupByWithOutGroupClause(p, fields) | ||
} | ||
|
||
func (b *planBuilder) checkOnlyFullGroupByWithGroupClause(p LogicalPlan, fields []*ast.SelectField, orderBy *ast.OrderByClause, gby *ast.GroupByClause, from ast.ResultSetNode, where ast.ExprNode) { | ||
gbyCols := make(map[*expression.Column]struct{}, len(fields)) | ||
gbyExprs := make([]ast.ExprNode, 0, len(fields)) | ||
schema := p.Schema() | ||
|
@@ -1342,6 +1350,51 @@ func (b *planBuilder) checkOnlyFullGroupBy(p LogicalPlan, fields []*ast.SelectFi | |
} | ||
} | ||
|
||
func (b *planBuilder) checkOnlyFullGroupByWithOutGroupClause(p LogicalPlan, fields []*ast.SelectField) { | ||
resolver := colResolverForOnlyFullGroupBy{} | ||
//for idx, field := range fields { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Remove the useless comment. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. ok |
||
for idx, field := range fields { | ||
resolver.exprIdx = idx | ||
field.Accept(&resolver) | ||
if err := resolver.Check(); err != nil { | ||
b.err = err | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. ok |
||
return | ||
} | ||
} | ||
} | ||
|
||
type colResolverForOnlyFullGroupBy struct { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Please add comments for it. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. ok |
||
firstNonAggCol *ast.ColumnName | ||
exprIdx int | ||
firstNonAggColIdex int | ||
hasAggFunc bool | ||
} | ||
|
||
func (c *colResolverForOnlyFullGroupBy) Enter(node ast.Node) (ast.Node, bool) { | ||
switch node.(type) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. use There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. ok |
||
case *ast.AggregateFuncExpr: | ||
c.hasAggFunc = true | ||
return node, true | ||
case *ast.ColumnNameExpr: | ||
if c.firstNonAggCol == nil { | ||
c.firstNonAggCol, c.firstNonAggColIdex = node.(*ast.ColumnNameExpr).Name, c.exprIdx | ||
} | ||
return node, true | ||
} | ||
return node, false | ||
} | ||
|
||
func (c *colResolverForOnlyFullGroupBy) Leave(node ast.Node) (ast.Node, bool) { | ||
return node, true | ||
} | ||
|
||
func (c *colResolverForOnlyFullGroupBy) Check() error { | ||
if c.hasAggFunc && c.firstNonAggCol != nil { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. How about There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. No, this situation is not handled by this checker. ColumnRefs in predicates is not affected under this circumstance because predicates are processed prior to aggregations. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. At least, this PR is an improvement. @shenli |
||
return ErrMixOfGroupFuncAndFields.GenByArgs(c.firstNonAggColIdex+1, c.firstNonAggCol.Name.O) | ||
} | ||
return nil | ||
} | ||
|
||
type colResolver struct { | ||
p LogicalPlan | ||
cols map[*expression.Column]struct{} | ||
|
@@ -1512,10 +1565,11 @@ func (b *planBuilder) buildSelect(sel *ast.SelectStmt) LogicalPlan { | |
if b.err != nil { | ||
return nil | ||
} | ||
if b.ctx.GetSessionVars().SQLMode.HasOnlyFullGroupBy() { | ||
b.checkOnlyFullGroupBy(p, sel.Fields.Fields, sel.OrderBy, sel.GroupBy, sel.From.TableRefs, sel.Where) | ||
} | ||
} | ||
if b.ctx.GetSessionVars().SQLMode.HasOnlyFullGroupBy() && sel.From != nil { | ||
b.checkOnlyFullGroupBy(p, sel.Fields.Fields, sel.OrderBy, sel.GroupBy, sel.From.TableRefs, sel.Where) | ||
} | ||
|
||
// We must resolve having and order by clause before build projection, | ||
// because when the query is "select a+1 as b from t having sum(b) < 0", we must replace sum(b) to sum(a+1), | ||
// which only can be done before building projection and extracting Agg functions. | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please check this error.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done. @zimulala PTAL :)