Skip to content

Commit 1ae91e3

Browse files
[release-18.0] bugfix: add HAVING columns inside derived tables (#16976) (#16977)
Signed-off-by: Andres Taylor <andres@planetscale.com> Co-authored-by: Andrés Taylor <andres@planetscale.com>
1 parent afb135d commit 1ae91e3

File tree

2 files changed

+67
-15
lines changed

2 files changed

+67
-15
lines changed

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

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,12 @@ func expandSelectHorizon(ctx *plancontext.PlanningContext, horizon *Horizon, sel
9090
for _, order := range horizon.Query.GetOrderBy() {
9191
qp.addDerivedColumn(ctx, order.Expr)
9292
}
93+
sel, isSel := horizon.Query.(*sqlparser.Select)
94+
if isSel && sel.Having != nil {
95+
for _, pred := range sqlparser.SplitAndExpression(nil, sel.Having.Expr) {
96+
qp.addDerivedColumn(ctx, pred)
97+
}
98+
}
9399
}
94100

95101
op, err := createProjectionFromSelect(ctx, horizon)
@@ -307,6 +313,7 @@ outer:
307313
func createProjectionForComplexAggregation(a *Aggregator, qp *QueryProjection) (ops.Operator, error) {
308314
p := newAliasedProjection(a)
309315
p.DT = a.DT
316+
a.DT = nil // we don't need the derived table twice
310317
for _, expr := range qp.SelectExprs {
311318
ae, err := expr.GetAliasedExpr()
312319
if err != nil {

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

Lines changed: 60 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -571,6 +571,35 @@
571571
]
572572
}
573573
},
574+
{
575+
"comment": "using HAVING inside a derived table still produces viable plans",
576+
"query": "select id from (select id from user group by id having (count(user.id) = 2) limit 2 offset 0) subquery_for_limit",
577+
"plan": {
578+
"QueryType": "SELECT",
579+
"Original": "select id from (select id from user group by id having (count(user.id) = 2) limit 2 offset 0) subquery_for_limit",
580+
"Instructions": {
581+
"OperatorType": "Limit",
582+
"Count": "INT64(2)",
583+
"Offset": "INT64(0)",
584+
"Inputs": [
585+
{
586+
"OperatorType": "Route",
587+
"Variant": "Scatter",
588+
"Keyspace": {
589+
"Name": "user",
590+
"Sharded": true
591+
},
592+
"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",
593+
"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 :__upper_limit",
594+
"Table": "`user`"
595+
}
596+
]
597+
},
598+
"TablesUsed": [
599+
"user.user"
600+
]
601+
}
602+
},
574603
{
575604
"comment": "sum with distinct no unique vindex",
576605
"query": "select col1, sum(distinct col2) from user group by col1",
@@ -3613,25 +3642,41 @@
36133642
"QueryType": "SELECT",
36143643
"Original": "select * from (select id from user having count(*) = 1) s",
36153644
"Instructions": {
3616-
"OperatorType": "Filter",
3617-
"Predicate": "count(*) = 1",
3618-
"ResultColumns": 1,
3645+
"OperatorType": "SimpleProjection",
3646+
"Columns": [
3647+
0
3648+
],
36193649
"Inputs": [
36203650
{
3621-
"OperatorType": "Aggregate",
3622-
"Variant": "Scalar",
3623-
"Aggregates": "any_value(0) AS id, sum_count_star(1) AS count(*)",
3651+
"OperatorType": "Projection",
3652+
"Expressions": [
3653+
"[COLUMN 0] as id",
3654+
"[COLUMN 1] = [COLUMN 2] as count(*) = 1"
3655+
],
36243656
"Inputs": [
36253657
{
3626-
"OperatorType": "Route",
3627-
"Variant": "Scatter",
3628-
"Keyspace": {
3629-
"Name": "user",
3630-
"Sharded": true
3631-
},
3632-
"FieldQuery": "select id, count(*) from `user` where 1 != 1",
3633-
"Query": "select id, count(*) from `user`",
3634-
"Table": "`user`"
3658+
"OperatorType": "Filter",
3659+
"Predicate": "count(*) = 1",
3660+
"Inputs": [
3661+
{
3662+
"OperatorType": "Aggregate",
3663+
"Variant": "Scalar",
3664+
"Aggregates": "any_value(0) AS id, sum_count_star(1) AS count(*), any_value(2)",
3665+
"Inputs": [
3666+
{
3667+
"OperatorType": "Route",
3668+
"Variant": "Scatter",
3669+
"Keyspace": {
3670+
"Name": "user",
3671+
"Sharded": true
3672+
},
3673+
"FieldQuery": "select id, count(*), 1 from `user` where 1 != 1",
3674+
"Query": "select id, count(*), 1 from `user`",
3675+
"Table": "`user`"
3676+
}
3677+
]
3678+
}
3679+
]
36353680
}
36363681
]
36373682
}

0 commit comments

Comments
 (0)