-
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
executor: refine StreamAggExec when child is empty #7002
Merged
Merged
Changes from 11 commits
Commits
Show all changes
13 commits
Select commit
Hold shift + click to select a range
0587a4f
executor: refine StreamAggExec when child is empty
XuHuaiyu 26ac446
Merge branch 'master' of https://github.com/pingcap/tidb into streama…
XuHuaiyu fd7a0d9
address comment
XuHuaiyu 1e34814
Merge branch 'master' into streamagg_defaultval
zz-jason 323b518
test
XuHuaiyu e1eb7f8
fix c
XuHuaiyu 6654d43
Merge branch 'master' of https://github.com/pingcap/tidb into streama…
XuHuaiyu 6404a9f
Merge branch 'streamagg_defaultval' of https://github.com/XuHuaiyu/ti…
XuHuaiyu cb4f289
Merge branch 'master' into streamagg_defaultval
zz-jason 3b95344
address comment
XuHuaiyu 99c842e
Merge branch 'streamagg_defaultval' of https://github.com/XuHuaiyu/ti…
XuHuaiyu 3aa59c8
address comment
XuHuaiyu 1e875f2
Merge branch 'master' into streamagg_defaultval
XuHuaiyu File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -110,39 +110,86 @@ func (a *AggFuncDesc) typeInfer(ctx sessionctx.Context) { | |
} | ||
} | ||
|
||
// CalculateDefaultValue gets the default value when the aggregation function's input is null. | ||
// The input stands for the schema of Aggregation's child. If the function can't produce a default value, the second | ||
// EvalNullValueInOuterJoin gets the null value when the aggregation is upon an outer join, | ||
// and the aggregation function's input is null. | ||
// If there is no matching row for the inner table of an outer join, | ||
// an aggregation function only involves constant and/or columns belongs to the inner table | ||
// will be set to the null value. | ||
// The input stands for the schema of Aggregation's child. If the function can't produce a null value, the second | ||
// return value will be false. | ||
// e.g. | ||
// Table t with only one row: | ||
// +-------+---------+---------+ | ||
// | Table | Field | Type | | ||
// +-------+---------+---------+ | ||
// | t | a | int(11) | | ||
// +-------+---------+---------+ | ||
// +------+ | ||
// | a | | ||
// +------+ | ||
// | 1 | | ||
// +------+ | ||
// | ||
// According to MySQL, DefaultValue of the aggregation function can be tested as the following sql: | ||
// Table s which is empty: | ||
// +-------+---------+---------+ | ||
// | Table | Field | Type | | ||
// +-------+---------+---------+ | ||
// | s | a | int(11) | | ||
// +-------+---------+---------+ | ||
// | ||
// mysql> CREATE TABLE `t` ( | ||
// -> `a` int(11) DEFAULT NULL, | ||
// -> `b` int(11) DEFAULT NULL | ||
// -> ); | ||
// mysql> | ||
// +------+--------+--------+----------+------------+-----------+----------------------+--------+--------+-----------------+ | ||
// | a | avg(a) | sum(a) | count(a) | bit_xor(a) | bit_or(a) | bit_and(a) | max(a) | min(a) | group_concat(a) | | ||
// +------+--------+--------+----------+------------+-----------+----------------------+--------+--------+-----------------+ | ||
// | NULL | NULL | NULL | 0 | 0 | 0 | 18446744073709551615 | NULL | NULL | NULL | | ||
// +------+--------+--------+----------+------------+-----------+----------------------+--------+--------+-----------------+ | ||
// 1 row in set (0.01 sec) | ||
func (a *AggFuncDesc) CalculateDefaultValue(ctx sessionctx.Context, schema *expression.Schema) (types.Datum, bool) { | ||
// Query: `select t.a as `t.a`, count(95), sum(95), avg(95), bit_or(95), bit_and(95), bit_or(95), max(95), min(95), s.a as `s.a`, avg(95) from t left join s on t.a = s.a;` | ||
// +------+-----------+---------+---------+------------+-------------+------------+---------+---------+------+----------+ | ||
// | t.a | count(95) | sum(95) | avg(95) | bit_or(95) | bit_and(95) | bit_or(95) | max(95) | min(95) | s.a | avg(s.a) | | ||
// +------+-----------+---------+---------+------------+-------------+------------+---------+---------+------+----------+ | ||
// | 1 | 1 | 95 | 95.0000 | 95 | 95 | 95 | 95 | 95 | NULL | NULL | | ||
// +------+-----------+---------+---------+------------+-------------+------------+---------+---------+------+----------+ | ||
func (a *AggFuncDesc) EvalNullValueInOuterJoin(ctx sessionctx.Context, schema *expression.Schema) (types.Datum, bool) { | ||
switch a.Name { | ||
case ast.AggFuncCount: | ||
return a.calculateDefaultValue4Count(ctx, schema) | ||
return a.evalNullValueInOuterJoin4Count(ctx, schema) | ||
case ast.AggFuncSum, ast.AggFuncMax, ast.AggFuncMin, | ||
ast.AggFuncFirstRow, ast.AggFuncAvg, ast.AggFuncGroupConcat: | ||
return a.calculateDefaultValue4Sum(ctx, schema) | ||
ast.AggFuncFirstRow: | ||
return a.evalNullValueInOuterJoin4Sum(ctx, schema) | ||
case ast.AggFuncAvg, ast.AggFuncGroupConcat: | ||
return types.Datum{}, false | ||
case ast.AggFuncBitAnd: | ||
return a.calculateDefaultValue4BitAnd(ctx, schema) | ||
return a.evalNullValueInOuterJoin4BitAnd(ctx, schema) | ||
case ast.AggFuncBitOr, ast.AggFuncBitXor: | ||
return a.calculateDefaultValue4BitOr(ctx, schema) | ||
return a.evalNullValueInOuterJoin4BitOr(ctx, schema) | ||
default: | ||
panic("unsupported agg function") | ||
} | ||
} | ||
|
||
// GetDefaultValue gets the default value when the aggregation function's input is null. | ||
// According to MySQL, default values of the aggregation function are listed as follows: | ||
// e.g. | ||
// Table t which is empty: | ||
// +-------+---------+---------+ | ||
// | Table | Field | Type | | ||
// +-------+---------+---------+ | ||
// | t | a | int(11) | | ||
// +-------+---------+---------+ | ||
// | ||
// Query: `select a, avg(a), sum(a), count(a), bit_xor(a), bit_or(a), bit_and(a), max(a), min(a), group_concat(a) from t;` | ||
// +------+--------+--------+----------+------------+-----------+----------------------+--------+--------+-----------------+ | ||
// | a | avg(a) | sum(a) | count(a) | bit_xor(a) | bit_or(a) | bit_and(a) | max(a) | min(a) | group_concat(a) | | ||
// +------+--------+--------+----------+------------+-----------+----------------------+--------+--------+-----------------+ | ||
// | NULL | NULL | NULL | 0 | 0 | 0 | 18446744073709551615 | NULL | NULL | NULL | | ||
// +------+--------+--------+----------+------------+-----------+----------------------+--------+--------+-----------------+ | ||
func (a *AggFuncDesc) GetDefaultValue() (v types.Datum) { | ||
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. Can this function be moved to the |
||
switch a.Name { | ||
case ast.AggFuncCount, ast.AggFuncBitOr, ast.AggFuncBitXor: | ||
v = types.NewIntDatum(0) | ||
case ast.AggFuncFirstRow, ast.AggFuncAvg, ast.AggFuncSum, ast.AggFuncMax, | ||
ast.AggFuncMin, ast.AggFuncGroupConcat: | ||
v = types.Datum{} | ||
case ast.AggFuncBitAnd: | ||
v = types.NewUintDatum(uint64(math.MaxUint64)) | ||
} | ||
return v | ||
} | ||
|
||
// GetAggFunc gets an evaluator according to the aggregation function signature. | ||
func (a *AggFuncDesc) GetAggFunc() Aggregation { | ||
aggFunc := aggFunction{AggFuncDesc: a} | ||
|
@@ -246,11 +293,18 @@ func (a *AggFuncDesc) typeInfer4BitFuncs(ctx sessionctx.Context) { | |
// TODO: a.Args[0] = expression.WrapWithCastAsInt(ctx, a.Args[0]) | ||
} | ||
|
||
func (a *AggFuncDesc) calculateDefaultValue4Count(ctx sessionctx.Context, schema *expression.Schema) (types.Datum, bool) { | ||
return types.NewDatum(0), true | ||
func (a *AggFuncDesc) evalNullValueInOuterJoin4Count(ctx sessionctx.Context, schema *expression.Schema) (types.Datum, bool) { | ||
for _, arg := range a.Args { | ||
result := expression.EvaluateExprWithNull(ctx, schema, arg) | ||
con, ok := result.(*expression.Constant) | ||
if !ok || con.Value.IsNull() { | ||
return types.Datum{}, ok | ||
} | ||
} | ||
return types.NewDatum(1), true | ||
} | ||
|
||
func (a *AggFuncDesc) calculateDefaultValue4Sum(ctx sessionctx.Context, schema *expression.Schema) (types.Datum, bool) { | ||
func (a *AggFuncDesc) evalNullValueInOuterJoin4Sum(ctx sessionctx.Context, schema *expression.Schema) (types.Datum, bool) { | ||
result := expression.EvaluateExprWithNull(ctx, schema, a.Args[0]) | ||
con, ok := result.(*expression.Constant) | ||
if !ok || con.Value.IsNull() { | ||
|
@@ -259,7 +313,7 @@ func (a *AggFuncDesc) calculateDefaultValue4Sum(ctx sessionctx.Context, schema * | |
return con.Value, true | ||
} | ||
|
||
func (a *AggFuncDesc) calculateDefaultValue4BitAnd(ctx sessionctx.Context, schema *expression.Schema) (types.Datum, bool) { | ||
func (a *AggFuncDesc) evalNullValueInOuterJoin4BitAnd(ctx sessionctx.Context, schema *expression.Schema) (types.Datum, bool) { | ||
result := expression.EvaluateExprWithNull(ctx, schema, a.Args[0]) | ||
con, ok := result.(*expression.Constant) | ||
if !ok || con.Value.IsNull() { | ||
|
@@ -268,7 +322,7 @@ func (a *AggFuncDesc) calculateDefaultValue4BitAnd(ctx sessionctx.Context, schem | |
return con.Value, true | ||
} | ||
|
||
func (a *AggFuncDesc) calculateDefaultValue4BitOr(ctx sessionctx.Context, schema *expression.Schema) (types.Datum, bool) { | ||
func (a *AggFuncDesc) evalNullValueInOuterJoin4BitOr(ctx sessionctx.Context, schema *expression.Schema) (types.Datum, bool) { | ||
result := expression.EvaluateExprWithNull(ctx, schema, a.Args[0]) | ||
con, ok := result.(*expression.Constant) | ||
if !ok || con.Value.IsNull() { | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
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.
Why don't check the value of
err
here? If you have any particular reason to do so, is it better you add it here?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.
err is checked in line 892
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.
got it.