diff --git a/go/test/endtoend/vtgate/vitess_tester/aggregation/aggregation.test b/go/test/endtoend/vtgate/vitess_tester/aggregation/aggregation.test index 8b0997eed1a..93a103a60ed 100644 --- a/go/test/endtoend/vtgate/vitess_tester/aggregation/aggregation.test +++ b/go/test/endtoend/vtgate/vitess_tester/aggregation/aggregation.test @@ -11,6 +11,7 @@ CREATE TABLE `t2` ( `id` bigint unsigned NOT NULL AUTO_INCREMENT, `t1_id` int unsigned NOT NULL, + `col` int unsigned, PRIMARY KEY (`id`) ) ENGINE InnoDB, CHARSET utf8mb4, @@ -31,10 +32,10 @@ values (1, 'A'), (3, 'C'), (4, 'D'); -insert into t2 (id, t1_id) -values (1, 1), - (2, 2), - (3, 3); +insert into t2 (id, t1_id, col) +values (1, 1, 1), + (2, 2, 2), + (3, 3, 3); insert into t3 (id, name) values (1, 'A'), @@ -64,4 +65,10 @@ from (select id, count(*) as num_segments from t1 group by 1 order by 2 desc lim join t2 u on u.id = t.id; select name -from (select name from t1 group by name having count(t1.id) > 1) t1; \ No newline at end of file +from (select name from t1 group by name having count(t1.id) > 1) t1; + +select t1_id +from (select t1_id, col + from t2 + group by 1, 2) t +group by 1; diff --git a/go/vt/vtgate/engine/ordered_aggregate.go b/go/vt/vtgate/engine/ordered_aggregate.go index 324e531c4dd..605cf25bfac 100644 --- a/go/vt/vtgate/engine/ordered_aggregate.go +++ b/go/vt/vtgate/engine/ordered_aggregate.go @@ -103,6 +103,7 @@ func (oa *OrderedAggregate) TryExecute(ctx context.Context, vcursor VCursor, bin return qr.Truncate(oa.TruncateColumnCount), nil } +// executeGroupBy is used when the plan contains grouping but not aggregations func (oa *OrderedAggregate) executeGroupBy(result *sqltypes.Result) (*sqltypes.Result, error) { if len(result.Rows) < 1 { return result, nil diff --git a/go/vt/vtgate/planbuilder/operators/aggregator.go b/go/vt/vtgate/planbuilder/operators/aggregator.go index f353ee02d1e..03ea8e36d8e 100644 --- a/go/vt/vtgate/planbuilder/operators/aggregator.go +++ b/go/vt/vtgate/planbuilder/operators/aggregator.go @@ -292,7 +292,7 @@ func isDerived(op Operator) bool { } func (a *Aggregator) GetColumns(ctx *plancontext.PlanningContext) (res []*sqlparser.AliasedExpr) { - if isDerived(a.Source) { + if isDerived(a.Source) && len(a.Aggregations) > 0 { return truncate(a, a.Columns) } diff --git a/go/vt/vtgate/planbuilder/testdata/aggr_cases.json b/go/vt/vtgate/planbuilder/testdata/aggr_cases.json index 8b268e367dd..ef7f3564788 100644 --- a/go/vt/vtgate/planbuilder/testdata/aggr_cases.json +++ b/go/vt/vtgate/planbuilder/testdata/aggr_cases.json @@ -7406,5 +7406,43 @@ "user.user_extra" ] } + }, + { + "comment": "Group-only Aggregation on top of a derived table should return the correct number of columns", + "query": "select col from (select col, intcol from user group by 1, 2) t group by 1", + "plan": { + "QueryType": "SELECT", + "Original": "select col from (select col, intcol from user group by 1, 2) t group by 1", + "Instructions": { + "OperatorType": "Aggregate", + "Variant": "Ordered", + "GroupBy": "0", + "ResultColumns": 1, + "Inputs": [ + { + "OperatorType": "Aggregate", + "Variant": "Ordered", + "GroupBy": "0, 1", + "Inputs": [ + { + "OperatorType": "Route", + "Variant": "Scatter", + "Keyspace": { + "Name": "user", + "Sharded": true + }, + "FieldQuery": "select col, intcol from `user` where 1 != 1 group by col, intcol", + "OrderBy": "0 ASC, 1 ASC", + "Query": "select col, intcol from `user` group by col, intcol order by col asc, intcol asc", + "Table": "`user`" + } + ] + } + ] + }, + "TablesUsed": [ + "user.user" + ] + } } ]