From f048fc7ac5b5760700811718ca680971d9ecc825 Mon Sep 17 00:00:00 2001 From: ti-srebot <66930949+ti-srebot@users.noreply.github.com> Date: Fri, 24 Jul 2020 18:01:40 +0800 Subject: [PATCH] planner: resolveFromPlan when tbl.col in havingClause (#18349) (#18432) --- planner/core/logical_plan_builder.go | 22 +++++++++++++++++----- planner/core/logical_plan_test.go | 16 ++++++++++++++++ 2 files changed, 33 insertions(+), 5 deletions(-) diff --git a/planner/core/logical_plan_builder.go b/planner/core/logical_plan_builder.go index fe7b753a446cd..5ed83fb47d7dd 100644 --- a/planner/core/logical_plan_builder.go +++ b/planner/core/logical_plan_builder.go @@ -1225,7 +1225,6 @@ type havingWindowAndOrderbyExprResolver struct { inWindowFunc bool inWindowSpec bool inExpr bool - orderBy bool err error p LogicalPlan selectFields []*ast.SelectField @@ -1311,10 +1310,10 @@ func (a *havingWindowAndOrderbyExprResolver) Leave(n ast.Node) (node ast.Node, o a.inWindowSpec = false case *ast.ColumnNameExpr: resolveFieldsFirst := true - if a.inAggFunc || a.inWindowFunc || a.inWindowSpec || (a.orderBy && a.inExpr) || a.curClause == fieldList { + if a.inAggFunc || a.inWindowFunc || a.inWindowSpec || (a.curClause == orderByClause && a.inExpr) || a.curClause == fieldList { resolveFieldsFirst = false } - if !a.inAggFunc && !a.orderBy { + if !a.inAggFunc && a.curClause != orderByClause { for _, item := range a.gbyItems { if col, ok := item.Expr.(*ast.ColumnNameExpr); ok && (colMatch(v.Name, col.Name) || colMatch(col.Name, v.Name)) { @@ -1334,8 +1333,22 @@ func (a *havingWindowAndOrderbyExprResolver) Leave(n ast.Node) (node ast.Node, o return node, false } if index == -1 { - if a.orderBy { + if a.curClause == orderByClause { index, a.err = a.resolveFromSchema(v, a.p.Schema()) + } else if a.curClause == havingClause && v.Name.Table.L != "" { + // For SQLs like: + // select a from t b having b.a; + index, a.err = a.resolveFromSchema(v, a.p.Schema()) + if a.err != nil { + return node, false + } + if index != -1 { + // For SQLs like: + // select a+1 from t having t.a; + newV := v + newV.Name = &ast.ColumnName{Name: v.Name.Name} + index, a.err = resolveFromSelectFields(newV, a.selectFields, true) + } } else { index, a.err = resolveFromSelectFields(v, a.selectFields, true) } @@ -1406,7 +1419,6 @@ func (b *PlanBuilder) resolveHavingAndOrderBy(sel *ast.SelectStmt, p LogicalPlan } havingAggMapper := extractor.aggMapper extractor.aggMapper = make(map[*ast.AggregateFuncExpr]int) - extractor.orderBy = true extractor.inExpr = false // Extract agg funcs from order by clause. if sel.OrderBy != nil { diff --git a/planner/core/logical_plan_test.go b/planner/core/logical_plan_test.go index 1ef2d35c672d0..7d142fb696057 100644 --- a/planner/core/logical_plan_test.go +++ b/planner/core/logical_plan_test.go @@ -1466,6 +1466,22 @@ func (s *testPlanSuite) TestValidate(c *C) { sql: "select concat(c_str, d_str) from t group by `concat(c_str,d_str)`", err: ErrUnknownColumn, }, + { + sql: "select a from t b having b.a", + err: nil, + }, + { + sql: "select b.a from t b having b.a", + err: nil, + }, + { + sql: "select b.a from t b having a", + err: nil, + }, + { + sql: "select a+1 from t having t.a", + err: ErrUnknownColumn, + }, } ctx := context.Background()