Merge branch 'master' into qiuyesuifeng/exists-subquery
This commit is contained in:
487
parser/parser.y
487
parser/parser.y
@ -58,11 +58,11 @@ import (
|
||||
|
||||
/*yy:token "1.%d" */ floatLit "floating-point literal"
|
||||
/*yy:token "%c" */ identifier "identifier"
|
||||
/*yy:token "%di" */ imaginaryLit "imaginary literal"
|
||||
/*yy:token "%d" */ intLit "integer literal"
|
||||
/*yy:token "\"%c\"" */ stringLit "string literal"
|
||||
|
||||
|
||||
abs "ABS"
|
||||
add "ADD"
|
||||
after "AFTER"
|
||||
all "ALL"
|
||||
@ -74,6 +74,7 @@ import (
|
||||
as "AS"
|
||||
asc "ASC"
|
||||
autoIncrement "AUTO_INCREMENT"
|
||||
avg "AVG"
|
||||
begin "BEGIN"
|
||||
between "BETWEEN"
|
||||
by "BY"
|
||||
@ -82,16 +83,24 @@ import (
|
||||
cast "CAST"
|
||||
character "CHARACTER"
|
||||
charsetKwd "CHARSET"
|
||||
coalesce "COALESCE"
|
||||
collation "COLLATE"
|
||||
column "COLUMN"
|
||||
columns "COLUMNS"
|
||||
commit "COMMIT"
|
||||
concat "CONCAT"
|
||||
concatWs "CONCAT_WS"
|
||||
constraint "CONSTRAINT"
|
||||
convert "CONVERT"
|
||||
count "COUNT"
|
||||
create "CREATE"
|
||||
cross "CROSS"
|
||||
database "DATABASE"
|
||||
databases "DATABASES"
|
||||
day "DAY"
|
||||
dayofmonth "DAYOFMONTH"
|
||||
dayofweek "DAYOFWEEK"
|
||||
dayofyear "DAYOFYEAR"
|
||||
deallocate "DEALLOCATE"
|
||||
defaultKwd "DEFAULT"
|
||||
delayed "DELAYED"
|
||||
@ -115,16 +124,20 @@ import (
|
||||
first "FIRST"
|
||||
foreign "FOREIGN"
|
||||
forKwd "FOR"
|
||||
foundRows "FOUND_ROWS"
|
||||
from "FROM"
|
||||
full "FULL"
|
||||
fulltext "FULLTEXT"
|
||||
ge ">="
|
||||
global "GLOBAL"
|
||||
group "GROUP"
|
||||
groupConcat "GROUP_CONCAT"
|
||||
having "HAVING"
|
||||
highPriority "HIGH_PRIORITY"
|
||||
hour "HOUR"
|
||||
ignore "IGNORE"
|
||||
ifKwd "IF"
|
||||
ifNull "IFNULL"
|
||||
in "IN"
|
||||
index "INDEX"
|
||||
inner "INNER"
|
||||
@ -135,19 +148,26 @@ import (
|
||||
key "KEY"
|
||||
le "<="
|
||||
left "LEFT"
|
||||
length "LENGTH"
|
||||
like "LIKE"
|
||||
limit "LIMIT"
|
||||
local "LOCAL"
|
||||
lock "LOCK"
|
||||
lowPriority "LOW_PRIORITY"
|
||||
lsh "<<"
|
||||
max "MAX"
|
||||
microsecond "MICROSECOND"
|
||||
min "MIN"
|
||||
minute "MINUTE"
|
||||
mod "MOD"
|
||||
mode "MODE"
|
||||
month "MONTH"
|
||||
names "NAMES"
|
||||
neq "!="
|
||||
neqSynonym "<>"
|
||||
not "NOT"
|
||||
null "NULL"
|
||||
nullIf "NULLIF"
|
||||
offset "OFFSET"
|
||||
on "ON"
|
||||
or "OR"
|
||||
@ -161,14 +181,15 @@ import (
|
||||
quick "QUICK"
|
||||
references "REFERENCES"
|
||||
regexp "REGEXP"
|
||||
repeat "REPEAT"
|
||||
right "RIGHT"
|
||||
rlike "RLIKE"
|
||||
rollback "ROLLBACK"
|
||||
row "ROW"
|
||||
rsh ">>"
|
||||
runeType "rune"
|
||||
schema "SCHEMA"
|
||||
schemas "SCHEMAS"
|
||||
second "SECOND"
|
||||
selectKwd "SELECT"
|
||||
session "SESSION"
|
||||
set "SET"
|
||||
@ -179,6 +200,7 @@ import (
|
||||
start "START"
|
||||
stringType "string"
|
||||
substring "SUBSTRING"
|
||||
sum "SUM"
|
||||
sysVar "SYS_VAR"
|
||||
tableKwd "TABLE"
|
||||
tables "TABLES"
|
||||
@ -198,9 +220,13 @@ import (
|
||||
values "VALUES"
|
||||
variables "VARIABLES"
|
||||
warnings "WARNINGS"
|
||||
week "WEEK"
|
||||
weekday "WEEKDAY"
|
||||
weekofyear "WEEKOFYEAR"
|
||||
when "WHEN"
|
||||
where "WHERE"
|
||||
xor "XOR"
|
||||
yearweek "YEARWEEK"
|
||||
zerofill "ZEROFILL"
|
||||
|
||||
calcFoundRows "SQL_CALC_FOUND_ROWS"
|
||||
@ -262,7 +288,6 @@ import (
|
||||
parseExpression "parse expression prefix"
|
||||
|
||||
%type <item>
|
||||
AggAllOpt "All option in aggregate function"
|
||||
AlterTableStmt "Alter table statement"
|
||||
AlterSpecification "Alter table specification"
|
||||
AlterSpecificationList "Alter table specification list"
|
||||
@ -307,6 +332,7 @@ import (
|
||||
DefaultKwdOpt "optional DEFAULT keyword"
|
||||
DefaultValueExpr "DefaultValueExpr(Now or Signed Literal)"
|
||||
DeleteFromStmt "DELETE FROM statement"
|
||||
DistinctOpt "Distinct option"
|
||||
DoStmt "Do statement"
|
||||
DropDatabaseStmt "DROP DATABASE statement"
|
||||
DropIndexStmt "DROP INDEX statement"
|
||||
@ -328,8 +354,11 @@ import (
|
||||
FieldList "field expression list"
|
||||
FromClause "From clause"
|
||||
Function "function expr"
|
||||
FunctionCall "function call post part"
|
||||
FunctionCallArgList "function call optional argument list"
|
||||
FunctionCallAgg "Function call on aggregate data"
|
||||
FunctionCallConflict "Function call with reserved keyword as function name"
|
||||
FunctionCallKeyword "Function call with keyword as function name"
|
||||
FunctionCallNonKeyword "Function call with nonkeyword as function name"
|
||||
FunctionNameConflict "Built-in function call names which are conflict with keywords"
|
||||
GlobalScope "The scope of variable"
|
||||
GroupByClause "GROUP BY clause"
|
||||
GroupByList "GROUP BY list"
|
||||
@ -463,7 +492,6 @@ import (
|
||||
NUM "numbers"
|
||||
LengthNum "Field length num(uint64)"
|
||||
|
||||
FunctionNameConflict "Built-in function call names which are conflict with keywords"
|
||||
|
||||
|
||||
%token tableRefPriority
|
||||
@ -471,6 +499,9 @@ import (
|
||||
%precedence lowerThanCalcFoundRows
|
||||
%precedence calcFoundRows
|
||||
|
||||
%precedence lowerThanInsertValues
|
||||
%precedence insertValues
|
||||
|
||||
%left join inner cross left right full
|
||||
/* A dummy token to force the priority of TableRef production in a join. */
|
||||
%left tableRefPriority
|
||||
@ -657,39 +688,6 @@ BeginTransactionStmt:
|
||||
$$ = &stmts.BeginStmt{}
|
||||
}
|
||||
|
||||
FunctionCall:
|
||||
'(' AggAllOpt FunctionCallArgList ')'
|
||||
{
|
||||
$$ = []interface{}{false, $3}
|
||||
}
|
||||
| '(' "DISTINCT" AggAllOpt ExpressionList')'
|
||||
{
|
||||
/* Distinct must have expression list, can not empty and '*' */
|
||||
$$ = []interface{}{true, $4}
|
||||
}
|
||||
|
||||
AggAllOpt:
|
||||
{
|
||||
|
||||
}
|
||||
| "ALL"
|
||||
{
|
||||
/* TODO: not all functions support ALL, so later we will distinguish to handle them */
|
||||
/* ALL has nothing to do. */
|
||||
}
|
||||
|
||||
FunctionCallArgList:
|
||||
/* EMPTY */
|
||||
{
|
||||
$$ = []expression.Expression{}
|
||||
}
|
||||
/* select count(*) from table */
|
||||
| '*'
|
||||
{
|
||||
$$ = []expression.Expression{ expressions.Value{Val: expressions.TypeStar("*")} }
|
||||
}
|
||||
| ExpressionList
|
||||
|
||||
ColumnDef:
|
||||
ColumnName Type ConstraintOpts
|
||||
{
|
||||
@ -1593,14 +1591,16 @@ Identifier:
|
||||
identifier | UnReservedKeyword | NotKeywordToken
|
||||
|
||||
UnReservedKeyword:
|
||||
"AUTO_INCREMENT" | "AFTER" | "BEGIN" | "BIT" | "BOOL" | "BOOLEAN" | "CHARSET" | "COLUMNS" | "COMMIT"
|
||||
"AUTO_INCREMENT" | "AFTER" | "AVG" | "BEGIN" | "BIT" | "BOOL" | "BOOLEAN" | "CHARSET" | "COLUMNS" | "COMMIT"
|
||||
| "DATE" | "DATETIME" | "DEALLOCATE" | "DO" | "END" | "ENGINE" | "ENGINES" | "EXECUTE" | "FIRST" | "FULL"
|
||||
| "LOCAL" | "NAMES" | "OFFSET" | "PASSWORD" %prec lowerThanEq | "PREPARE" | "QUICK" | "ROLLBACK" | "SESSION" | "SIGNED"
|
||||
| "START" | "GLOBAL" | "TABLES"| "TEXT" | "TIME" | "TIMESTAMP" | "TRANSACTION" | "TRUNCATE" | "UNKNOWN"
|
||||
| "VALUE" | "WARNINGS" | "YEAR" | "NOW" | "MODE"
|
||||
| "VALUE" | "WARNINGS" | "YEAR" | "MODE" | "WEEK" | "ANY" | "SOME"
|
||||
|
||||
NotKeywordToken:
|
||||
"SQL_CALC_FOUND_ROWS" | "SUBSTRING" %prec lowerThanLeftParen
|
||||
"ABS" | "COALESCE" | "CONCAT" | "CONCAT_WS" | "COUNT" | "DAY" | "DAYOFMONTH" | "DAYOFWEEK" | "DAYOFYEAR" | "FOUND_ROWS" | "GROUP_CONCAT"
|
||||
| "HOUR" | "IFNULL" | "LENGTH" | "MAX" | "MICROSECOND" | "MIN" | "MINUTE" | "NULLIF" | "MONTH" | "NOW" | "SECOND" | "SQL_CALC_FOUND_ROWS"
|
||||
| "SUBSTRING" %prec lowerThanLeftParen | "SUM" | "WEEKDAY" | "WEEKOFYEAR" | "YEARWEEK"
|
||||
|
||||
/************************************************************************************
|
||||
*
|
||||
@ -1641,7 +1641,7 @@ InsertRest:
|
||||
{
|
||||
$$ = &stmts.InsertIntoStmt{ColNames: $2.([]string), Sel: $4.(*stmts.SelectStmt)}
|
||||
}
|
||||
| ValueSym ExpressionListList
|
||||
| ValueSym ExpressionListList %prec insertValues
|
||||
{
|
||||
$$ = &stmts.InsertIntoStmt{Lists: $2.([][]expression.Expression)}
|
||||
}
|
||||
@ -1723,7 +1723,6 @@ Literal:
|
||||
$$ = int64(1)
|
||||
}
|
||||
| floatLit
|
||||
| imaginaryLit
|
||||
| intLit
|
||||
| stringLit
|
||||
|
||||
@ -1844,30 +1843,51 @@ PrimaryExpression:
|
||||
}
|
||||
|
||||
Function:
|
||||
PrimaryExpression FunctionCall
|
||||
FunctionCallKeyword
|
||||
| FunctionCallNonKeyword
|
||||
| FunctionCallConflict
|
||||
| FunctionCallAgg
|
||||
|
||||
FunctionNameConflict:
|
||||
"DATABASE" | "SCHEMA" | "IF" | "LEFT" | "REPEAT"
|
||||
|
||||
FunctionCallConflict:
|
||||
FunctionNameConflict '(' ExpressionList ')'
|
||||
{
|
||||
x := yylex.(*lexer)
|
||||
f, ok := $1.(*expressions.Ident)
|
||||
if !ok {
|
||||
x.err("", "expected identifier or qualified identifier")
|
||||
return 1
|
||||
}
|
||||
|
||||
var err error
|
||||
args := $2.([]interface{})
|
||||
if $$, err = expressions.NewCall(f.O, args[1].([]expression.Expression), args[0].(bool)); err != nil {
|
||||
$$, err = expressions.NewCall($1.(string), $3.([]expression.Expression), false)
|
||||
if err != nil {
|
||||
x.err("", "%v", err)
|
||||
return 1
|
||||
}
|
||||
}
|
||||
| FunctionNameConflict FunctionCall
|
||||
|
||||
DistinctOpt:
|
||||
{
|
||||
$$ = false
|
||||
}
|
||||
| "ALL"
|
||||
{
|
||||
$$ = false
|
||||
}
|
||||
| "DISTINCT"
|
||||
{
|
||||
$$ = true
|
||||
}
|
||||
| "DISTINCT" "ALL"
|
||||
{
|
||||
$$ = true
|
||||
}
|
||||
|
||||
FunctionCallKeyword:
|
||||
"AVG" '(' DistinctOpt ExpressionList ')'
|
||||
{
|
||||
x := yylex.(*lexer)
|
||||
var err error
|
||||
args := $2.([]interface{})
|
||||
$$, err = expressions.NewCall($1.(string), args[1].([]expression.Expression), false)
|
||||
$$, err = expressions.NewCall($1.(string), $4.([]expression.Expression), $3.(bool))
|
||||
if err != nil {
|
||||
x.err("", "%v", err)
|
||||
l := yylex.(*lexer)
|
||||
l.err("", "%v", err)
|
||||
return 1
|
||||
}
|
||||
}
|
||||
@ -1890,11 +1910,6 @@ Function:
|
||||
}
|
||||
$$ = x
|
||||
}
|
||||
| "VALUES" '(' Identifier ')'
|
||||
{
|
||||
// TODO: support qualified identifier for column_name
|
||||
$$ = &expressions.Values{CIStr: model.NewCIStr($3.(string))}
|
||||
}
|
||||
| "CONVERT" '(' Expression "USING" CharsetName ')'
|
||||
{
|
||||
// See: https://dev.mysql.com/doc/refman/5.7/en/cast-functions.html#function_convert
|
||||
@ -1912,6 +1927,237 @@ Function:
|
||||
IsConvert: true,
|
||||
}
|
||||
}
|
||||
| "DATE" '(' Expression ')'
|
||||
{
|
||||
args := []expression.Expression{$3.(expression.Expression)}
|
||||
var err error
|
||||
$$, err = expressions.NewCall($1.(string), args, false)
|
||||
if err != nil {
|
||||
l := yylex.(*lexer)
|
||||
l.err("", "%v", err)
|
||||
return 1
|
||||
}
|
||||
}
|
||||
| "VALUES" '(' Identifier ')' %prec lowerThanInsertValues
|
||||
{
|
||||
// TODO: support qualified identifier for column_name
|
||||
$$ = &expressions.Values{CIStr: model.NewCIStr($3.(string))}
|
||||
}
|
||||
| "WEEK" '(' ExpressionList ')'
|
||||
{
|
||||
var err error
|
||||
$$, err = expressions.NewCall($1.(string), $3.([]expression.Expression), false)
|
||||
if err != nil {
|
||||
l := yylex.(*lexer)
|
||||
l.err("", "%v", err)
|
||||
return 1
|
||||
}
|
||||
}
|
||||
| "YEAR" '(' Expression ')'
|
||||
{
|
||||
args := []expression.Expression{$3.(expression.Expression)}
|
||||
var err error
|
||||
$$, err = expressions.NewCall($1.(string), args, false)
|
||||
if err != nil {
|
||||
l := yylex.(*lexer)
|
||||
l.err("", "%v", err)
|
||||
return 1
|
||||
}
|
||||
}
|
||||
|
||||
FunctionCallNonKeyword:
|
||||
"COALESCE" '(' ExpressionList ')'
|
||||
{
|
||||
var err error
|
||||
$$, err = expressions.NewCall($1.(string), $3.([]expression.Expression), false)
|
||||
if err != nil {
|
||||
l := yylex.(*lexer)
|
||||
l.err("", "%v", err)
|
||||
return 1
|
||||
}
|
||||
}
|
||||
| "ABS" '(' Expression ')'
|
||||
{
|
||||
args := []expression.Expression{$3.(expression.Expression)}
|
||||
var err error
|
||||
$$, err = expressions.NewCall($1.(string), args, false)
|
||||
if err != nil {
|
||||
l := yylex.(*lexer)
|
||||
l.err("", "%v", err)
|
||||
return 1
|
||||
}
|
||||
}
|
||||
| "CONCAT" '(' ExpressionList ')'
|
||||
{
|
||||
var err error
|
||||
$$, err = expressions.NewCall($1.(string), $3.([]expression.Expression), false)
|
||||
if err != nil {
|
||||
l := yylex.(*lexer)
|
||||
l.err("", "%v", err)
|
||||
return 1
|
||||
}
|
||||
}
|
||||
| "CONCAT_WS" '(' ExpressionList ')'
|
||||
{
|
||||
var err error
|
||||
$$, err = expressions.NewCall($1.(string), $3.([]expression.Expression), false)
|
||||
if err != nil {
|
||||
l := yylex.(*lexer)
|
||||
l.err("", "%v", err)
|
||||
return 1
|
||||
}
|
||||
}
|
||||
| "DAY" '(' Expression ')'
|
||||
{
|
||||
args := []expression.Expression{$3.(expression.Expression)}
|
||||
var err error
|
||||
$$, err = expressions.NewCall($1.(string), args, false)
|
||||
if err != nil {
|
||||
l := yylex.(*lexer)
|
||||
l.err("", "%v", err)
|
||||
return 1
|
||||
}
|
||||
}
|
||||
| "DAYOFWEEK" '(' Expression ')'
|
||||
{
|
||||
args := []expression.Expression{$3.(expression.Expression)}
|
||||
var err error
|
||||
$$, err = expressions.NewCall($1.(string), args, false)
|
||||
if err != nil {
|
||||
l := yylex.(*lexer)
|
||||
l.err("", "%v", err)
|
||||
return 1
|
||||
}
|
||||
}
|
||||
| "DAYOFMONTH" '(' Expression ')'
|
||||
{
|
||||
args := []expression.Expression{$3.(expression.Expression)}
|
||||
var err error
|
||||
$$, err = expressions.NewCall($1.(string), args, false)
|
||||
if err != nil {
|
||||
l := yylex.(*lexer)
|
||||
l.err("", "%v", err)
|
||||
return 1
|
||||
}
|
||||
}
|
||||
| "DAYOFYEAR" '(' Expression ')'
|
||||
{
|
||||
args := []expression.Expression{$3.(expression.Expression)}
|
||||
var err error
|
||||
$$, err = expressions.NewCall($1.(string), args, false)
|
||||
if err != nil {
|
||||
l := yylex.(*lexer)
|
||||
l.err("", "%v", err)
|
||||
return 1
|
||||
}
|
||||
}
|
||||
| "FOUND_ROWS" '(' ')'
|
||||
{
|
||||
args := []expression.Expression{}
|
||||
var err error
|
||||
$$, err = expressions.NewCall($1.(string), args, false)
|
||||
if err != nil {
|
||||
l := yylex.(*lexer)
|
||||
l.err("", "%v", err)
|
||||
return 1
|
||||
}
|
||||
}
|
||||
| "HOUR" '(' Expression ')'
|
||||
{
|
||||
args := []expression.Expression{$3.(expression.Expression)}
|
||||
var err error
|
||||
$$, err = expressions.NewCall($1.(string), args, false)
|
||||
if err != nil {
|
||||
l := yylex.(*lexer)
|
||||
l.err("", "%v", err)
|
||||
return 1
|
||||
}
|
||||
}
|
||||
| "IFNULL" '(' ExpressionList ')'
|
||||
{
|
||||
var err error
|
||||
$$, err = expressions.NewCall($1.(string), $3.([]expression.Expression), false)
|
||||
if err != nil {
|
||||
l := yylex.(*lexer)
|
||||
l.err("", "%v", err)
|
||||
return 1
|
||||
}
|
||||
}
|
||||
| "LENGTH" '(' Expression ')'
|
||||
{
|
||||
args := []expression.Expression{$3.(expression.Expression)}
|
||||
var err error
|
||||
$$, err = expressions.NewCall($1.(string), args, false)
|
||||
if err != nil {
|
||||
l := yylex.(*lexer)
|
||||
l.err("", "%v", err)
|
||||
return 1
|
||||
}
|
||||
}
|
||||
| "MICROSECOND" '(' Expression ')'
|
||||
{
|
||||
args := []expression.Expression{$3.(expression.Expression)}
|
||||
var err error
|
||||
$$, err = expressions.NewCall($1.(string), args, false)
|
||||
if err != nil {
|
||||
l := yylex.(*lexer)
|
||||
l.err("", "%v", err)
|
||||
return 1
|
||||
}
|
||||
}
|
||||
| "MINUTE" '(' Expression ')'
|
||||
{
|
||||
args := []expression.Expression{$3.(expression.Expression)}
|
||||
var err error
|
||||
$$, err = expressions.NewCall($1.(string), args, false)
|
||||
if err != nil {
|
||||
l := yylex.(*lexer)
|
||||
l.err("", "%v", err)
|
||||
return 1
|
||||
}
|
||||
}
|
||||
| "MONTH" '(' Expression ')'
|
||||
{
|
||||
args := []expression.Expression{$3.(expression.Expression)}
|
||||
var err error
|
||||
$$, err = expressions.NewCall($1.(string), args, false)
|
||||
if err != nil {
|
||||
l := yylex.(*lexer)
|
||||
l.err("", "%v", err)
|
||||
return 1
|
||||
}
|
||||
}
|
||||
| "NOW" '(' ExpressionList ')'
|
||||
{
|
||||
var err error
|
||||
$$, err = expressions.NewCall($1.(string), $3.([]expression.Expression),false)
|
||||
if err != nil {
|
||||
l := yylex.(*lexer)
|
||||
l.err("", "%v", err)
|
||||
return 1
|
||||
}
|
||||
}
|
||||
| "NULLIF" '(' ExpressionList ')'
|
||||
{
|
||||
var err error
|
||||
$$, err = expressions.NewCall($1.(string), $3.([]expression.Expression), false)
|
||||
if err != nil {
|
||||
l := yylex.(*lexer)
|
||||
l.err("", "%v", err)
|
||||
return 1
|
||||
}
|
||||
}
|
||||
| "SECOND" '(' Expression ')'
|
||||
{
|
||||
args := []expression.Expression{$3.(expression.Expression)}
|
||||
var err error
|
||||
$$, err = expressions.NewCall($1.(string), args, false)
|
||||
if err != nil {
|
||||
l := yylex.(*lexer)
|
||||
l.err("", "%v", err)
|
||||
return 1
|
||||
}
|
||||
}
|
||||
| "SUBSTRING" '(' Expression ',' Expression ')'
|
||||
{
|
||||
$$ = &expressions.FunctionSubstring{
|
||||
@ -1942,7 +2188,104 @@ Function:
|
||||
Len: $7.(expression.Expression),
|
||||
}
|
||||
}
|
||||
| "WEEKDAY" '(' Expression ')'
|
||||
{
|
||||
args := []expression.Expression{$3.(expression.Expression)}
|
||||
var err error
|
||||
$$, err = expressions.NewCall($1.(string), args, false)
|
||||
if err != nil {
|
||||
l := yylex.(*lexer)
|
||||
l.err("", "%v", err)
|
||||
return 1
|
||||
}
|
||||
}
|
||||
| "WEEKOFYEAR" '(' Expression ')'
|
||||
{
|
||||
args := []expression.Expression{$3.(expression.Expression)}
|
||||
var err error
|
||||
$$, err = expressions.NewCall($1.(string), args, false)
|
||||
if err != nil {
|
||||
l := yylex.(*lexer)
|
||||
l.err("", "%v", err)
|
||||
return 1
|
||||
}
|
||||
}
|
||||
| "YEARWEEK" '(' ExpressionList ')'
|
||||
{
|
||||
var err error
|
||||
$$, err = expressions.NewCall($1.(string), $3.([]expression.Expression),false)
|
||||
if err != nil {
|
||||
l := yylex.(*lexer)
|
||||
l.err("", "%v", err)
|
||||
return 1
|
||||
}
|
||||
}
|
||||
|
||||
FunctionCallAgg:
|
||||
"COUNT" '(' DistinctOpt ExpressionList ')'
|
||||
{
|
||||
var err error
|
||||
$$, err = expressions.NewCall($1.(string), $4.([]expression.Expression), $3.(bool))
|
||||
if err != nil {
|
||||
l := yylex.(*lexer)
|
||||
l.err("", "%v", err)
|
||||
return 1
|
||||
}
|
||||
}
|
||||
| "COUNT" '(' DistinctOpt '*' ')'
|
||||
{
|
||||
var err error
|
||||
args := []expression.Expression{ expressions.Value{Val: expressions.TypeStar("*")} }
|
||||
$$, err = expressions.NewCall($1.(string), args, $3.(bool))
|
||||
if err != nil {
|
||||
l := yylex.(*lexer)
|
||||
l.err("", "%v", err)
|
||||
return 1
|
||||
}
|
||||
}
|
||||
| "GROUP_CONCAT" '(' DistinctOpt ExpressionList ')'
|
||||
{
|
||||
var err error
|
||||
$$, err = expressions.NewCall($1.(string), $4.([]expression.Expression),$3.(bool))
|
||||
if err != nil {
|
||||
l := yylex.(*lexer)
|
||||
l.err("", "%v", err)
|
||||
return 1
|
||||
}
|
||||
}
|
||||
| "MAX" '(' DistinctOpt Expression ')'
|
||||
{
|
||||
args := []expression.Expression{$4.(expression.Expression)}
|
||||
var err error
|
||||
$$, err = expressions.NewCall($1.(string), args, $3.(bool))
|
||||
if err != nil {
|
||||
l := yylex.(*lexer)
|
||||
l.err("", "%v", err)
|
||||
return 1
|
||||
}
|
||||
}
|
||||
| "MIN" '(' DistinctOpt Expression ')'
|
||||
{
|
||||
args := []expression.Expression{$4.(expression.Expression)}
|
||||
var err error
|
||||
$$, err = expressions.NewCall($1.(string), args, $3.(bool))
|
||||
if err != nil {
|
||||
l := yylex.(*lexer)
|
||||
l.err("", "%v", err)
|
||||
return 1
|
||||
}
|
||||
}
|
||||
| "SUM" '(' DistinctOpt Expression ')'
|
||||
{
|
||||
args := []expression.Expression{$4.(expression.Expression)}
|
||||
var err error
|
||||
$$, err = expressions.NewCall($1.(string), args, $3.(bool))
|
||||
if err != nil {
|
||||
l := yylex.(*lexer)
|
||||
l.err("", "%v", err)
|
||||
return 1
|
||||
}
|
||||
}
|
||||
|
||||
ExpressionOpt:
|
||||
{
|
||||
@ -2035,24 +2378,6 @@ CastType:
|
||||
}
|
||||
|
||||
|
||||
FunctionNameConflict:
|
||||
"DATABASE"
|
||||
{
|
||||
$$ = expressions.BuiltinFuncDatabase
|
||||
}
|
||||
| "SCHEMA"
|
||||
{
|
||||
$$ = expressions.BuiltinFuncDatabase
|
||||
}
|
||||
| "IF"
|
||||
{
|
||||
$$ = expressions.BuiltinFuncIf
|
||||
}
|
||||
| "LEFT"
|
||||
{
|
||||
$$ = expressions.BuiltinFuncLeft
|
||||
}
|
||||
|
||||
PrimaryFactor:
|
||||
PrimaryFactor '|' PrimaryFactor %prec '|'
|
||||
{
|
||||
|
||||
@ -317,7 +317,7 @@ func (s *testParserSuite) TestParser0(c *C) {
|
||||
"date", "datetime", "deallocate", "do", "end", "engine", "engines", "execute", "first", "full",
|
||||
"local", "names", "offset", "password", "prepare", "quick", "rollback", "session", "signed",
|
||||
"start", "global", "tables", "text", "time", "timestamp", "transaction", "truncate", "unknown",
|
||||
"value", "warnings", "year", "now", "substring", "mode",
|
||||
"value", "warnings", "year", "now", "substring", "mode", "any", "some",
|
||||
}
|
||||
for _, kw := range unreservedKws {
|
||||
src := fmt.Sprintf("SELECT %s FROM tbl;", kw)
|
||||
|
||||
101
parser/scanner.l
101
parser/scanner.l
@ -224,6 +224,7 @@ x [xX]
|
||||
y [yY]
|
||||
z [zZ]
|
||||
|
||||
abs {a}{b}{s}
|
||||
add {a}{d}{d}
|
||||
after {a}{f}{t}{e}{r}
|
||||
all {a}{l}{l}
|
||||
@ -233,6 +234,7 @@ any {a}{n}{y}
|
||||
as {a}{s}
|
||||
asc {a}{s}{c}
|
||||
auto_increment {a}{u}{t}{o}_{i}{n}{c}{r}{e}{m}{e}{n}{t}
|
||||
avg {a}{v}{g}
|
||||
begin {b}{e}{g}{i}{n}
|
||||
between {b}{e}{t}{w}{e}{e}{n}
|
||||
by {b}{y}
|
||||
@ -240,16 +242,24 @@ case {c}{a}{s}{e}
|
||||
cast {c}{a}{s}{t}
|
||||
character {c}{h}{a}{r}{a}{c}{t}{e}{r}
|
||||
charset {c}{h}{a}{r}{s}{e}{t}
|
||||
coalesce {c}{o}{a}{l}{e}{s}{c}{e}
|
||||
collate {c}{o}{l}{l}{a}{t}{e}
|
||||
column {c}{o}{l}{u}{m}{n}
|
||||
columns {c}{o}{l}{u}{m}{n}{s}
|
||||
commit {c}{o}{m}{m}{i}{t}
|
||||
concat {c}{o}{n}{c}{a}{t}
|
||||
concat_ws {c}{o}{n}{c}{a}{t}_{w}{s}
|
||||
constraint {c}{o}{n}{s}{t}{r}{a}{i}{n}{t}
|
||||
convert {c}{o}{n}{v}{e}{r}{t}
|
||||
count {c}{o}{u}{n}{t}
|
||||
create {c}{r}{e}{a}{t}{e}
|
||||
cross {c}{r}{o}{s}{s}
|
||||
database {d}{a}{t}{a}{b}{a}{s}{e}
|
||||
databases {d}{a}{t}{a}{b}{a}{s}{e}{s}
|
||||
day {d}{a}{y}
|
||||
dayofweek {d}{a}{y}{o}{f}{w}{e}{e}{k}
|
||||
dayofmonth {d}{a}{y}{o}{f}{m}{o}{n}{t}{h}
|
||||
dayofyear {d}{a}{y}{o}{f}{y}{e}{a}{r}
|
||||
deallocate {d}{e}{a}{l}{l}{o}{c}{a}{t}{e}
|
||||
default {d}{e}{f}{a}{u}{l}{t}
|
||||
delayed {d}{e}{l}{a}{y}{e}{d}
|
||||
@ -271,14 +281,18 @@ explain {e}{x}{p}{l}{a}{i}{n}
|
||||
first {f}{i}{r}{s}{t}
|
||||
for {f}{o}{r}
|
||||
foreign {f}{o}{r}{e}{i}{g}{n}
|
||||
found_rows {f}{o}{u}{n}{d}_{r}{o}{w}{s}
|
||||
from {f}{r}{o}{m}
|
||||
full {f}{u}{l}{l}
|
||||
fulltext {f}{u}{l}{l}{t}{e}{x}{t}
|
||||
global {g}{l}{o}{b}{a}{l}
|
||||
group {g}{r}{o}{u}{p}
|
||||
group_concat {g}{r}{o}{u}{p}_{c}{o}{n}{c}{a}{t}
|
||||
having {h}{a}{v}{i}{n}{g}
|
||||
high_priority {h}{i}{g}{h}_{p}{r}{i}{o}{r}{i}{t}{y}
|
||||
hour {h}{o}{u}{r}
|
||||
if {i}{f}
|
||||
ifnull {i}{f}{n}{u}{l}{l}
|
||||
ignore {i}{g}{n}{o}{r}{e}
|
||||
in {i}{n}
|
||||
index {i}{n}{d}{e}{x}
|
||||
@ -289,13 +303,17 @@ is {i}{s}
|
||||
join {j}{o}{i}{n}
|
||||
key {k}{e}{y}
|
||||
left {l}{e}{f}{t}
|
||||
length {l}{e}{n}{g}{t}{h}
|
||||
like {l}{i}{k}{e}
|
||||
limit {l}{i}{m}{i}{t}
|
||||
local {l}{o}{c}{a}{l}
|
||||
lock {l}{o}{c}{k}
|
||||
low_priority {l}{o}{w}_{p}{r}{i}{o}{r}{i}{t}{y}
|
||||
microsecond {m}{i}{c}{r}{o}{s}{e}{c}{o}{n}{d}
|
||||
minute {m}{i}{n}{u}{t}{e}
|
||||
mod {m}{o}{d}
|
||||
mode {m}{o}{d}{e}
|
||||
month {m}{o}{n}{t}{h}
|
||||
names {n}{a}{m}{e}{s}
|
||||
not {n}{o}{t}
|
||||
offset {o}{f}{f}{s}{e}{t}
|
||||
@ -307,6 +325,7 @@ password {p}{a}{s}{s}{w}{o}{r}{d}
|
||||
prepare {p}{r}{e}{p}{a}{r}{e}
|
||||
primary {p}{r}{i}{m}{a}{r}{y}
|
||||
quick {q}{u}{i}{c}{k}
|
||||
repeat {r}{e}{p}{e}{a}{t}
|
||||
references {r}{e}{f}{e}{r}{e}{n}{c}{e}{s}
|
||||
regexp {r}{e}{g}{e}{x}{p}
|
||||
right {r}{i}{g}{h}{t}
|
||||
@ -315,6 +334,7 @@ rollback {r}{o}{l}{l}{b}{a}{c}{k}
|
||||
row {r}{o}{w}
|
||||
schema {s}{c}{h}{e}{m}{a}
|
||||
schemas {s}{c}{h}{e}{m}{a}{s}
|
||||
second {s}{e}{c}{o}{n}{d}
|
||||
select {s}{e}{l}{e}{c}{t}
|
||||
session {s}{e}{s}{s}{i}{o}{n}
|
||||
set {s}{e}{t}
|
||||
@ -323,22 +343,30 @@ show {s}{h}{o}{w}
|
||||
some {s}{o}{m}{e}
|
||||
start {s}{t}{a}{r}{t}
|
||||
substring {s}{u}{b}{s}{t}{r}{i}{n}{g}
|
||||
sum {s}{u}{m}
|
||||
table {t}{a}{b}{l}{e}
|
||||
tables {t}{a}{b}{l}{e}{s}
|
||||
then {t}{h}{e}{n}
|
||||
transaction {t}{r}{a}{n}{s}{a}{c}{t}{i}{o}{n}
|
||||
truncate {t}{r}{u}{n}{c}{a}{t}{e}
|
||||
max {m}{a}{x}
|
||||
min {m}{i}{n}
|
||||
unknown {u}{n}{k}{n}{o}{w}{n}
|
||||
union {u}{n}{i}{o}{n}
|
||||
unique {u}{n}{i}{q}{u}{e}
|
||||
nullif {n}{u}{l}{l}{i}{f}
|
||||
update {u}{p}{d}{a}{t}{e}
|
||||
value {v}{a}{l}{u}{e}
|
||||
values {v}{a}{l}{u}{e}{s}
|
||||
variables {v}{a}{r}{i}{a}{b}{l}{e}{s}
|
||||
warnings {w}{a}{r}{n}{i}{n}{g}{s}
|
||||
week {w}{e}{e}{k}
|
||||
weekday {w}{e}{e}{k}{d}{a}{y}
|
||||
weekofyear {w}{e}{e}{k}{o}{f}{y}{e}{a}{r}
|
||||
where {w}{h}{e}{r}{e}
|
||||
when {w}{h}{e}{n}
|
||||
xor {x}{o}{r}
|
||||
yearweek {y}{e}{a}{r}{w}{e}{e}{k}
|
||||
|
||||
null {n}{u}{l}{l}
|
||||
false {f}{a}{l}{s}{e}
|
||||
@ -455,6 +483,8 @@ sys_var "@@"(({global}".")|({session}".")|{local}".")?{ident}
|
||||
|
||||
"?" return placeholder
|
||||
|
||||
{abs} lval.item = string(l.val)
|
||||
return abs
|
||||
{add} return add
|
||||
{after} lval.item = string(l.val)
|
||||
return after
|
||||
@ -467,6 +497,8 @@ sys_var "@@"(({global}".")|({session}".")|{local}".")?{ident}
|
||||
{as} return as
|
||||
{auto_increment} lval.item = string(l.val)
|
||||
return autoIncrement
|
||||
{avg} lval.item = string(l.val)
|
||||
return avg
|
||||
{begin} lval.item = string(l.val)
|
||||
return begin
|
||||
{between} return between
|
||||
@ -476,18 +508,35 @@ sys_var "@@"(({global}".")|({session}".")|{local}".")?{ident}
|
||||
{character} return character
|
||||
{charset} lval.item = string(l.val)
|
||||
return charsetKwd
|
||||
{coalesce} lval.item = string(l.val)
|
||||
return coalesce
|
||||
{collate} return collation
|
||||
{column} return column
|
||||
{columns} lval.item = string(l.val)
|
||||
return columns
|
||||
{commit} lval.item = string(l.val)
|
||||
return commit
|
||||
{concat} lval.item = string(l.val)
|
||||
return concat
|
||||
{concat_ws} lval.item = string(l.val)
|
||||
return concatWs
|
||||
{constraint} return constraint
|
||||
{convert} return convert
|
||||
{count} lval.item = string(l.val)
|
||||
return count
|
||||
{create} return create
|
||||
{cross} return cross
|
||||
{database} return database
|
||||
{database} lval.item = string(l.val)
|
||||
return database
|
||||
{databases} return databases
|
||||
{day} lval.item = string(l.val)
|
||||
return day
|
||||
{dayofweek} lval.item = string(l.val)
|
||||
return dayofweek
|
||||
{dayofmonth} lval.item = string(l.val)
|
||||
return dayofmonth
|
||||
{dayofyear} lval.item = string(l.val)
|
||||
return dayofyear
|
||||
{deallocate} lval.item = string(l.val)
|
||||
return deallocate
|
||||
{default} return defaultKwd
|
||||
@ -517,14 +566,23 @@ sys_var "@@"(({global}".")|({session}".")|{local}".")?{ident}
|
||||
return first
|
||||
{for} return forKwd
|
||||
{foreign} return foreign
|
||||
{found_rows} lval.item = string(l.val)
|
||||
return foundRows
|
||||
{from} return from
|
||||
{full} lval.item = string(l.val)
|
||||
return full
|
||||
{fulltext} return fulltext
|
||||
{group} return group
|
||||
{group_concat} lval.item = string(l.val)
|
||||
return groupConcat
|
||||
{having} return having
|
||||
{high_priority} return highPriority
|
||||
{if} return ifKwd
|
||||
{hour} lval.item = string(l.val)
|
||||
return hour
|
||||
{if} lval.item = string(l.val)
|
||||
return ifKwd
|
||||
{ifnull} lval.item = string(l.val)
|
||||
return ifNull
|
||||
{ignore} return ignore
|
||||
{index} return index
|
||||
{inner} return inner
|
||||
@ -534,16 +592,29 @@ sys_var "@@"(({global}".")|({session}".")|{local}".")?{ident}
|
||||
{is} return is
|
||||
{join} return join
|
||||
{key} return key
|
||||
{left} return left
|
||||
{left} lval.item = string(l.val)
|
||||
return left
|
||||
{length} lval.item = string(l.val)
|
||||
return length
|
||||
{like} return like
|
||||
{limit} return limit
|
||||
{local} lval.item = string(l.val)
|
||||
return local
|
||||
{lock} return lock
|
||||
{low_priority} return lowPriority
|
||||
{max} lval.item = string(l.val)
|
||||
return max
|
||||
{microsecond} lval.item = string(l.val)
|
||||
return microsecond
|
||||
{min} lval.item = string(l.val)
|
||||
return min
|
||||
{minute} lval.item = string(l.val)
|
||||
return minute
|
||||
{mod} return mod
|
||||
{mode} lval.item = string(l.val)
|
||||
return mode
|
||||
{month} lval.item = string(l.val)
|
||||
return month
|
||||
{names} lval.item = string(l.val)
|
||||
return names
|
||||
{not} return not
|
||||
@ -565,7 +636,8 @@ sys_var "@@"(({global}".")|({session}".")|{local}".")?{ident}
|
||||
return rollback
|
||||
{row} lval.item = string(l.val)
|
||||
return row
|
||||
{schema} return schema
|
||||
{schema} lval.item = string(l.val)
|
||||
return schema
|
||||
{schemas} return schemas
|
||||
{session} lval.item = string(l.val)
|
||||
return session
|
||||
@ -575,6 +647,8 @@ sys_var "@@"(({global}".")|({session}".")|{local}".")?{ident}
|
||||
return start
|
||||
{global} lval.item = string(l.val)
|
||||
return global
|
||||
{repeat} lval.item = string(l.val)
|
||||
return repeat
|
||||
{regexp} return regexp
|
||||
{references} return references
|
||||
{rlike} return rlike
|
||||
@ -584,7 +658,8 @@ sys_var "@@"(({global}".")|({session}".")|{local}".")?{ident}
|
||||
|
||||
{user_var} lval.item = string(l.val)
|
||||
return userVar
|
||||
|
||||
{second} lval.item = string(l.val)
|
||||
return second
|
||||
{select} return selectKwd
|
||||
|
||||
{set} return set
|
||||
@ -592,6 +667,8 @@ sys_var "@@"(({global}".")|({session}".")|{local}".")?{ident}
|
||||
{show} return show
|
||||
{substring} lval.item = string(l.val)
|
||||
return substring
|
||||
{sum} lval.item = string(l.val)
|
||||
return sum
|
||||
{table} return tableKwd
|
||||
{tables} lval.item = string(l.val)
|
||||
return tables
|
||||
@ -600,11 +677,13 @@ sys_var "@@"(({global}".")|({session}".")|{local}".")?{ident}
|
||||
return transaction
|
||||
{truncate} lval.item = string(l.val)
|
||||
return truncate
|
||||
{update} return update
|
||||
{union} return union
|
||||
{unique} return unique
|
||||
{unknown} lval.item = string(l.val)
|
||||
return unknown
|
||||
{nullif} lval.item = string(l.val)
|
||||
return nullIf
|
||||
{update} return update
|
||||
{use} return use
|
||||
{using} return using
|
||||
{value} lval.item = string(l.val)
|
||||
@ -614,10 +693,18 @@ sys_var "@@"(({global}".")|({session}".")|{local}".")?{ident}
|
||||
return variables
|
||||
{warnings} lval.item = string(l.val)
|
||||
return warnings
|
||||
{week} lval.item = string(l.val)
|
||||
return week
|
||||
{weekday} lval.item = string(l.val)
|
||||
return weekday
|
||||
{weekofyear} lval.item = string(l.val)
|
||||
return weekofyear
|
||||
{when} return when
|
||||
{where} return where
|
||||
{xor} return xor
|
||||
|
||||
{yearweek} lval.item = string(l.val)
|
||||
return yearweek
|
||||
|
||||
{signed} lval.item = string(l.val)
|
||||
return signed
|
||||
{unsigned} return unsigned
|
||||
|
||||
Reference in New Issue
Block a user