Skip to content

Commit 4c91f53

Browse files
authored
planner: do not eliminate group_concat in aggregate elimination (#9967)
1 parent bab9e90 commit 4c91f53

File tree

4 files changed

+36
-0
lines changed

4 files changed

+36
-0
lines changed

cmd/explaintest/r/explain.result

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,3 +22,18 @@ c1 timestamp YES NULL
2222
desc t id;
2323
Field Type Null Key Default Extra
2424
id int(11) YES NULL
25+
drop table if exists t;
26+
create table t(id int primary key, a int, b int);
27+
explain select group_concat(a) from t group by id;
28+
id count task operator info
29+
StreamAgg_8 8000.00 root group by:col_1, funcs:group_concat(col_0, ",")
30+
└─Projection_18 10000.00 root cast(test.t.a), test.t.id
31+
└─TableReader_15 10000.00 root data:TableScan_14
32+
└─TableScan_14 10000.00 cop table:t, range:[-inf,+inf], keep order:true, stats:pseudo
33+
explain select group_concat(a, b) from t group by id;
34+
id count task operator info
35+
StreamAgg_8 8000.00 root group by:col_2, funcs:group_concat(col_0, col_1, ",")
36+
└─Projection_18 10000.00 root cast(test.t.a), cast(test.t.b), test.t.id
37+
└─TableReader_15 10000.00 root data:TableScan_14
38+
└─TableScan_14 10000.00 cop table:t, range:[-inf,+inf], keep order:true, stats:pseudo
39+
drop table t;

cmd/explaintest/t/explain.test

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,3 +6,9 @@ describe t;
66
desc t;
77
desc t c1;
88
desc t id;
9+
10+
drop table if exists t;
11+
create table t(id int primary key, a int, b int);
12+
explain select group_concat(a) from t group by id;
13+
explain select group_concat(a, b) from t group by id;
14+
drop table t;

executor/aggregate_test.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -584,6 +584,7 @@ func (s *testSuite1) TestAggEliminator(c *C) {
584584
tk.MustQuery("select min(b) from t").Check(testkit.Rows("-2"))
585585
tk.MustQuery("select max(b*b) from t").Check(testkit.Rows("4"))
586586
tk.MustQuery("select min(b*b) from t").Check(testkit.Rows("1"))
587+
tk.MustQuery("select group_concat(b, b) from t group by a").Check(testkit.Rows("-1-1", "-2-2", "11", "<nil>"))
587588
}
588589

589590
func (s *testSuite1) TestMaxMinFloatScalaFunc(c *C) {

planner/core/rule_aggregation_elimination.go

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,20 @@ type aggregationEliminateChecker struct {
3636
// For count(expr), sum(expr), avg(expr), count(distinct expr, [expr...]) we may need to rewrite the expr. Details are shown below.
3737
// If we can eliminate agg successful, we return a projection. Else we return a nil pointer.
3838
func (a *aggregationEliminateChecker) tryToEliminateAggregation(agg *LogicalAggregation) *LogicalProjection {
39+
for _, af := range agg.AggFuncs {
40+
// TODO(issue #9968): Actually, we can rewrite GROUP_CONCAT when all the
41+
// arguments it accepts are promised to be NOT-NULL.
42+
// When it accepts only 1 argument, we can extract this argument into a
43+
// projection.
44+
// When it accepts multiple arguments, we can wrap the arguments with a
45+
// function CONCAT_WS and extract this function into a projection.
46+
// BUT, GROUP_CONCAT should truncate the final result according to the
47+
// system variable `group_concat_max_len`. To ensure the correctness of
48+
// the result, we close the elimination of GROUP_CONCAT here.
49+
if af.Name == ast.AggFuncGroupConcat {
50+
return nil
51+
}
52+
}
3953
schemaByGroupby := expression.NewSchema(agg.groupByCols...)
4054
coveredByUniqueKey := false
4155
for _, key := range agg.children[0].Schema().Keys {

0 commit comments

Comments
 (0)