Skip to content

Commit

Permalink
planner/core: correct column name with unary plus sign (#8702) (#16149)
Browse files Browse the repository at this point in the history
  • Loading branch information
sre-bot authored Apr 8, 2020
1 parent 4f03354 commit a238da8
Show file tree
Hide file tree
Showing 3 changed files with 26 additions and 11 deletions.
2 changes: 1 addition & 1 deletion cmd/explaintest/r/select.result
Original file line number Diff line number Diff line change
Expand Up @@ -137,7 +137,7 @@ select !(1 + 2);
!(1 + 2)
0
select + - 1, --1, +-+-+1, + "123";
+ - 1 --1 +-+-+1 + "123"
+ - 1 --1 +-+-+1 123
-1 1 1 123
select --------------------1, ++++++++++++++++++++1;
--------------------1 ++++++++++++++++++++1
Expand Down
10 changes: 10 additions & 0 deletions executor/executor_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2072,6 +2072,16 @@ func (s *testSuiteP2) TestColumnName(c *C) {
// It's a compatibility issue. Should be empty instead.
c.Assert(fields[0].ColumnAsName.L, Equals, "if(1,c,c)")
rs.Close()

// Test case for query a column wrapped with parentheses and unary plus.
// In this case, the column name should be its original name.
rs, err = tk.Exec("select (c), (+c), +(c), +(+(c)), ++c from t")
c.Check(err, IsNil)
fields = rs.Fields()
for i := 0; i < 5; i++ {
c.Check(fields[0].Column.Name.L, Equals, "c")
c.Check(fields[0].ColumnAsName.L, Equals, "c")
}
}

func (s *testSuiteP2) TestSelectVar(c *C) {
Expand Down
25 changes: 15 additions & 10 deletions planner/core/logical_plan_builder.go
Original file line number Diff line number Diff line change
Expand Up @@ -557,10 +557,12 @@ 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(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
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
} else {
colName = origColName
}
Expand All @@ -580,7 +582,7 @@ func (b *planBuilder) buildProjectionFieldNameFromExpressions(field *ast.SelectF
return agg.Args[0].(*ast.ColumnNameExpr).Name.Name
}

innerExpr := getInnerFromParentheses(field.Expr)
innerExpr := getInnerFromParenthesesAndUnaryPlus(field.Expr)
valueExpr, isValueExpr := innerExpr.(*driver.ValueExpr)

// Non-literal: Output as inputed, except that comments need to be removed.
Expand Down Expand Up @@ -617,13 +619,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 {
var origTblName, tblName, origColName, colName, dbName model.CIStr
innerNode := getInnerFromParentheses(field.Expr)
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 {
if _, ok := innerNode.(*ast.ColumnNameExpr); ok && isCol {
// Field is a column reference.
colName, origColName, tblName, origTblName, dbName = b.buildProjectionFieldNameFromColumns(field, colNameField, col)
colName, origColName, tblName, origTblName, dbName = b.buildProjectionFieldNameFromColumns(field, col)
} else if field.AsName.L != "" {
// Field has alias.
colName = field.AsName
Expand Down Expand Up @@ -2576,9 +2578,12 @@ func appendVisitInfo(vi []visitInfo, priv mysql.PrivilegeType, db, tbl, col stri
})
}

func getInnerFromParentheses(expr ast.ExprNode) ast.ExprNode {
func getInnerFromParenthesesAndUnaryPlus(expr ast.ExprNode) ast.ExprNode {
if pexpr, ok := expr.(*ast.ParenthesesExpr); ok {
return getInnerFromParentheses(pexpr.Expr)
return getInnerFromParenthesesAndUnaryPlus(pexpr.Expr)
}
if uexpr, ok := expr.(*ast.UnaryOperationExpr); ok && uexpr.Op == opcode.Plus {
return getInnerFromParenthesesAndUnaryPlus(uexpr.V)
}
return expr
}

0 comments on commit a238da8

Please sign in to comment.