Skip to content

Commit 7b0c698

Browse files
vitess-bot[bot]vitess-bot
authored andcommitted
bugfix: add HAVING columns inside derived tables (#16976)
Signed-off-by: Andres Taylor <[email protected]>
1 parent b4780ce commit 7b0c698

File tree

4 files changed

+103
-31
lines changed

4 files changed

+103
-31
lines changed

go/test/endtoend/vtgate/vitess_tester/aggregation/aggregation.test

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -61,4 +61,7 @@ from (select 1 as one
6161

6262
select u.id, u.t1_id, t.num_segments
6363
from (select id, count(*) as num_segments from t1 group by 1 order by 2 desc limit 20) t
64-
join t2 u on u.id = t.id;
64+
join t2 u on u.id = t.id;
65+
66+
select name
67+
from (select name from t1 group by name having count(t1.id) > 1) t1;

go/vt/vtgate/planbuilder/operators/horizon_expanding.go

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,12 @@ func expandSelectHorizon(ctx *plancontext.PlanningContext, horizon *Horizon, sel
7878
for _, order := range horizon.Query.GetOrderBy() {
7979
qp.addDerivedColumn(ctx, order.Expr)
8080
}
81+
sel, isSel := horizon.Query.(*sqlparser.Select)
82+
if isSel && sel.Having != nil {
83+
for _, pred := range sqlparser.SplitAndExpression(nil, sel.Having.Expr) {
84+
qp.addDerivedColumn(ctx, pred)
85+
}
86+
}
8187
}
8288

8389
op := createProjectionFromSelect(ctx, horizon)

go/vt/vtgate/planbuilder/testdata/aggr_cases.json

Lines changed: 61 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -615,6 +615,35 @@
615615
]
616616
}
617617
},
618+
{
619+
"comment": "using HAVING inside a derived table still produces viable plans",
620+
"query": "select id from (select id from user group by id having (count(user.id) = 2) limit 2 offset 0) subquery_for_limit",
621+
"plan": {
622+
"QueryType": "SELECT",
623+
"Original": "select id from (select id from user group by id having (count(user.id) = 2) limit 2 offset 0) subquery_for_limit",
624+
"Instructions": {
625+
"OperatorType": "Limit",
626+
"Count": "2",
627+
"Offset": "0",
628+
"Inputs": [
629+
{
630+
"OperatorType": "Route",
631+
"Variant": "Scatter",
632+
"Keyspace": {
633+
"Name": "user",
634+
"Sharded": true
635+
},
636+
"FieldQuery": "select id from (select id, count(`user`.id) = 2 from `user` where 1 != 1 group by id) as subquery_for_limit where 1 != 1",
637+
"Query": "select id from (select id, count(`user`.id) = 2 from `user` group by id having count(`user`.id) = 2) as subquery_for_limit limit 2",
638+
"Table": "`user`"
639+
}
640+
]
641+
},
642+
"TablesUsed": [
643+
"user.user"
644+
]
645+
}
646+
},
618647
{
619648
"comment": "sum with distinct no unique vindex",
620649
"query": "select col1, sum(distinct col2) from user group by col1",
@@ -3774,25 +3803,42 @@
37743803
"QueryType": "SELECT",
37753804
"Original": "select * from (select id from user having count(*) = 1) s",
37763805
"Instructions": {
3777-
"OperatorType": "Filter",
3778-
"Predicate": "count(*) = 1",
3779-
"ResultColumns": 1,
3806+
"OperatorType": "SimpleProjection",
3807+
"ColumnNames": [
3808+
"0:id"
3809+
],
3810+
"Columns": "0",
37803811
"Inputs": [
37813812
{
3782-
"OperatorType": "Aggregate",
3783-
"Variant": "Scalar",
3784-
"Aggregates": "any_value(0) AS id, sum_count_star(1) AS count(*)",
3813+
"OperatorType": "Projection",
3814+
"Expressions": [
3815+
":0 as id",
3816+
"count(*) = 1 as count(*) = 1"
3817+
],
37853818
"Inputs": [
37863819
{
3787-
"OperatorType": "Route",
3788-
"Variant": "Scatter",
3789-
"Keyspace": {
3790-
"Name": "user",
3791-
"Sharded": true
3792-
},
3793-
"FieldQuery": "select id, count(*) from `user` where 1 != 1",
3794-
"Query": "select id, count(*) from `user`",
3795-
"Table": "`user`"
3820+
"OperatorType": "Filter",
3821+
"Predicate": "count(*) = 1",
3822+
"Inputs": [
3823+
{
3824+
"OperatorType": "Aggregate",
3825+
"Variant": "Scalar",
3826+
"Aggregates": "any_value(0) AS id, sum_count_star(1) AS count(*), any_value(2)",
3827+
"Inputs": [
3828+
{
3829+
"OperatorType": "Route",
3830+
"Variant": "Scatter",
3831+
"Keyspace": {
3832+
"Name": "user",
3833+
"Sharded": true
3834+
},
3835+
"FieldQuery": "select id, count(*), 1 from `user` where 1 != 1",
3836+
"Query": "select id, count(*), 1 from `user`",
3837+
"Table": "`user`"
3838+
}
3839+
]
3840+
}
3841+
]
37963842
}
37973843
]
37983844
}

go/vt/vtgate/planbuilder/testdata/cte_cases.json

Lines changed: 32 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -379,25 +379,42 @@
379379
"QueryType": "SELECT",
380380
"Original": "with s as (select id from user having count(*) = 1) select * from s",
381381
"Instructions": {
382-
"OperatorType": "Filter",
383-
"Predicate": "count(*) = 1",
384-
"ResultColumns": 1,
382+
"OperatorType": "SimpleProjection",
383+
"ColumnNames": [
384+
"0:id"
385+
],
386+
"Columns": "0",
385387
"Inputs": [
386388
{
387-
"OperatorType": "Aggregate",
388-
"Variant": "Scalar",
389-
"Aggregates": "any_value(0) AS id, sum_count_star(1) AS count(*)",
389+
"OperatorType": "Projection",
390+
"Expressions": [
391+
":0 as id",
392+
"count(*) = 1 as count(*) = 1"
393+
],
390394
"Inputs": [
391395
{
392-
"OperatorType": "Route",
393-
"Variant": "Scatter",
394-
"Keyspace": {
395-
"Name": "user",
396-
"Sharded": true
397-
},
398-
"FieldQuery": "select id, count(*) from `user` where 1 != 1",
399-
"Query": "select id, count(*) from `user`",
400-
"Table": "`user`"
396+
"OperatorType": "Filter",
397+
"Predicate": "count(*) = 1",
398+
"Inputs": [
399+
{
400+
"OperatorType": "Aggregate",
401+
"Variant": "Scalar",
402+
"Aggregates": "any_value(0) AS id, sum_count_star(1) AS count(*), any_value(2)",
403+
"Inputs": [
404+
{
405+
"OperatorType": "Route",
406+
"Variant": "Scatter",
407+
"Keyspace": {
408+
"Name": "user",
409+
"Sharded": true
410+
},
411+
"FieldQuery": "select id, count(*), 1 from `user` where 1 != 1",
412+
"Query": "select id, count(*), 1 from `user`",
413+
"Table": "`user`"
414+
}
415+
]
416+
}
417+
]
401418
}
402419
]
403420
}

0 commit comments

Comments
 (0)