-
Notifications
You must be signed in to change notification settings - Fork 5.9k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
parser: support sql_mode 'IGNORE SPACE' #5106
Changes from 5 commits
8a4bbe8
694b8c0
8439169
2730b3b
a04a3b2
6276a97
a941c25
fdb6110
e61e76a
2d53514
8380384
6ef56f7
dd69562
763145c
8846cc7
87b62fd
5b75b17
76b4f26
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -25,6 +25,41 @@ import ( | |
|
||
var _ = yyLexer(&Scanner{}) | ||
|
||
var ignoreSpaceFuncMap = map[string]int{ | ||
"adddate": builtinAddDate, | ||
"bit_and": builtinBitAnd, | ||
"bit_or": builtinBitOr, | ||
"bit_xor": builtinBitXor, | ||
"cast": builtinCast, | ||
"count": builtinCount, | ||
"curdate": builtinCurDate, | ||
"curtime": builtinCurTime, | ||
"date_add": builtinDateAdd, | ||
"date_sub": builtinDateSub, | ||
"extract": builtinExtract, | ||
"group_concat": builtinGroupConcat, | ||
"max": builtinMax, | ||
"mid": builtinSubstring, | ||
"min": builtinMin, | ||
"now": builtinNow, | ||
"position": builtinPosition, | ||
"session_user": builtinUser, | ||
"std": builtinStd, | ||
"stddev": builtinStddev, | ||
"stddev_pop": builtinStddevPop, | ||
"stddev_samp": builtinStddevSamp, | ||
"subdate": builtinSubDate, | ||
"substr": builtinSubstring, | ||
"substring": builtinSubstring, | ||
"sum": builtinSum, | ||
"sysdate": builtinSysDate, | ||
"system_user": builtinUser, | ||
"trim": builtinTrim, | ||
"variance": builtinVariance, | ||
"var_Pop": builtinVarPop, | ||
"var_samp": builtinVarSamp, | ||
} | ||
|
||
// Pos represents the position of a token. | ||
type Pos struct { | ||
Line int | ||
|
@@ -435,7 +470,16 @@ func scanIdentifier(s *Scanner) (int, Pos, string) { | |
pos := s.r.pos() | ||
s.r.inc() | ||
s.r.incAsLongAs(isIdentChar) | ||
return identifier, pos, s.r.data(&pos) | ||
lit := s.r.data(&pos) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It's quite performance sensitive here. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @tiancaiamao ok, I'll take a look. thx :) There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @tiancaiamao I've refine this place. PTAL |
||
if t, ok := ignoreSpaceFuncMap[strings.ToLower(lit)]; ok { | ||
if s.sqlMode.HasIgnoreSpaceMode() { | ||
s.skipWhitespace() | ||
} | ||
if s.r.peek() == '(' { | ||
return t, pos, lit | ||
} | ||
} | ||
return identifier, pos, lit | ||
} | ||
|
||
var ( | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -415,6 +415,36 @@ import ( | |
tidbSMJ "TIDB_SMJ" | ||
tidbINLJ "TIDB_INLJ" | ||
|
||
builtinAddDate | ||
builtinBitAnd | ||
builtinBitOr | ||
builtinBitXor | ||
builtinCast | ||
builtinCount | ||
builtinCurDate | ||
builtinCurTime | ||
builtinDateAdd | ||
builtinDateSub | ||
builtinExtract | ||
builtinGroupConcat | ||
builtinMax | ||
builtinMin | ||
builtinNow | ||
builtinPosition | ||
builtinStd | ||
builtinStddev | ||
builtinStddevPop | ||
builtinStddevSamp | ||
builtinSubDate | ||
builtinSubstring | ||
builtinSum | ||
builtinSysDate | ||
builtinTrim | ||
builtinUser | ||
builtinVariance | ||
builtinVarPop | ||
builtinVarSamp | ||
|
||
%token <item> | ||
|
||
/*yy:token "1.%d" */ floatLit "floating-point literal" | ||
|
@@ -1456,7 +1486,7 @@ NowSymOptionFraction: | |
* TODO: Process other three keywords | ||
*/ | ||
NowSymFunc: | ||
"CURRENT_TIMESTAMP" | "LOCALTIME" | "LOCALTIMESTAMP" | "NOW" | ||
"CURRENT_TIMESTAMP" | "LOCALTIME" | "LOCALTIMESTAMP" | builtinNow | ||
NowSym: | ||
"CURRENT_TIMESTAMP" | "LOCALTIME" | "LOCALTIMESTAMP" | ||
|
||
|
@@ -2829,7 +2859,7 @@ SimpleExpr: | |
FunctionType: ast.CastBinaryOperator, | ||
} | ||
} | ||
| "CAST" '(' Expression "AS" CastType ')' | ||
| builtinCast '(' Expression "AS" CastType ')' | ||
{ | ||
/* See https://dev.mysql.com/doc/refman/5.7/en/cast-functions.html#function_cast */ | ||
tp := $5.(*types.FieldType) | ||
|
@@ -2953,7 +2983,7 @@ FunctionNameConflict: | |
| "MICROSECOND" | ||
| "MINUTE" | ||
| "MONTH" | ||
| "NOW" | ||
| builtinNow | ||
| "QUARTER" | ||
| "REPEAT" | ||
| "REPLACE" | ||
|
@@ -2989,10 +3019,18 @@ FunctionCallKeyword: | |
{ | ||
$$ = &ast.FuncCallExpr{FnName: model.NewCIStr($1), Args: $3.([]ast.ExprNode)} | ||
} | ||
| builtinUser '(' ExpressionListOpt ')' | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. keep the code indentation There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @zz-jason ok |
||
{ | ||
$$ = &ast.FuncCallExpr{FnName: model.NewCIStr($1), Args: $3.([]ast.ExprNode)} | ||
} | ||
| FunctionNameOptionalBraces OptionalBraces | ||
{ | ||
$$ = &ast.FuncCallExpr{FnName: model.NewCIStr($1)} | ||
} | ||
| builtinCurDate '(' ')' | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. keep code indentation There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. ok |
||
{ | ||
$$ = &ast.FuncCallExpr{FnName: model.NewCIStr($1)} | ||
} | ||
| FunctionNameDatetimePrecision FuncDatetimePrec | ||
{ | ||
args := []ast.ExprNode{} | ||
|
@@ -3048,7 +3086,11 @@ FunctionCallKeyword: | |
} | ||
|
||
FunctionCallNonKeyword: | ||
"CURTIME" '(' FuncDatetimePrecListOpt ')' | ||
builtinCurTime '(' FuncDatetimePrecListOpt ')' | ||
{ | ||
$$ = &ast.FuncCallExpr{FnName: model.NewCIStr($1), Args: $3.([]ast.ExprNode)} | ||
} | ||
| builtinSysDate '(' FuncDatetimePrecListOpt ')' | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. ditto There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. done |
||
{ | ||
$$ = &ast.FuncCallExpr{FnName: model.NewCIStr($1), Args: $3.([]ast.ExprNode)} | ||
} | ||
|
@@ -3085,7 +3127,7 @@ FunctionCallNonKeyword: | |
}, | ||
} | ||
} | ||
| "EXTRACT" '(' TimeUnit "FROM" Expression ')' | ||
| builtinExtract '(' TimeUnit "FROM" Expression ')' | ||
{ | ||
timeUnit := ast.NewValueExpr($3) | ||
$$ = &ast.FuncCallExpr{ | ||
|
@@ -3100,32 +3142,32 @@ FunctionCallNonKeyword: | |
Args: []ast.ExprNode{ast.NewValueExpr($3), $5}, | ||
} | ||
} | ||
| "POSITION" '(' BitExpr "IN" Expression ')' | ||
| builtinPosition '(' BitExpr "IN" Expression ')' | ||
{ | ||
$$ = &ast.FuncCallExpr{FnName: model.NewCIStr($1), Args: []ast.ExprNode{$3, $5}} | ||
} | ||
| "SUBSTRING" '(' Expression ',' Expression ')' | ||
| builtinSubstring '(' Expression ',' Expression ')' | ||
{ | ||
$$ = &ast.FuncCallExpr{ | ||
FnName: model.NewCIStr($1), | ||
Args: []ast.ExprNode{$3, $5}, | ||
} | ||
} | ||
| "SUBSTRING" '(' Expression "FROM" Expression ')' | ||
| builtinSubstring '(' Expression "FROM" Expression ')' | ||
{ | ||
$$ = &ast.FuncCallExpr{ | ||
FnName: model.NewCIStr($1), | ||
Args: []ast.ExprNode{$3, $5}, | ||
} | ||
} | ||
| "SUBSTRING" '(' Expression ',' Expression ',' Expression ')' | ||
| builtinSubstring '(' Expression ',' Expression ',' Expression ')' | ||
{ | ||
$$ = &ast.FuncCallExpr{ | ||
FnName: model.NewCIStr($1), | ||
Args: []ast.ExprNode{$3, $5, $7}, | ||
} | ||
} | ||
| "SUBSTRING" '(' Expression "FROM" Expression "FOR" Expression ')' | ||
| builtinSubstring '(' Expression "FROM" Expression "FOR" Expression ')' | ||
{ | ||
$$ = &ast.FuncCallExpr{ | ||
FnName: model.NewCIStr($1), | ||
|
@@ -3146,21 +3188,21 @@ FunctionCallNonKeyword: | |
Args: []ast.ExprNode{ast.NewValueExpr($3), $5, $7}, | ||
} | ||
} | ||
| "TRIM" '(' Expression ')' | ||
| builtinTrim '(' Expression ')' | ||
{ | ||
$$ = &ast.FuncCallExpr{ | ||
FnName: model.NewCIStr($1), | ||
Args: []ast.ExprNode{$3}, | ||
} | ||
} | ||
| "TRIM" '(' Expression "FROM" Expression ')' | ||
| builtinTrim '(' Expression "FROM" Expression ')' | ||
{ | ||
$$ = &ast.FuncCallExpr{ | ||
FnName: model.NewCIStr($1), | ||
Args: []ast.ExprNode{$5, $3}, | ||
} | ||
} | ||
| "TRIM" '(' TrimDirection "FROM" Expression ')' | ||
| builtinTrim '(' TrimDirection "FROM" Expression ')' | ||
{ | ||
nilVal := ast.NewValueExpr(nil) | ||
direction := ast.NewValueExpr(int($3.(ast.TrimDirectionType))) | ||
|
@@ -3169,7 +3211,7 @@ FunctionCallNonKeyword: | |
Args: []ast.ExprNode{$5, nilVal, direction}, | ||
} | ||
} | ||
| "TRIM" '(' TrimDirection Expression "FROM" Expression ')' | ||
| builtinTrim '(' TrimDirection Expression "FROM" Expression ')' | ||
{ | ||
direction := ast.NewValueExpr(int($3.(ast.TrimDirectionType))) | ||
$$ = &ast.FuncCallExpr{ | ||
|
@@ -3198,13 +3240,13 @@ GetFormatSelector: | |
|
||
|
||
FunctionNameDateArith: | ||
"DATE_ADD" | ||
| "DATE_SUB" | ||
builtinDateAdd | ||
| builtinDateSub | ||
|
||
|
||
FunctionNameDateArithMultiForms: | ||
"ADDDATE" | ||
| "SUBDATE" | ||
builtinAddDate | ||
| builtinSubDate | ||
|
||
|
||
TrimDirection: | ||
|
@@ -3238,36 +3280,36 @@ SumExpr: | |
{ | ||
$$ = &ast.AggregateFuncExpr{F: $1, Args: []ast.ExprNode{$3}} | ||
} | ||
| "COUNT" '(' DistinctKwd ExpressionList ')' | ||
| builtinCount '(' DistinctKwd ExpressionList ')' | ||
{ | ||
$$ = &ast.AggregateFuncExpr{F: $1, Args: $4.([]ast.ExprNode), Distinct: true} | ||
} | ||
| "COUNT" '(' "ALL" Expression ')' | ||
| builtinCount '(' "ALL" Expression ')' | ||
{ | ||
$$ = &ast.AggregateFuncExpr{F: $1, Args: []ast.ExprNode{$4}} | ||
} | ||
| "COUNT" '(' Expression ')' | ||
| builtinCount '(' Expression ')' | ||
{ | ||
$$ = &ast.AggregateFuncExpr{F: $1, Args: []ast.ExprNode{$3}} | ||
} | ||
| "COUNT" '(' '*' ')' | ||
| builtinCount '(' '*' ')' | ||
{ | ||
args := []ast.ExprNode{ast.NewValueExpr(1)} | ||
$$ = &ast.AggregateFuncExpr{F: $1, Args: args} | ||
} | ||
| "GROUP_CONCAT" '(' BuggyDefaultFalseDistinctOpt ExpressionList ')' | ||
| builtinGroupConcat '(' BuggyDefaultFalseDistinctOpt ExpressionList ')' | ||
{ | ||
$$ = &ast.AggregateFuncExpr{F: $1, Args: $4.([]ast.ExprNode), Distinct: $3.(bool)} | ||
} | ||
| "MAX" '(' BuggyDefaultFalseDistinctOpt Expression ')' | ||
| builtinMax '(' BuggyDefaultFalseDistinctOpt Expression ')' | ||
{ | ||
$$ = &ast.AggregateFuncExpr{F: $1, Args: []ast.ExprNode{$4}, Distinct: $3.(bool)} | ||
} | ||
| "MIN" '(' BuggyDefaultFalseDistinctOpt Expression ')' | ||
| builtinMin '(' BuggyDefaultFalseDistinctOpt Expression ')' | ||
{ | ||
$$ = &ast.AggregateFuncExpr{F: $1, Args: []ast.ExprNode{$4}, Distinct: $3.(bool)} | ||
} | ||
| "SUM" '(' BuggyDefaultFalseDistinctOpt Expression ')' | ||
| builtinSum '(' BuggyDefaultFalseDistinctOpt Expression ')' | ||
{ | ||
$$ = &ast.AggregateFuncExpr{F: $1, Args: []ast.ExprNode{$4}, Distinct: $3.(bool)} | ||
} | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -828,7 +828,7 @@ func (s *testParserSuite) TestBuiltin(c *C) { | |
|
||
// for date, day, weekday | ||
{"SELECT CURRENT_DATE, CURRENT_DATE(), CURDATE()", true}, | ||
{"SELECT CURRENT_DATE, CURRENT_DATE(), CURDATE(1)", true}, | ||
{"SELECT CURRENT_DATE, CURRENT_DATE(), CURDATE(1)", false}, | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Why this is false case? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @shenli it seems that MySQL doesn't support |
||
{"SELECT DATEDIFF('2003-12-31', '2003-12-30');", true}, | ||
{"SELECT DATE('2003-12-31 01:02:03');", true}, | ||
{"SELECT DATE();", true}, | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
How do we obtain tis map ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@zz-jason I've rewrite this part. PTAL