github.com/insionng/yougam@v0.0.0-20170714101924-2bc18d833463/libraries/pingcap/tidb/parser/parser.y (about)

     1  %{
     2  // Copyright 2013 The ql Authors. All rights reserved.
     3  // Use of this source code is governed by a BSD-style
     4  // license that can be found in the LICENSES/QL-LICENSE file.
     5  
     6  // Copyright 2015 PingCAP, Inc.
     7  //
     8  // Licensed under the Apache License, Version 2.0 (the "License");
     9  // you may not use this file except in compliance with the License.
    10  // You may obtain a copy of the License at
    11  //
    12  //     http://www.apache.org/licenses/LICENSE-2.0
    13  //
    14  // Unless required by applicable law or agreed to in writing, software
    15  // distributed under the License is distributed on an "AS IS" BASIS,
    16  // See the License for the specific language governing permissions and
    17  // limitations under the License.
    18  
    19  // Initial yacc source generated by ebnf2y[1]
    20  // at 2013-10-04 23:10:47.861401015 +0200 CEST
    21  //
    22  //  $ ebnf2y -o ql.y -oe ql.ebnf -start StatementList -pkg ql -p _
    23  // 
    24  //   [1]: http://github.com/cznic/ebnf2y
    25  
    26  package parser
    27  
    28  import (
    29  	"strings"
    30  	
    31  	"github.com/pingcap/tidb/mysql"
    32  	"github.com/pingcap/tidb/ast"
    33  	"github.com/pingcap/tidb/model"
    34  	"github.com/pingcap/tidb/parser/opcode"
    35  	"github.com/pingcap/tidb/util/charset"
    36  	"github.com/pingcap/tidb/util/types"
    37  )
    38  
    39  %}
    40  
    41  %union {
    42  	offset int // offset
    43  	line int
    44  	col  int
    45  	item interface{}
    46  	list []interface{}
    47  }
    48  
    49  %token	<item>
    50  
    51  	/*yy:token "1.%d"   */	floatLit        "floating-point literal"
    52  	/*yy:token "%c"     */	identifier      "identifier"
    53  	/*yy:token "%d"     */	intLit          "integer literal"
    54  	/*yy:token "\"%c\"" */	stringLit       "string literal"
    55  	/*yy:token "%x"     */	hexLit          "hexadecimal literal"
    56  	/*yy:token "%b"     */	bitLit          "bit literal"
    57  
    58  
    59  	abs		"ABS"
    60  	add		"ADD"
    61  	addDate		"ADDDATE"
    62  	admin		"ADMIN"
    63  	after		"AFTER"
    64  	all 		"ALL"
    65  	alter		"ALTER"
    66  	and		"AND"
    67  	andand		"&&"
    68  	andnot		"&^"
    69  	any 		"ANY"
    70  	as		"AS"
    71  	asc		"ASC"
    72  	ascii		"ASCII"
    73  	assignmentEq	":="
    74  	at		"AT"
    75  	autoIncrement	"AUTO_INCREMENT"
    76  	avg		"AVG"
    77  	avgRowLength	"AVG_ROW_LENGTH"
    78  	begin		"BEGIN"
    79  	between		"BETWEEN"
    80  	both		"BOTH"
    81  	btree		"BTREE"
    82  	by		"BY"
    83  	byteType	"BYTE"
    84  	caseKwd		"CASE"
    85  	cast		"CAST"
    86  	character	"CHARACTER"
    87  	charsetKwd	"CHARSET"
    88  	check 		"CHECK"
    89  	checksum	"CHECKSUM"
    90  	coalesce	"COALESCE"
    91  	collate 	"COLLATE"
    92  	collation	"COLLATION"
    93  	column		"COLUMN"
    94  	columns		"COLUMNS"
    95  	comment 	"COMMENT"
    96  	commit		"COMMIT"
    97  	committed	"COMMITTED"
    98  	compact		"COMPACT"
    99  	compressed	"COMPRESSED"
   100  	compression	"COMPRESSION"
   101  	concat		"CONCAT"
   102  	concatWs	"CONCAT_WS"
   103  	connection 	"CONNECTION"
   104  	connectionID 	"CONNECTION_ID"
   105  	constraint	"CONSTRAINT"
   106  	convert		"CONVERT"
   107  	count		"COUNT"
   108  	create		"CREATE"
   109  	cross 		"CROSS"
   110  	curDate 	"CURDATE"
   111  	utcDate 	"UTC_DATE"
   112  	currentDate 	"CURRENT_DATE"
   113  	curTime 	"CUR_TIME"
   114  	currentTime 	"CURRENT_TIME"
   115  	currentUser	"CURRENT_USER"
   116  	database	"DATABASE"
   117  	databases	"DATABASES"
   118  	dateAdd		"DATE_ADD"
   119  	dateSub		"DATE_SUB"
   120  	day		"DAY"
   121  	dayname		"DAYNAME"
   122  	dayofmonth	"DAYOFMONTH"
   123  	dayofweek	"DAYOFWEEK"
   124  	dayofyear	"DAYOFYEAR"
   125  	ddl		"DDL"
   126  	deallocate	"DEALLOCATE"
   127  	defaultKwd	"DEFAULT"
   128  	delayed		"DELAYED"
   129  	delayKeyWrite	"DELAY_KEY_WRITE"
   130  	deleteKwd	"DELETE"
   131  	desc		"DESC"
   132  	describe	"DESCRIBE"
   133  	disable		"DISABLE"
   134  	distinct	"DISTINCT"
   135  	div 		"DIV"
   136  	do		"DO"
   137  	drop		"DROP"
   138  	dual 		"DUAL"
   139  	duplicate	"DUPLICATE"
   140  	dynamic		"DYNAMIC"
   141  	elseKwd		"ELSE"
   142  	enable		"ENABLE"
   143  	end		"END"
   144  	engine		"ENGINE"
   145  	engines		"ENGINES"
   146  	enum 		"ENUM"
   147  	eq		"="
   148  	escape 		"ESCAPE"
   149  	execute		"EXECUTE"
   150  	exists		"EXISTS"
   151  	explain		"EXPLAIN"
   152  	extract		"EXTRACT"
   153  	falseKwd	"false"
   154  	fields		"FIELDS"
   155  	first		"FIRST"
   156  	fixed		"FIXED"
   157  	foreign		"FOREIGN"
   158  	forKwd		"FOR"
   159  	force		"FORCE"
   160  	foundRows	"FOUND_ROWS"
   161  	from		"FROM"
   162  	full		"FULL"
   163  	fulltext	"FULLTEXT"
   164  	ge		">="
   165  	global		"GLOBAL"
   166  	grant		"GRANT"
   167  	grants		"GRANTS"
   168  	group		"GROUP"
   169  	groupConcat	"GROUP_CONCAT"
   170  	hash		"HASH"
   171  	having		"HAVING"
   172  	highPriority	"HIGH_PRIORITY"
   173  	hour		"HOUR"
   174  	identified	"IDENTIFIED"
   175  	ignore		"IGNORE"
   176  	ifKwd		"IF"
   177  	ifNull		"IFNULL"
   178  	in		"IN"
   179  	index		"INDEX"
   180  	inner 		"INNER"
   181  	insert		"INSERT"
   182  	interval	"INTERVAL"
   183  	into		"INTO"
   184  	is		"IS"
   185  	isNull		"ISNULL"
   186  	isolation	"ISOLATION"
   187  	join		"JOIN"
   188  	key		"KEY"
   189  	keyBlockSize	"KEY_BLOCK_SIZE"
   190  	keys		"KEYS"
   191  	le		"<="
   192  	leading		"LEADING"
   193  	left		"LEFT"
   194  	length		"LENGTH"
   195  	level		"LEVEL"
   196  	like		"LIKE"
   197  	limit		"LIMIT"
   198  	local		"LOCAL"
   199  	locate		"LOCATE"
   200  	lock		"LOCK"
   201  	lower 		"LOWER"
   202  	lcase 		"LCASE"
   203  	lowPriority	"LOW_PRIORITY"
   204  	lsh		"<<"
   205  	ltrim		"LTRIM"
   206  	max		"MAX"
   207  	maxRows		"MAX_ROWS"
   208  	microsecond	"MICROSECOND"
   209  	min		"MIN"
   210  	minute		"MINUTE"
   211  	minRows		"MIN_ROWS"
   212  	mod 		"MOD"
   213  	mode		"MODE"
   214  	month		"MONTH"
   215  	names		"NAMES"
   216  	national	"NATIONAL"
   217  	neq		"!="
   218  	neqSynonym	"<>"
   219  	not		"NOT"
   220  	null		"NULL"
   221  	nulleq		"<=>"
   222  	nullIf		"NULLIF"
   223  	offset		"OFFSET"
   224  	on		"ON"
   225  	only		"ONLY"
   226  	option		"OPTION"
   227  	or		"OR"
   228  	order		"ORDER"
   229  	oror		"||"
   230  	outer		"OUTER"
   231  	password	"PASSWORD"
   232  	placeholder	"PLACEHOLDER"
   233  	pow 		"POW"
   234  	power 		"POWER"
   235  	prepare		"PREPARE"
   236  	primary		"PRIMARY"
   237  	procedure	"PROCEDURE"
   238  	quarter		"QUARTER"
   239  	quick		"QUICK"
   240  	rand		"RAND"
   241  	read		"READ"
   242  	redundant	"REDUNDANT"
   243  	references	"REFERENCES"
   244  	regexpKwd	"REGEXP"
   245  	repeat		"REPEAT"
   246  	repeatable	"REPEATABLE"
   247  	replace		"REPLACE"
   248  	right		"RIGHT"
   249  	rlike		"RLIKE"
   250  	rollback	"ROLLBACK"
   251  	round		"ROUND"
   252  	row 		"ROW"
   253  	rowFormat	"ROW_FORMAT"
   254  	rsh		">>"
   255  	rtrim 		"RTRIM"
   256  	reverse		"REVERSE"
   257  	schema		"SCHEMA"
   258  	schemas		"SCHEMAS"
   259  	second		"SECOND"
   260  	selectKwd	"SELECT"
   261  	serializable	"SERIALIZABLE"
   262  	session		"SESSION"
   263  	set		"SET"
   264  	share		"SHARE"
   265  	show		"SHOW"
   266  	signed		"SIGNED"
   267  	some 		"SOME"
   268  	start		"START"
   269  	status		"STATUS"
   270  	stringType	"string"
   271  	subDate		"SUBDATE"
   272  	strcmp		"STRCMP"
   273  	substring	"SUBSTRING"
   274  	substringIndex	"SUBSTRING_INDEX"
   275  	sum		"SUM"
   276  	sysVar		"SYS_VAR"
   277  	sysDate		"SYSDATE"
   278  	tableKwd	"TABLE"
   279  	tables		"TABLES"
   280  	then		"THEN"
   281  	to		"TO"
   282  	trailing	"TRAILING"
   283  	transaction	"TRANSACTION"
   284  	triggers	"TRIGGERS"
   285  	trim		"TRIM"
   286  	trueKwd		"true"
   287  	truncate	"TRUNCATE"
   288  	uncommitted	"UNCOMMITTED"
   289  	underscoreCS	"UNDERSCORE_CHARSET"
   290  	unknown 	"UNKNOWN"
   291  	union		"UNION"
   292  	unique		"UNIQUE"
   293  	unlock		"UNLOCK"
   294  	unsigned	"UNSIGNED"
   295  	update		"UPDATE"
   296  	upper 		"UPPER"
   297  	ucase 		"UCASE"
   298  	use		"USE"
   299  	user		"USER"
   300  	using		"USING"
   301  	userVar		"USER_VAR"
   302  	value		"VALUE"
   303  	values		"VALUES"
   304  	variables	"VARIABLES"
   305  	version		"VERSION"
   306  	warnings	"WARNINGS"
   307  	week		"WEEK"
   308  	weekday		"WEEKDAY"
   309  	weekofyear	"WEEKOFYEAR"
   310  	when		"WHEN"
   311  	where		"WHERE"
   312  	write		"WRITE"
   313  	xor 		"XOR"
   314  	yearweek	"YEARWEEK"
   315  	zerofill	"ZEROFILL"
   316  	
   317  	calcFoundRows	"SQL_CALC_FOUND_ROWS"
   318  	sqlCache	"SQL_CACHE"
   319  	sqlNoCache	"SQL_NO_CACHE"
   320  
   321  	currentTs	"CURRENT_TIMESTAMP"
   322  	localTime	"LOCALTIME"
   323  	localTs		"LOCALTIMESTAMP"
   324  	now		"NOW"
   325  	
   326  	tinyIntType	"TINYINT"
   327  	smallIntType	"SMALLINT"
   328  	mediumIntType	"MEDIUMINT"
   329  	intType		"INT"
   330  	integerType	"INTEGER"
   331  	bigIntType	"BIGINT"
   332  	bitType		"BIT"
   333  	
   334  	decimalType	"DECIMAL"
   335  	numericType	"NUMERIC"
   336  	floatType	"float"
   337  	doubleType	"DOUBLE"
   338  	precisionType	"PRECISION"
   339  	realType	"REAL"
   340  	
   341  	dateType	"DATE"
   342  	timeType	"TIME"
   343  	datetimeType	"DATETIME"
   344  	timestampType	"TIMESTAMP"
   345  	yearType	"YEAR"
   346  	
   347  	charType	"CHAR"
   348  	varcharType	"VARCHAR"
   349  	binaryType	"BINARY"
   350  	varbinaryType	"VARBINARY"
   351  	tinyblobType	"TINYBLOB"
   352  	blobType	"BLOB"
   353  	mediumblobType	"MEDIUMBLOB"
   354  	longblobType	"LONGBLOB"
   355  	tinytextType	"TINYTEXT"
   356  	textType	"TEXT"
   357  	mediumtextType	"MEDIUMTEXT"
   358  	longtextType	"LONGTEXT"
   359  	
   360  	int16Type	"int16"
   361  	int24Type	"int24"
   362  	int32Type	"int32"
   363  	int64Type	"int64"
   364  	int8Type	"int8"
   365  	uintType	"uint"
   366  	uint16Type	"uint16"
   367  	uint32Type	"uint32"
   368  	uint64Type	"uint64"
   369  	uint8Type	"uint8"
   370  	float32Type	"float32"
   371  	float64Type	"float64"
   372  	boolType	"BOOL"
   373  	booleanType	"BOOLEAN"
   374  
   375  	parseExpression	"parse expression prefix"
   376  
   377  	secondMicrosecond	"SECOND_MICROSECOND"
   378  	minuteMicrosecond	"MINUTE_MICROSECOND"
   379  	minuteSecond 		"MINUTE_SECOND"
   380  	hourMicrosecond		"HOUR_MICROSECOND"
   381  	hourSecond 		"HOUR_SECOND"
   382  	hourMinute 		"HOUR_MINUTE"
   383  	dayMicrosecond 		"DAY_MICROSECOND"
   384  	daySecond 		"DAY_SECOND"
   385  	dayMinute 		"DAY_MINUTE"
   386  	dayHour			"DAY_HOUR"
   387  	yearMonth		"YEAR_MONTH"
   388  
   389  	restrict	"RESTRICT"
   390  	cascade		"CASCADE"
   391  	no		"NO"
   392  	action		"ACTION"
   393  
   394  
   395  %type   <item>
   396  	AdminStmt		"Check table statement or show ddl statement"
   397  	AlterTableStmt		"Alter table statement"
   398  	AlterTableSpec		"Alter table specification"
   399  	AlterTableSpecList	"Alter table specification list"
   400  	AnyOrAll		"Any or All for subquery"
   401  	Assignment		"assignment"
   402  	AssignmentList		"assignment list"
   403  	AssignmentListOpt	"assignment list opt"
   404  	AuthOption		"User auth option"
   405  	AuthString		"Password string value"
   406  	BeginTransactionStmt	"BEGIN TRANSACTION statement"
   407  	CastType		"Cast function target type"
   408  	ColumnDef		"table column definition"
   409  	ColumnName		"column name"
   410  	ColumnNameList		"column name list"
   411  	ColumnNameListOpt	"column name list opt"
   412  	ColumnKeywordOpt	"Column keyword or empty"
   413  	ColumnSetValue		"insert statement set value by column name"
   414  	ColumnSetValueList	"insert statement set value by column name list"
   415  	CommaOpt		"optional comma"
   416  	CommitStmt		"COMMIT statement"
   417  	CompareOp		"Compare opcode"
   418  	ColumnOption		"column definition option"
   419  	ColumnOptionList	"column definition option list"
   420  	ColumnOptionListOpt	"optional column definition option list"
   421  	Constraint		"table constraint"
   422  	ConstraintElem		"table constraint element"
   423  	ConstraintKeywordOpt	"Constraint Keyword or empty"
   424  	CreateDatabaseStmt	"Create Database Statement"
   425  	CreateIndexStmt		"CREATE INDEX statement"
   426  	CreateIndexStmtUnique	"CREATE INDEX optional UNIQUE clause"
   427  	DatabaseOption		"CREATE Database specification"
   428  	DatabaseOptionList	"CREATE Database specification list"
   429  	DatabaseOptionListOpt	"CREATE Database specification list opt"
   430  	CreateTableStmt		"CREATE TABLE statement"
   431  	CreateUserStmt		"CREATE User statement"
   432  	CrossOpt		"Cross join option"
   433  	DateArithOpt		"Date arith dateadd or datesub option"
   434  	DateArithMultiFormsOpt	"Date arith adddate or subdate option"
   435  	DateArithInterval       "Date arith interval part"
   436  	DatabaseSym		"DATABASE or SCHEMA"
   437  	DBName			"Database Name"
   438  	DeallocateSym		"Deallocate or drop"
   439  	DeallocateStmt		"Deallocate prepared statement"
   440  	Default			"DEFAULT clause"
   441  	DefaultOpt		"optional DEFAULT clause"
   442  	DefaultKwdOpt		"optional DEFAULT keyword"
   443  	DefaultValueExpr	"DefaultValueExpr(Now or Signed Literal)"
   444  	DeleteFromStmt		"DELETE FROM statement"
   445  	DistinctOpt		"Distinct option"
   446  	DoStmt			"Do statement"
   447  	DropDatabaseStmt	"DROP DATABASE statement"
   448  	DropIndexStmt		"DROP INDEX statement"
   449  	DropTableStmt		"DROP TABLE statement"
   450  	EmptyStmt		"empty statement"
   451  	EqOpt			"= or empty"
   452  	EscapedTableRef 	"escaped table reference"
   453  	ExecuteStmt		"Execute statement"
   454  	ExplainSym		"EXPLAIN or DESCRIBE or DESC"
   455  	ExplainStmt		"EXPLAIN statement"
   456  	Expression		"expression"
   457  	ExpressionList		"expression list"
   458  	ExpressionListOpt	"expression list opt"
   459  	ExpressionListList	"expression list list"
   460  	Factor			"expression factor"
   461  	PredicateExpr		"Predicate expression factor"
   462  	Field			"field expression"
   463  	FieldAsName		"Field alias name"
   464  	FieldAsNameOpt		"Field alias name opt"
   465  	FieldList		"field expression list"
   466  	TableRefsClause		"Table references clause"
   467  	Function		"function expr"
   468  	FunctionCallAgg		"Function call on aggregate data"
   469  	FunctionCallConflict	"Function call with reserved keyword as function name"
   470  	FunctionCallKeyword	"Function call with keyword as function name"
   471  	FunctionCallNonKeyword	"Function call with nonkeyword as function name"
   472  	FunctionNameConflict	"Built-in function call names which are conflict with keywords"
   473  	FuncDatetimePrec	"Function datetime precision"
   474  	GlobalScope		"The scope of variable"
   475  	GrantStmt		"Grant statement"
   476  	GroupByClause		"GROUP BY clause"
   477  	HashString		"Hashed string"
   478  	HavingClause		"HAVING clause"
   479  	IfExists		"If Exists"
   480  	IfNotExists		"If Not Exists"
   481  	IgnoreOptional		"IGNORE or empty"
   482  	IndexColName		"Index column name"
   483  	IndexColNameList	"List of index column name"
   484  	IndexHint		"index hint"
   485  	IndexHintList		"index hint list"
   486  	IndexHintListOpt	"index hint list opt"
   487  	IndexHintScope		"index hint scope"
   488  	IndexHintType		"index hint type"
   489  	IndexName		"index name"
   490  	IndexNameList		"index name list"
   491  	IndexOption		"Index Option"
   492  	IndexType		"index type"
   493  	IndexTypeOpt		"Optional index type"
   494  	InsertIntoStmt		"INSERT INTO statement"
   495  	InsertValues		"Rest part of INSERT/REPLACE INTO statement"
   496  	IntoOpt			"INTO or EmptyString"
   497  	IsolationLevel		"Isolation level"
   498  	JoinTable 		"join table"
   499  	JoinType		"join type"
   500  	KeyOrIndex		"{KEY|INDEX}"
   501  	LikeEscapeOpt 		"like escape option"
   502  	LimitClause		"LIMIT clause"
   503  	Literal			"literal value"
   504  	LockTablesStmt		"Lock tables statement"
   505  	LockType		"Table locks type"
   506  	logAnd			"logical and operator"
   507  	logOr			"logical or operator"
   508  	LowPriorityOptional	"LOW_PRIORITY or empty"
   509  	name			"name"
   510  	NationalOpt		"National option"
   511  	NotOpt			"optional NOT"
   512  	NowSym			"CURRENT_TIMESTAMP/LOCALTIME/LOCALTIMESTAMP/NOW"
   513  	NumLiteral		"Num/Int/Float/Decimal Literal"
   514  	ObjectType		"Grant statement object type"
   515  	OnDuplicateKeyUpdate	"ON DUPLICATE KEY UPDATE value list"
   516  	Operand			"operand"
   517  	OptFull			"Full or empty"
   518  	OptInteger		"Optional Integer keyword"
   519  	OptTable		"Optional table keyword"
   520  	Order			"ORDER BY clause optional collation specification"
   521  	OrderBy			"ORDER BY clause"
   522  	ByItem			"BY item"
   523  	OrderByOptional		"Optional ORDER BY clause optional"
   524  	ByList			"BY list"
   525  	OuterOpt		"optional OUTER clause"
   526  	QuickOptional		"QUICK or empty"
   527  	PasswordOpt		"Password option"
   528  	ColumnPosition		"Column position [First|After ColumnName]"
   529  	PreparedStmt		"PreparedStmt"
   530  	PrepareSQL		"Prepare statement sql string"
   531  	PrimaryExpression	"primary expression"
   532  	PrimaryFactor		"primary expression factor"
   533  	PrimaryOpt		"Optional primary keyword"
   534  	Priority		"insert statement priority"
   535  	PrivElem		"Privilege element"
   536  	PrivElemList		"Privilege element list"
   537  	PrivLevel		"Privilege scope"
   538  	PrivType		"Privilege type"
   539  	ReferDef		"Reference definition"
   540  	OnDeleteOpt		"optional ON DELETE clause"
   541  	OnUpdateOpt		"optional ON UPDATE clause"
   542  	ReferOpt		"reference option"
   543  	RegexpSym		"REGEXP or RLIKE"
   544  	ReplaceIntoStmt		"REPLACE INTO statement"
   545  	ReplacePriority		"replace statement priority"
   546  	RollbackStmt		"ROLLBACK statement"
   547  	RowFormat		"Row format option"
   548  	SelectLockOpt		"FOR UPDATE or LOCK IN SHARE MODE,"
   549  	SelectStmt		"SELECT statement"
   550  	SelectStmtCalcFoundRows	"SELECT statement optional SQL_CALC_FOUND_ROWS"
   551  	SelectStmtSQLCache	"SELECT statement optional SQL_CAHCE/SQL_NO_CACHE"
   552  	SelectStmtDistinct	"SELECT statement optional DISTINCT clause"
   553  	SelectStmtFieldList	"SELECT statement field list"
   554  	SelectStmtLimit		"SELECT statement optional LIMIT clause"
   555  	SelectStmtOpts		"Select statement options"
   556  	SelectStmtGroup		"SELECT statement optional GROUP BY clause"
   557  	SetStmt			"Set variable statement"
   558  	ShowStmt		"Show engines/databases/tables/columns/warnings/status statement"
   559  	ShowTargetFilterable    "Show target that can be filtered by WHERE or LIKE"
   560  	ShowDatabaseNameOpt	"Show tables/columns statement database name option"
   561  	ShowTableAliasOpt       "Show table alias option"
   562  	ShowLikeOrWhereOpt	"Show like or where clause option"
   563  	SignedLiteral		"Literal or NumLiteral with sign"
   564  	Statement		"statement"
   565  	StatementList		"statement list"
   566  	StringName		"string literal or identifier"
   567  	StringList 		"string list"
   568  	ExplainableStmt		"explainable statement"
   569  	SubSelect		"Sub Select"
   570  	Symbol			"Constraint Symbol"
   571  	SystemVariable		"System defined variable name"
   572  	TableAsName		"table alias name"
   573  	TableAsNameOpt 		"table alias name optional"
   574  	TableElement		"table definition element"
   575  	TableElementList	"table definition element list"
   576  	TableFactor 		"table factor"
   577  	TableLock		"Table name and lock type"
   578  	TableLockList		"Table lock list"
   579  	TableName		"Table name"
   580  	TableNameList		"Table name list"
   581  	TableOption		"create table option"
   582  	TableOptionList		"create table option list"
   583  	TableOptionListOpt	"create table option list opt"
   584  	TableRef 		"table reference"
   585  	TableRefs 		"table references"
   586  	TimeUnit		"Time unit"
   587  	TransactionChar		"Transaction characteristic"
   588  	TransactionChars	"Transaction characteristic list"
   589  	TrimDirection		"Trim string direction"
   590  	TruncateTableStmt	"TRANSACTION TABLE statement"
   591  	UnionOpt		"Union Option(empty/ALL/DISTINCT)"
   592  	UnionStmt		"Union select state ment"
   593  	UnionClauseList		"Union select clause list"
   594  	UnionSelect		"Union (select) item"
   595  	UnlockTablesStmt	"Unlock tables statement"
   596  	UpdateStmt		"UPDATE statement"
   597  	Username		"Username"
   598  	UserSpec		"Username and auth option"
   599  	UserSpecList		"Username and auth option list"
   600  	UserVariable		"User defined variable name"
   601  	UserVariableList	"User defined variable name list"
   602  	UseStmt			"USE statement"
   603  	ValueSym		"Value or Values"
   604  	VariableAssignment	"set variable value"
   605  	VariableAssignmentList	"set variable value list"
   606  	Variable		"User or system variable"
   607  	WhereClause		"WHERE clause"
   608  	WhereClauseOptional	"Optinal WHERE clause"
   609  
   610  	Identifier		"identifier or unreserved keyword"
   611  	UnReservedKeyword	"MySQL unreserved keywords"
   612  	NotKeywordToken		"Tokens not mysql keyword but treated specially"
   613  
   614  	WhenClause		"When clause"
   615  	WhenClauseList		"When clause list"
   616  	ElseOpt			"Optional else clause"
   617  	ExpressionOpt		"Optional expression"
   618  
   619  	Type			"Types"
   620  
   621  	NumericType		"Numeric types"
   622  	IntegerType		"Integer Types types"
   623  	FixedPointType		"Exact value types"
   624  	FloatingPointType	"Approximate value types"
   625  	BitValueType		"bit value types"
   626  
   627  	StringType		"String types"
   628  	BlobType		"Blob types"
   629  	TextType		"Text types"
   630  
   631  	DateAndTimeType		"Date and Time types"
   632  
   633  	OptFieldLen		"Field length or empty"
   634  	FieldLen		"Field length"
   635  	FieldOpts		"Field type definition option list"
   636  	FieldOpt		"Field type definition option"
   637  	FloatOpt		"Floating-point type option"
   638  	Precision		"Floating-point precision option"
   639  	OptBinary		"Optional BINARY"
   640  	CharsetKw		"charset or charater set"
   641  	OptCharset		"Optional Character setting"
   642  	OptCollate		"Optional Collate setting"
   643  	NUM			"numbers"
   644  	LengthNum		"Field length num(uint64)"
   645  
   646  %token	tableRefPriority
   647  
   648  %precedence lowerThanCalcFoundRows
   649  %precedence calcFoundRows
   650  
   651  %precedence lowerThanSQLCache
   652  %precedence sqlCache sqlNoCache
   653  
   654  %precedence lowerThanSetKeyword
   655  %precedence set
   656  
   657  %precedence lowerThanInsertValues
   658  %precedence insertValues
   659  
   660  %precedence lowerThanKey
   661  %precedence key 
   662  
   663  %left   join inner cross left right full
   664  /* A dummy token to force the priority of TableRef production in a join. */
   665  %left   tableRefPriority
   666  %precedence lowerThanOn
   667  %precedence on
   668  %right  assignmentEq
   669  %left 	oror or
   670  %left 	xor
   671  %left 	andand and
   672  %left 	between
   673  %precedence	lowerThanEq
   674  %left 	eq ge le neq neqSynonym '>' '<' is like in
   675  %left 	'|'
   676  %left 	'&'
   677  %left 	rsh lsh
   678  %left 	'-' '+'
   679  %left 	'*' '/' '%' div mod
   680  %left 	'^'
   681  %left 	'~' neg
   682  %right 	not
   683  %right	collate
   684  
   685  %precedence lowerThanLeftParen
   686  %precedence '('
   687  %precedence lowerThanQuick
   688  %precedence quick
   689  %precedence lowerThanEscape
   690  %precedence escape
   691  %precedence lowerThanComma
   692  %precedence ','
   693  
   694  %start	Start
   695  
   696  %%
   697  
   698  Start:
   699  	StatementList
   700  |	parseExpression Expression
   701  	{
   702  		yylex.(*lexer).expr = $2.(ast.ExprNode)
   703  	}
   704  
   705  /**************************************AlterTableStmt***************************************
   706   * See: https://dev.mysql.com/doc/refman/5.7/en/alter-table.html
   707   *******************************************************************************************/
   708  AlterTableStmt:
   709  	"ALTER" IgnoreOptional "TABLE" TableName AlterTableSpecList
   710  	{
   711  		$$ = &ast.AlterTableStmt{
   712  			Table: $4.(*ast.TableName),
   713  			Specs: $5.([]*ast.AlterTableSpec),
   714  		}
   715  	}
   716  
   717  AlterTableSpec:
   718  	TableOptionListOpt
   719  	{
   720  		$$ = &ast.AlterTableSpec{
   721  			Tp:	ast.AlterTableOption,
   722  			Options:$1.([]*ast.TableOption),
   723  		}
   724  	}
   725  |	"ADD" ColumnKeywordOpt ColumnDef ColumnPosition
   726  	{
   727  		$$ = &ast.AlterTableSpec{
   728  			Tp: 		ast.AlterTableAddColumn,
   729  			Column:		$3.(*ast.ColumnDef),
   730  			Position:	$4.(*ast.ColumnPosition),
   731  		}
   732  	}	
   733  |	"ADD" Constraint
   734  	{
   735  		constraint := $2.(*ast.Constraint)
   736  		$$ = &ast.AlterTableSpec{
   737  			Tp: ast.AlterTableAddConstraint,
   738  			Constraint: constraint,
   739  		}
   740  	}
   741  |	"DROP" ColumnKeywordOpt ColumnName
   742  	{
   743  		$$ = &ast.AlterTableSpec{
   744  			Tp: ast.AlterTableDropColumn,
   745  			DropColumn: $3.(*ast.ColumnName),
   746  		}
   747  	}
   748  |	"DROP" "PRIMARY" "KEY"
   749  	{
   750  		$$ = &ast.AlterTableSpec{Tp: ast.AlterTableDropPrimaryKey}
   751  	}
   752  |	"DROP" KeyOrIndex IndexName
   753  	{
   754  		$$ = &ast.AlterTableSpec{
   755  			Tp: ast.AlterTableDropIndex,
   756  			Name: $3.(string),
   757  		}
   758  	}
   759  |	"DROP" "FOREIGN" "KEY" Symbol
   760  	{
   761  		$$ = &ast.AlterTableSpec{
   762  			Tp: ast.AlterTableDropForeignKey,
   763  			Name: $4.(string),
   764  		}
   765  	}
   766  |	"DISABLE" "KEYS"
   767  	{
   768  		$$ = &ast.AlterTableSpec{}
   769  	}
   770  |	"ENABLE" "KEYS"
   771  	{
   772  		$$ = &ast.AlterTableSpec{}
   773  	}
   774  
   775  KeyOrIndex:
   776  	"KEY"|"INDEX"
   777  
   778  ColumnKeywordOpt:
   779  	{}
   780  |	"COLUMN"
   781  
   782  ColumnPosition:
   783  	{
   784  		$$ = &ast.ColumnPosition{Tp: ast.ColumnPositionNone}
   785  	}	
   786  |	"FIRST"
   787  	{
   788  		$$ = &ast.ColumnPosition{Tp: ast.ColumnPositionFirst}
   789  	}
   790  |	"AFTER" ColumnName
   791  	{
   792  		$$ = &ast.ColumnPosition{
   793  			Tp: ast.ColumnPositionAfter,
   794  			RelativeColumn: $2.(*ast.ColumnName),
   795  		}
   796  	}
   797  
   798  AlterTableSpecList:
   799  	AlterTableSpec
   800  	{
   801  		$$ = []*ast.AlterTableSpec{$1.(*ast.AlterTableSpec)}
   802  	}
   803  |	AlterTableSpecList ',' AlterTableSpec
   804  	{
   805  		$$ = append($1.([]*ast.AlterTableSpec), $3.(*ast.AlterTableSpec))
   806  	}
   807  
   808  ConstraintKeywordOpt:
   809  	{
   810  		$$ = nil
   811  	}
   812  |	"CONSTRAINT" 
   813  	{
   814  		$$ = nil
   815  	}
   816  |	"CONSTRAINT" Symbol 
   817  	{
   818  		$$ = $2.(string)
   819  	}
   820  
   821  Symbol:
   822  	Identifier
   823  
   824  /*******************************************************************************************/
   825  Assignment:
   826  	ColumnName eq Expression
   827  	{
   828  		$$ = &ast.Assignment{Column: $1.(*ast.ColumnName), Expr:$3.(ast.ExprNode)}
   829  	}
   830  
   831  AssignmentList:
   832  	Assignment
   833  	{
   834  		$$ = []*ast.Assignment{$1.(*ast.Assignment)}
   835  	}
   836  |	AssignmentList ',' Assignment
   837  	{
   838  		$$ = append($1.([]*ast.Assignment), $3.(*ast.Assignment))
   839  	}
   840  
   841  AssignmentListOpt:
   842  	/* EMPTY */
   843  	{
   844  		$$ = []*ast.Assignment{}
   845  	}
   846  |	AssignmentList
   847  
   848  BeginTransactionStmt:
   849  	"BEGIN"
   850  	{
   851  		$$ = &ast.BeginStmt{}
   852  	}
   853  |	"START" "TRANSACTION"
   854  	{
   855  		$$ = &ast.BeginStmt{}
   856  	}
   857  
   858  ColumnDef:
   859  	ColumnName Type ColumnOptionListOpt
   860  	{
   861  		$$ = &ast.ColumnDef{Name: $1.(*ast.ColumnName), Tp: $2.(*types.FieldType), Options: $3.([]*ast.ColumnOption)}
   862  	}
   863  
   864  ColumnName:
   865  	Identifier
   866  	{
   867  		$$ = &ast.ColumnName{Name: model.NewCIStr($1.(string))}
   868  	}
   869  |	Identifier '.' Identifier
   870  	{
   871  		$$ = &ast.ColumnName{Table: model.NewCIStr($1.(string)), Name: model.NewCIStr($3.(string))}
   872  	}
   873  |	Identifier '.' Identifier '.' Identifier
   874  	{
   875  		$$ = &ast.ColumnName{Schema: model.NewCIStr($1.(string)), Table: model.NewCIStr($3.(string)), Name: model.NewCIStr($5.(string))}
   876  	}
   877  
   878  ColumnNameList:
   879  	ColumnName
   880  	{
   881  		$$ = []*ast.ColumnName{$1.(*ast.ColumnName)}
   882  	}
   883  |	ColumnNameList ',' ColumnName
   884  	{
   885  		$$ = append($1.([]*ast.ColumnName), $3.(*ast.ColumnName))
   886  	}
   887  
   888  ColumnNameListOpt:
   889  	/* EMPTY */
   890  	{
   891  		$$ = []*ast.ColumnName{}
   892  	}
   893  |	ColumnNameList
   894  	{
   895  		$$ = $1.([]*ast.ColumnName)
   896  	}
   897  
   898  CommitStmt:
   899  	"COMMIT"
   900  	{
   901  		$$ = &ast.CommitStmt{}
   902  	}
   903  
   904  PrimaryOpt:
   905  	{} | "PRIMARY"
   906  
   907  ColumnOption:
   908  	"NOT" "NULL"
   909  	{
   910  		$$ = &ast.ColumnOption{Tp: ast.ColumnOptionNotNull}
   911  	}
   912  |	"NULL"
   913  	{
   914  		$$ = &ast.ColumnOption{Tp: ast.ColumnOptionNull}
   915  	}
   916  |	"AUTO_INCREMENT"
   917  	{
   918  		$$ = &ast.ColumnOption{Tp: ast.ColumnOptionAutoIncrement}
   919  	}
   920  |	PrimaryOpt "KEY" 
   921  	{
   922  		// KEY is normally a synonym for INDEX. The key attribute PRIMARY KEY 
   923  		// can also be specified as just KEY when given in a column definition. 
   924  		// See: http://dev.mysql.com/doc/refman/5.7/en/create-table.html
   925  		$$ = &ast.ColumnOption{Tp: ast.ColumnOptionPrimaryKey}
   926  	}
   927  |	"UNIQUE" %prec lowerThanKey
   928  	{
   929  		$$ = &ast.ColumnOption{Tp: ast.ColumnOptionUniqKey}
   930  	}
   931  |	"UNIQUE" "KEY"
   932  	{
   933  		$$ = &ast.ColumnOption{Tp: ast.ColumnOptionUniqKey}
   934  	}
   935  |	"DEFAULT" DefaultValueExpr
   936  	{
   937  		$$ = &ast.ColumnOption{Tp: ast.ColumnOptionDefaultValue, Expr: $2.(ast.ExprNode)}
   938  	}
   939  |	"ON" "UPDATE" NowSym
   940  	{
   941  		nowFunc := &ast.FuncCallExpr{FnName: model.NewCIStr("CURRENT_TIMESTAMP")}
   942  		$$ = &ast.ColumnOption{Tp: ast.ColumnOptionOnUpdate, Expr: nowFunc}
   943  	}
   944  |	"COMMENT" stringLit
   945  	{
   946  		$$ =  &ast.ColumnOption{Tp: ast.ColumnOptionComment, Expr: ast.NewValueExpr($2)}
   947  	}
   948  |	"CHECK" '(' Expression ')'
   949  	{
   950  		// See: https://dev.mysql.com/doc/refman/5.7/en/create-table.html
   951  		// The CHECK clause is parsed but ignored by all storage engines.
   952  		$$ = &ast.ColumnOption{}
   953  	}
   954  
   955  ColumnOptionList:
   956  	ColumnOption
   957  	{
   958  		$$ = []*ast.ColumnOption{$1.(*ast.ColumnOption)}
   959  	}
   960  |	ColumnOptionList ColumnOption
   961  	{
   962  		$$ = append($1.([]*ast.ColumnOption), $2.(*ast.ColumnOption))
   963  	}
   964  
   965  ColumnOptionListOpt:
   966  	{
   967  		$$ = []*ast.ColumnOption{}
   968  	}
   969  |	ColumnOptionList
   970  	{
   971  		$$ = $1.([]*ast.ColumnOption)
   972  	}
   973  
   974  ConstraintElem:
   975  	"PRIMARY" "KEY" IndexTypeOpt '(' IndexColNameList ')' IndexOption
   976  	{
   977  		c := &ast.Constraint{
   978  			Tp: ast.ConstraintPrimaryKey, 
   979  			Keys: $5.([]*ast.IndexColName),
   980  		}
   981  		if $7 != nil {
   982  			c.Option = $7.(*ast.IndexOption)
   983  		}
   984  		if $3 != nil {
   985  			if c.Option == nil {
   986  				c.Option = &ast.IndexOption{}
   987  			}
   988  			c.Option.Tp = $3.(model.IndexType)	
   989  		}
   990  		$$ = c
   991  	}
   992  |	"FULLTEXT" "KEY" IndexName '(' IndexColNameList ')' IndexOption
   993  	{
   994  		c := &ast.Constraint{
   995  			Tp:	ast.ConstraintFulltext,
   996  			Keys:	$5.([]*ast.IndexColName),
   997  			Name:	$3.(string),
   998  		}
   999  		if $7 != nil {
  1000  			c.Option = $7.(*ast.IndexOption)
  1001  		}
  1002  		$$ = c
  1003  	}
  1004  |	"INDEX" IndexName IndexTypeOpt '(' IndexColNameList ')' IndexOption
  1005  	{
  1006  		c := &ast.Constraint{
  1007  			Tp:	ast.ConstraintIndex,
  1008  			Keys:	$5.([]*ast.IndexColName),
  1009  			Name:	$2.(string),
  1010  		}
  1011  		if $7 != nil {
  1012  			c.Option = $7.(*ast.IndexOption)
  1013  		}
  1014  		if $3 != nil {
  1015  			if c.Option == nil {
  1016  				c.Option = &ast.IndexOption{}
  1017  			}
  1018  			c.Option.Tp = $3.(model.IndexType)	
  1019  		}
  1020  		$$ = c
  1021  	}
  1022  |	"KEY" IndexName IndexTypeOpt '(' IndexColNameList ')' IndexOption
  1023  	{
  1024  		c := &ast.Constraint{
  1025  			Tp:	ast.ConstraintKey,
  1026  			Keys:	$5.([]*ast.IndexColName),
  1027  			Name:	$2.(string),
  1028  		}
  1029  		if $7 != nil {
  1030  			c.Option = $7.(*ast.IndexOption)
  1031  		}
  1032  		if $3 != nil {
  1033  			if c.Option == nil {
  1034  				c.Option = &ast.IndexOption{}
  1035  			}
  1036  			c.Option.Tp = $3.(model.IndexType)	
  1037  		}
  1038  		$$ = c
  1039  	}
  1040  |	"UNIQUE" IndexName IndexTypeOpt '(' IndexColNameList ')' IndexOption
  1041  	{
  1042  		c := &ast.Constraint{
  1043  			Tp:	ast.ConstraintUniq,
  1044  			Keys:	$5.([]*ast.IndexColName),
  1045  			Name:	$2.(string),
  1046  		}
  1047  		if $7 != nil {
  1048  			c.Option = $7.(*ast.IndexOption)
  1049  		}
  1050  		if $3 != nil {
  1051  			if c.Option == nil {
  1052  				c.Option = &ast.IndexOption{}
  1053  			}
  1054  			c.Option.Tp = $3.(model.IndexType)	
  1055  		}
  1056  		$$ = c
  1057  	}
  1058  |	"UNIQUE" "INDEX" IndexName IndexTypeOpt '(' IndexColNameList ')' IndexOption
  1059  	{
  1060  		c := &ast.Constraint{
  1061  			Tp:	ast.ConstraintUniqIndex,
  1062  			Keys:	$6.([]*ast.IndexColName),
  1063  			Name:	$3.(string),
  1064  		}
  1065  		if $8 != nil {
  1066  			c.Option = $8.(*ast.IndexOption)
  1067  		}
  1068  		if $4 != nil {
  1069  			if c.Option == nil {
  1070  				c.Option = &ast.IndexOption{}
  1071  			}
  1072  			c.Option.Tp = $4.(model.IndexType)	
  1073  		}
  1074  		$$ = c
  1075  	}
  1076  |	"UNIQUE" "KEY" IndexName IndexTypeOpt '(' IndexColNameList ')' IndexOption
  1077  	{
  1078  		c := &ast.Constraint{
  1079  			Tp:	ast.ConstraintUniqKey,
  1080  			Keys:	$6.([]*ast.IndexColName),
  1081  			Name:	$3.(string),
  1082  		}
  1083  		if $8 != nil {
  1084  			c.Option = $8.(*ast.IndexOption)
  1085  		}
  1086  		if $4 != nil {
  1087  			if c.Option == nil {
  1088  				c.Option = &ast.IndexOption{}
  1089  			}
  1090  			c.Option.Tp = $4.(model.IndexType)	
  1091  		}
  1092  		$$ = c
  1093  	}
  1094  |	"FOREIGN" "KEY" IndexName '(' IndexColNameList ')' ReferDef
  1095  	{
  1096  		$$ = &ast.Constraint{
  1097  			Tp:	ast.ConstraintForeignKey,
  1098  			Keys:	$5.([]*ast.IndexColName),
  1099  			Name:	$3.(string),
  1100  			Refer:	$7.(*ast.ReferenceDef),
  1101  		}
  1102  	}
  1103  
  1104  ReferDef:
  1105  	"REFERENCES" TableName '(' IndexColNameList ')' OnDeleteOpt OnUpdateOpt
  1106  	{
  1107  		var onDeleteOpt *ast.OnDeleteOpt
  1108  		if $6 != nil {
  1109  			onDeleteOpt = $6.(*ast.OnDeleteOpt)
  1110  		}
  1111  		var onUpdateOpt *ast.OnUpdateOpt
  1112  		if $7 != nil {
  1113  			onUpdateOpt = $7.(*ast.OnUpdateOpt)
  1114  		}
  1115  		$$ = &ast.ReferenceDef{
  1116  			Table: $2.(*ast.TableName),
  1117  			IndexColNames: $4.([]*ast.IndexColName),
  1118  			OnDelete: onDeleteOpt,
  1119  			OnUpdate: onUpdateOpt,
  1120  		}
  1121  	}
  1122  
  1123  OnDeleteOpt:
  1124  	{
  1125  		$$ = &ast.OnDeleteOpt{}
  1126  	} %prec lowerThanOn
  1127  |	"ON" "DELETE" ReferOpt
  1128  	{
  1129  		$$ = &ast.OnDeleteOpt{ReferOpt: $3.(ast.ReferOptionType)}
  1130  	}
  1131  
  1132  OnUpdateOpt:
  1133  	{
  1134  		$$ = &ast.OnUpdateOpt{}
  1135  	} %prec lowerThanOn
  1136  |	"ON" "UPDATE" ReferOpt
  1137  	{
  1138  		$$ = &ast.OnUpdateOpt{ReferOpt: $3.(ast.ReferOptionType)}
  1139  	}
  1140  
  1141  ReferOpt:
  1142  	"RESTRICT"
  1143  	{
  1144  		$$ = ast.ReferOptionRestrict
  1145  	}
  1146  |	"CASCADE"
  1147  	{
  1148  		$$ = ast.ReferOptionCascade
  1149  	}
  1150  |	"SET" "NULL"
  1151  	{
  1152  		$$ = ast.ReferOptionSetNull
  1153  	}
  1154  |	"NO" "ACTION"
  1155  	{
  1156  		$$ = ast.ReferOptionNoAction
  1157  	}
  1158  
  1159  /*
  1160   * The DEFAULT clause specifies a default value for a column. 
  1161   * With one exception, the default value must be a constant; 
  1162   * it cannot be a function or an expression. This means, for example, 
  1163   * that you cannot set the default for a date column to be the value of 
  1164   * a function such as NOW() or CURRENT_DATE. The exception is that you 
  1165   * can specify CURRENT_TIMESTAMP as the default for a TIMESTAMP or DATETIME column.
  1166   *
  1167   * See: http://dev.mysql.com/doc/refman/5.7/en/create-table.html
  1168   *      https://github.com/mysql/mysql-server/blob/5.7/sql/sql_yacc.yy#L6832
  1169   */
  1170  DefaultValueExpr:
  1171  	NowSym
  1172  	{
  1173  		$$ = &ast.FuncCallExpr{FnName: model.NewCIStr("CURRENT_TIMESTAMP")}
  1174  	}
  1175  |	NowSym '(' ')'
  1176  	{
  1177  		$$ = &ast.FuncCallExpr{FnName: model.NewCIStr("CURRENT_TIMESTAMP")}
  1178  	}
  1179  |	SignedLiteral
  1180  
  1181  // TODO: Process other three keywords
  1182  NowSym:
  1183  	"CURRENT_TIMESTAMP"
  1184  |	"LOCALTIME"
  1185  |	"LOCALTIMESTAMP"
  1186  |	"NOW"
  1187  
  1188  SignedLiteral:
  1189  	Literal
  1190  	{
  1191  		$$ = ast.NewValueExpr($1)
  1192  	}
  1193  |	'+' NumLiteral
  1194  	{
  1195  		$$ = &ast.UnaryOperationExpr{Op: opcode.Plus, V: ast.NewValueExpr($2)}
  1196  	}
  1197  |	'-' NumLiteral
  1198  	{
  1199  		$$ = &ast.UnaryOperationExpr{Op: opcode.Minus, V: ast.NewValueExpr($2)}
  1200  	}
  1201  
  1202  // TODO: support decimal literal
  1203  NumLiteral:
  1204  	intLit
  1205  |	floatLit
  1206  
  1207  
  1208  CreateIndexStmt:
  1209  	"CREATE" CreateIndexStmtUnique "INDEX" Identifier "ON" TableName '(' IndexColNameList ')'
  1210  	{
  1211  		$$ = &ast.CreateIndexStmt{
  1212  			Unique: $2.(bool),
  1213  			IndexName: $4.(string),
  1214                  	Table: $6.(*ast.TableName),
  1215  			IndexColNames: $8.([]*ast.IndexColName),
  1216  		}
  1217  		if yylex.(*lexer).root {
  1218  			break
  1219  		}
  1220  	}
  1221  
  1222  CreateIndexStmtUnique:
  1223  	{
  1224  		$$ = false
  1225  	}
  1226  |	"UNIQUE"
  1227  	{
  1228  		$$ = true
  1229  	}
  1230  
  1231  IndexColName:
  1232  	ColumnName OptFieldLen Order
  1233  	{
  1234  		//Order is parsed but just ignored as MySQL did
  1235  		$$ = &ast.IndexColName{Column: $1.(*ast.ColumnName), Length: $2.(int)}
  1236  	}
  1237  
  1238  IndexColNameList:
  1239  	{
  1240  		$$ = []*ast.IndexColName{}
  1241  	}
  1242  |	IndexColName
  1243  	{
  1244  		$$ = []*ast.IndexColName{$1.(*ast.IndexColName)}
  1245  	}
  1246  |	IndexColNameList ',' IndexColName
  1247  	{
  1248  		$$ = append($1.([]*ast.IndexColName), $3.(*ast.IndexColName))
  1249  	}
  1250  
  1251  
  1252  
  1253  /*******************************************************************
  1254   *
  1255   *  Create Database Statement
  1256   *  CREATE {DATABASE | SCHEMA} [IF NOT EXISTS] db_name
  1257   *      [create_specification] ...
  1258   *
  1259   *  create_specification:
  1260   *      [DEFAULT] CHARACTER SET [=] charset_name
  1261   *    | [DEFAULT] COLLATE [=] collation_name
  1262   *******************************************************************/
  1263  CreateDatabaseStmt:
  1264  	"CREATE" DatabaseSym IfNotExists DBName DatabaseOptionListOpt
  1265  	{
  1266  		$$ = &ast.CreateDatabaseStmt{
  1267  			IfNotExists:	$3.(bool),
  1268  			Name:		$4.(string),
  1269  			Options:	$5.([]*ast.DatabaseOption),
  1270  		}
  1271  
  1272  		if yylex.(*lexer).root {
  1273  			break
  1274  		}
  1275  	}
  1276  
  1277  DBName:
  1278  	Identifier
  1279  
  1280  DatabaseOption:
  1281  	DefaultKwdOpt CharsetKw EqOpt StringName
  1282  	{
  1283  		$$ = &ast.DatabaseOption{Tp: ast.DatabaseOptionCharset, Value: $4.(string)}
  1284  	}
  1285  |	DefaultKwdOpt "COLLATE" EqOpt StringName
  1286  	{
  1287  		$$ = &ast.DatabaseOption{Tp: ast.DatabaseOptionCollate, Value: $4.(string)}
  1288  	} 
  1289  
  1290  DatabaseOptionListOpt:
  1291  	{
  1292  		$$ = []*ast.DatabaseOption{}
  1293  	}
  1294  |	DatabaseOptionList
  1295  
  1296  DatabaseOptionList:
  1297  	DatabaseOption
  1298  	{
  1299  		$$ = []*ast.DatabaseOption{$1.(*ast.DatabaseOption)}
  1300  	}
  1301  |	DatabaseOptionList DatabaseOption
  1302  	{
  1303  		$$ = append($1.([]*ast.DatabaseOption), $2.(*ast.DatabaseOption))
  1304  	}
  1305  
  1306  /*******************************************************************
  1307   *
  1308   *  Create Table Statement
  1309   *
  1310   *  Example:
  1311   *      CREATE TABLE Persons
  1312   *      (
  1313   *          P_Id int NOT NULL,
  1314   *          LastName varchar(255) NOT NULL,
  1315   *          FirstName varchar(255),
  1316   *          Address varchar(255),
  1317   *          City varchar(255),
  1318   *          PRIMARY KEY (P_Id)
  1319   *      )
  1320   *******************************************************************/
  1321  CreateTableStmt:
  1322  	"CREATE" "TABLE" IfNotExists TableName '(' TableElementList ')' TableOptionListOpt
  1323  	{
  1324  		tes := $6.([]interface {})
  1325  		var columnDefs []*ast.ColumnDef
  1326  		var constraints []*ast.Constraint
  1327  		for _, te := range tes {
  1328  			switch te := te.(type) {
  1329  			case *ast.ColumnDef:
  1330  				columnDefs = append(columnDefs, te)
  1331  			case *ast.Constraint:
  1332  				constraints = append(constraints, te)
  1333  			}
  1334  		}
  1335  		if len(columnDefs) == 0 {
  1336  			yylex.(*lexer).err("Column Definition List can't be empty.")
  1337  			return 1
  1338  		}
  1339  		$$ = &ast.CreateTableStmt{
  1340  			Table:          $4.(*ast.TableName),
  1341  			IfNotExists:    $3.(bool),
  1342  			Cols:           columnDefs, 
  1343  			Constraints:    constraints,
  1344  			Options:        $8.([]*ast.TableOption),
  1345  		}
  1346  	}
  1347  
  1348  Default:
  1349  	"DEFAULT" Expression
  1350  	{
  1351  		$$ = $2
  1352  	}
  1353  
  1354  DefaultOpt:
  1355  	{
  1356  		$$ = nil
  1357  	}
  1358  |	Default
  1359  
  1360  DefaultKwdOpt:
  1361  	{}
  1362  |	"DEFAULT"
  1363  
  1364  /******************************************************************
  1365   * Do statement
  1366   * See: https://dev.mysql.com/doc/refman/5.7/en/do.html
  1367   ******************************************************************/
  1368  DoStmt:
  1369  	"DO" ExpressionList
  1370  	{
  1371  		$$ = &ast.DoStmt {
  1372  			Exprs: $2.([]ast.ExprNode),
  1373  		}
  1374  	}
  1375  
  1376  /*******************************************************************
  1377   *
  1378   *  Delete Statement
  1379   *
  1380   *******************************************************************/
  1381  DeleteFromStmt:
  1382  	"DELETE" LowPriorityOptional QuickOptional IgnoreOptional "FROM" TableName WhereClauseOptional OrderByOptional LimitClause
  1383  	{
  1384  		// Single Table
  1385  		join := &ast.Join{Left: &ast.TableSource{Source: $6.(ast.ResultSetNode)}, Right: nil}
  1386  		x := &ast.DeleteStmt{
  1387  			TableRefs:	&ast.TableRefsClause{TableRefs: join},
  1388  			LowPriority:	$2.(bool),
  1389  			Quick:		$3.(bool),
  1390  			Ignore:		$4.(bool),
  1391  		}
  1392  		if $7 != nil {
  1393  			x.Where = $7.(ast.ExprNode)
  1394  		}
  1395  		if $8 != nil {
  1396  			x.Order = $8.(*ast.OrderByClause)
  1397  		}
  1398  		if $9 != nil {
  1399  			x.Limit = $9.(*ast.Limit)
  1400  		}
  1401  
  1402  		$$ = x
  1403  		if yylex.(*lexer).root {
  1404  			break
  1405  		}
  1406  	}
  1407  |	"DELETE" LowPriorityOptional QuickOptional IgnoreOptional TableNameList "FROM" TableRefs WhereClauseOptional
  1408  	{
  1409  		// Multiple Table
  1410  		x := &ast.DeleteStmt{
  1411  			LowPriority:	$2.(bool),
  1412  			Quick:		$3.(bool),
  1413  			Ignore:		$4.(bool),
  1414  			IsMultiTable:	true,
  1415  			BeforeFrom:	true,
  1416  			Tables:		&ast.DeleteTableList{Tables: $5.([]*ast.TableName)},
  1417  			TableRefs:	&ast.TableRefsClause{TableRefs: $7.(*ast.Join)},
  1418  		}
  1419  		if $8 != nil {
  1420  			x.Where = $8.(ast.ExprNode)
  1421  		}
  1422  		$$ = x
  1423  		if yylex.(*lexer).root {
  1424  			break
  1425  		}
  1426  	}
  1427  |	"DELETE" LowPriorityOptional QuickOptional IgnoreOptional "FROM" TableNameList "USING" TableRefs WhereClauseOptional
  1428  	{
  1429  		// Multiple Table
  1430  		x := &ast.DeleteStmt{
  1431  			LowPriority:	$2.(bool),
  1432  			Quick:		$3.(bool),
  1433  			Ignore:		$4.(bool),
  1434  			IsMultiTable:	true,
  1435  			Tables:		&ast.DeleteTableList{Tables: $6.([]*ast.TableName)},
  1436  			TableRefs:	&ast.TableRefsClause{TableRefs: $8.(*ast.Join)},
  1437  		}
  1438  		if $9 != nil {
  1439  			x.Where = $9.(ast.ExprNode)
  1440  		}
  1441  		$$ = x
  1442  		if yylex.(*lexer).root {
  1443  			break
  1444  		}
  1445  	}
  1446  
  1447  DatabaseSym:
  1448  	"DATABASE" | "SCHEMA"
  1449  
  1450  DropDatabaseStmt:
  1451  	"DROP" DatabaseSym IfExists DBName
  1452  	{
  1453  		$$ = &ast.DropDatabaseStmt{IfExists: $3.(bool), Name: $4.(string)}
  1454  		if yylex.(*lexer).root {
  1455  			break
  1456  		}
  1457  	}
  1458  
  1459  DropIndexStmt:
  1460  	"DROP" "INDEX" IfExists Identifier "ON" TableName
  1461  	{
  1462  		$$ = &ast.DropIndexStmt{IfExists: $3.(bool), IndexName: $4.(string), Table: $6.(*ast.TableName)}
  1463  	}
  1464  
  1465  DropTableStmt:
  1466  	"DROP" TableOrTables TableNameList
  1467  	{
  1468  		$$ = &ast.DropTableStmt{Tables: $3.([]*ast.TableName)}
  1469  		if yylex.(*lexer).root {
  1470  			break
  1471  		}
  1472  	}
  1473  |	"DROP" TableOrTables "IF" "EXISTS" TableNameList
  1474  	{
  1475  		$$ = &ast.DropTableStmt{IfExists: true, Tables: $5.([]*ast.TableName)}
  1476  		if yylex.(*lexer).root {
  1477  			break
  1478  		}
  1479  	}
  1480  
  1481  TableOrTables:
  1482  	"TABLE"
  1483  |	"TABLES"
  1484  
  1485  EqOpt:
  1486  	{
  1487  	}
  1488  |	eq
  1489  	{
  1490  	}
  1491  
  1492  EmptyStmt:
  1493  	/* EMPTY */
  1494  	{
  1495  		$$ = nil
  1496  	}
  1497  
  1498  ExplainSym:
  1499  	"EXPLAIN"
  1500  |	"DESCRIBE"
  1501  |	"DESC"
  1502  
  1503  ExplainStmt:
  1504  	ExplainSym TableName
  1505  	{
  1506  		$$ = &ast.ExplainStmt{
  1507  			Stmt: &ast.ShowStmt{
  1508  				Tp:	ast.ShowColumns,
  1509  				Table:	$2.(*ast.TableName),
  1510  			},
  1511  		}
  1512  	}
  1513  |	ExplainSym TableName ColumnName
  1514  	{
  1515  		$$ = &ast.ExplainStmt{
  1516  			Stmt: &ast.ShowStmt{
  1517  				Tp:	ast.ShowColumns,
  1518  				Table:	$2.(*ast.TableName),
  1519  				Column:	$3.(*ast.ColumnName),
  1520  			},
  1521  		}
  1522  	}
  1523  |	ExplainSym ExplainableStmt
  1524  	{
  1525  		$$ = &ast.ExplainStmt{Stmt: $2.(ast.StmtNode)}
  1526  	}
  1527  
  1528  LengthNum:
  1529  	NUM
  1530  	{
  1531  		switch v := $1.(type) {
  1532  		case int64:
  1533  			$$ = uint64(v)
  1534  		case uint64:
  1535  			$$ = uint64(v)
  1536  		}
  1537  	}
  1538  
  1539  NUM:
  1540  	intLit
  1541  
  1542  Expression:
  1543  	"USER_VAR" assignmentEq Expression %prec assignmentEq
  1544  	{
  1545  		v := $1.(string)
  1546  		v = strings.TrimPrefix(v, "@")
  1547  		$$ = &ast.VariableExpr{
  1548  				Name: 	  v,
  1549  				IsGlobal: false,
  1550  				IsSystem: false,
  1551  				Value:	  $3.(ast.ExprNode),
  1552  		}
  1553  	}
  1554  |	Expression logOr Expression %prec oror
  1555  	{
  1556  		$$ = &ast.BinaryOperationExpr{Op: opcode.OrOr, L: $1.(ast.ExprNode), R: $3.(ast.ExprNode)}
  1557  	}
  1558  |	Expression "XOR" Expression %prec xor
  1559  	{
  1560  		$$ = &ast.BinaryOperationExpr{Op: opcode.LogicXor, L: $1.(ast.ExprNode), R: $3.(ast.ExprNode)}
  1561  	}
  1562  |	Expression logAnd Expression %prec andand
  1563  	{
  1564  		$$ = &ast.BinaryOperationExpr{Op: opcode.AndAnd, L: $1.(ast.ExprNode), R: $3.(ast.ExprNode)}
  1565  	}
  1566  |	"NOT" Expression %prec not
  1567  	{
  1568  		$$ = &ast.UnaryOperationExpr{Op: opcode.Not, V: $2.(ast.ExprNode)}
  1569  	}
  1570  |	Factor "IS" NotOpt trueKwd %prec is
  1571  	{
  1572  		$$ = &ast.IsTruthExpr{Expr:$1.(ast.ExprNode), Not: $3.(bool), True: int64(1)}
  1573  	}
  1574  |	Factor "IS" NotOpt falseKwd %prec is
  1575  	{
  1576  		$$ = &ast.IsTruthExpr{Expr:$1.(ast.ExprNode), Not: $3.(bool), True: int64(0)}
  1577  	}
  1578  |	Factor "IS" NotOpt "UNKNOWN" %prec is
  1579  	{
  1580  		/* https://dev.mysql.com/doc/refman/5.7/en/comparison-operators.html#operator_is */
  1581  		$$ = &ast.IsNullExpr{Expr: $1.(ast.ExprNode), Not: $3.(bool)}
  1582  	}
  1583  |	Factor
  1584  
  1585  
  1586  logOr:
  1587  	"||"
  1588  	{
  1589  	}
  1590  |	"OR"
  1591  	{
  1592  	}
  1593  
  1594  logAnd:
  1595  	"&&"
  1596  	{
  1597  	}
  1598  |	"AND"
  1599  	{
  1600  	}
  1601  
  1602  name:
  1603  	Identifier
  1604  
  1605  ExpressionList:
  1606  	Expression
  1607  	{
  1608  		$$ = []ast.ExprNode{$1.(ast.ExprNode)}
  1609  	}
  1610  |	ExpressionList ',' Expression
  1611  	{
  1612  		$$ = append($1.([]ast.ExprNode), $3.(ast.ExprNode))
  1613  	}
  1614  
  1615  ExpressionListOpt:
  1616  	{
  1617  		$$ = []ast.ExprNode{}
  1618  	}
  1619  |	ExpressionList
  1620  
  1621  Factor:
  1622  	Factor "IS" NotOpt "NULL" %prec is
  1623  	{
  1624  		$$ = &ast.IsNullExpr{Expr: $1.(ast.ExprNode), Not: $3.(bool)}
  1625  	}
  1626  |	Factor CompareOp PredicateExpr %prec eq
  1627  	{
  1628  		$$ = &ast.BinaryOperationExpr{Op: $2.(opcode.Op), L: $1.(ast.ExprNode), R: $3.(ast.ExprNode)}
  1629  	}
  1630  |	Factor CompareOp "USER_VAR" assignmentEq PredicateExpr %prec assignmentEq
  1631  	{
  1632  		v := $3.(string)
  1633  		v = strings.TrimPrefix(v, "@")
  1634  		variable := &ast.VariableExpr{
  1635  				Name: 	  v,
  1636  				IsGlobal: false,
  1637  				IsSystem: false,
  1638  				Value:	  $5.(ast.ExprNode),
  1639  		}
  1640  		$$ = &ast.BinaryOperationExpr{Op: $2.(opcode.Op), L: $1.(ast.ExprNode), R: variable}
  1641  	}
  1642  |	Factor CompareOp AnyOrAll SubSelect %prec eq
  1643  	{
  1644  		sq := $4.(*ast.SubqueryExpr)
  1645  		sq.MultiRows = true
  1646  		$$ = &ast.CompareSubqueryExpr{Op: $2.(opcode.Op), L: $1.(ast.ExprNode), R: sq, All: $3.(bool)}
  1647  	}
  1648  |	PredicateExpr
  1649  
  1650  CompareOp:
  1651  	">="
  1652  	{
  1653  		$$ = opcode.GE
  1654  	}
  1655  |	'>'
  1656  	{
  1657  		$$ = opcode.GT
  1658  	}
  1659  |	"<="
  1660  	{
  1661  		$$ = opcode.LE
  1662  	}
  1663  |	'<'
  1664  	{
  1665  		$$ = opcode.LT
  1666  	}
  1667  |	"!="
  1668  	{
  1669  		$$ = opcode.NE
  1670  	}
  1671  |	"<>"
  1672  	{
  1673  		$$ = opcode.NE
  1674  	}
  1675  |	"="
  1676  	{
  1677  		$$ = opcode.EQ
  1678  	}
  1679  |	"<=>"
  1680  	{
  1681  		$$ = opcode.NullEQ
  1682  	}
  1683  
  1684  AnyOrAll:
  1685  	"ANY"
  1686  	{
  1687  		$$ = false
  1688  	}
  1689  |	"SOME"
  1690  	{
  1691  		$$ = false
  1692  	}
  1693  |	"ALL"
  1694  	{
  1695  		$$ = true
  1696  	}
  1697  
  1698  PredicateExpr:
  1699  	PrimaryFactor NotOpt "IN" '(' ExpressionList ')'
  1700  	{
  1701  		$$ = &ast.PatternInExpr{Expr: $1.(ast.ExprNode), Not: $2.(bool), List: $5.([]ast.ExprNode)}
  1702  	}
  1703  |	PrimaryFactor NotOpt "IN" SubSelect
  1704  	{
  1705  		sq := $4.(*ast.SubqueryExpr)
  1706  		sq.MultiRows = true
  1707  		$$ = &ast.PatternInExpr{Expr: $1.(ast.ExprNode), Not: $2.(bool), Sel: sq}
  1708  	}
  1709  |	PrimaryFactor NotOpt "BETWEEN" PrimaryFactor "AND" PredicateExpr
  1710  	{
  1711  		$$ = &ast.BetweenExpr{
  1712  			Expr:	$1.(ast.ExprNode),
  1713  			Left:	$4.(ast.ExprNode),
  1714  			Right:	$6.(ast.ExprNode),
  1715  			Not:	$2.(bool),
  1716  		}
  1717  	}
  1718  |	PrimaryFactor NotOpt "LIKE" PrimaryExpression LikeEscapeOpt
  1719  	{
  1720  		escape := $5.(string)
  1721  		if len(escape) > 1 {
  1722  			yylex.(*lexer).errf("Incorrect arguments %s to ESCAPE", escape)
  1723  			return 1
  1724  		} else if len(escape) == 0 {
  1725  			escape = "\\"
  1726  		}
  1727  		$$ = &ast.PatternLikeExpr{
  1728  			Expr:		$1.(ast.ExprNode),
  1729  			Pattern:	$4.(ast.ExprNode),
  1730  			Not: 		$2.(bool),
  1731  			Escape: 	escape[0],
  1732  		}
  1733  	}
  1734  |	PrimaryFactor NotOpt RegexpSym PrimaryExpression
  1735  	{
  1736  		$$ = &ast.PatternRegexpExpr{Expr: $1.(ast.ExprNode), Pattern: $4.(ast.ExprNode), Not: $2.(bool)}
  1737  	}
  1738  |	PrimaryFactor
  1739  
  1740  RegexpSym:
  1741  	"REGEXP"
  1742  |	"RLIKE"
  1743  
  1744  LikeEscapeOpt:
  1745  	%prec lowerThanEscape
  1746  	{
  1747  		$$ = "\\"
  1748  	}
  1749  |	"ESCAPE" stringLit
  1750  	{
  1751  		$$ = $2
  1752  	}
  1753  
  1754  NotOpt:
  1755  	{
  1756  		$$ = false
  1757  	}
  1758  |	"NOT"
  1759  	{
  1760  		$$ = true
  1761  	}
  1762  
  1763  Field:
  1764  	'*'
  1765  	{
  1766  		$$ = &ast.SelectField{WildCard: &ast.WildCardField{}}
  1767  	}
  1768  |	Identifier '.' '*'
  1769  	{
  1770  		wildCard := &ast.WildCardField{Table: model.NewCIStr($1.(string))}
  1771  		$$ = &ast.SelectField{WildCard: wildCard}
  1772  	}
  1773  |	Identifier '.' Identifier '.' '*'
  1774  	{
  1775  		wildCard := &ast.WildCardField{Schema: model.NewCIStr($1.(string)), Table: model.NewCIStr($3.(string))}
  1776  		$$ = &ast.SelectField{WildCard: wildCard}
  1777  	}
  1778  |	Expression FieldAsNameOpt
  1779  	{
  1780  		expr := $1.(ast.ExprNode)
  1781  		asName := $2.(string)
  1782  		$$ = &ast.SelectField{Expr: expr, AsName: model.NewCIStr(asName)}
  1783  	}
  1784  
  1785  FieldAsNameOpt:
  1786  	/* EMPTY */
  1787  	{
  1788  		$$ = ""
  1789  	}
  1790  |	FieldAsName
  1791  	{
  1792  		$$ = $1
  1793  	}
  1794  
  1795  FieldAsName:
  1796  	Identifier
  1797  	{
  1798  		$$ = $1
  1799  	}
  1800  |	"AS" Identifier
  1801  	{
  1802  		$$ = $2
  1803  	}
  1804  |	stringLit
  1805  	{
  1806  		$$ = $1
  1807  	}
  1808  |	"AS" stringLit
  1809  	{
  1810  		$$ = $2
  1811  	}
  1812  
  1813  FieldList:
  1814  	Field
  1815  	{
  1816  		field := $1.(*ast.SelectField)
  1817  		field.Offset = yylex.(*lexer).startOffset(yyS[yypt].offset)
  1818  		$$ = []*ast.SelectField{field}
  1819  	}
  1820  |	FieldList ',' Field
  1821  	{
  1822  
  1823  		fl := $1.([]*ast.SelectField)
  1824  		last := fl[len(fl)-1]
  1825  		l := yylex.(*lexer)
  1826  		if last.Expr != nil && last.AsName.O == "" {
  1827  			lastEnd := l.endOffset(yyS[yypt-1].offset)
  1828  			last.SetText(l.src[last.Offset:lastEnd])
  1829  		}
  1830  		newField := $3.(*ast.SelectField)
  1831  		newField.Offset = l.startOffset(yyS[yypt].offset)
  1832  		$$ = append(fl, newField)
  1833  	}
  1834  
  1835  GroupByClause:
  1836  	"GROUP" "BY" ByList
  1837  	{
  1838  		$$ = &ast.GroupByClause{Items: $3.([]*ast.ByItem)}
  1839  	}
  1840  
  1841  HavingClause:
  1842  	{
  1843  		$$ = nil
  1844  	}
  1845  |	"HAVING" Expression
  1846  	{
  1847  		$$ = &ast.HavingClause{Expr: $2.(ast.ExprNode)}
  1848  	}
  1849  
  1850  IfExists:
  1851  	{
  1852  		$$ = false
  1853  	}
  1854  |	"IF" "EXISTS"
  1855  	{
  1856  		$$ = true
  1857  	}
  1858  
  1859  IfNotExists:
  1860  	{
  1861  		$$ = false
  1862  	}
  1863  |	"IF" "NOT" "EXISTS"
  1864  	{
  1865  		$$ = true
  1866  	}
  1867  
  1868  
  1869  IgnoreOptional:
  1870  	{
  1871  		$$ = false
  1872  	}
  1873  |	"IGNORE"
  1874  	{
  1875  		$$ = true
  1876  	}
  1877  
  1878  IndexName:
  1879  	{
  1880  		$$ = ""
  1881  	}
  1882  |	Identifier
  1883  	{
  1884  		//"index name"
  1885  		$$ = $1.(string)
  1886  	}
  1887  
  1888  IndexOption:
  1889  	{
  1890  		$$ = nil
  1891  	}
  1892  |	"KEY_BLOCK_SIZE" EqOpt LengthNum 
  1893  	{
  1894  		$$ = &ast.IndexOption{
  1895  			KeyBlockSize: $1.(uint64),
  1896  		}	
  1897  	}
  1898  |	IndexType
  1899  	{
  1900  		$$ = &ast.IndexOption {
  1901  			Tp: $1.(model.IndexType),
  1902  		}
  1903  	}
  1904  |	"COMMENT" stringLit
  1905  	{
  1906  		$$ = &ast.IndexOption {
  1907  			Comment: $2.(string),
  1908  		}
  1909  	}
  1910  	   
  1911  IndexType:
  1912  	"USING" "BTREE"	
  1913  	{
  1914  		$$ = model.IndexTypeBtree
  1915  	}
  1916  |	"USING" "HASH"
  1917  	{
  1918  		$$ = model.IndexTypeHash
  1919  	}
  1920  
  1921  IndexTypeOpt:
  1922  	{
  1923  		$$ = nil 
  1924  	}
  1925  |	IndexType
  1926  	{
  1927  		$$ = $1
  1928  	}
  1929  
  1930  /**********************************Identifier********************************************/
  1931  Identifier:
  1932  	identifier | UnReservedKeyword | NotKeywordToken
  1933  
  1934  UnReservedKeyword:
  1935  	"ASCII" | "AUTO_INCREMENT" | "AFTER" | "AVG" | "BEGIN" | "BIT" | "BOOL" | "BOOLEAN" | "BTREE" | "CHARSET" | "COLUMNS" | "COMMIT" | "COMPACT" | "COMPRESSED"
  1936  |	"DATE" | "DATETIME" | "DEALLOCATE" | "DO" | "DYNAMIC" | "END" | "ENGINE" | "ENGINES" | "EXECUTE" | "FIRST" | "FIXED" | "FULL" | "HASH" 
  1937  |	"LOCAL" | "NAMES" | "OFFSET" | "PASSWORD" %prec lowerThanEq | "PREPARE" | "QUICK" | "REDUNDANT" | "ROLLBACK" | "SESSION" | "SIGNED" 
  1938  |	"START" | "STATUS" | "GLOBAL" | "TABLES"| "TEXT" | "TIME" | "TIMESTAMP" | "TRANSACTION" | "TRUNCATE" | "UNKNOWN"
  1939  |	"VALUE" | "WARNINGS" | "YEAR" |	"MODE" | "WEEK" | "ANY" | "SOME" | "USER" | "IDENTIFIED" | "COLLATION"
  1940  |	"COMMENT" | "AVG_ROW_LENGTH" | "CONNECTION" | "CHECKSUM" | "COMPRESSION" | "KEY_BLOCK_SIZE" | "MAX_ROWS" | "MIN_ROWS"
  1941  |	"NATIONAL" | "ROW" | "ROW_FORMAT" | "QUARTER" | "ESCAPE" | "GRANTS" | "FIELDS" | "TRIGGERS" | "DELAY_KEY_WRITE" | "ISOLATION"
  1942  |	"REPEATABLE" | "COMMITTED" | "UNCOMMITTED" | "ONLY" | "SERIALIZABLE" | "LEVEL" | "VARIABLES" | "SQL_CACHE" | "SQL_NO_CACHE" | "ACTION" | "DISABLE" | "ENABLE" | "REVERSE"
  1943  
  1944  NotKeywordToken:
  1945  	"ABS" | "ADDDATE" | "ADMIN" | "COALESCE" | "CONCAT" | "CONCAT_WS" | "CONNECTION_ID" | "CUR_TIME"| "COUNT" | "DAY"
  1946  |	"DATE_ADD" | "DATE_SUB" | "DAYNAME" | "DAYOFMONTH" | "DAYOFWEEK" | "DAYOFYEAR" | "FOUND_ROWS" | "GROUP_CONCAT"| "HOUR"
  1947  |	"IFNULL" | "ISNULL" | "LCASE" | "LENGTH" | "LOCATE" | "LOWER" | "LTRIM" | "MAX" | "MICROSECOND" | "MIN" | "MINUTE" | "NULLIF" | "MONTH" | "NOW" | "POW"
  1948  |	"POWER" | "RAND" | "SECOND" | "SQL_CALC_FOUND_ROWS" | "SUBDATE" | "SUBSTRING" %prec lowerThanLeftParen
  1949  |	"SUBSTRING_INDEX" | "SUM" | "TRIM" | "RTRIM" | "UCASE" | "UPPER" | "VERSION" | "WEEKDAY" | "WEEKOFYEAR" | "YEARWEEK" | "ROUND"
  1950  
  1951  /************************************************************************************
  1952   *
  1953   *  Insert Statements
  1954   *
  1955   *  TODO: support PARTITION
  1956   **********************************************************************************/
  1957  InsertIntoStmt:
  1958  	"INSERT" Priority IgnoreOptional IntoOpt TableName InsertValues OnDuplicateKeyUpdate
  1959  	{
  1960  		x := $6.(*ast.InsertStmt)
  1961  		x.Priority = $2.(int)
  1962  		// Wraps many layers here so that it can be processed the same way as select statement.
  1963  		ts := &ast.TableSource{Source: $5.(*ast.TableName)}
  1964  		x.Table = &ast.TableRefsClause{TableRefs: &ast.Join{Left: ts}}
  1965  		if $7 != nil {
  1966  			x.OnDuplicate = $7.([]*ast.Assignment)
  1967  		}
  1968  		$$ = x
  1969  		if yylex.(*lexer).root {
  1970  			break
  1971  		}
  1972  	}
  1973  
  1974  IntoOpt:
  1975  	{
  1976  	}
  1977  |	"INTO"
  1978  	{
  1979  	}
  1980  
  1981  InsertValues:
  1982  	'(' ColumnNameListOpt ')' ValueSym ExpressionListList
  1983  	{
  1984  		$$ = &ast.InsertStmt{
  1985  			Columns:   $2.([]*ast.ColumnName),
  1986  			Lists:      $5.([][]ast.ExprNode),
  1987  		}
  1988  	}
  1989  |	'(' ColumnNameListOpt ')' SelectStmt
  1990  	{
  1991  		$$ = &ast.InsertStmt{Columns: $2.([]*ast.ColumnName), Select: $4.(*ast.SelectStmt)}
  1992  	}
  1993  |	'(' ColumnNameListOpt ')' UnionStmt
  1994  	{
  1995  		$$ = &ast.InsertStmt{Columns: $2.([]*ast.ColumnName), Select: $4.(*ast.UnionStmt)}
  1996  	}
  1997  |	ValueSym ExpressionListList %prec insertValues
  1998  	{
  1999  		$$ = &ast.InsertStmt{Lists:  $2.([][]ast.ExprNode)}
  2000  	}
  2001  |	SelectStmt
  2002  	{
  2003  		$$ = &ast.InsertStmt{Select: $1.(*ast.SelectStmt)}
  2004  	}
  2005  |	UnionStmt
  2006  	{
  2007  		$$ = &ast.InsertStmt{Select: $1.(*ast.UnionStmt)}
  2008  	}
  2009  |	"SET" ColumnSetValueList
  2010  	{
  2011  		$$ = &ast.InsertStmt{Setlist: $2.([]*ast.Assignment)}
  2012  	}
  2013  
  2014  ValueSym:
  2015  	"VALUE"
  2016  |	"VALUES"
  2017  
  2018  ExpressionListList:
  2019  	'(' ')'
  2020  	{
  2021  		$$ = [][]ast.ExprNode{[]ast.ExprNode{}}
  2022  	}
  2023  |	'(' ')' ',' ExpressionListList
  2024  	{
  2025  		$$ = append([][]ast.ExprNode{[]ast.ExprNode{}}, $4.([][]ast.ExprNode)...)
  2026  	}
  2027  |	'(' ExpressionList ')'
  2028  	{
  2029  		$$ = [][]ast.ExprNode{$2.([]ast.ExprNode)}
  2030  	}
  2031  |	'(' ExpressionList ')' ',' ExpressionListList
  2032  	{
  2033  		$$ = append([][]ast.ExprNode{$2.([]ast.ExprNode)}, $5.([][]ast.ExprNode)...)
  2034  	}
  2035  
  2036  ColumnSetValue:
  2037  	ColumnName eq Expression
  2038  	{
  2039  		$$ = &ast.Assignment{
  2040  			Column:	$1.(*ast.ColumnName),
  2041  			Expr:	$3.(ast.ExprNode),
  2042  		}
  2043  	}
  2044  
  2045  ColumnSetValueList:
  2046  	{
  2047  		$$ = []*ast.Assignment{}
  2048  	}
  2049  |	ColumnSetValue
  2050  	{
  2051  		$$ = []*ast.Assignment{$1.(*ast.Assignment)}
  2052  	}
  2053  |	ColumnSetValueList ',' ColumnSetValue
  2054  	{
  2055  		$$ = append($1.([]*ast.Assignment), $3.(*ast.Assignment))
  2056  	}
  2057  
  2058  /* 
  2059   * ON DUPLICATE KEY UPDATE col_name=expr [, col_name=expr] ... 
  2060   * See: https://dev.mysql.com/doc/refman/5.7/en/insert-on-duplicate.html
  2061   */ 
  2062  OnDuplicateKeyUpdate:
  2063  	{
  2064  		$$ = nil
  2065  	}
  2066  |	"ON" "DUPLICATE" "KEY" "UPDATE" AssignmentList
  2067  	{
  2068  		$$ = $5
  2069  	}
  2070  
  2071  /***********************************Insert Statements END************************************/
  2072  
  2073  /************************************************************************************
  2074   *  Replace Statements
  2075   *  See: https://dev.mysql.com/doc/refman/5.7/en/replace.html
  2076   *
  2077   *  TODO: support PARTITION
  2078   **********************************************************************************/
  2079  ReplaceIntoStmt:
  2080  	"REPLACE" ReplacePriority IntoOpt TableName InsertValues
  2081  	{
  2082  		x := $5.(*ast.InsertStmt)
  2083  		x.IsReplace = true
  2084  		x.Priority = $2.(int)
  2085  		ts := &ast.TableSource{Source: $4.(*ast.TableName)}
  2086  		x.Table = &ast.TableRefsClause{TableRefs: &ast.Join{Left: ts}}
  2087  		$$ = x
  2088  	}
  2089  
  2090  ReplacePriority:
  2091  	{
  2092  		$$ = ast.NoPriority
  2093  	}
  2094  |	"LOW_PRIORITY"
  2095  	{
  2096  		$$ = ast.LowPriority
  2097  	}
  2098  |	"DELAYED"
  2099  	{
  2100  		$$ = ast.DelayedPriority
  2101  	}
  2102  
  2103  /***********************************Replace Statements END************************************/
  2104  
  2105  Literal:
  2106  	"false"
  2107  	{
  2108  		$$ = int64(0)
  2109  	}
  2110  |	"NULL"
  2111  |	"true"
  2112  	{
  2113  		$$ = int64(1)
  2114  	}
  2115  |	floatLit
  2116  |	intLit
  2117  |	stringLit
  2118  	{
  2119  		tp := types.NewFieldType(mysql.TypeString)
  2120  		l := yylex.(*lexer)
  2121  		tp.Charset, tp.Collate = l.GetCharsetInfo()
  2122  		expr := ast.NewValueExpr($1)
  2123  		expr.SetType(tp)
  2124  		$$ = expr
  2125  	}
  2126  |	"UNDERSCORE_CHARSET" stringLit
  2127  	{
  2128  		// See: https://dev.mysql.com/doc/refman/5.7/en/charset-literal.html
  2129  		tp := types.NewFieldType(mysql.TypeString)
  2130  		tp.Charset = $1.(string)
  2131  		co, err := charset.GetDefaultCollation(tp.Charset)
  2132  		if err != nil {
  2133  			l := yylex.(*lexer)
  2134  			l.errf("Get collation error for charset: %s", tp.Charset)
  2135  			return 1
  2136  		}
  2137  		tp.Collate = co
  2138  		expr := ast.NewValueExpr($2)
  2139  		expr.SetType(tp)
  2140  		$$ = expr
  2141  	}
  2142  |	hexLit
  2143  |	bitLit
  2144  
  2145  Operand:
  2146  	Literal
  2147  	{
  2148  		$$ = ast.NewValueExpr($1)
  2149  	}
  2150  |	ColumnName
  2151  	{
  2152  		$$ = &ast.ColumnNameExpr{Name: $1.(*ast.ColumnName)}
  2153  	}
  2154  |	'(' Expression ')'
  2155  	{
  2156  		l := yylex.(*lexer)
  2157  		startOffset := l.startOffset(yyS[yypt-1].offset)
  2158  		endOffset := l.endOffset(yyS[yypt].offset)
  2159  		expr := $2.(ast.ExprNode)
  2160  		expr.SetText(l.src[startOffset:endOffset])
  2161  		$$ = &ast.ParenthesesExpr{Expr: expr}
  2162  	}
  2163  |	"DEFAULT" %prec lowerThanLeftParen
  2164  	{
  2165  		$$ = &ast.DefaultExpr{}
  2166  	}
  2167  |	"DEFAULT" '(' ColumnName ')'
  2168  	{
  2169  		$$ = &ast.DefaultExpr{Name: $3.(*ast.ColumnName)}
  2170  	}
  2171  |	Variable
  2172  	{
  2173  		$$ = $1
  2174  	}
  2175  |	"PLACEHOLDER"
  2176  	{
  2177  		$$ = &ast.ParamMarkerExpr{
  2178  			Offset: yyS[yypt].offset,
  2179  		}
  2180  	}
  2181  |	"ROW" '(' Expression ',' ExpressionList ')'
  2182  	{
  2183  		values := append([]ast.ExprNode{$3.(ast.ExprNode)}, $5.([]ast.ExprNode)...)
  2184  		$$ = &ast.RowExpr{Values: values}
  2185  	}
  2186  |	'(' Expression ',' ExpressionList ')'
  2187  	{
  2188  		values := append([]ast.ExprNode{$2.(ast.ExprNode)}, $4.([]ast.ExprNode)...)
  2189  		$$ = &ast.RowExpr{Values: values}
  2190  	}
  2191  |	"EXISTS" SubSelect
  2192  	{
  2193  		sq := $2.(*ast.SubqueryExpr)
  2194  		sq.Exists = true
  2195  		$$ = &ast.ExistsSubqueryExpr{Sel: sq}
  2196  	}
  2197  
  2198  OrderBy:
  2199  	"ORDER" "BY" ByList
  2200  	{
  2201  		$$ = &ast.OrderByClause{Items: $3.([]*ast.ByItem)}
  2202  	}
  2203  
  2204  ByList:
  2205  	ByItem
  2206  	{
  2207  		$$ = []*ast.ByItem{$1.(*ast.ByItem)}
  2208  	}
  2209  |	ByList ',' ByItem
  2210  	{
  2211  		$$ = append($1.([]*ast.ByItem), $3.(*ast.ByItem))
  2212  	}
  2213  
  2214  ByItem:
  2215  	Expression Order 
  2216  	{
  2217  		expr := $1
  2218  		valueExpr, ok := expr.(*ast.ValueExpr)
  2219  		if ok {
  2220  			position, isPosition := valueExpr.GetValue().(int64)
  2221  			if isPosition {
  2222  				expr = &ast.PositionExpr{N: int(position)}
  2223  			}
  2224  		}
  2225  		$$ = &ast.ByItem{Expr: expr.(ast.ExprNode), Desc: $2.(bool)}
  2226  	}
  2227  
  2228  Order:
  2229  	/* EMPTY */
  2230  	{
  2231  		$$ = false // ASC by default
  2232  	}
  2233  |	"ASC"
  2234  	{
  2235  		$$ = false
  2236  	}
  2237  |	"DESC"
  2238  	{
  2239  		$$ = true
  2240  	}
  2241  
  2242  OrderByOptional:
  2243  	{
  2244  		$$ = nil
  2245  	}
  2246  |	OrderBy
  2247  	{
  2248  		$$ = $1
  2249  	}
  2250  	
  2251  PrimaryExpression:
  2252  	Operand
  2253  |	Function
  2254  |	SubSelect
  2255  |	'!' PrimaryExpression %prec neg
  2256  	{
  2257  		$$ = &ast.UnaryOperationExpr{Op: opcode.Not, V: $2.(ast.ExprNode)}
  2258  	}
  2259  |	'~'  PrimaryExpression %prec neg
  2260  	{
  2261  		$$ = &ast.UnaryOperationExpr{Op: opcode.BitNeg, V: $2.(ast.ExprNode)}
  2262  	}
  2263  |	'-' PrimaryExpression %prec neg
  2264  	{
  2265  		$$ = &ast.UnaryOperationExpr{Op: opcode.Minus, V: $2.(ast.ExprNode)}
  2266  	}
  2267  |	'+' PrimaryExpression %prec neg
  2268  	{
  2269  		$$ = &ast.UnaryOperationExpr{Op: opcode.Plus, V: $2.(ast.ExprNode)}
  2270  	}
  2271  |	"BINARY" PrimaryExpression %prec neg
  2272  	{
  2273  		// See: https://dev.mysql.com/doc/refman/5.7/en/cast-functions.html#operator_binary
  2274  		x := types.NewFieldType(mysql.TypeString)
  2275  		x.Charset = charset.CharsetBin
  2276  		x.Collate = charset.CharsetBin
  2277  		$$ = &ast.FuncCastExpr{
  2278  			Expr: $2.(ast.ExprNode), 
  2279  			Tp: x,
  2280  			FunctionType: ast.CastBinaryOperator,
  2281  		}	
  2282  	}
  2283  |	PrimaryExpression "COLLATE" StringName %prec neg
  2284  	{
  2285  		// TODO: Create a builtin function hold expr and collation. When do evaluation, convert expr result using the collation.
  2286  		$$ = $1
  2287  	}
  2288  
  2289  Function:
  2290  	FunctionCallKeyword
  2291  |	FunctionCallNonKeyword
  2292  |	FunctionCallConflict
  2293  |	FunctionCallAgg
  2294  
  2295  FunctionNameConflict:
  2296  	"DATABASE" | "SCHEMA" | "IF" | "LEFT" | "REPEAT" | "CURRENT_USER" | "CURRENT_DATE" | "VERSION" | "UTC_DATE"
  2297  
  2298  FunctionCallConflict:
  2299  	FunctionNameConflict '(' ExpressionListOpt ')' 
  2300  	{
  2301  		$$ = &ast.FuncCallExpr{FnName: model.NewCIStr($1.(string)), Args: $3.([]ast.ExprNode)}
  2302  	}
  2303  |	"CURRENT_USER"
  2304  	{
  2305  		// See: https://dev.mysql.com/doc/refman/5.7/en/information-functions.html#function_current-user
  2306  		$$ = &ast.FuncCallExpr{FnName: model.NewCIStr($1.(string))}
  2307  	}
  2308  |	"CURRENT_DATE"
  2309  	{
  2310  		$$ = &ast.FuncCallExpr{FnName: model.NewCIStr($1.(string))}
  2311  	}
  2312  |	"UTC_DATE"
  2313  	{
  2314  		$$ = &ast.FuncCallExpr{FnName: model.NewCIStr($1.(string))}
  2315  	}
  2316  |	"MOD" '(' PrimaryFactor ',' PrimaryFactor ')'
  2317  	{
  2318  		$$ = &ast.BinaryOperationExpr{Op: opcode.Mod, L: $3.(ast.ExprNode), R: $5.(ast.ExprNode)}
  2319  	}
  2320  
  2321  DistinctOpt:
  2322  	{
  2323  		$$ = false
  2324  	}
  2325  |	"ALL"
  2326  	{
  2327  		$$ = false
  2328  	}
  2329  |	"DISTINCT"
  2330  	{
  2331  		$$ = true
  2332  	}
  2333  |	"DISTINCT" "ALL"
  2334  	{
  2335  		$$ = true
  2336  	}
  2337  
  2338  FunctionCallKeyword:
  2339  	"CAST" '(' Expression "AS" CastType ')'
  2340  	{
  2341  		/* See: https://dev.mysql.com/doc/refman/5.7/en/cast-functions.html#function_cast */
  2342  		$$ = &ast.FuncCastExpr{
  2343  			Expr: $3.(ast.ExprNode), 
  2344  			Tp: $5.(*types.FieldType),
  2345  			FunctionType: ast.CastFunction,
  2346  		}
  2347  	}
  2348  |	"CASE" ExpressionOpt WhenClauseList ElseOpt "END"	
  2349  	{
  2350  		x := &ast.CaseExpr{WhenClauses: $3.([]*ast.WhenClause)}
  2351  		if $2 != nil {
  2352  			x.Value = $2.(ast.ExprNode)
  2353  		}
  2354  		if $4 != nil {
  2355  			x.ElseClause = $4.(ast.ExprNode)
  2356  		}
  2357  		$$ = x
  2358  	}
  2359  |	"CONVERT" '(' Expression "USING" StringName ')' 
  2360  	{
  2361  		// See: https://dev.mysql.com/doc/refman/5.7/en/cast-functions.html#function_convert
  2362  		charset := ast.NewValueExpr($5)
  2363  		$$ = &ast.FuncCallExpr{
  2364  			FnName: model.NewCIStr($1.(string)),
  2365  			Args: []ast.ExprNode{$3.(ast.ExprNode), charset},
  2366  		}
  2367  	}
  2368  |	"CONVERT" '(' Expression ',' CastType ')'
  2369  	{
  2370  		// See: https://dev.mysql.com/doc/refman/5.7/en/cast-functions.html#function_convert
  2371  		$$ = &ast.FuncCastExpr{
  2372  			Expr: $3.(ast.ExprNode), 
  2373  			Tp: $5.(*types.FieldType),
  2374  			FunctionType: ast.CastConvertFunction,
  2375  		}	
  2376  	}
  2377  |	"ASCII" '(' Expression ')'
  2378  	{
  2379  		$$ = &ast.FuncCallExpr{FnName: model.NewCIStr($1.(string)), Args: []ast.ExprNode{$3.(ast.ExprNode)}}
  2380  	}
  2381  |	"DATE" '(' Expression ')'
  2382  	{
  2383  		$$ = &ast.FuncCallExpr{FnName: model.NewCIStr($1.(string)), Args: []ast.ExprNode{$3.(ast.ExprNode)}}
  2384  	}
  2385  |	"USER" '(' ')'
  2386  	{
  2387  		$$ = &ast.FuncCallExpr{FnName: model.NewCIStr($1.(string))}
  2388  	}
  2389  |	"VALUES" '(' ColumnName ')' %prec lowerThanInsertValues
  2390  	{
  2391  		// TODO: support qualified identifier for column_name
  2392  		$$ = &ast.ValuesExpr{Column: &ast.ColumnNameExpr{Name: $3.(*ast.ColumnName)}}
  2393  	}
  2394  |	"WEEK" '(' ExpressionList ')'
  2395  	{
  2396  		$$ = &ast.FuncCallExpr{FnName: model.NewCIStr($1.(string)), Args: $3.([]ast.ExprNode)}
  2397  	}
  2398  |	"YEAR" '(' Expression ')'
  2399  	{
  2400  		$$ = &ast.FuncCallExpr{FnName:model.NewCIStr($1.(string)), Args: []ast.ExprNode{$3.(ast.ExprNode)}}
  2401  	}
  2402  
  2403  FunctionCallNonKeyword:
  2404  	"COALESCE" '(' ExpressionList ')'
  2405  	{
  2406  		$$ = &ast.FuncCallExpr{FnName: model.NewCIStr($1.(string)), Args: $3.([]ast.ExprNode)}
  2407  	}
  2408  |	"CURDATE" '(' ')'
  2409  	{
  2410  		$$ = &ast.FuncCallExpr{FnName: model.NewCIStr($1.(string))}
  2411  	}
  2412  |	"CUR_TIME" '(' ExpressionOpt ')' 
  2413  	{
  2414  		args := []ast.ExprNode{}
  2415  		if $3 != nil {
  2416  			args = append(args, $3.(ast.ExprNode))
  2417  		}
  2418  		$$ = &ast.FuncCallExpr{FnName: model.NewCIStr($1.(string)), Args: args}
  2419  	}
  2420  |	"CURRENT_TIME" FuncDatetimePrec
  2421  	{
  2422  		args := []ast.ExprNode{}
  2423  		if $2 != nil {
  2424  			args = append(args, $2.(ast.ExprNode))
  2425  		}
  2426  		$$ = &ast.FuncCallExpr{FnName: model.NewCIStr($1.(string)), Args: args}
  2427  	}
  2428  |	"CURRENT_TIMESTAMP" FuncDatetimePrec
  2429  	{
  2430  		args := []ast.ExprNode{}
  2431  		if $2 != nil {
  2432  			args = append(args, $2.(ast.ExprNode))
  2433  		}
  2434  		$$ = &ast.FuncCallExpr{FnName: model.NewCIStr($1.(string)), Args: args}
  2435  	}
  2436  |	"ABS" '(' Expression ')'
  2437  	{
  2438  		$$ = &ast.FuncCallExpr{FnName: model.NewCIStr($1.(string)), Args: []ast.ExprNode{$3.(ast.ExprNode)}}
  2439  	}
  2440  |	"CONCAT" '(' ExpressionList ')'
  2441  	{
  2442  		$$ = &ast.FuncCallExpr{FnName: model.NewCIStr($1.(string)), Args: $3.([]ast.ExprNode)}
  2443  	}
  2444  |	"CONCAT_WS" '(' ExpressionList ')'
  2445  	{
  2446  		$$ = &ast.FuncCallExpr{FnName: model.NewCIStr($1.(string)), Args: $3.([]ast.ExprNode)}
  2447  	}
  2448  |	"DAY" '(' Expression ')'
  2449  	{
  2450  		$$ =  &ast.FuncCallExpr{FnName: model.NewCIStr($1.(string)), Args: []ast.ExprNode{$3.(ast.ExprNode)}}
  2451  	}
  2452  |	"DAYNAME" '(' Expression ')'
  2453  	{
  2454  		$$ = &ast.FuncCallExpr{FnName: model.NewCIStr($1.(string)), Args: []ast.ExprNode{$3.(ast.ExprNode)}}
  2455  	}
  2456  |	"DAYOFWEEK" '(' Expression ')'
  2457  	{
  2458  		$$ = &ast.FuncCallExpr{FnName: model.NewCIStr($1.(string)), Args: []ast.ExprNode{$3.(ast.ExprNode)}}
  2459  	}
  2460  |	"DAYOFMONTH" '(' Expression ')'
  2461  	{
  2462  		$$ = &ast.FuncCallExpr{FnName: model.NewCIStr($1.(string)), Args: []ast.ExprNode{$3.(ast.ExprNode)}}
  2463  	}
  2464  |	"DAYOFYEAR" '(' Expression ')'
  2465  	{
  2466  		$$ = &ast.FuncCallExpr{FnName: model.NewCIStr($1.(string)), Args: []ast.ExprNode{$3.(ast.ExprNode)}}
  2467  	}
  2468  |	DateArithOpt '(' Expression ',' "INTERVAL" Expression TimeUnit ')'
  2469  	{
  2470  		op := ast.NewValueExpr($1)
  2471  		dateArithInterval := ast.NewValueExpr(
  2472  			ast.DateArithInterval{
  2473  				Unit: $7.(string),
  2474  				Interval: $6.(ast.ExprNode),
  2475  			},
  2476  		)
  2477  
  2478  		$$ = &ast.FuncCallExpr{
  2479  			FnName: model.NewCIStr("DATE_ARITH"),
  2480  			Args: []ast.ExprNode{
  2481  				op,
  2482  				$3.(ast.ExprNode),
  2483  				dateArithInterval,
  2484  			},
  2485  		}
  2486  	}
  2487  |	DateArithMultiFormsOpt '(' Expression ',' DateArithInterval')'
  2488  	{
  2489  		op := ast.NewValueExpr($1)
  2490  		dateArithInterval := ast.NewValueExpr($5)
  2491  		$$ = &ast.FuncCallExpr{
  2492  			FnName: model.NewCIStr("DATE_ARITH"),
  2493  			Args: []ast.ExprNode{
  2494  				op,
  2495  				$3.(ast.ExprNode),
  2496  				dateArithInterval,
  2497  			},
  2498  		}
  2499  	}
  2500  |	"EXTRACT" '(' TimeUnit "FROM" Expression ')'
  2501  	{
  2502  		timeUnit := ast.NewValueExpr($3)
  2503  		$$ = &ast.FuncCallExpr{
  2504  			FnName: model.NewCIStr($1.(string)),
  2505  			Args: []ast.ExprNode{timeUnit, $5.(ast.ExprNode)},
  2506  		}
  2507  	}
  2508  |	"FOUND_ROWS" '(' ')'
  2509  	{
  2510  		$$ =  &ast.FuncCallExpr{FnName: model.NewCIStr($1.(string))}
  2511  	}
  2512  |	"HOUR" '(' Expression ')'
  2513  	{
  2514  		$$ = &ast.FuncCallExpr{FnName: model.NewCIStr($1.(string)), Args: []ast.ExprNode{$3.(ast.ExprNode)}}
  2515  	}
  2516  |	"IFNULL" '(' ExpressionList ')'
  2517  	{
  2518  		$$ = &ast.FuncCallExpr{FnName: model.NewCIStr($1.(string)), Args: $3.([]ast.ExprNode)}
  2519  	}
  2520  |	"ISNULL" '(' Expression ')'
  2521  	{
  2522  		$$ = &ast.FuncCallExpr{FnName: model.NewCIStr($1.(string)), Args: []ast.ExprNode{$3.(ast.ExprNode)}}
  2523  	}
  2524  |	"LENGTH" '(' Expression ')'
  2525  	{
  2526  		$$ = &ast.FuncCallExpr{FnName: model.NewCIStr($1.(string)), Args: []ast.ExprNode{$3.(ast.ExprNode)}}
  2527  	}
  2528  |	"LOCATE" '(' Expression ',' Expression ')'
  2529  	{
  2530  		$$ = &ast.FuncCallExpr{
  2531  			FnName: model.NewCIStr($1.(string)),
  2532  			Args: []ast.ExprNode{$3.(ast.ExprNode), $5.(ast.ExprNode)},
  2533  		}
  2534  	}
  2535  |	"LOCATE" '(' Expression ',' Expression ',' Expression ')'
  2536  	{
  2537  		$$ = &ast.FuncCallExpr{
  2538  			FnName: model.NewCIStr($1.(string)),
  2539  			Args: []ast.ExprNode{$3.(ast.ExprNode), $5.(ast.ExprNode), $7.(ast.ExprNode)},
  2540  		}
  2541  	}
  2542  |	"LOWER" '(' Expression ')'
  2543  	{
  2544  		$$ = &ast.FuncCallExpr{FnName: model.NewCIStr($1.(string)), Args: []ast.ExprNode{$3.(ast.ExprNode)}}
  2545  	}
  2546  |	"LCASE" '(' Expression ')'
  2547  	{
  2548  		$$ = &ast.FuncCallExpr{FnName: model.NewCIStr($1.(string)), Args: []ast.ExprNode{$3.(ast.ExprNode)}}
  2549  	}
  2550  |	"LTRIM" '(' Expression ')'
  2551  	{
  2552  		$$ = &ast.FuncCallExpr{FnName: model.NewCIStr($1.(string)), Args: []ast.ExprNode{$3.(ast.ExprNode)}}
  2553  	}
  2554  |	"MICROSECOND" '(' Expression ')'
  2555  	{
  2556  		$$ = &ast.FuncCallExpr{FnName: model.NewCIStr($1.(string)), Args: []ast.ExprNode{$3.(ast.ExprNode)}}
  2557  	}
  2558  |	"MINUTE" '(' Expression ')'
  2559  	{
  2560  		$$ = &ast.FuncCallExpr{FnName: model.NewCIStr($1.(string)), Args: []ast.ExprNode{$3.(ast.ExprNode)}}
  2561  	}
  2562  |	"MONTH" '(' Expression ')'
  2563  	{
  2564  		$$ = &ast.FuncCallExpr{FnName: model.NewCIStr($1.(string)), Args: []ast.ExprNode{$3.(ast.ExprNode)}}
  2565  	}
  2566  |	"NOW" '(' ExpressionOpt ')'
  2567  	{
  2568  		args := []ast.ExprNode{}
  2569  		if $3 != nil {
  2570  			args = append(args, $3.(ast.ExprNode))
  2571  		}
  2572  		$$ = &ast.FuncCallExpr{FnName: model.NewCIStr($1.(string)), Args: args}
  2573  	}
  2574  |	"NULLIF" '(' ExpressionList ')'
  2575  	{
  2576  		$$ = &ast.FuncCallExpr{FnName: model.NewCIStr($1.(string)), Args: $3.([]ast.ExprNode)}
  2577  	}
  2578  |	"POW" '(' Expression ',' Expression ')'
  2579  	{
  2580  		args := []ast.ExprNode{$3.(ast.ExprNode), $5.(ast.ExprNode)}
  2581  		$$ = &ast.FuncCallExpr{FnName: model.NewCIStr($1.(string)), Args: args}
  2582  	}
  2583  |	"POWER" '(' Expression ',' Expression ')'
  2584  	{
  2585  		args := []ast.ExprNode{$3.(ast.ExprNode), $5.(ast.ExprNode)}
  2586  		$$ = &ast.FuncCallExpr{FnName: model.NewCIStr($1.(string)), Args: args}
  2587  	}
  2588  |	"RAND" '(' ExpressionOpt ')'
  2589  	{
  2590  
  2591  		args := []ast.ExprNode{}
  2592  		if $3 != nil {
  2593  			args = append(args, $3.(ast.ExprNode))
  2594  		}
  2595  		$$ = &ast.FuncCallExpr{FnName: model.NewCIStr($1.(string)), Args: args}
  2596  	}
  2597  |	"REPLACE" '(' Expression ',' Expression ',' Expression ')'
  2598  	{
  2599  		args := []ast.ExprNode{$3.(ast.ExprNode), $5.(ast.ExprNode), $7.(ast.ExprNode)}
  2600  		$$ = &ast.FuncCallExpr{FnName: model.NewCIStr($1.(string)), Args: args}
  2601  	}
  2602  |	"REVERSE" '(' Expression ')'
  2603  	{
  2604  		$$ = &ast.FuncCallExpr{FnName: model.NewCIStr($1.(string)), Args: []ast.ExprNode{$3.(ast.ExprNode)}}
  2605  	}
  2606  |	"RTRIM" '(' Expression ')'
  2607  	{
  2608  		$$ = &ast.FuncCallExpr{FnName: model.NewCIStr($1.(string)), Args: []ast.ExprNode{$3.(ast.ExprNode)}}
  2609  	}
  2610  |	"SECOND" '(' Expression ')'
  2611  	{
  2612  		$$ = &ast.FuncCallExpr{FnName: model.NewCIStr($1.(string)), Args: []ast.ExprNode{$3.(ast.ExprNode)}}
  2613  	}
  2614  |	"STRCMP" '(' Expression ',' Expression ')'
  2615  	{
  2616  		$$ = &ast.FuncCallExpr{FnName: model.NewCIStr($1.(string)), Args: []ast.ExprNode{$3.(ast.ExprNode), $5.(ast.ExprNode)}}
  2617  	}
  2618  |	"SUBSTRING" '(' Expression ',' Expression ')'
  2619  	{
  2620  		$$ = &ast.FuncCallExpr{
  2621  			FnName: model.NewCIStr($1.(string)),
  2622  			Args: []ast.ExprNode{$3.(ast.ExprNode), $5.(ast.ExprNode)},
  2623  		}
  2624  	}
  2625  |	"SUBSTRING" '(' Expression "FROM" Expression ')'
  2626  	{
  2627  		$$ = &ast.FuncCallExpr{
  2628  			FnName: model.NewCIStr($1.(string)),
  2629  			Args: []ast.ExprNode{$3.(ast.ExprNode), $5.(ast.ExprNode)},
  2630  		}
  2631  	}
  2632  |	"SUBSTRING" '(' Expression ',' Expression ',' Expression ')'
  2633  	{
  2634  		$$ = &ast.FuncCallExpr{
  2635  			FnName: model.NewCIStr($1.(string)),
  2636  			Args: []ast.ExprNode{$3.(ast.ExprNode), $5.(ast.ExprNode), $7.(ast.ExprNode)},
  2637  		}
  2638  	}
  2639  |	"SUBSTRING" '(' Expression "FROM" Expression "FOR" Expression ')'
  2640  	{
  2641  		$$ = &ast.FuncCallExpr{
  2642  			FnName: model.NewCIStr($1.(string)),
  2643  			Args: []ast.ExprNode{$3.(ast.ExprNode), $5.(ast.ExprNode), $7.(ast.ExprNode)},
  2644  		}
  2645  	}
  2646  |	"SUBSTRING_INDEX" '(' Expression ',' Expression ',' Expression ')'
  2647  	{
  2648  		$$ = &ast.FuncCallExpr{
  2649  			FnName: model.NewCIStr($1.(string)),
  2650  			Args: []ast.ExprNode{$3.(ast.ExprNode), $5.(ast.ExprNode), $7.(ast.ExprNode)},
  2651  		}
  2652  	}
  2653  |	"SYSDATE" '(' ExpressionOpt ')'
  2654  	{
  2655  		args := []ast.ExprNode{}
  2656  		if $3 != nil {
  2657  			args = append(args, $3.(ast.ExprNode))
  2658  		}
  2659  		$$ = &ast.FuncCallExpr{FnName: model.NewCIStr($1.(string)), Args: args}
  2660  	}
  2661  |	"TRIM" '(' Expression ')'
  2662  	{
  2663  		$$ = &ast.FuncCallExpr{
  2664  			FnName: model.NewCIStr($1.(string)),
  2665  			Args: []ast.ExprNode{$3.(ast.ExprNode)},
  2666  		}
  2667  	}
  2668  |	"TRIM" '(' Expression "FROM" Expression ')'
  2669  	{
  2670  		$$ = &ast.FuncCallExpr{
  2671  			FnName: model.NewCIStr($1.(string)),
  2672  			Args: []ast.ExprNode{$5.(ast.ExprNode), $3.(ast.ExprNode)},
  2673  		}
  2674  	}
  2675  |	"TRIM" '(' TrimDirection "FROM" Expression ')'
  2676  	{
  2677  		nilVal := ast.NewValueExpr(nil)
  2678  		direction := ast.NewValueExpr($3)
  2679  		$$ = &ast.FuncCallExpr{
  2680  			FnName: model.NewCIStr($1.(string)),
  2681  			Args: []ast.ExprNode{$5.(ast.ExprNode), nilVal, direction},
  2682  		}
  2683  	}
  2684  |	"TRIM" '(' TrimDirection Expression "FROM" Expression ')'
  2685  	{
  2686  		direction := ast.NewValueExpr($3)
  2687  		$$ = &ast.FuncCallExpr{
  2688  			FnName: model.NewCIStr($1.(string)),
  2689  			Args: []ast.ExprNode{$6.(ast.ExprNode),$4.(ast.ExprNode), direction},
  2690  		}
  2691  	}
  2692  |	"UPPER" '(' Expression ')'
  2693  	{
  2694  		$$ = &ast.FuncCallExpr{FnName: model.NewCIStr($1.(string)), Args: []ast.ExprNode{$3.(ast.ExprNode)}}
  2695  	}
  2696  |	"UCASE" '(' Expression ')'
  2697  	{
  2698  		$$ = &ast.FuncCallExpr{FnName: model.NewCIStr($1.(string)), Args: []ast.ExprNode{$3.(ast.ExprNode)}}
  2699  	}
  2700  |	"WEEKDAY" '(' Expression ')'
  2701  	{
  2702  		$$ = &ast.FuncCallExpr{FnName: model.NewCIStr($1.(string)), Args: []ast.ExprNode{$3.(ast.ExprNode)}}
  2703  	}
  2704  |	"WEEKOFYEAR" '(' Expression ')'
  2705  	{
  2706  		$$ = &ast.FuncCallExpr{FnName: model.NewCIStr($1.(string)), Args: []ast.ExprNode{$3.(ast.ExprNode)}}
  2707  	}
  2708  |	"YEARWEEK" '(' ExpressionList ')'
  2709  	{
  2710  		$$ = &ast.FuncCallExpr{FnName: model.NewCIStr($1.(string)), Args: $3.([]ast.ExprNode)}
  2711  	}
  2712  |	"CONNECTION_ID" '(' ')'
  2713  	{
  2714  		$$ = &ast.FuncCallExpr{FnName: model.NewCIStr($1.(string))}
  2715  	}
  2716  |	"ROUND" '(' ExpressionList ')'
  2717  	{
  2718  		$$ = &ast.FuncCallExpr{FnName: model.NewCIStr($1.(string)), Args: $3.([]ast.ExprNode)}
  2719  	}
  2720  
  2721  DateArithOpt:
  2722  	"DATE_ADD"
  2723  	{
  2724  		$$ = ast.DateAdd
  2725  	}
  2726  |	"DATE_SUB"
  2727  	{
  2728  		$$ = ast.DateSub
  2729  	}
  2730  
  2731  DateArithMultiFormsOpt:
  2732  	"ADDDATE"
  2733  	{
  2734  		$$ = ast.DateAdd
  2735  	}
  2736  |	"SUBDATE"
  2737  	{
  2738  		$$ = ast.DateSub
  2739  	}
  2740  
  2741  DateArithInterval:
  2742  	Expression
  2743  	{
  2744  		$$ = ast.DateArithInterval{
  2745  					Unit: "day",
  2746  					Interval: $1.(ast.ExprNode),
  2747  		}
  2748  	}
  2749  |	"INTERVAL" Expression TimeUnit
  2750  	{
  2751  		$$ = ast.DateArithInterval{Unit: $3.(string), Interval: $2.(ast.ExprNode)}
  2752  	}
  2753  
  2754  TrimDirection:
  2755  	"BOTH"
  2756  	{
  2757  		$$ = ast.TrimBoth
  2758  	}
  2759  |	"LEADING"
  2760  	{
  2761  		$$ = ast.TrimLeading
  2762  	}
  2763  |	"TRAILING"
  2764  	{
  2765  		$$ = ast.TrimTrailing
  2766  	}
  2767  
  2768  FunctionCallAgg:
  2769  	"AVG" '(' DistinctOpt ExpressionList ')'
  2770  	{
  2771  		$$ = &ast.AggregateFuncExpr{F: $1.(string), Args: $4.([]ast.ExprNode), Distinct: $3.(bool)}
  2772  	}
  2773  |	"COUNT" '(' DistinctOpt ExpressionList ')'
  2774  	{
  2775  		$$ = &ast.AggregateFuncExpr{F: $1.(string), Args: $4.([]ast.ExprNode), Distinct: $3.(bool)}
  2776  	}
  2777  |	"COUNT" '(' DistinctOpt '*' ')'
  2778  	{
  2779  		args := []ast.ExprNode{ast.NewValueExpr(ast.UnquoteString("*"))}
  2780  		$$ = &ast.AggregateFuncExpr{F: $1.(string), Args: args, Distinct: $3.(bool)}
  2781  	}
  2782  |	"GROUP_CONCAT" '(' DistinctOpt ExpressionList ')'
  2783  	{
  2784  		$$ = &ast.AggregateFuncExpr{F: $1.(string), Args: $4.([]ast.ExprNode), Distinct: $3.(bool)}
  2785  	}
  2786  |	"MAX" '(' DistinctOpt Expression ')'
  2787  	{
  2788  		$$ = &ast.AggregateFuncExpr{F: $1.(string), Args: []ast.ExprNode{$4.(ast.ExprNode)}, Distinct: $3.(bool)}
  2789  	}
  2790  |	"MIN" '(' DistinctOpt Expression ')'
  2791  	{
  2792  		$$ = &ast.AggregateFuncExpr{F: $1.(string), Args: []ast.ExprNode{$4.(ast.ExprNode)}, Distinct: $3.(bool)}
  2793  	}
  2794  |	"SUM" '(' DistinctOpt Expression ')'
  2795  	{
  2796  		$$ = &ast.AggregateFuncExpr{F: $1.(string), Args: []ast.ExprNode{$4.(ast.ExprNode)}, Distinct: $3.(bool)}
  2797  	}
  2798  
  2799  FuncDatetimePrec:
  2800  	{
  2801  		$$ = nil
  2802  	}
  2803  |	'(' ')'
  2804  	{
  2805  		$$ = nil
  2806  	}
  2807  |	'(' Expression ')'
  2808  	{
  2809  		$$ = $2
  2810  	}
  2811  
  2812  TimeUnit:
  2813  	"MICROSECOND" | "SECOND" | "MINUTE" | "HOUR" | "DAY" | "WEEK" 
  2814  |	"MONTH" | "QUARTER" | "YEAR" | "SECOND_MICROSECOND" | "MINUTE_MICROSECOND"
  2815  |	"MINUTE_SECOND" | "HOUR_MICROSECOND" | "HOUR_SECOND" | "HOUR_MINUTE" 
  2816  |	"DAY_MICROSECOND" | "DAY_SECOND" | "DAY_MINUTE" | "DAY_HOUR" | "YEAR_MONTH"
  2817  
  2818  ExpressionOpt:
  2819  	{
  2820  		$$ = nil
  2821  	}
  2822  |	Expression
  2823  	{	
  2824  		$$ = $1
  2825  	}
  2826  
  2827  WhenClauseList:
  2828  	WhenClause
  2829  	{
  2830  		$$ = []*ast.WhenClause{$1.(*ast.WhenClause)}
  2831  	}
  2832  |	WhenClauseList WhenClause
  2833  	{
  2834  		$$ = append($1.([]*ast.WhenClause), $2.(*ast.WhenClause))
  2835  	}
  2836  
  2837  WhenClause:
  2838  	"WHEN" Expression "THEN" Expression
  2839  	{
  2840  		$$ = &ast.WhenClause{
  2841  			Expr: $2.(ast.ExprNode),
  2842  			Result: $4.(ast.ExprNode),
  2843  		}
  2844  	}
  2845  
  2846  ElseOpt:
  2847  	/* empty */
  2848  	{
  2849  		$$ = nil	
  2850  	}
  2851  |	"ELSE" Expression
  2852  	{
  2853  		$$ = $2
  2854  	}
  2855  
  2856  CastType:
  2857  	"BINARY" OptFieldLen
  2858  	{
  2859  		x := types.NewFieldType(mysql.TypeString)
  2860  		x.Flen = $2.(int) 
  2861  		x.Charset = charset.CharsetBin
  2862  		x.Collate = charset.CharsetBin
  2863  		$$ = x
  2864  	}
  2865  |	"CHAR" OptFieldLen OptBinary OptCharset
  2866  	{
  2867  		x := types.NewFieldType(mysql.TypeString)
  2868  		x.Flen = $2.(int) 
  2869  		if $3.(bool) {
  2870  			x.Flag |= mysql.BinaryFlag
  2871  		}
  2872  		x.Charset = $4.(string)
  2873  		$$ = x
  2874  	}
  2875  |	"DATE"
  2876  	{
  2877  		x := types.NewFieldType(mysql.TypeDate)
  2878  		$$ = x
  2879  	}
  2880  |	"DATETIME" OptFieldLen
  2881  	{
  2882  		x := types.NewFieldType(mysql.TypeDatetime)
  2883  		x.Decimal = $2.(int)
  2884  		$$ = x
  2885  	}
  2886  |	"DECIMAL" FloatOpt
  2887  	{
  2888  		fopt := $2.(*ast.FloatOpt)
  2889  		x := types.NewFieldType(mysql.TypeNewDecimal)
  2890  		x.Flen = fopt.Flen
  2891  		x.Decimal = fopt.Decimal
  2892  		$$ = x
  2893  	}
  2894  |	"TIME" OptFieldLen
  2895  	{
  2896  		x := types.NewFieldType(mysql.TypeDuration)
  2897  		x.Decimal = $2.(int)
  2898  		$$ = x
  2899  	}
  2900  |	"SIGNED" OptInteger
  2901  	{
  2902  		x := types.NewFieldType(mysql.TypeLonglong)
  2903  		$$ = x
  2904  	}
  2905  |	"UNSIGNED" OptInteger
  2906  	{
  2907  		x := types.NewFieldType(mysql.TypeLonglong)
  2908  		x.Flag |= mysql.UnsignedFlag
  2909  		$$ = x
  2910  	}
  2911  
  2912  
  2913  PrimaryFactor:
  2914  	PrimaryFactor '|' PrimaryFactor %prec '|'
  2915  	{
  2916  		$$ = &ast.BinaryOperationExpr{Op: opcode.Or, L: $1.(ast.ExprNode), R: $3.(ast.ExprNode)}
  2917  	}
  2918  |	PrimaryFactor '&' PrimaryFactor %prec '&'
  2919  	{
  2920  		$$ = &ast.BinaryOperationExpr{Op: opcode.And, L: $1.(ast.ExprNode), R: $3.(ast.ExprNode)}
  2921  	}
  2922  |	PrimaryFactor "<<" PrimaryFactor %prec lsh
  2923  	{
  2924  		$$ = &ast.BinaryOperationExpr{Op: opcode.LeftShift, L: $1.(ast.ExprNode), R: $3.(ast.ExprNode)}
  2925  	}
  2926  |	PrimaryFactor ">>" PrimaryFactor %prec rsh
  2927  	{
  2928  		$$ = &ast.BinaryOperationExpr{Op: opcode.RightShift, L: $1.(ast.ExprNode), R: $3.(ast.ExprNode)}
  2929  	}
  2930  |	PrimaryFactor '+' PrimaryFactor %prec '+'
  2931  	{
  2932  		$$ = &ast.BinaryOperationExpr{Op: opcode.Plus, L: $1.(ast.ExprNode), R: $3.(ast.ExprNode)}
  2933  	}
  2934  |	PrimaryFactor '-' PrimaryFactor %prec '-'
  2935  	{
  2936  		$$ = &ast.BinaryOperationExpr{Op: opcode.Minus, L: $1.(ast.ExprNode), R: $3.(ast.ExprNode)}
  2937  	}
  2938  |	PrimaryFactor '*' PrimaryFactor %prec '*'
  2939  	{
  2940  		$$ = &ast.BinaryOperationExpr{Op: opcode.Mul, L: $1.(ast.ExprNode), R: $3.(ast.ExprNode)}
  2941  	}
  2942  |	PrimaryFactor '/' PrimaryFactor %prec '/'
  2943  	{
  2944  		$$ = &ast.BinaryOperationExpr{Op: opcode.Div, L: $1.(ast.ExprNode), R: $3.(ast.ExprNode)}
  2945  	}
  2946  |	PrimaryFactor '%' PrimaryFactor %prec '%'
  2947  	{
  2948  		$$ = &ast.BinaryOperationExpr{Op: opcode.Mod, L: $1.(ast.ExprNode), R: $3.(ast.ExprNode)}
  2949  	}
  2950  |	PrimaryFactor "DIV" PrimaryFactor %prec div
  2951  	{
  2952  		$$ = &ast.BinaryOperationExpr{Op: opcode.IntDiv, L: $1.(ast.ExprNode), R: $3.(ast.ExprNode)}
  2953  	}
  2954  |	PrimaryFactor "MOD" PrimaryFactor %prec mod
  2955  	{
  2956  		$$ = &ast.BinaryOperationExpr{Op: opcode.Mod, L: $1.(ast.ExprNode), R: $3.(ast.ExprNode)}
  2957  	}
  2958  |	PrimaryFactor '^' PrimaryFactor
  2959  	{
  2960  		$$ = &ast.BinaryOperationExpr{Op: opcode.Xor, L: $1.(ast.ExprNode), R: $3.(ast.ExprNode)}
  2961  	}
  2962  |	PrimaryExpression
  2963  
  2964  
  2965  Priority:
  2966  	{
  2967  		$$ = ast.NoPriority
  2968  	}
  2969  |	"LOW_PRIORITY"
  2970  	{
  2971  		$$ = ast.LowPriority
  2972  	}
  2973  |	"HIGH_PRIORITY"
  2974  	{
  2975  		$$ = ast.HighPriority
  2976  	}
  2977  |	"DELAYED"
  2978  	{
  2979  		$$ = ast.DelayedPriority
  2980  	}
  2981  
  2982  LowPriorityOptional:
  2983  	{
  2984  		$$ = false
  2985  	}
  2986  |	"LOW_PRIORITY"
  2987  	{
  2988  		$$ = true
  2989  	}
  2990  
  2991  TableName:
  2992  	Identifier
  2993  	{
  2994  		$$ = &ast.TableName{Name:model.NewCIStr($1.(string))}
  2995  	}
  2996  |	Identifier '.' Identifier
  2997  	{
  2998  		$$ = &ast.TableName{Schema:model.NewCIStr($1.(string)),	Name:model.NewCIStr($3.(string))}
  2999  	}
  3000  
  3001  TableNameList:
  3002  	TableName
  3003  	{
  3004  		tbl := []*ast.TableName{$1.(*ast.TableName)}
  3005  		$$ = tbl
  3006  	}
  3007  |	TableNameList ',' TableName
  3008  	{
  3009  		$$ = append($1.([]*ast.TableName), $3.(*ast.TableName))
  3010  	}
  3011  
  3012  QuickOptional:
  3013  	%prec lowerThanQuick
  3014  	{
  3015  		$$ = false
  3016  	}
  3017  |	"QUICK"
  3018  	{
  3019  		$$ = true
  3020  	}
  3021  
  3022  /***************************Prepared Statement Start******************************
  3023   * See: https://dev.mysql.com/doc/refman/5.7/en/prepare.html
  3024   * Example:
  3025   * PREPARE stmt_name FROM 'SELECT SQRT(POW(?,2) + POW(?,2)) AS hypotenuse';
  3026   * OR
  3027   * SET @s = 'SELECT SQRT(POW(?,2) + POW(?,2)) AS hypotenuse';
  3028   * PREPARE stmt_name FROM @s;
  3029   */
  3030  
  3031  PreparedStmt:
  3032  	"PREPARE" Identifier "FROM" PrepareSQL
  3033  	{
  3034  		var sqlText string
  3035  		var sqlVar *ast.VariableExpr
  3036  		switch $4.(type) {
  3037  		case string:
  3038  			sqlText = $4.(string)
  3039  		case *ast.VariableExpr:
  3040  			sqlVar = $4.(*ast.VariableExpr)
  3041  		}
  3042  		$$ = &ast.PrepareStmt{
  3043  			Name:		$2.(string), 
  3044  			SQLText:	sqlText, 
  3045  			SQLVar: 	sqlVar,
  3046  		}
  3047  	}
  3048  
  3049  PrepareSQL:
  3050  	stringLit
  3051  |	UserVariable
  3052  
  3053  
  3054  /*
  3055   * See: https://dev.mysql.com/doc/refman/5.7/en/execute.html
  3056   * Example:
  3057   * EXECUTE stmt1 USING @a, @b;
  3058   * OR
  3059   * EXECUTE stmt1;
  3060   */
  3061  ExecuteStmt:
  3062  	"EXECUTE" Identifier
  3063  	{
  3064  		$$ = &ast.ExecuteStmt{Name: $2.(string)}
  3065  	}
  3066  |	"EXECUTE" Identifier "USING" UserVariableList
  3067  	{
  3068  		$$ = &ast.ExecuteStmt{
  3069  			Name: $2.(string), 
  3070  			UsingVars: $4.([]ast.ExprNode),
  3071  		}
  3072  	}
  3073  
  3074  UserVariableList:
  3075  	UserVariable
  3076  	{
  3077  		$$ = []ast.ExprNode{$1.(ast.ExprNode)}		
  3078  	}
  3079  |	UserVariableList ',' UserVariable
  3080  	{
  3081  		$$ = append($1.([]ast.ExprNode), $3.(ast.ExprNode))		
  3082  	}
  3083  
  3084  /*
  3085   * See: https://dev.mysql.com/doc/refman/5.0/en/deallocate-prepare.html
  3086   */
  3087  
  3088  DeallocateStmt:
  3089  	DeallocateSym "PREPARE" Identifier
  3090  	{
  3091  		$$ = &ast.DeallocateStmt{Name: $3.(string)}
  3092  	}
  3093  
  3094  DeallocateSym:
  3095  	"DEALLOCATE" | "DROP"
  3096  
  3097  /****************************Prepared Statement End*******************************/
  3098  
  3099  
  3100  RollbackStmt:
  3101  	"ROLLBACK"
  3102  	{
  3103  		$$ = &ast.RollbackStmt{}
  3104  	}
  3105  
  3106  SelectStmt:
  3107  	"SELECT" SelectStmtOpts SelectStmtFieldList SelectStmtLimit SelectLockOpt
  3108  	{
  3109  		st := &ast.SelectStmt {
  3110  			Distinct:      $2.(bool),
  3111  			Fields:        $3.(*ast.FieldList),
  3112  			LockTp:	       $5.(ast.SelectLockType),
  3113  		}
  3114  		lastField := st.Fields.Fields[len(st.Fields.Fields)-1]
  3115  		if lastField.Expr != nil && lastField.AsName.O == "" {
  3116  			src := yylex.(*lexer).src
  3117  			var lastEnd int
  3118  			if $4 != nil {
  3119  				lastEnd = yyS[yypt-1].offset-1
  3120  			} else if $5 != ast.SelectLockNone {
  3121  				lastEnd = yyS[yypt].offset-1
  3122  			} else {
  3123  				lastEnd = len(src)
  3124  				if src[lastEnd-1] == ';' {
  3125  					lastEnd--
  3126  				}
  3127  			}
  3128  			lastField.SetText(src[lastField.Offset:lastEnd])
  3129  		}
  3130  		if $4 != nil {
  3131  			st.Limit = $4.(*ast.Limit)
  3132  		}
  3133  		$$ = st
  3134  	}
  3135  |	"SELECT" SelectStmtOpts SelectStmtFieldList FromDual WhereClauseOptional SelectStmtLimit SelectLockOpt
  3136  	{
  3137  		st := &ast.SelectStmt {
  3138  			Distinct:      $2.(bool),
  3139  			Fields:        $3.(*ast.FieldList),
  3140  			LockTp:	       $7.(ast.SelectLockType),
  3141  		}
  3142  		lastField := st.Fields.Fields[len(st.Fields.Fields)-1]
  3143  		if lastField.Expr != nil && lastField.AsName.O == "" {
  3144  			lastEnd := yyS[yypt-3].offset-1
  3145  			lastField.SetText(yylex.(*lexer).src[lastField.Offset:lastEnd])
  3146  		}
  3147  		if $5 != nil {
  3148  			st.Where = $5.(ast.ExprNode)
  3149  		}
  3150  		if $6 != nil {
  3151  			st.Limit = $6.(*ast.Limit)
  3152  		}
  3153  		$$ = st
  3154  	}
  3155  |	"SELECT" SelectStmtOpts SelectStmtFieldList "FROM"
  3156  	TableRefsClause WhereClauseOptional SelectStmtGroup HavingClause OrderByOptional
  3157  	SelectStmtLimit SelectLockOpt
  3158  	{
  3159  		st := &ast.SelectStmt{
  3160  			Distinct:	$2.(bool),
  3161  			Fields:		$3.(*ast.FieldList),
  3162  			From:		$5.(*ast.TableRefsClause),
  3163  			LockTp:		$11.(ast.SelectLockType),
  3164  		}
  3165  
  3166  		lastField := st.Fields.Fields[len(st.Fields.Fields)-1]
  3167  		if lastField.Expr != nil && lastField.AsName.O == "" {
  3168  			lastEnd := yyS[yypt-7].offset-1
  3169  			lastField.SetText(yylex.(*lexer).src[lastField.Offset:lastEnd])
  3170  		}
  3171  
  3172  		if $6 != nil {
  3173  			st.Where = $6.(ast.ExprNode)
  3174  		}
  3175  
  3176  		if $7 != nil {
  3177  			st.GroupBy = $7.(*ast.GroupByClause)
  3178  		}
  3179  
  3180  		if $8 != nil {
  3181  			st.Having = $8.(*ast.HavingClause)
  3182  		}
  3183  
  3184  		if $9 != nil {
  3185  			st.OrderBy = $9.(*ast.OrderByClause)
  3186  		}
  3187  
  3188  		if $10 != nil {
  3189  			st.Limit = $10.(*ast.Limit)
  3190  		}
  3191  
  3192  		$$ = st
  3193  	}
  3194  
  3195  FromDual:
  3196  	"FROM" "DUAL"
  3197  
  3198  
  3199  TableRefsClause:
  3200  	TableRefs
  3201  	{
  3202  		$$ = &ast.TableRefsClause{TableRefs: $1.(*ast.Join)}
  3203  	}
  3204  
  3205  TableRefs:
  3206  	EscapedTableRef
  3207  	{
  3208  		if j, ok := $1.(*ast.Join); ok {
  3209  			// if $1 is Join, use it directly
  3210  			$$ = j
  3211  		} else {
  3212  			$$ = &ast.Join{Left: $1.(ast.ResultSetNode), Right: nil}
  3213  		}
  3214  	}
  3215  |	TableRefs ',' EscapedTableRef
  3216  	{
  3217  		/* from a, b is default cross join */
  3218  		$$ = &ast.Join{Left: $1.(ast.ResultSetNode), Right: $3.(ast.ResultSetNode), Tp: ast.CrossJoin}
  3219  	}
  3220  
  3221  EscapedTableRef:
  3222  	TableRef %prec lowerThanSetKeyword
  3223  	{
  3224  		$$ = $1
  3225  	}
  3226  |	'{' Identifier TableRef '}'
  3227  	{
  3228  		/* 
  3229  		* ODBC escape syntax for outer join is { OJ join_table } 
  3230  		* Use an Identifier for OJ 
  3231  		*/
  3232  		$$ = $3
  3233  	}
  3234  
  3235  TableRef:
  3236  	TableFactor 
  3237  	{
  3238  		$$ = $1
  3239  	}
  3240  |	JoinTable
  3241  	{
  3242  		$$ = $1
  3243  	}
  3244  
  3245  TableFactor:
  3246  	TableName TableAsNameOpt IndexHintListOpt
  3247  	{
  3248  		tn := $1.(*ast.TableName)
  3249  		tn.IndexHints = $3.([]*ast.IndexHint)
  3250  		$$ = &ast.TableSource{Source: tn, AsName: $2.(model.CIStr)}
  3251  	}
  3252  |	'(' SelectStmt ')' TableAsName
  3253  	{
  3254  		st := $2.(*ast.SelectStmt)
  3255  		l := yylex.(*lexer)
  3256  		endOffset := l.endOffset(yyS[yypt-1].offset)
  3257  		l.SetLastSelectFieldText(st, endOffset)
  3258  		$$ = &ast.TableSource{Source: $2.(*ast.SelectStmt), AsName: $4.(model.CIStr)}
  3259  	}
  3260  |	'(' UnionStmt ')' TableAsName
  3261  	{
  3262  		$$ = &ast.TableSource{Source: $2.(*ast.UnionStmt), AsName: $4.(model.CIStr)}
  3263  	}
  3264  |	'(' TableRefs ')'
  3265  	{
  3266  		$$ = $2
  3267  	}
  3268  
  3269  TableAsNameOpt:
  3270  	{
  3271  		$$ = model.CIStr{}
  3272  	}
  3273  |	TableAsName
  3274  	{
  3275  		$$ = $1
  3276  	}
  3277  
  3278  TableAsName:
  3279  	Identifier
  3280  	{
  3281  		$$ = model.NewCIStr($1.(string))
  3282  	}
  3283  |	"AS" Identifier
  3284  	{
  3285  		$$ = model.NewCIStr($2.(string))
  3286  	}
  3287  
  3288  IndexHintType:
  3289  	"USE" KeyOrIndex
  3290  	{
  3291  		$$ = ast.HintUse
  3292  	}
  3293  |	"IGNORE" KeyOrIndex
  3294  	{
  3295  		$$ = ast.HintIgnore
  3296  	}
  3297  |	"FORCE" KeyOrIndex
  3298  	{
  3299  		$$ = ast.HintForce
  3300  	}
  3301  
  3302  IndexHintScope:
  3303  	{
  3304  		$$ = ast.HintForScan
  3305  	}
  3306  |	"FOR" "JOIN"
  3307  	{
  3308  		$$ = ast.HintForJoin
  3309  	}
  3310  |	"FOR" "ORDER" "BY"
  3311  	{
  3312  		$$ = ast.HintForOrderBy
  3313  	}
  3314  |	"FOR" "GROUP" "BY"
  3315  	{
  3316  		$$ = ast.HintForGroupBy
  3317  	}
  3318  
  3319  
  3320  IndexHint:
  3321  	IndexHintType IndexHintScope '(' IndexNameList ')'
  3322  	{
  3323  		$$ = &ast.IndexHint{
  3324  			IndexNames:	$4.([]model.CIStr),
  3325  			HintType:	$1.(ast.IndexHintType),
  3326  			HintScope:	$2.(ast.IndexHintScope),
  3327  		}
  3328  	}
  3329  
  3330  IndexNameList:
  3331  	{
  3332  		var nameList []model.CIStr
  3333  		$$ = nameList
  3334  	}
  3335  |	Identifier
  3336  	{
  3337  		$$ = []model.CIStr{model.NewCIStr($1.(string))}
  3338  	}
  3339  |	IndexNameList ',' Identifier
  3340  	{
  3341  		$$ = append($1.([]model.CIStr), model.NewCIStr($3.(string)))
  3342  	}
  3343  
  3344  
  3345  IndexHintList:
  3346  	IndexHint
  3347  	{
  3348  		$$ = []*ast.IndexHint{$1.(*ast.IndexHint)}
  3349  	}
  3350  |	IndexHintList IndexHint
  3351   	{
  3352   		$$ = append($1.([]*ast.IndexHint), $2.(*ast.IndexHint))
  3353   	}
  3354   	
  3355  IndexHintListOpt:
  3356  	{
  3357  		var hintList []*ast.IndexHint
  3358  		$$ = hintList
  3359  	}
  3360  |	IndexHintList
  3361  	{
  3362  		$$ = $1
  3363  	}
  3364  
  3365  JoinTable:
  3366  	/* Use %prec to evaluate production TableRef before cross join */
  3367  	TableRef CrossOpt TableRef %prec tableRefPriority
  3368  	{
  3369  		$$ = &ast.Join{Left: $1.(ast.ResultSetNode), Right: $3.(ast.ResultSetNode), Tp: ast.CrossJoin}
  3370  	}
  3371  |	TableRef CrossOpt TableRef "ON" Expression
  3372  	{
  3373  		on := &ast.OnCondition{Expr: $5.(ast.ExprNode)}
  3374  		$$ = &ast.Join{Left: $1.(ast.ResultSetNode), Right: $3.(ast.ResultSetNode), Tp: ast.CrossJoin, On: on}
  3375  	}
  3376  |	TableRef JoinType OuterOpt "JOIN" TableRef "ON" Expression
  3377  	{
  3378  		on := &ast.OnCondition{Expr: $7.(ast.ExprNode)}
  3379  		$$ = &ast.Join{Left: $1.(ast.ResultSetNode), Right: $5.(ast.ResultSetNode), Tp: $2.(ast.JoinType), On: on}
  3380  	}
  3381  	/* Support Using */
  3382  
  3383  JoinType:
  3384  	"LEFT"
  3385  	{
  3386  		$$ = ast.LeftJoin
  3387  	}
  3388  |	"RIGHT"
  3389  	{
  3390  		$$ = ast.RightJoin
  3391  	}
  3392  
  3393  OuterOpt:
  3394  	{
  3395  		$$ = nil
  3396  	}
  3397  |	"OUTER"
  3398  
  3399  
  3400  CrossOpt:
  3401  	"JOIN"
  3402  |	"CROSS" "JOIN"
  3403  |	"INNER" "JOIN"
  3404  
  3405  
  3406  LimitClause:
  3407  	{
  3408  		$$ = nil
  3409  	}
  3410  |	"LIMIT" LengthNum
  3411  	{
  3412  		$$ = &ast.Limit{Count: $2.(uint64)}
  3413  	}
  3414  
  3415  SelectStmtLimit:
  3416  	{
  3417  		$$ = nil
  3418  	}
  3419  |	"LIMIT" LengthNum 
  3420  	{
  3421  		$$ = &ast.Limit{Count: $2.(uint64)}
  3422  	}
  3423  |	"LIMIT" LengthNum ',' LengthNum 
  3424  	{
  3425  		$$ = &ast.Limit{Offset: $2.(uint64), Count: $4.(uint64)}
  3426  	}
  3427  |	"LIMIT" LengthNum "OFFSET" LengthNum
  3428  	{
  3429  		$$ = &ast.Limit{Offset: $4.(uint64), Count: $2.(uint64)}
  3430  	}
  3431  
  3432  SelectStmtDistinct:
  3433  	/* EMPTY */
  3434  	{
  3435  		$$ = false
  3436  	}
  3437  |	"ALL"
  3438  	{
  3439  		$$ = false
  3440  	}
  3441  |	"DISTINCT"
  3442  	{
  3443  		$$ = true
  3444  	}
  3445  
  3446  SelectStmtOpts:
  3447  	SelectStmtDistinct SelectStmtSQLCache SelectStmtCalcFoundRows
  3448  	{
  3449  		// TODO: return calc_found_rows opt and support more other options
  3450  		$$ = $1
  3451  	}
  3452  
  3453  SelectStmtCalcFoundRows:
  3454  	%prec lowerThanCalcFoundRows
  3455  	{
  3456  		$$ = false
  3457  	}
  3458  |	"SQL_CALC_FOUND_ROWS"
  3459  	{
  3460  		$$ = true
  3461  	}
  3462  SelectStmtSQLCache:
  3463  	%prec lowerThanSQLCache
  3464  	{
  3465  		$$ = false
  3466  	}
  3467  |	"SQL_CACHE"
  3468  	{
  3469  		$$ = true
  3470  	}
  3471  |	"SQL_NO_CACHE"
  3472  	{
  3473  		$$ = false
  3474  	}
  3475  
  3476  SelectStmtFieldList:
  3477  	FieldList
  3478  	{
  3479  		$$ = &ast.FieldList{Fields: $1.([]*ast.SelectField)}
  3480  	}
  3481  
  3482  SelectStmtGroup:
  3483  	/* EMPTY */
  3484  	{
  3485  		$$ = nil
  3486  	}
  3487  |	GroupByClause
  3488  
  3489  // See: https://dev.mysql.com/doc/refman/5.7/en/subqueries.html
  3490  SubSelect:
  3491  	'(' SelectStmt ')'
  3492  	{
  3493  		s := $2.(*ast.SelectStmt)
  3494  		l := yylex.(*lexer)
  3495  		endOffset := l.endOffset(yyS[yypt].offset)
  3496  		l.SetLastSelectFieldText(s, endOffset)
  3497  		src := yylex.(*lexer).src
  3498  		// See the implementation of yyParse function
  3499  		s.SetText(src[yyS[yypt-1].offset-1:yyS[yypt].offset-1])
  3500  		$$ = &ast.SubqueryExpr{Query: s}
  3501  	}
  3502  |	'(' UnionStmt ')'
  3503  	{
  3504  		s := $2.(*ast.UnionStmt)
  3505  		src := yylex.(*lexer).src
  3506  		// See the implementation of yyParse function
  3507  		s.SetText(src[yyS[yypt-1].offset-1:yyS[yypt].offset-1])
  3508  		$$ = &ast.SubqueryExpr{Query: s}
  3509  	}
  3510  
  3511  // See: https://dev.mysql.com/doc/refman/5.7/en/innodb-locking-reads.html
  3512  SelectLockOpt:
  3513  	/* empty */
  3514  	{
  3515  		$$ = ast.SelectLockNone
  3516  	}
  3517  |	"FOR" "UPDATE"
  3518  	{
  3519  		$$ = ast.SelectLockForUpdate
  3520  	}
  3521  |	"LOCK" "IN" "SHARE" "MODE"
  3522  	{
  3523  		$$ = ast.SelectLockInShareMode
  3524  	}
  3525  
  3526  // See: https://dev.mysql.com/doc/refman/5.7/en/union.html
  3527  UnionStmt:
  3528  	UnionClauseList "UNION" UnionOpt SelectStmt
  3529  	{
  3530  		union := $1.(*ast.UnionStmt)
  3531  		union.Distinct = union.Distinct || $3.(bool)
  3532  		lastSelect := union.SelectList.Selects[len(union.SelectList.Selects)-1]
  3533  		l := yylex.(*lexer)
  3534  		endOffset := l.endOffset(yyS[yypt-2].offset)
  3535  		l.SetLastSelectFieldText(lastSelect, endOffset)
  3536  		union.SelectList.Selects = append(union.SelectList.Selects, $4.(*ast.SelectStmt))
  3537  		$$ = union
  3538  	}
  3539  |	UnionClauseList "UNION" UnionOpt '(' SelectStmt ')' OrderByOptional SelectStmtLimit
  3540  	{
  3541  		union := $1.(*ast.UnionStmt)
  3542  		union.Distinct = union.Distinct || $3.(bool)
  3543  		lastSelect := union.SelectList.Selects[len(union.SelectList.Selects)-1]
  3544  		l := yylex.(*lexer)
  3545  		endOffset := l.endOffset(yyS[yypt-6].offset)
  3546  		l.SetLastSelectFieldText(lastSelect, endOffset)
  3547  		st := $5.(*ast.SelectStmt)
  3548  		endOffset = l.endOffset(yyS[yypt-2].offset)
  3549  		l.SetLastSelectFieldText(st, endOffset)
  3550  		union.SelectList.Selects = append(union.SelectList.Selects, st)
  3551  		if $7 != nil {
  3552  			union.OrderBy = $7.(*ast.OrderByClause)
  3553  		}
  3554  		if $8 != nil {
  3555  			union.Limit = $8.(*ast.Limit)
  3556  		}
  3557  		$$ = union
  3558  	}
  3559  
  3560  UnionClauseList:
  3561  	UnionSelect
  3562  	{
  3563  		selectList := &ast.UnionSelectList{Selects: []*ast.SelectStmt{$1.(*ast.SelectStmt)}}
  3564  		$$ = &ast.UnionStmt{
  3565  			SelectList: selectList,
  3566  		}
  3567  	}
  3568  |	UnionClauseList "UNION" UnionOpt UnionSelect
  3569  	{
  3570  		union := $1.(*ast.UnionStmt)
  3571  		union.Distinct = union.Distinct || $3.(bool)
  3572  		lastSelect := union.SelectList.Selects[len(union.SelectList.Selects)-1]
  3573  		l := yylex.(*lexer)
  3574  		endOffset := l.endOffset(yyS[yypt-2].offset)
  3575  		l.SetLastSelectFieldText(lastSelect, endOffset)
  3576  		union.SelectList.Selects = append(union.SelectList.Selects, $4.(*ast.SelectStmt))
  3577  		$$ = union
  3578  	}
  3579  
  3580  UnionSelect:
  3581  	SelectStmt
  3582  |	'(' SelectStmt ')'
  3583  	{
  3584  		st := $2.(*ast.SelectStmt)
  3585  		l := yylex.(*lexer)
  3586  		endOffset := l.endOffset(yyS[yypt].offset)
  3587  		l.SetLastSelectFieldText(st, endOffset)
  3588  		$$ = st
  3589  	}
  3590  
  3591  UnionOpt:
  3592  	{
  3593  		$$ = true
  3594  	}
  3595  |	"ALL"
  3596  	{
  3597  		$$ = false
  3598  	}
  3599  |	"DISTINCT"
  3600  	{
  3601  		$$ = true
  3602  	}
  3603  
  3604  
  3605  /********************Set Statement*******************************/
  3606  SetStmt:
  3607  	"SET" VariableAssignmentList
  3608  	{
  3609  		$$ = &ast.SetStmt{Variables: $2.([]*ast.VariableAssignment)}
  3610  	}
  3611  |	"SET" "NAMES" StringName
  3612  	{
  3613  		$$ = &ast.SetCharsetStmt{Charset: $3.(string)} 
  3614  	}
  3615  |	"SET" "NAMES" StringName "COLLATE" StringName
  3616  	{
  3617  		$$ = &ast.SetCharsetStmt{
  3618  			Charset: $3.(string),
  3619  			Collate: $5.(string),
  3620  		} 
  3621  	}
  3622  |	"SET" CharsetKw StringName
  3623  	{
  3624  		$$ = &ast.SetCharsetStmt{Charset: $3.(string)} 
  3625  	}
  3626  |	"SET" "PASSWORD" eq PasswordOpt
  3627  	{
  3628  		$$ = &ast.SetPwdStmt{Password: $4.(string)}
  3629  	}
  3630  |	"SET" "PASSWORD" "FOR" Username eq PasswordOpt
  3631  	{
  3632  		$$ = &ast.SetPwdStmt{User: $4.(string), Password: $6.(string)}
  3633  	}
  3634  |	"SET" "GLOBAL" "TRANSACTION" TransactionChars 
  3635  	{
  3636  		// Parsed but ignored
  3637  	}
  3638  |	"SET" "SESSION" "TRANSACTION" TransactionChars
  3639  	{
  3640  		// Parsed but ignored
  3641  	}
  3642  
  3643  TransactionChars:
  3644  	TransactionChar
  3645  |	TransactionChars ',' TransactionChar
  3646  
  3647  TransactionChar:
  3648  	"ISOLATION" "LEVEL" IsolationLevel
  3649  |	"READ" "WRITE"
  3650  |	"READ" "ONLY"
  3651  
  3652  IsolationLevel:
  3653  	"REPEATABLE" "READ"
  3654  |	"READ"	"COMMITTED"
  3655  |	"READ"	"UNCOMMITTED"
  3656  |	"SERIALIZABLE"
  3657  
  3658  VariableAssignment:
  3659  	Identifier eq Expression
  3660  	{
  3661  		$$ = &ast.VariableAssignment{Name: $1.(string), Value: $3.(ast.ExprNode), IsSystem: true}
  3662  	}
  3663  |	"GLOBAL" Identifier eq Expression
  3664  	{
  3665  		$$ = &ast.VariableAssignment{Name: $2.(string), Value: $4.(ast.ExprNode), IsGlobal: true, IsSystem: true}
  3666  	}
  3667  |	"SESSION" Identifier eq Expression
  3668  	{
  3669  		$$ = &ast.VariableAssignment{Name: $2.(string), Value: $4.(ast.ExprNode), IsSystem: true}
  3670  	}
  3671  |	"LOCAL" Identifier eq Expression
  3672  	{
  3673  		$$ = &ast.VariableAssignment{Name: $2.(string), Value: $4.(ast.ExprNode), IsSystem: true}
  3674  	}
  3675  |	"SYS_VAR" eq Expression
  3676  	{
  3677  		v := strings.ToLower($1.(string))
  3678  		var isGlobal bool
  3679  		if strings.HasPrefix(v, "@@global.") {
  3680  			isGlobal = true
  3681  			v = strings.TrimPrefix(v, "@@global.")
  3682  		} else if strings.HasPrefix(v, "@@session.") {
  3683  			v = strings.TrimPrefix(v, "@@session.")
  3684  		} else if strings.HasPrefix(v, "@@local.") {
  3685  			v = strings.TrimPrefix(v, "@@local.")
  3686  		} else if strings.HasPrefix(v, "@@") {
  3687  			v = strings.TrimPrefix(v, "@@")
  3688  		}
  3689  		$$ = &ast.VariableAssignment{Name: v, Value: $3.(ast.ExprNode), IsGlobal: isGlobal, IsSystem: true}
  3690  	}
  3691  |	"USER_VAR" eq Expression
  3692  	{
  3693  		v := $1.(string)
  3694  		v = strings.TrimPrefix(v, "@")
  3695  		$$ = &ast.VariableAssignment{Name: v, Value: $3.(ast.ExprNode)}
  3696  	}
  3697  |	"USER_VAR" assignmentEq Expression
  3698  	{
  3699  		v := $1.(string)
  3700  		v = strings.TrimPrefix(v, "@")
  3701  		$$ = &ast.VariableAssignment{Name: v, Value: $3.(ast.ExprNode)}
  3702  	}
  3703  
  3704  VariableAssignmentList:
  3705  	{
  3706  		$$ = []*ast.VariableAssignment{}
  3707  	}
  3708  |	VariableAssignment
  3709  	{
  3710  		$$ = []*ast.VariableAssignment{$1.(*ast.VariableAssignment)}
  3711  	}
  3712  |	VariableAssignmentList ',' VariableAssignment
  3713  	{
  3714  		$$ = append($1.([]*ast.VariableAssignment), $3.(*ast.VariableAssignment))
  3715  	}
  3716  
  3717  Variable:
  3718  	SystemVariable | UserVariable
  3719  
  3720  SystemVariable:
  3721  	"SYS_VAR"
  3722  	{
  3723  		v := strings.ToLower($1.(string))
  3724  		var isGlobal bool
  3725  		if strings.HasPrefix(v, "@@global.") {
  3726  			isGlobal = true
  3727  			v = strings.TrimPrefix(v, "@@global.")
  3728  		} else if strings.HasPrefix(v, "@@session.") {
  3729  			v = strings.TrimPrefix(v, "@@session.")
  3730  		} else if strings.HasPrefix(v, "@@local.") {
  3731  			v = strings.TrimPrefix(v, "@@local.")
  3732  		} else if strings.HasPrefix(v, "@@") {
  3733  			v = strings.TrimPrefix(v, "@@")
  3734  		}
  3735  		$$ = &ast.VariableExpr{Name: v, IsGlobal: isGlobal, IsSystem: true}
  3736  	}
  3737  
  3738  UserVariable:
  3739  	"USER_VAR"
  3740  	{
  3741  		v := $1.(string)
  3742  		v = strings.TrimPrefix(v, "@")
  3743  		$$ = &ast.VariableExpr{Name: v, IsGlobal: false, IsSystem: false}
  3744  	}
  3745  
  3746  Username:
  3747  	stringLit "AT" stringLit	
  3748  	{
  3749  		$$ = $1.(string) + "@" + $3.(string)
  3750  	}
  3751  
  3752  PasswordOpt:
  3753  	stringLit
  3754  	{
  3755  		$$ = $1.(string)
  3756  	}
  3757  |	"PASSWORD" '(' AuthString ')' 
  3758  	{
  3759  		$$ = $3.(string)
  3760  	}
  3761  
  3762  AuthString:
  3763  	stringLit
  3764  	{
  3765  		$$ = $1.(string)
  3766  	}
  3767  
  3768  /****************************Admin Statement*******************************/
  3769  AdminStmt:
  3770  	"ADMIN" "SHOW" "DDL"
  3771  	{
  3772  		$$ = &ast.AdminStmt{Tp: ast.AdminShowDDL}
  3773  	}
  3774  |	"ADMIN" "CHECK" "TABLE" TableNameList
  3775  	{
  3776  		$$ = &ast.AdminStmt{
  3777  			Tp:	ast.AdminCheckTable,
  3778  			Tables: $4.([]*ast.TableName),
  3779  		}
  3780  	}
  3781  
  3782  /****************************Show Statement*******************************/
  3783  ShowStmt:
  3784  	"SHOW" ShowTargetFilterable ShowLikeOrWhereOpt
  3785  	{
  3786  		stmt := $2.(*ast.ShowStmt)
  3787  		if $3 != nil {
  3788  			if x, ok := $3.(*ast.PatternLikeExpr); ok {
  3789  				stmt.Pattern = x
  3790  			} else {
  3791  				stmt.Where = $3.(ast.ExprNode)
  3792  			}
  3793  		}
  3794  		$$ = stmt
  3795  	}
  3796  |	"SHOW" "CREATE" "TABLE" TableName
  3797  	{
  3798  		$$ = &ast.ShowStmt{
  3799  			Tp:	ast.ShowCreateTable,
  3800  			Table:	$4.(*ast.TableName),
  3801  		}
  3802  	}
  3803  |	"SHOW" "GRANTS"
  3804  	{
  3805  		// See: https://dev.mysql.com/doc/refman/5.7/en/show-grants.html
  3806  		$$ = &ast.ShowStmt{Tp: ast.ShowGrants}
  3807  	}
  3808  |	"SHOW" "GRANTS" "FOR" Username
  3809  	{
  3810  		// See: https://dev.mysql.com/doc/refman/5.7/en/show-grants.html
  3811  		$$ = &ast.ShowStmt{
  3812  			Tp:	ast.ShowGrants,
  3813  			User:	$4.(string),
  3814  		}
  3815  	}
  3816  |	"SHOW" "INDEX" "FROM" TableName
  3817  	{
  3818  		$$ = &ast.ShowStmt{
  3819  			Tp: ast.ShowIndex,
  3820  			Table: $4.(*ast.TableName),
  3821  		}
  3822  	}
  3823  
  3824  ShowTargetFilterable:
  3825  	"ENGINES"
  3826  	{
  3827  		$$ = &ast.ShowStmt{Tp: ast.ShowEngines}
  3828  	}
  3829  |	"DATABASES"
  3830  	{
  3831  		$$ = &ast.ShowStmt{Tp: ast.ShowDatabases}
  3832  	}
  3833  |	"SCHEMAS"
  3834  	{
  3835  		$$ = &ast.ShowStmt{Tp: ast.ShowDatabases}
  3836  	}
  3837  |	"CHARACTER" "SET"
  3838  	{
  3839  		$$ = &ast.ShowStmt{Tp: ast.ShowCharset}
  3840  	}
  3841  |	OptFull "TABLES" ShowDatabaseNameOpt
  3842  	{
  3843  		$$ = &ast.ShowStmt{
  3844  			Tp:	ast.ShowTables,
  3845  			DBName:	$3.(string),
  3846  			Full:	$1.(bool),
  3847  		}
  3848  	}
  3849  |	"TABLE" "STATUS" ShowDatabaseNameOpt
  3850  	{
  3851  		$$ = &ast.ShowStmt{
  3852  			Tp:	ast.ShowTableStatus,
  3853  			DBName:	$3.(string),
  3854  		}
  3855  	}
  3856  |	OptFull "COLUMNS" ShowTableAliasOpt ShowDatabaseNameOpt
  3857  	{
  3858  		$$ = &ast.ShowStmt{
  3859  			Tp:     ast.ShowColumns,
  3860  			Table:	$3.(*ast.TableName),
  3861  			DBName:	$4.(string),
  3862  			Full:	$1.(bool),
  3863  		}
  3864  	}
  3865  |	OptFull "FIELDS" ShowTableAliasOpt ShowDatabaseNameOpt
  3866  	{
  3867  		// SHOW FIELDS is a synonym for SHOW COLUMNS.
  3868  		$$ = &ast.ShowStmt{
  3869  			Tp:     ast.ShowColumns,
  3870  			Table:	$3.(*ast.TableName),
  3871  			DBName:	$4.(string),
  3872  			Full:	$1.(bool),
  3873  		}
  3874  	}
  3875  |	"WARNINGS"
  3876  	{
  3877  		$$ = &ast.ShowStmt{Tp: ast.ShowWarnings}
  3878  	}
  3879  |	GlobalScope "VARIABLES"
  3880  	{
  3881  		$$ = &ast.ShowStmt{
  3882  			Tp: ast.ShowVariables,
  3883  			GlobalScope: $1.(bool),
  3884  		}
  3885  	}
  3886  |	GlobalScope "STATUS"
  3887  	{
  3888  		$$ = &ast.ShowStmt{
  3889  			Tp: ast.ShowStatus,
  3890  			GlobalScope: $1.(bool),
  3891  		}
  3892  	}
  3893  |	"COLLATION"
  3894  	{
  3895  		$$ = &ast.ShowStmt{
  3896  			Tp: 	ast.ShowCollation,
  3897  		}
  3898  	}
  3899  |	"TRIGGERS" ShowDatabaseNameOpt
  3900  	{
  3901  		$$ = &ast.ShowStmt{
  3902  			Tp:	ast.ShowTriggers,
  3903  			DBName:	$2.(string),
  3904  		}
  3905  	}
  3906  |	"PROCEDURE" "STATUS"
  3907  	{
  3908  		$$ = &ast.ShowStmt {
  3909  			Tp: ast.ShowProcedureStatus,
  3910  		}
  3911  	}
  3912  
  3913  ShowLikeOrWhereOpt:
  3914  	{
  3915  		$$ = nil 
  3916  	}
  3917  |	"LIKE" PrimaryExpression
  3918  	{
  3919  		$$ = &ast.PatternLikeExpr{
  3920  			Pattern: $2.(ast.ExprNode),
  3921  			Escape: '\\',
  3922  		}
  3923  	}
  3924  |	"WHERE" Expression
  3925  	{
  3926  		$$ = $2.(ast.ExprNode)
  3927  	}
  3928  
  3929  GlobalScope:
  3930  	{
  3931  		$$ = false	
  3932  	}
  3933  |	"GLOBAL"
  3934  	{
  3935  		$$ = true	
  3936  	}
  3937  |	"SESSION" 
  3938  	{
  3939  		$$ = false	
  3940  	}
  3941  
  3942  OptFull:
  3943  	{
  3944  		$$ = false
  3945  	}
  3946  |	"FULL"
  3947  	{
  3948  		$$ = true
  3949  	}
  3950  
  3951  ShowDatabaseNameOpt:
  3952  	{
  3953  		$$ = ""
  3954  	}
  3955  |	"FROM" DBName
  3956  	{
  3957  		$$ = $2.(string)
  3958  	}
  3959  |	"IN" DBName
  3960  	{
  3961  		$$ = $2.(string)
  3962  	}
  3963  
  3964  ShowTableAliasOpt:
  3965  	"FROM" TableName
  3966  	{
  3967  		$$ = $2.(*ast.TableName)
  3968  	}
  3969  |	"IN" TableName
  3970  	{
  3971  		$$ = $2.(*ast.TableName)
  3972  	}
  3973  
  3974  Statement:
  3975  	EmptyStmt
  3976  |	AdminStmt
  3977  |	AlterTableStmt
  3978  |	BeginTransactionStmt
  3979  |	CommitStmt
  3980  |	DeallocateStmt
  3981  |	DeleteFromStmt
  3982  |	ExecuteStmt
  3983  |	ExplainStmt
  3984  |	CreateDatabaseStmt
  3985  |	CreateIndexStmt
  3986  |	CreateTableStmt
  3987  |	CreateUserStmt
  3988  |	DoStmt
  3989  |	DropDatabaseStmt
  3990  |	DropIndexStmt
  3991  |	DropTableStmt
  3992  |	GrantStmt
  3993  |	InsertIntoStmt
  3994  |	PreparedStmt
  3995  |	RollbackStmt
  3996  |	ReplaceIntoStmt
  3997  |	SelectStmt
  3998  |	UnionStmt
  3999  |	SetStmt
  4000  |	ShowStmt
  4001  |	TruncateTableStmt
  4002  |	UpdateStmt
  4003  |	UseStmt
  4004  |	SubSelect
  4005  	{
  4006  		// `(select 1)`; is a valid select statement
  4007  		// TODO: This is used to fix issue #320. There may be a better solution.
  4008  		$$ = $1.(*ast.SubqueryExpr).Query
  4009  	}
  4010  |	UnlockTablesStmt
  4011  |	LockTablesStmt
  4012  
  4013  ExplainableStmt:
  4014  	SelectStmt
  4015  |	DeleteFromStmt
  4016  |	UpdateStmt
  4017  |	InsertIntoStmt
  4018  |	ReplaceIntoStmt
  4019  
  4020  StatementList:
  4021  	Statement
  4022  	{
  4023  		if $1 != nil {
  4024  			s := $1.(ast.StmtNode)
  4025  			s.SetText(yylex.(*lexer).stmtText())
  4026  			yylex.(*lexer).list = append(yylex.(*lexer).list, s)
  4027  		}
  4028  	}
  4029  |	StatementList ';' Statement
  4030  	{
  4031  		if $3 != nil {
  4032  			s := $3.(ast.StmtNode)
  4033  			s.SetText(yylex.(*lexer).stmtText())
  4034  			yylex.(*lexer).list = append(yylex.(*lexer).list, s)
  4035  		}
  4036  	}
  4037  
  4038  Constraint:
  4039  	ConstraintKeywordOpt ConstraintElem
  4040  	{
  4041  		cst := $2.(*ast.Constraint)
  4042  		if $1 != nil {
  4043  			cst.Name = $1.(string)
  4044  		}
  4045  		$$ = cst
  4046  	}
  4047  
  4048  TableElement:
  4049  	ColumnDef
  4050  	{
  4051  		$$ = $1.(*ast.ColumnDef)
  4052  	}
  4053  |	Constraint
  4054  	{
  4055  		$$ = $1.(*ast.Constraint)
  4056  	}
  4057  |	"CHECK" '(' Expression ')'
  4058  	{
  4059  		/* Nothing to do now */
  4060  		$$ = nil 
  4061  	}
  4062  
  4063  TableElementList:
  4064  	TableElement
  4065  	{
  4066  		if $1 != nil {
  4067  			$$ = []interface{}{$1.(interface{})}
  4068  		} else {
  4069  			$$ = []interface{}{}
  4070  		}
  4071  	}
  4072  |	TableElementList ',' TableElement
  4073  	{
  4074  		if $3 != nil {
  4075  			$$ = append($1.([]interface{}), $3)
  4076  		} else {
  4077  			$$ = $1
  4078  		}
  4079  	}
  4080  
  4081  TableOption:
  4082  	"ENGINE" Identifier
  4083  	{
  4084  		$$ = &ast.TableOption{Tp: ast.TableOptionEngine, StrValue: $2.(string)} 
  4085  	}
  4086  |	"ENGINE" eq Identifier
  4087  	{
  4088  		$$ = &ast.TableOption{Tp: ast.TableOptionEngine, StrValue: $3.(string)} 
  4089  	}
  4090  |	DefaultKwdOpt CharsetKw EqOpt StringName
  4091  	{
  4092  		$$ = &ast.TableOption{Tp: ast.TableOptionCharset, StrValue: $4.(string)} 
  4093  	}
  4094  |	DefaultKwdOpt "COLLATE" EqOpt StringName
  4095  	{
  4096  		$$ = &ast.TableOption{Tp: ast.TableOptionCollate, StrValue: $4.(string)} 
  4097  	}
  4098  |	"AUTO_INCREMENT" eq LengthNum
  4099  	{
  4100  		$$ = &ast.TableOption{Tp: ast.TableOptionAutoIncrement, UintValue: $3.(uint64)}
  4101  	}
  4102  |	"COMMENT" EqOpt stringLit
  4103  	{
  4104  		$$ = &ast.TableOption{Tp: ast.TableOptionComment, StrValue: $3.(string)} 
  4105  	}
  4106  |	"AVG_ROW_LENGTH" EqOpt LengthNum
  4107  	{
  4108  		$$ = &ast.TableOption{Tp: ast.TableOptionAvgRowLength, UintValue: $3.(uint64)} 
  4109  	}
  4110  |	"CONNECTION" EqOpt stringLit
  4111  	{
  4112  		$$ = &ast.TableOption{Tp: ast.TableOptionConnection, StrValue: $3.(string)} 
  4113  	}
  4114  |	"CHECKSUM" EqOpt LengthNum
  4115  	{
  4116  		$$ = &ast.TableOption{Tp: ast.TableOptionCheckSum, UintValue: $3.(uint64)} 
  4117  	}
  4118  |	"PASSWORD" EqOpt stringLit
  4119  	{
  4120  		$$ = &ast.TableOption{Tp: ast.TableOptionPassword, StrValue: $3.(string)} 
  4121  	}
  4122  |	"COMPRESSION" EqOpt Identifier
  4123  	{
  4124  		$$ = &ast.TableOption{Tp: ast.TableOptionCompression, StrValue: $3.(string)} 
  4125  	}
  4126  |	"KEY_BLOCK_SIZE" EqOpt LengthNum
  4127  	{
  4128  		$$ = &ast.TableOption{Tp: ast.TableOptionKeyBlockSize, UintValue: $3.(uint64)} 
  4129  	}
  4130  |	"MAX_ROWS" EqOpt LengthNum
  4131  	{
  4132  		$$ = &ast.TableOption{Tp: ast.TableOptionMaxRows, UintValue: $3.(uint64)} 
  4133  	}
  4134  |	"MIN_ROWS" EqOpt LengthNum
  4135  	{
  4136  		$$ = &ast.TableOption{Tp: ast.TableOptionMinRows, UintValue: $3.(uint64)} 
  4137  	}
  4138  |	"DELAY_KEY_WRITE" EqOpt LengthNum
  4139  	{
  4140  		$$ = &ast.TableOption{Tp: ast.TableOptionDelayKeyWrite, UintValue: $3.(uint64)} 
  4141  	}
  4142  |	RowFormat
  4143  	{
  4144  		$$ = &ast.TableOption{Tp: ast.TableOptionRowFormat, UintValue: $1.(uint64)}
  4145  	}
  4146  
  4147  
  4148  TableOptionListOpt:
  4149  	{
  4150  		$$ = []*ast.TableOption{}
  4151  	}
  4152  |	TableOptionList %prec lowerThanComma
  4153  
  4154  TableOptionList:
  4155  	TableOption
  4156  	{
  4157  		$$ = []*ast.TableOption{$1.(*ast.TableOption)}
  4158  	}
  4159  |	TableOptionList TableOption
  4160  	{
  4161  		$$ = append($1.([]*ast.TableOption), $2.(*ast.TableOption))
  4162  	}
  4163  |	TableOptionList ','  TableOption
  4164  	{
  4165  		$$ = append($1.([]*ast.TableOption), $3.(*ast.TableOption))
  4166  	}
  4167  
  4168  OptTable:
  4169  	{} | "TABLE"
  4170  
  4171  TruncateTableStmt:
  4172  	"TRUNCATE" OptTable TableName
  4173  	{
  4174  		$$ = &ast.TruncateTableStmt{Table: $3.(*ast.TableName)}
  4175  	}
  4176  
  4177  RowFormat:
  4178  	 "ROW_FORMAT" EqOpt "DEFAULT"
  4179  	{
  4180  		$$ = ast.RowFormatDefault
  4181  	}
  4182  |	"ROW_FORMAT" EqOpt "DYNAMIC"
  4183  	{
  4184  		$$ = ast.RowFormatDynamic
  4185  	}
  4186  |	"ROW_FORMAT" EqOpt "FIXED"
  4187  	{
  4188  		$$ = ast.RowFormatFixed
  4189  	}
  4190  |	"ROW_FORMAT" EqOpt "COMPRESSED"
  4191  	{
  4192  		$$ = ast.RowFormatCompressed
  4193  	}
  4194  |	"ROW_FORMAT" EqOpt "REDUNDANT"
  4195  	{
  4196  		$$ = ast.RowFormatRedundant
  4197  	}
  4198  |	"ROW_FORMAT" EqOpt "COMPACT"
  4199  	{
  4200  		$$ = ast.RowFormatCompact
  4201  	}
  4202  
  4203  /*************************************Type Begin***************************************/
  4204  Type:
  4205  	NumericType
  4206  	{
  4207  		$$ = $1
  4208  	}
  4209  |	StringType
  4210  	{
  4211  		$$ = $1
  4212  	}
  4213  |	DateAndTimeType
  4214  	{
  4215  		$$ = $1
  4216  	}
  4217  |	"float32"
  4218  	{
  4219  		x := types.NewFieldType($1.(byte))
  4220  		$$ = x
  4221  	}
  4222  |	"float64"
  4223  	{
  4224  		x := types.NewFieldType($1.(byte))
  4225  		$$ = x
  4226  	}
  4227  |	"int64"
  4228  	{
  4229  		x := types.NewFieldType($1.(byte))
  4230  		$$ = x
  4231  	}
  4232  |	"string"
  4233  	{
  4234  		x := types.NewFieldType($1.(byte))
  4235  		$$ = x
  4236  	}
  4237  |	"uint"
  4238  	{
  4239  		x := types.NewFieldType($1.(byte))
  4240  		$$ = x
  4241  	}
  4242  |	"uint64"
  4243  	{
  4244  		x := types.NewFieldType($1.(byte))
  4245  		$$ = x
  4246  	}
  4247  
  4248  NumericType:
  4249  	IntegerType OptFieldLen FieldOpts
  4250  	{
  4251  		// TODO: check flen 0
  4252  		x := types.NewFieldType($1.(byte))
  4253  		x.Flen = $2.(int)
  4254  		for _, o := range $3.([]*ast.TypeOpt) {
  4255  			if o.IsUnsigned {
  4256  				x.Flag |= mysql.UnsignedFlag
  4257  			}
  4258  			if o.IsZerofill {
  4259  				x.Flag |= mysql.ZerofillFlag
  4260  			}
  4261  		}
  4262  		$$ = x
  4263  	}
  4264  |	FixedPointType FloatOpt FieldOpts
  4265  	{
  4266  		fopt := $2.(*ast.FloatOpt)
  4267  		x := types.NewFieldType($1.(byte))
  4268  		x.Flen = fopt.Flen 
  4269  		x.Decimal = fopt.Decimal
  4270  		for _, o := range $3.([]*ast.TypeOpt) {
  4271  			if o.IsUnsigned {
  4272  				x.Flag |= mysql.UnsignedFlag
  4273  			}
  4274  			if o.IsZerofill {
  4275  				x.Flag |= mysql.ZerofillFlag
  4276  			}
  4277  		}
  4278  		$$ = x
  4279  	}
  4280  |	FloatingPointType FloatOpt FieldOpts
  4281  	{
  4282  		fopt := $2.(*ast.FloatOpt)
  4283  		x := types.NewFieldType($1.(byte))
  4284  		x.Flen = fopt.Flen 
  4285  		if x.Tp == mysql.TypeFloat {
  4286  			// Fix issue #312
  4287  			if x.Flen > 53 {
  4288  				yylex.(*lexer).errf("Float len(%d) should not be greater than 53", x.Flen)
  4289  				return 1
  4290  			}
  4291  			if x.Flen > 24 { 
  4292  				x.Tp = mysql.TypeDouble
  4293  			}
  4294  		}
  4295  		x.Decimal =fopt.Decimal
  4296  		for _, o := range $3.([]*ast.TypeOpt) {
  4297  			if o.IsUnsigned {
  4298  				x.Flag |= mysql.UnsignedFlag
  4299  			}
  4300  			if o.IsZerofill {
  4301  				x.Flag |= mysql.ZerofillFlag
  4302  			}
  4303  		}
  4304  		$$ = x
  4305  	}
  4306  |	BitValueType OptFieldLen
  4307  	{
  4308  		x := types.NewFieldType($1.(byte))
  4309  		x.Flen = $2.(int)
  4310  		if x.Flen == -1 || x.Flen == 0 {
  4311  			x.Flen = 1
  4312  		} else if x.Flen > 64 {
  4313  			yylex.(*lexer).errf("invalid field length %d for bit type, must in [1, 64]", x.Flen)
  4314  		}
  4315  		$$ = x
  4316  	}
  4317  
  4318  IntegerType:
  4319  	"TINYINT"
  4320  	{
  4321  		$$ = mysql.TypeTiny
  4322  	}
  4323  |	"SMALLINT"
  4324  	{
  4325  		$$ = mysql.TypeShort
  4326  	}
  4327  |	"MEDIUMINT"
  4328  	{
  4329  		$$ = mysql.TypeInt24
  4330  	}
  4331  |	"INT"
  4332  	{
  4333  		$$ = mysql.TypeLong 
  4334  	}
  4335  |	"INTEGER"
  4336  	{
  4337  		$$ = mysql.TypeLong
  4338  	}
  4339  |	"BIGINT"
  4340  	{
  4341  		$$ = mysql.TypeLonglong
  4342  	}
  4343  |	"BOOL"
  4344  	{
  4345  		$$ = mysql.TypeTiny        
  4346  	}
  4347  |	"BOOLEAN"
  4348  	{
  4349  		$$ = mysql.TypeTiny        
  4350  	}
  4351  
  4352  OptInteger:
  4353  	{} | "INTEGER"
  4354  
  4355  FixedPointType:
  4356  	"DECIMAL"
  4357  	{
  4358  		$$ = mysql.TypeNewDecimal
  4359  	}
  4360  |	"NUMERIC"
  4361  	{
  4362  		$$ = mysql.TypeNewDecimal
  4363  	}
  4364  
  4365  FloatingPointType:
  4366  	"float"
  4367  	{
  4368  		$$ = mysql.TypeFloat
  4369  	}
  4370  |	"REAL"
  4371  	{
  4372  		$$ = mysql.TypeDouble
  4373  	}
  4374  |	"DOUBLE"
  4375  	{
  4376  		$$ = mysql.TypeDouble
  4377  	}
  4378  |	"DOUBLE" "PRECISION"
  4379  	{
  4380  		$$ = mysql.TypeDouble
  4381  	}
  4382  
  4383  BitValueType:
  4384  	"BIT"
  4385  	{
  4386  		$$ = mysql.TypeBit 
  4387  	}
  4388  
  4389  StringType:
  4390  	NationalOpt "CHAR" FieldLen OptBinary OptCharset OptCollate
  4391  	{
  4392  		x := types.NewFieldType(mysql.TypeString)
  4393  		x.Flen = $3.(int)
  4394  		if $4.(bool) {
  4395  			x.Flag |= mysql.BinaryFlag
  4396  		}
  4397  		$$ = x
  4398  	}
  4399  |	NationalOpt "CHAR" OptBinary OptCharset OptCollate
  4400  	{
  4401  		x := types.NewFieldType(mysql.TypeString)
  4402  		if $3.(bool) {
  4403  			x.Flag |= mysql.BinaryFlag
  4404  		}
  4405  		$$ = x
  4406  	}
  4407  |	NationalOpt "VARCHAR" FieldLen OptBinary OptCharset OptCollate
  4408  	{
  4409  		x := types.NewFieldType(mysql.TypeVarchar)
  4410  		x.Flen = $3.(int) 
  4411  		if $4.(bool) {
  4412  			x.Flag |= mysql.BinaryFlag
  4413  		}
  4414  		x.Charset = $5.(string)
  4415  		x.Collate = $6.(string)
  4416  		$$ = x
  4417  	}
  4418  |	"BINARY" OptFieldLen
  4419  	{
  4420  		x := types.NewFieldType(mysql.TypeString)
  4421  		x.Flen = $2.(int) 
  4422  		x.Charset = charset.CharsetBin 
  4423  		x.Collate = charset.CharsetBin
  4424  		$$ = x
  4425  	}
  4426  |	"VARBINARY" FieldLen
  4427  	{
  4428  		x := types.NewFieldType(mysql.TypeVarchar)
  4429  		x.Flen = $2.(int) 
  4430  		x.Charset = charset.CharsetBin 
  4431  		x.Collate = charset.CharsetBin
  4432  		$$ = x
  4433  	}
  4434  |	BlobType
  4435  	{
  4436  		$$ = $1.(*types.FieldType)
  4437  	}
  4438  |	TextType OptBinary OptCharset OptCollate
  4439  	{
  4440  		x := $1.(*types.FieldType)
  4441  		if $2.(bool) {
  4442  			x.Flag |= mysql.BinaryFlag
  4443  		}
  4444  		x.Charset = $3.(string)
  4445  		x.Collate = $4.(string)
  4446  		$$ = x
  4447  	}
  4448  |	"ENUM" '(' StringList ')' OptCharset OptCollate
  4449  	{
  4450  		x := types.NewFieldType(mysql.TypeEnum)
  4451  		x.Elems = $3.([]string)
  4452  		x.Charset = $5.(string)
  4453  		x.Collate = $6.(string)
  4454  		$$ = x
  4455  	}
  4456  |	"SET" '(' StringList ')' OptCharset OptCollate
  4457  	{
  4458  		x := types.NewFieldType(mysql.TypeSet)
  4459  		x.Elems = $3.([]string)
  4460  		x.Charset = $5.(string)
  4461  		x.Collate = $6.(string)
  4462  		$$ = x
  4463  	}
  4464  
  4465  NationalOpt:
  4466  	{
  4467  
  4468  	}
  4469  |	"NATIONAL"
  4470  	{
  4471  
  4472  	}
  4473  
  4474  BlobType:
  4475  	"TINYBLOB"
  4476  	{
  4477  		x := types.NewFieldType(mysql.TypeTinyBlob)
  4478  		x.Charset = charset.CharsetBin
  4479  		x.Collate = charset.CharsetBin
  4480  		$$ = x
  4481  	}
  4482  |	"BLOB" OptFieldLen
  4483  	{
  4484  		x := types.NewFieldType(mysql.TypeBlob)
  4485  		x.Flen = $2.(int) 
  4486  		x.Charset = charset.CharsetBin
  4487  		x.Collate = charset.CharsetBin
  4488  		$$ = x
  4489  	}
  4490  |	"MEDIUMBLOB"
  4491  	{
  4492  		x := types.NewFieldType(mysql.TypeMediumBlob)
  4493  		x.Charset = charset.CharsetBin
  4494  		x.Collate = charset.CharsetBin
  4495  		$$ = x
  4496  	}
  4497  |	"LONGBLOB"
  4498  	{
  4499  		x := types.NewFieldType(mysql.TypeLongBlob)
  4500  		x.Charset = charset.CharsetBin
  4501  		x.Collate = charset.CharsetBin
  4502  		$$ = x
  4503  	}
  4504  
  4505  TextType:
  4506  	"TINYTEXT"
  4507  	{
  4508  		x := types.NewFieldType(mysql.TypeTinyBlob)
  4509  		$$ = x
  4510  
  4511  	}
  4512  |	"TEXT" OptFieldLen
  4513  	{
  4514  		x := types.NewFieldType(mysql.TypeBlob)
  4515  		x.Flen = $2.(int) 
  4516  		$$ = x
  4517  	}
  4518  |	"MEDIUMTEXT"
  4519  	{
  4520  		x := types.NewFieldType(mysql.TypeMediumBlob)
  4521  		$$ = x
  4522  	}
  4523  |	"LONGTEXT"
  4524  	{
  4525  		x := types.NewFieldType(mysql.TypeLongBlob)
  4526  		$$ = x
  4527  	}
  4528  
  4529  
  4530  DateAndTimeType:
  4531  	"DATE"
  4532  	{
  4533  		x := types.NewFieldType(mysql.TypeDate)
  4534  		$$ = x
  4535  	}
  4536  |	"DATETIME" OptFieldLen
  4537  	{
  4538  		x := types.NewFieldType(mysql.TypeDatetime)
  4539  		x.Decimal = $2.(int)
  4540  		$$ = x
  4541  	}
  4542  |	"TIMESTAMP" OptFieldLen
  4543  	{
  4544  		x := types.NewFieldType(mysql.TypeTimestamp)
  4545  		x.Decimal = $2.(int)
  4546  		$$ = x
  4547  	}
  4548  |	"TIME" OptFieldLen
  4549  	{
  4550  		x := types.NewFieldType(mysql.TypeDuration)
  4551  		x.Decimal = $2.(int)
  4552  		$$ = x
  4553  	}
  4554  |	"YEAR" OptFieldLen
  4555  	{
  4556  		x := types.NewFieldType(mysql.TypeYear)
  4557  		x.Flen = $2.(int)
  4558  		$$ = x
  4559  	}
  4560  
  4561  FieldLen:
  4562  	'(' LengthNum ')'
  4563  	{
  4564  		$$ = int($2.(uint64))
  4565  	}
  4566  
  4567  OptFieldLen:
  4568  	{
  4569  		/* -1 means unspecified field length*/
  4570  		$$ = types.UnspecifiedLength 
  4571  	}
  4572  |	FieldLen
  4573  	{   
  4574  		$$ = $1.(int)
  4575  	}
  4576  
  4577  FieldOpt:
  4578  	"UNSIGNED"
  4579  	{
  4580  		$$ = &ast.TypeOpt{IsUnsigned: true}
  4581  	}
  4582  |	"ZEROFILL"
  4583  	{
  4584  		$$ = &ast.TypeOpt{IsZerofill: true, IsUnsigned: true}
  4585  	}
  4586  
  4587  FieldOpts:
  4588  	{
  4589  		$$ = []*ast.TypeOpt{}
  4590  	}
  4591  |	FieldOpts FieldOpt
  4592  	{
  4593  		$$ = append($1.([]*ast.TypeOpt), $2.(*ast.TypeOpt)) 
  4594  	}
  4595  
  4596  FloatOpt:
  4597  	{
  4598  		$$ = &ast.FloatOpt{Flen: types.UnspecifiedLength, Decimal: types.UnspecifiedLength}
  4599  	}
  4600  |	FieldLen
  4601  	{
  4602  		$$ = &ast.FloatOpt{Flen: $1.(int), Decimal: types.UnspecifiedLength}
  4603  	}
  4604  |	Precision
  4605  	{
  4606  		$$ = $1.(*ast.FloatOpt)
  4607  	}
  4608  
  4609  Precision:
  4610  	'(' LengthNum ',' LengthNum ')'
  4611  	{
  4612  		$$ = &ast.FloatOpt{Flen: int($2.(uint64)), Decimal: int($4.(uint64))}
  4613  	}
  4614  
  4615  OptBinary:
  4616  	{
  4617  		$$ = false
  4618  	}
  4619  |	"BINARY"
  4620  	{
  4621  		$$ = true
  4622  	}
  4623  
  4624  OptCharset:
  4625  	{
  4626  		$$ = ""
  4627  	}
  4628  |	CharsetKw StringName
  4629  	{
  4630  		$$ = $2.(string)
  4631  	}
  4632  
  4633  CharsetKw:
  4634  	"CHARACTER" "SET"
  4635  |	"CHARSET"
  4636  
  4637  OptCollate:
  4638  	{
  4639  		$$ = ""
  4640  	}
  4641  |	"COLLATE" StringName
  4642  	{
  4643  		$$ = $2.(string)
  4644  	}
  4645  
  4646  StringList:
  4647  	stringLit
  4648  	{
  4649  		$$ = []string{$1.(string)}
  4650  	}
  4651  |	StringList ',' stringLit
  4652  	{
  4653  		$$ = append($1.([]string), $3.(string))
  4654  	}
  4655  
  4656  StringName:
  4657  	stringLit
  4658  	{
  4659  		$$ = $1.(string)
  4660  	}
  4661  |	Identifier
  4662  	{
  4663  		$$ = $1.(string)
  4664  	}
  4665  
  4666  /***********************************************************************************
  4667   * Update Statement
  4668   * See: https://dev.mysql.com/doc/refman/5.7/en/update.html
  4669   ***********************************************************************************/
  4670  UpdateStmt:
  4671  	"UPDATE" LowPriorityOptional IgnoreOptional TableRef "SET" AssignmentList WhereClauseOptional OrderByOptional LimitClause
  4672  	{
  4673  		var refs *ast.Join
  4674  		if x, ok := $4.(*ast.Join); ok {
  4675  			refs = x
  4676  		} else {
  4677  			refs = &ast.Join{Left: $4.(ast.ResultSetNode)}
  4678  		}
  4679  		st := &ast.UpdateStmt{
  4680  			LowPriority:	$2.(bool),
  4681  			TableRefs:	&ast.TableRefsClause{TableRefs: refs},
  4682  			List:		$6.([]*ast.Assignment),
  4683  		}
  4684  		if $7 != nil {
  4685  			st.Where = $7.(ast.ExprNode)
  4686  		}
  4687  		if $8 != nil {
  4688  			st.Order = $8.(*ast.OrderByClause)
  4689  		}
  4690  		if $9 != nil {
  4691  			st.Limit = $9.(*ast.Limit)
  4692  		}
  4693  		$$ = st
  4694  		if yylex.(*lexer).root {
  4695  			break
  4696  		}
  4697  	}
  4698  |	"UPDATE" LowPriorityOptional IgnoreOptional TableRefs "SET" AssignmentList WhereClauseOptional
  4699  	{
  4700  		st := &ast.UpdateStmt{
  4701  			LowPriority:	$2.(bool),
  4702  			TableRefs:	&ast.TableRefsClause{TableRefs: $4.(*ast.Join)},
  4703  			List:		$6.([]*ast.Assignment),
  4704  		}
  4705  		if $7 != nil {
  4706  			st.Where = $7.(ast.ExprNode)
  4707  		}
  4708  		$$ = st
  4709  		if yylex.(*lexer).root {
  4710  			break
  4711  		}
  4712  	}
  4713  
  4714  UseStmt:
  4715  	"USE" DBName
  4716  	{
  4717  		$$ = &ast.UseStmt{DBName: $2.(string)}
  4718  		if yylex.(*lexer).root {
  4719  			break
  4720  		}
  4721  	}
  4722  
  4723  WhereClause:
  4724  	"WHERE" Expression
  4725  	{
  4726  		$$ = $2.(ast.ExprNode)
  4727  	}
  4728  
  4729  WhereClauseOptional:
  4730  	{
  4731  		$$ = nil
  4732  	}
  4733  |	WhereClause
  4734  	{
  4735  		$$ = $1
  4736  	}
  4737  
  4738  CommaOpt:
  4739  	{
  4740  	}
  4741  |	','
  4742  	{
  4743  	}
  4744  
  4745  /************************************************************************************
  4746   *  Account Management Statements
  4747   *  https://dev.mysql.com/doc/refman/5.7/en/account-management-sql.html
  4748   ************************************************************************************/
  4749  CreateUserStmt:
  4750  	"CREATE" "USER" IfNotExists UserSpecList
  4751  	{
  4752   		// See: https://dev.mysql.com/doc/refman/5.7/en/create-user.html
  4753  		$$ = &ast.CreateUserStmt{
  4754  			IfNotExists: $3.(bool),
  4755  			Specs: $4.([]*ast.UserSpec),
  4756  		}
  4757  	}
  4758  
  4759  UserSpec:
  4760  	Username AuthOption	
  4761  	{
  4762  		userSpec := &ast.UserSpec{
  4763  			User: $1.(string),
  4764  		}
  4765  		if $2 != nil {
  4766  			userSpec.AuthOpt = $2.(*ast.AuthOption)
  4767  		}
  4768  		$$ = userSpec
  4769  	}
  4770  
  4771  UserSpecList:
  4772  	UserSpec
  4773  	{
  4774  		$$ = []*ast.UserSpec{$1.(*ast.UserSpec)}
  4775  	}
  4776  |	UserSpecList ',' UserSpec
  4777  	{
  4778  		$$ = append($1.([]*ast.UserSpec), $3.(*ast.UserSpec))
  4779  	}
  4780  
  4781  AuthOption:
  4782  	{
  4783  		$$ = nil
  4784  	}
  4785  |	"IDENTIFIED" "BY" AuthString
  4786  	{
  4787  		$$ = &ast.AuthOption {
  4788  			AuthString: $3.(string),
  4789  			ByAuthString: true,
  4790  		}
  4791  	}
  4792  |	"IDENTIFIED" "BY" "PASSWORD" HashString
  4793  	{
  4794  		$$ = &ast.AuthOption{
  4795  			HashString: $4.(string),
  4796  		}
  4797  	}
  4798  
  4799  HashString:
  4800  	stringLit
  4801  
  4802  /*************************************************************************************
  4803   * Grant statement
  4804   * See: https://dev.mysql.com/doc/refman/5.7/en/grant.html
  4805   *************************************************************************************/
  4806  GrantStmt:
  4807  	 "GRANT" PrivElemList "ON" ObjectType PrivLevel "TO" UserSpecList
  4808  	 {
  4809  		$$ = &ast.GrantStmt{
  4810  			Privs: $2.([]*ast.PrivElem),
  4811  			ObjectType: $4.(ast.ObjectTypeType),
  4812  			Level: $5.(*ast.GrantLevel),
  4813  			Users: $7.([]*ast.UserSpec),
  4814  		}
  4815  	 }
  4816  
  4817  PrivElem:
  4818  	PrivType
  4819  	{
  4820  		$$ = &ast.PrivElem{
  4821  			Priv: $1.(mysql.PrivilegeType),
  4822  		}
  4823  	}
  4824  |	PrivType '(' ColumnNameList ')'
  4825  	{
  4826  		$$ = &ast.PrivElem{
  4827  			Priv: $1.(mysql.PrivilegeType),
  4828  			Cols: $3.([]*ast.ColumnName),
  4829  		}
  4830  	}
  4831  
  4832  PrivElemList:
  4833  	PrivElem
  4834  	{
  4835  		$$ = []*ast.PrivElem{$1.(*ast.PrivElem)}
  4836  	}
  4837  |	PrivElemList ',' PrivElem
  4838  	{
  4839  		$$ = append($1.([]*ast.PrivElem), $3.(*ast.PrivElem))
  4840  	}
  4841  
  4842  PrivType:
  4843  	"ALL"
  4844  	{
  4845  		$$ = mysql.AllPriv
  4846  	}
  4847  |	"ALTER"
  4848  	{
  4849  		$$ = mysql.AlterPriv
  4850  	}
  4851  |	"CREATE"
  4852  	{
  4853  		$$ = mysql.CreatePriv
  4854  	}
  4855  |	"CREATE" "USER"
  4856  	{
  4857  		$$ = mysql.CreateUserPriv
  4858  	}
  4859  |	"DELETE"
  4860  	{
  4861  		$$ = mysql.DeletePriv
  4862  	}
  4863  |	"DROP"
  4864  	{
  4865  		$$ = mysql.DropPriv
  4866  	}
  4867  |	"EXECUTE"
  4868  	{
  4869  		$$ = mysql.ExecutePriv
  4870  	}
  4871  |	"INDEX"
  4872  	{
  4873  		$$ = mysql.IndexPriv
  4874  	}
  4875  |	"INSERT"
  4876  	{
  4877  		$$ = mysql.InsertPriv
  4878  	}
  4879  |	"SELECT"
  4880  	{
  4881  		$$ = mysql.SelectPriv
  4882  	}
  4883  |	"SHOW" "DATABASES"
  4884  	{
  4885  		$$ = mysql.ShowDBPriv
  4886  	}
  4887  |	"UPDATE"
  4888  	{
  4889  		$$ = mysql.UpdatePriv
  4890  	}
  4891  |	"GRANT" "OPTION"
  4892  	{
  4893  		$$ = mysql.GrantPriv
  4894  	}
  4895  
  4896  ObjectType:
  4897  	{
  4898  		$$ = ast.ObjectTypeNone
  4899  	}
  4900  |	"TABLE"
  4901  	{
  4902  		$$ = ast.ObjectTypeTable
  4903  	}
  4904  
  4905  PrivLevel:
  4906  	'*'
  4907  	{
  4908  		$$ = &ast.GrantLevel {
  4909  			Level: ast.GrantLevelDB,
  4910  		}
  4911  	}
  4912  |	'*' '.' '*'
  4913  	{
  4914  		$$ = &ast.GrantLevel {
  4915  			Level: ast.GrantLevelGlobal,
  4916  		}
  4917  	}
  4918  | 	Identifier '.' '*'
  4919  	{
  4920  		$$ = &ast.GrantLevel {
  4921  			Level: ast.GrantLevelDB,
  4922  			DBName: $1.(string),
  4923  		}
  4924  	}
  4925  |	Identifier '.' Identifier
  4926  	{
  4927  		$$ = &ast.GrantLevel {
  4928  			Level: ast.GrantLevelTable,
  4929  			DBName: $1.(string),
  4930  			TableName: $3.(string),
  4931  		}
  4932  	}
  4933  |	Identifier
  4934  	{
  4935  		$$ = &ast.GrantLevel {
  4936  			Level: ast.GrantLevelTable,
  4937  			TableName: $1.(string),
  4938  		}
  4939  	}
  4940  
  4941  /*********************************************************************
  4942   * Lock/Unlock Tables
  4943   * See: http://dev.mysql.com/doc/refman/5.7/en/lock-tables.html
  4944   * All the statement leaves empty. This is used to prevent mysqldump error.
  4945   *********************************************************************/
  4946  
  4947  UnlockTablesStmt:
  4948  	"UNLOCK" "TABLES"
  4949  
  4950  LockTablesStmt:
  4951  	"LOCK" "TABLES" TableLockList
  4952  
  4953  TableLock:
  4954  	 TableName LockType
  4955  
  4956  LockType:
  4957  	"READ"
  4958  |	"READ" "LOCAL"
  4959  |	"WRITE"
  4960  
  4961  TableLockList:
  4962  	TableLock
  4963  |	TableLockList ',' TableLock 
  4964  
  4965  %%