diff --git a/go/vt/sqlparser/ast.go b/go/vt/sqlparser/ast.go index 0777d9c3a4f..f99edf0495d 100644 --- a/go/vt/sqlparser/ast.go +++ b/go/vt/sqlparser/ast.go @@ -1544,9 +1544,15 @@ func (node *FuncExpr) Format(buf *TrackedBuffer) { buf.Myprintf("%v.", node.Qualifier) } // Function names should not be back-quoted even - // if they match a reserved word. So, print the - // name as is. - buf.Myprintf("%s(%s%v)", node.Name.String(), distinct, node.Exprs) + // if they match a reserved word, only if they contain illegal characters + funcName := node.Name.String() + + if containEscapableChars(funcName) { + writeEscapedString(buf, funcName) + } else { + buf.WriteString(funcName) + } + buf.Myprintf("(%s%v)", distinct, node.Exprs) } // Format formats the node diff --git a/go/vt/sqlparser/ast_funcs.go b/go/vt/sqlparser/ast_funcs.go index a746301fdce..e1b6c07bec0 100644 --- a/go/vt/sqlparser/ast_funcs.go +++ b/go/vt/sqlparser/ast_funcs.go @@ -631,26 +631,37 @@ func (node *TableIdent) UnmarshalJSON(b []byte) error { return nil } -func formatID(buf *TrackedBuffer, original, lowered string) { +func containEscapableChars(s string) bool { isDbSystemVariable := false - if len(original) > 1 && original[:2] == "@@" { + if len(s) > 1 && s[:2] == "@@" { isDbSystemVariable = true } - for i, c := range original { + for i, c := range s { if !isLetter(uint16(c)) && (!isDbSystemVariable || !isCarat(uint16(c))) { if i == 0 || !isDigit(uint16(c)) { - goto mustEscape + return true } } } - if _, ok := keywords[lowered]; ok { - goto mustEscape + + return false +} + +func isKeyword(s string) bool { + _, isKeyword := keywords[s] + return isKeyword +} + +func formatID(buf *TrackedBuffer, original, lowered string) { + if containEscapableChars(original) || isKeyword(lowered) { + writeEscapedString(buf, original) + } else { + buf.Myprintf("%s", original) } - buf.Myprintf("%s", original) - return +} -mustEscape: +func writeEscapedString(buf *TrackedBuffer, original string) { buf.WriteByte('`') for _, c := range original { buf.WriteRune(c) diff --git a/go/vt/sqlparser/parse_test.go b/go/vt/sqlparser/parse_test.go index c986277f3d2..2ba6a02cf05 100644 --- a/go/vt/sqlparser/parse_test.go +++ b/go/vt/sqlparser/parse_test.go @@ -1523,6 +1523,12 @@ var ( }, { input: "select distinctrow a.* from (select (1) from dual union all select 1 from dual) a", output: "select distinct a.* from (select (1) from dual union all select 1 from dual) as a", + }, { + input: "select `weird function name`() from t", + }, { + input: "select status() from t", // should not escape function names that are keywords + }, { + input: "select * from `weird table name`", }} )