From 8de0fd60c5cbb89d0b1d554492c45b72278e6708 Mon Sep 17 00:00:00 2001 From: pingcap-github-bot Date: Tue, 23 Jul 2019 15:31:10 +0800 Subject: [PATCH] planner: correct the generation of the field name (#11324) (#11379) --- executor/executor_test.go | 7 +++++++ planner/core/logical_plan_builder.go | 18 ++++++++++-------- 2 files changed, 17 insertions(+), 8 deletions(-) diff --git a/executor/executor_test.go b/executor/executor_test.go index ec749e4b229b2..b08f4cd093581 100644 --- a/executor/executor_test.go +++ b/executor/executor_test.go @@ -2115,6 +2115,13 @@ func (s *testSuite) TestColumnName(c *C) { c.Assert(fields[1].ColumnAsName.L, Equals, "num") tk.MustExec("set @@tidb_enable_window_function = 0") rs.Close() + + rs, err = tk.Exec("select if(1,c,c) from t;") + c.Check(err, IsNil) + fields = rs.Fields() + c.Assert(fields[0].Column.Name.L, Equals, "if(1,c,c)") + // It's a compatibility issue. Should be empty instead. + c.Assert(fields[0].ColumnAsName.L, Equals, "if(1,c,c)") } func (s *testSuite) TestSelectVar(c *C) { diff --git a/planner/core/logical_plan_builder.go b/planner/core/logical_plan_builder.go index bfbebb17ac07a..46274ba031678 100644 --- a/planner/core/logical_plan_builder.go +++ b/planner/core/logical_plan_builder.go @@ -600,12 +600,10 @@ func (b *PlanBuilder) buildSelection(p LogicalPlan, where ast.ExprNode, AggMappe } // buildProjectionFieldNameFromColumns builds the field name, table name and database name when field expression is a column reference. -func (b *PlanBuilder) buildProjectionFieldNameFromColumns(field *ast.SelectField, c *expression.Column) (colName, origColName, tblName, origTblName, dbName model.CIStr) { - if astCol, ok := getInnerFromParenthesesAndUnaryPlus(field.Expr).(*ast.ColumnNameExpr); ok { - origColName, tblName, dbName = astCol.Name.Name, astCol.Name.Table, astCol.Name.Schema - } - if field.AsName.L != "" { - colName = field.AsName +func (b *PlanBuilder) buildProjectionFieldNameFromColumns(origField *ast.SelectField, colNameField *ast.ColumnNameExpr, c *expression.Column) (colName, origColName, tblName, origTblName, dbName model.CIStr) { + origColName, tblName, dbName = colNameField.Name.Name, colNameField.Name.Table, colNameField.Name.Schema + if origField.AsName.L != "" { + colName = origField.AsName } else { colName = origColName } @@ -686,9 +684,13 @@ func (b *PlanBuilder) buildProjectionFieldNameFromExpressions(field *ast.SelectF // buildProjectionField builds the field object according to SelectField in projection. func (b *PlanBuilder) buildProjectionField(id, position int, field *ast.SelectField, expr expression.Expression) (*expression.Column, error) { var origTblName, tblName, origColName, colName, dbName model.CIStr - if c, ok := expr.(*expression.Column); ok && !c.IsReferenced { + innerNode := getInnerFromParenthesesAndUnaryPlus(field.Expr) + col, isCol := expr.(*expression.Column) + // Correlated column won't affect the final output names. So we can put it in any of the three logic block. + // Don't put it into the first block just for simplifying the codes. + if colNameField, ok := innerNode.(*ast.ColumnNameExpr); ok && isCol { // Field is a column reference. - colName, origColName, tblName, origTblName, dbName = b.buildProjectionFieldNameFromColumns(field, c) + colName, origColName, tblName, origTblName, dbName = b.buildProjectionFieldNameFromColumns(field, colNameField, col) } else if field.AsName.L != "" { // Field has alias. colName = field.AsName