From 3de369f42d7a4e0b5f904d75fc9ddd6ed7acbc04 Mon Sep 17 00:00:00 2001 From: HuaiyuXu <391585975@qq.com> Date: Wed, 8 Jul 2020 13:53:40 +0800 Subject: [PATCH] cherry pick #18349 to release-4.0 Signed-off-by: ti-srebot --- 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 39bfc45ed3ca6..9b6a3cb7badb6 100644 --- a/planner/core/logical_plan_builder.go +++ b/planner/core/logical_plan_builder.go @@ -1431,7 +1431,6 @@ type havingWindowAndOrderbyExprResolver struct { inWindowFunc bool inWindowSpec bool inExpr bool - orderBy bool err error p LogicalPlan selectFields []*ast.SelectField @@ -1523,10 +1522,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)) { @@ -1546,8 +1545,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.resolveFromPlan(v, a.p) + } else if a.curClause == havingClause && v.Name.Table.L != "" { + // For SQLs like: + // select a from t b having b.a; + index, a.err = a.resolveFromPlan(v, a.p) + 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) } @@ -1619,7 +1632,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 08b380d109715..c32dc29fd3220 100644 --- a/planner/core/logical_plan_test.go +++ b/planner/core/logical_plan_test.go @@ -770,6 +770,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()