parser: support username without quotes (#3742)

This commit is contained in:
Wenxuan Shi
2017-07-14 21:16:24 -05:00
committed by Shen Li
parent d925b59702
commit 76cc17ebf7
4 changed files with 51 additions and 29 deletions

View File

@ -157,7 +157,7 @@ func (s *Scanner) Lex(v *yySymType) int {
return toHex(s, v, lit)
case bitLit:
return toBit(s, v, lit)
case userVar, sysVar, cast, curDate, extract:
case singleAtIdentifier, doubleAtIdentifier, cast, curDate, extract:
v.item = lit
return tok
case null:
@ -387,7 +387,7 @@ func startWithAt(s *Scanner) (tok int, pos Pos, lit string) {
ch1 := s.r.peek()
if isIdentFirstChar(ch1) {
s.r.incAsLongAs(isIdentChar)
tok, lit = userVar, s.r.data(&pos)
tok, lit = singleAtIdentifier, s.r.data(&pos)
} else if ch1 == '@' {
s.r.inc()
stream := s.r.s[pos.Offset+2:]
@ -401,7 +401,7 @@ func startWithAt(s *Scanner) (tok int, pos Pos, lit string) {
}
}
s.r.incAsLongAs(isIdentChar)
tok, lit = sysVar, s.r.data(&pos)
tok, lit = doubleAtIdentifier, s.r.data(&pos)
} else {
tok = at
}

View File

@ -66,15 +66,15 @@ func (s *testLexerSuite) TestSingleCharOther(c *C) {
runTest(c, table)
}
func (s *testLexerSuite) TestSysOrUserVar(c *C) {
func (s *testLexerSuite) TestAtLeadingIdentifier(c *C) {
defer testleak.AfterTest(c)()
table := []testCaseItem{
{"@a_3cbbc", userVar},
{"@a_3cbbc", singleAtIdentifier},
{"@-3cbbc", at},
{"@@global.test", sysVar},
{"@@session.test", sysVar},
{"@@local.test", sysVar},
{"@@test", sysVar},
{"@@global.test", doubleAtIdentifier},
{"@@session.test", doubleAtIdentifier},
{"@@local.test", doubleAtIdentifier},
{"@@test", doubleAtIdentifier},
}
runTest(c, table)
}

View File

@ -47,6 +47,8 @@ import (
%token <ident>
/*yy:token "%c" */ identifier "identifier"
/*yy:token "\"%c\"" */ stringLit "string literal"
singleAtIdentifier "identifier with single leading at"
doubleAtIdentifier "identifier with double leading at"
invalid "a special token never used by parser, used by lexer to indicate error"
hintBegin "hintBegin is a virtual token for optimizer hint grammar"
hintEnd "hintEnd is a virtual token for optimizer hint grammar"
@ -557,8 +559,6 @@ import (
nulleq "<=>"
placeholder "PLACEHOLDER"
rsh ">>"
sysVar "SYS_VAR"
userVar "USER_VAR"
%type <item>
AdminStmt "Check table statement or show ddl statement"
@ -1914,9 +1914,9 @@ NUM:
intLit
Expression:
"USER_VAR" assignmentEq Expression %prec assignmentEq
singleAtIdentifier assignmentEq Expression %prec assignmentEq
{
v := $1.(string)
v := $1
v = strings.TrimPrefix(v, "@")
$$ = &ast.VariableExpr{
Name: v,
@ -1988,9 +1988,9 @@ Factor:
{
$$ = &ast.BinaryOperationExpr{Op: $2.(opcode.Op), L: $1.(ast.ExprNode), R: $3.(ast.ExprNode)}
}
| Factor CompareOp "USER_VAR" assignmentEq PredicateExpr %prec assignmentEq
| Factor CompareOp singleAtIdentifier assignmentEq PredicateExpr %prec assignmentEq
{
v := $3.(string)
v := $3
v = strings.TrimPrefix(v, "@")
variable := &ast.VariableExpr{
Name: v,
@ -4927,9 +4927,9 @@ VariableAssignment:
{
$$ = &ast.VariableAssignment{Name: $2, Value: $4.(ast.ExprNode), IsSystem: true}
}
| "SYS_VAR" eq SetExpr
| doubleAtIdentifier eq SetExpr
{
v := strings.ToLower($1.(string))
v := strings.ToLower($1)
var isGlobal bool
if strings.HasPrefix(v, "@@global.") {
isGlobal = true
@ -4943,15 +4943,15 @@ VariableAssignment:
}
$$ = &ast.VariableAssignment{Name: v, Value: $3.(ast.ExprNode), IsGlobal: isGlobal, IsSystem: true}
}
| "USER_VAR" eq Expression
| singleAtIdentifier eq Expression
{
v := $1.(string)
v := $1
v = strings.TrimPrefix(v, "@")
$$ = &ast.VariableAssignment{Name: v, Value: $3.(ast.ExprNode)}
}
| "USER_VAR" assignmentEq Expression
| singleAtIdentifier assignmentEq Expression
{
v := $1.(string)
v := $1
v = strings.TrimPrefix(v, "@")
$$ = &ast.VariableAssignment{Name: v, Value: $3.(ast.ExprNode)}
}
@ -5005,9 +5005,9 @@ Variable:
SystemVariable | UserVariable
SystemVariable:
"SYS_VAR"
doubleAtIdentifier
{
v := strings.ToLower($1.(string))
v := strings.ToLower($1)
var isGlobal bool
if strings.HasPrefix(v, "@@global.") {
isGlobal = true
@ -5023,21 +5023,25 @@ SystemVariable:
}
UserVariable:
"USER_VAR"
singleAtIdentifier
{
v := $1.(string)
v := $1
v = strings.TrimPrefix(v, "@")
$$ = &ast.VariableExpr{Name: v, IsGlobal: false, IsSystem: false}
}
Username:
stringLit
StringName
{
$$ = $1 + "@%"
$$ = $1.(string) + "@%"
}
| stringLit "AT" stringLit
| StringName "AT" StringName
{
$$ = $1 + "@" + $3
$$ = $1.(string) + "@" + $3.(string)
}
| StringName singleAtIdentifier
{
$$ = $1.(string) + $2
}
UsernameList:

View File

@ -1412,6 +1412,24 @@ func (s *testParserSuite) TestPrivilege(c *C) {
table := []testCase{
// for create user
{`CREATE USER 'test'`, true},
{`CREATE USER test`, true},
{"CREATE USER `test`", true},
{"CREATE USER test-user", false},
{"CREATE USER test.user", false},
{"CREATE USER 'test-user'", true},
{"CREATE USER `test-user`", true},
{"CREATE USER test.user", false},
{"CREATE USER 'test.user'", true},
{"CREATE USER `test.user`", true},
{"CREATE USER uesr1@localhost", true},
{"CREATE USER `uesr1`@localhost", true},
{"CREATE USER uesr1@`localhost`", true},
{"CREATE USER `uesr1`@`localhost`", true},
{"CREATE USER 'uesr1'@localhost", true},
{"CREATE USER uesr1@'localhost'", true},
{"CREATE USER 'uesr1'@'localhost'", true},
{"CREATE USER 'uesr1'@`localhost`", true},
{"CREATE USER `uesr1`@'localhost'", true},
{`CREATE USER IF NOT EXISTS 'root'@'localhost' IDENTIFIED BY 'new-password'`, true},
{`CREATE USER 'root'@'localhost' IDENTIFIED BY 'new-password'`, true},
{`CREATE USER 'root'@'localhost' IDENTIFIED BY PASSWORD 'hashstring'`, true},