diff --git a/go/vt/vtgate/planbuilder/select.go b/go/vt/vtgate/planbuilder/select.go index 78ebcf3cc92..9bba8902fa0 100644 --- a/go/vt/vtgate/planbuilder/select.go +++ b/go/vt/vtgate/planbuilder/select.go @@ -130,47 +130,46 @@ func (pb *primitiveBuilder) processSelect(sel *sqlparser.Select, outer *symtab) } func tryAtVtgate(sel *sqlparser.Select) engine.Primitive { - if checkForDual(sel) { + dual := isOnlyDual(sel.From) + if !dual { + return nil + } + + exprs := make([]evalengine.Expr, len(sel.SelectExprs)) + cols := make([]string, len(sel.SelectExprs)) + for i, e := range sel.SelectExprs { + expr, ok := e.(*sqlparser.AliasedExpr) + if !ok { + return nil + } var err error - exprs := make([]evalengine.Expr, len(sel.SelectExprs)) - cols := make([]string, len(sel.SelectExprs)) - for i, e := range sel.SelectExprs { - expr := e.(*sqlparser.AliasedExpr) - exprs[i], err = sqlparser.Convert(expr.Expr) - if err != nil { - return nil - } - cols[i] = expr.As.String() + exprs[i], err = sqlparser.Convert(expr.Expr) + if err != nil { + return nil } - return &engine.Projection{ - Exprs: exprs, - Cols: cols, - Input: &engine.SingleRow{}, + cols[i] = expr.As.String() + if cols[i] == "" { + cols[i] = sqlparser.String(expr.Expr) } } - return nil + return &engine.Projection{ + Exprs: exprs, + Cols: cols, + Input: &engine.SingleRow{}, + } } -func checkForDual(sel *sqlparser.Select) bool { - if len(sel.From) == 1 { - if from, ok := sel.From[0].(*sqlparser.AliasedTableExpr); ok { - if tableName, ok := from.Expr.(sqlparser.TableName); ok { - if tableName.Name.String() == "dual" && tableName.Qualifier.IsEmpty() { - for _, expr := range sel.SelectExprs { - e, ok := expr.(*sqlparser.AliasedExpr) - if !ok { - return false - } - if _, ok := e.Expr.(*sqlparser.SQLVal); !ok { - return false - } - } - return true - } - } - } +func isOnlyDual(from sqlparser.TableExprs) bool { + if len(from) > 1 { + return false + } + table, ok := from[0].(*sqlparser.AliasedTableExpr) + if !ok { + return false } - return false + tableName, ok := table.Expr.(sqlparser.TableName) + + return ok && tableName.Name.String() == "dual" && tableName.Qualifier.IsEmpty() } // pushFilter identifies the target route for the specified bool expr, diff --git a/go/vt/vtgate/planbuilder/testdata/select_cases.txt b/go/vt/vtgate/planbuilder/testdata/select_cases.txt index c4bc3f25327..6de724de00e 100644 --- a/go/vt/vtgate/planbuilder/testdata/select_cases.txt +++ b/go/vt/vtgate/planbuilder/testdata/select_cases.txt @@ -1365,7 +1365,7 @@ "OperatorType": "Projection", "Variant": "", "Columns": [ - "" + "42" ], "Expressions": [ "INT64(42)" @@ -1378,3 +1378,26 @@ ] } } + +# testing SingleRow Projection with arithmetics +"select 42+2" +{ + "QueryType": "SELECT", + "Original": "select 42+2", + "Instructions": { + "OperatorType": "Projection", + "Variant": "", + "Columns": [ + "42 + 2" + ], + "Expressions": [ + "INT64(42) + INT64(2)" + ], + "Inputs": [ + { + "OperatorType": "SingleRow", + "Variant": "" + } + ] + } +}