github.com/XiaoMi/Gaea@v1.2.5/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/XiaoMi/Gaea/mysql"
    32  	"github.com/XiaoMi/Gaea/parser/ast"
    33  	"github.com/XiaoMi/Gaea/parser/model"
    34  	"github.com/XiaoMi/Gaea/parser/opcode"
    35  	"github.com/XiaoMi/Gaea/parser/auth"
    36  	"github.com/XiaoMi/Gaea/parser/types"
    37  )
    38  
    39  %}
    40  
    41  %union {
    42  	offset int // offset
    43  	item interface{}
    44  	ident string
    45  	expr ast.ExprNode
    46  	statement ast.StmtNode
    47  }
    48  
    49  %token	<ident>
    50  	/*yy:token "%c"     */	identifier      "identifier"
    51  	/*yy:token "_%c"    */  underscoreCS	"UNDERSCORE_CHARSET"
    52  	/*yy:token "\"%c\"" */	stringLit       "string literal"
    53  	singleAtIdentifier			"identifier with single leading at"
    54  	doubleAtIdentifier			"identifier with double leading at"
    55  	invalid					"a special token never used by parser, used by lexer to indicate error"
    56  	hintBegin				"hintBegin is a virtual token for optimizer hint grammar"
    57  	hintEnd					"hintEnd is a virtual token for optimizer hint grammar"
    58  	andand					"&&"
    59  	pipes					"||"
    60  
    61  	/* The following tokens belong to ODBCDateTimeType. */
    62  	odbcDateType			"d"
    63  	odbcTimeType			"t"
    64  	odbcTimestampType		"ts"
    65  
    66  	/* The following tokens belong to ReservedKeyword. */
    67  	add			"ADD"
    68  	all 			"ALL"
    69  	alter			"ALTER"
    70  	analyze			"ANALYZE"
    71  	and			"AND"
    72  	as			"AS"
    73  	asc			"ASC"
    74  	between			"BETWEEN"
    75  	bigIntType		"BIGINT"
    76  	binaryType		"BINARY"
    77  	blobType		"BLOB"
    78  	both			"BOTH"
    79  	by			"BY"
    80  	cascade			"CASCADE"
    81  	caseKwd			"CASE"
    82  	change        		"CHANGE"
    83  	character		"CHARACTER"
    84  	charType		"CHAR"
    85  	check 			"CHECK"
    86  	collate 		"COLLATE"
    87  	column			"COLUMN"
    88  	constraint		"CONSTRAINT"
    89  	convert			"CONVERT"
    90  	create			"CREATE"
    91  	cross 			"CROSS"
    92  	cumeDist		"CUME_DIST"
    93  	currentDate 		"CURRENT_DATE"
    94  	currentTime 		"CURRENT_TIME"
    95  	currentTs		"CURRENT_TIMESTAMP"
    96  	currentUser		"CURRENT_USER"
    97  	database		"DATABASE"
    98  	databases		"DATABASES"
    99  	dayHour			"DAY_HOUR"
   100  	dayMicrosecond		"DAY_MICROSECOND"
   101  	dayMinute		"DAY_MINUTE"
   102  	daySecond 		"DAY_SECOND"
   103  	decimalType		"DECIMAL"
   104  	defaultKwd		"DEFAULT"
   105  	delayed			"DELAYED"
   106  	deleteKwd		"DELETE"
   107  	denseRank		"DENSE_RANK"
   108  	desc			"DESC"
   109  	describe		"DESCRIBE"
   110  	distinct		"DISTINCT"
   111  	distinctRow		"DISTINCTROW"
   112  	div 			"DIV"
   113  	doubleType		"DOUBLE"
   114  	drop			"DROP"
   115  	dual 			"DUAL"
   116  	elseKwd			"ELSE"
   117  	enclosed		"ENCLOSED"
   118  	escaped 		"ESCAPED"
   119  	exists			"EXISTS"
   120  	explain			"EXPLAIN"
   121  	except			"EXCEPT"
   122  	falseKwd		"FALSE"
   123  	firstValue		"FIRST_VALUE"
   124  	floatType		"FLOAT"
   125  	forKwd			"FOR"
   126  	force			"FORCE"
   127  	foreign			"FOREIGN"
   128  	from			"FROM"
   129  	fulltext		"FULLTEXT"
   130  	generated		"GENERATED"
   131  	grant			"GRANT"
   132  	group			"GROUP"
   133  	groups			"GROUPS"
   134  	having			"HAVING"
   135  	highPriority		"HIGH_PRIORITY"
   136  	hourMicrosecond		"HOUR_MICROSECOND"
   137  	hourMinute		"HOUR_MINUTE"
   138  	hourSecond		"HOUR_SECOND"
   139  	ifKwd			"IF"
   140  	ignore			"IGNORE"
   141  	in			"IN"
   142  	index			"INDEX"
   143  	infile			"INFILE"
   144  	inner 			"INNER"
   145  	integerType		"INTEGER"
   146  	interval		"INTERVAL"
   147  	into			"INTO"
   148  	is			"IS"
   149  	insert			"INSERT"
   150  	intType			"INT"
   151  	int1Type		"INT1"
   152  	int2Type		"INT2"
   153  	int3Type		"INT3"
   154  	int4Type		"INT4"
   155  	int8Type		"INT8"
   156  	join			"JOIN"
   157  	key			"KEY"
   158  	keys			"KEYS"
   159  	kill			"KILL"
   160  	lag			"LAG"
   161  	lastValue		"LAST_VALUE"
   162  	lead			"LEAD"
   163  	leading			"LEADING"
   164  	left			"LEFT"
   165  	like			"LIKE"
   166  	limit			"LIMIT"
   167  	lines 			"LINES"
   168  	load			"LOAD"
   169  	localTime		"LOCALTIME"
   170  	localTs			"LOCALTIMESTAMP"
   171  	lock			"LOCK"
   172  	longblobType		"LONGBLOB"
   173  	longtextType		"LONGTEXT"
   174  	lowPriority		"LOW_PRIORITY"
   175  	maxValue		"MAXVALUE"
   176  	mediumblobType		"MEDIUMBLOB"
   177  	mediumIntType		"MEDIUMINT"
   178  	mediumtextType		"MEDIUMTEXT"
   179  	minuteMicrosecond	"MINUTE_MICROSECOND"
   180  	minuteSecond 		"MINUTE_SECOND"
   181  	mod 			"MOD"
   182  	not			"NOT"
   183  	noWriteToBinLog 	"NO_WRITE_TO_BINLOG"
   184  	nthValue		"NTH_VALUE"
   185  	ntile			"NTILE"
   186  	null			"NULL"
   187  	numericType		"NUMERIC"
   188  	nvarcharType		"NVARCHAR"
   189  	on			"ON"
   190  	option			"OPTION"
   191  	optionally		"OPTIONALLY"
   192  	or			"OR"
   193  	order			"ORDER"
   194  	outer			"OUTER"
   195  	over			"OVER"
   196  	packKeys		"PACK_KEYS"
   197  	partition		"PARTITION"
   198  	percentRank		"PERCENT_RANK"
   199  	precisionType		"PRECISION"
   200  	primary			"PRIMARY"
   201  	procedure		"PROCEDURE"
   202  	shardRowIDBits		"SHARD_ROW_ID_BITS"
   203  	rangeKwd		"RANGE"
   204  	rank			"RANK"
   205  	read			"READ"
   206  	realType		"REAL"
   207  	references		"REFERENCES"
   208  	regexpKwd		"REGEXP"
   209  	rename         		"RENAME"
   210  	repeat			"REPEAT"
   211  	replace			"REPLACE"
   212  	restrict		"RESTRICT"
   213  	revoke			"REVOKE"
   214  	right			"RIGHT"
   215  	rlike			"RLIKE"
   216  	row			"ROW"
   217  	rows			"ROWS"
   218  	rowNumber		"ROW_NUMBER"
   219  	secondMicrosecond	"SECOND_MICROSECOND"
   220  	selectKwd		"SELECT"
   221  	set			"SET"
   222  	show			"SHOW"
   223  	smallIntType		"SMALLINT"
   224  	sql			"SQL"
   225  	sqlCalcFoundRows	"SQL_CALC_FOUND_ROWS"
   226  	starting		"STARTING"
   227  	straightJoin		"STRAIGHT_JOIN"
   228  	tableKwd		"TABLE"
   229  	stored			"STORED"
   230  	terminated		"TERMINATED"
   231  	then			"THEN"
   232  	tinyblobType		"TINYBLOB"
   233  	tinyIntType		"TINYINT"
   234  	tinytextType		"TINYTEXT"
   235  	to			"TO"
   236  	trailing		"TRAILING"
   237  	trigger			"TRIGGER"
   238  	trueKwd			"TRUE"
   239  	unique			"UNIQUE"
   240  	union			"UNION"
   241  	unlock			"UNLOCK"
   242  	unsigned		"UNSIGNED"
   243  	update			"UPDATE"
   244  	usage			"USAGE"
   245  	use			"USE"
   246  	using			"USING"
   247  	utcDate 		"UTC_DATE"
   248  	utcTimestamp		"UTC_TIMESTAMP"
   249  	utcTime			"UTC_TIME"
   250  	values			"VALUES"
   251  	long			"LONG"
   252  	varcharType		"VARCHAR"
   253  	varbinaryType		"VARBINARY"
   254  	virtual			"VIRTUAL"
   255  	when			"WHEN"
   256  	where			"WHERE"
   257  	write			"WRITE"
   258  	window			"WINDOW"
   259  	with			"WITH"
   260  	xor 			"XOR"
   261  	yearMonth		"YEAR_MONTH"
   262  	zerofill		"ZEROFILL"
   263  	natural			"NATURAL"
   264  
   265  	/* The following tokens belong to UnReservedKeyword. */
   266  	action		"ACTION"
   267  	after		"AFTER"
   268  	always		"ALWAYS"
   269  	algorithm	"ALGORITHM"
   270  	any 		"ANY"
   271  	ascii		"ASCII"
   272  	autoIncrement	"AUTO_INCREMENT"
   273  	avgRowLength	"AVG_ROW_LENGTH"
   274  	avg		"AVG"
   275  	begin		"BEGIN"
   276  	binlog		"BINLOG"
   277  	bitType		"BIT"
   278  	booleanType	"BOOLEAN"
   279  	boolType	"BOOL"
   280  	btree		"BTREE"
   281  	byteType	"BYTE"
   282  	cascaded	"CASCADED"
   283  	charsetKwd	"CHARSET"
   284  	checksum	"CHECKSUM"
   285  	cleanup		"CLEANUP"
   286  	client		"CLIENT"
   287  	coalesce	"COALESCE"
   288  	collation	"COLLATION"
   289  	columns		"COLUMNS"
   290  	comment 	"COMMENT"
   291  	commit		"COMMIT"
   292  	committed	"COMMITTED"
   293  	compact		"COMPACT"
   294  	compressed	"COMPRESSED"
   295  	compression	"COMPRESSION"
   296  	connection 	"CONNECTION"
   297  	consistent	"CONSISTENT"
   298  	current		"CURRENT"
   299  	day		"DAY"
   300  	data 		"DATA"
   301  	dateType	"DATE"
   302  	datetimeType	"DATETIME"
   303  	deallocate	"DEALLOCATE"
   304  	definer		"DEFINER"
   305  	delayKeyWrite	"DELAY_KEY_WRITE"
   306  	disable		"DISABLE"
   307  	do		"DO"
   308  	duplicate	"DUPLICATE"
   309  	dynamic		"DYNAMIC"
   310  	enable		"ENABLE"
   311  	end		"END"
   312  	engine		"ENGINE"
   313  	engines		"ENGINES"
   314  	enum 		"ENUM"
   315  	event		"EVENT"
   316  	events		"EVENTS"
   317  	escape 		"ESCAPE"
   318  	exclusive       "EXCLUSIVE"
   319  	execute		"EXECUTE"
   320  	fields		"FIELDS"
   321  	first		"FIRST"
   322  	fixed		"FIXED"
   323  	flush		"FLUSH"
   324  	following	"FOLLOWING"
   325  	format		"FORMAT"
   326  	full		"FULL"
   327  	function	"FUNCTION"
   328  	grants		"GRANTS"
   329  	hash		"HASH"
   330  	hour		"HOUR"
   331  	identified	"IDENTIFIED"
   332  	isolation	"ISOLATION"
   333  	indexes		"INDEXES"
   334  	invoker		"INVOKER"
   335  	jsonType	"JSON"
   336  	keyBlockSize	"KEY_BLOCK_SIZE"
   337  	local		"LOCAL"
   338  	last		"LAST"
   339  	less		"LESS"
   340  	level		"LEVEL"
   341  	master		"MASTER"
   342  	microsecond	"MICROSECOND"
   343  	minute		"MINUTE"
   344  	mode		"MODE"
   345  	modify		"MODIFY"
   346  	month		"MONTH"
   347  	maxRows		"MAX_ROWS"
   348  	maxConnectionsPerHour	"MAX_CONNECTIONS_PER_HOUR"
   349  	maxQueriesPerHour	"MAX_QUERIES_PER_HOUR"
   350  	maxUpdatesPerHour	"MAX_UPDATES_PER_HOUR"
   351  	maxUserConnections	"MAX_USER_CONNECTIONS"
   352  	merge		"MERGE"
   353  	minRows		"MIN_ROWS"
   354  	names		"NAMES"
   355  	national	"NATIONAL"
   356  	no		"NO"
   357  	none		"NONE"
   358  	nulls		"NULLS"
   359  	offset		"OFFSET"
   360  	only		"ONLY"
   361  	password	"PASSWORD"
   362  	partitions	"PARTITIONS"
   363  	pipesAsOr
   364  	plugins		"PLUGINS"
   365  	preceding	"PRECEDING"
   366  	prepare		"PREPARE"
   367  	privileges	"PRIVILEGES"
   368  	process		"PROCESS"
   369  	processlist	"PROCESSLIST"
   370  	profiles	"PROFILES"
   371  	quarter		"QUARTER"
   372  	query		"QUERY"
   373  	queries		"QUERIES"
   374  	quick		"QUICK"
   375  	recover 	"RECOVER"
   376  	redundant	"REDUNDANT"
   377  	reload		"RELOAD"
   378  	repeatable	"REPEATABLE"
   379  	respect		"RESPECT"
   380  	replication	"REPLICATION"
   381  	reverse		"REVERSE"
   382  	role		"ROLE"
   383  	rollback	"ROLLBACK"
   384  	routine		"ROUTINE"
   385  	rowCount	"ROW_COUNT"
   386  	rowFormat	"ROW_FORMAT"
   387  	savepoint	"SAVEPOINT"
   388  	second		"SECOND"
   389  	security	"SECURITY"
   390  	separator 	"SEPARATOR"
   391  	serializable	"SERIALIZABLE"
   392  	session		"SESSION"
   393  	share		"SHARE"
   394  	shared		"SHARED"
   395  	signed		"SIGNED"
   396  	slave		"SLAVE"
   397  	slow		"SLOW"
   398  	snapshot	"SNAPSHOT"
   399  	sqlCache	"SQL_CACHE"
   400  	sqlNoCache	"SQL_NO_CACHE"
   401  	start		"START"
   402  	statsPersistent	"STATS_PERSISTENT"
   403  	status		"STATUS"
   404  	subpartition	"SUBPARTITION"
   405  	subpartitions	"SUBPARTITIONS"
   406  	super		"SUPER"
   407  	some 		"SOME"
   408  	global		"GLOBAL"
   409  	tables		"TABLES"
   410  	tablespace	"TABLESPACE"
   411  	temporary	"TEMPORARY"
   412  	temptable	"TEMPTABLE"
   413  	textType	"TEXT"
   414  	than		"THAN"
   415  	timeType	"TIME"
   416  	timestampType	"TIMESTAMP"
   417  	trace		"TRACE"
   418  	transaction	"TRANSACTION"
   419  	triggers	"TRIGGERS"
   420  	truncate	"TRUNCATE"
   421  	unbounded	"UNBOUNDED"
   422  	uncommitted	"UNCOMMITTED"
   423  	unknown 	"UNKNOWN"
   424  	user		"USER"
   425  	undefined	"UNDEFINED"
   426  	value		"VALUE"
   427  	variables	"VARIABLES"
   428  	view		"VIEW"
   429  	binding		"BINDING"
   430  	bindings	"BINDINGS"
   431  	warnings	"WARNINGS"
   432  	identSQLErrors	"ERRORS"
   433  	week		"WEEK"
   434  	yearType	"YEAR"
   435  	work        "WORK"
   436  	chain       "CHAIN"
   437  	release     "RELEASE"
   438  
   439  	/* The following tokens belong to NotKeywordToken. */
   440  	addDate			"ADDDATE"
   441  	bitAnd			"BIT_AND"
   442  	bitOr			"BIT_OR"
   443  	bitXor			"BIT_XOR"
   444  	cast			"CAST"
   445  	copyKwd			"COPY"
   446  	count			"COUNT"
   447  	curTime			"CURTIME"
   448  	dateAdd			"DATE_ADD"
   449  	dateSub			"DATE_SUB"
   450  	extract			"EXTRACT"
   451  	getFormat		"GET_FORMAT"
   452  	groupConcat		"GROUP_CONCAT"
   453  	next_row_id		"NEXT_ROW_ID"
   454  	inplace 		"INPLACE"
   455  	instant			"INSTANT"
   456  	internal		"INTERNAL"
   457  	min			"MIN"
   458  	max			"MAX"
   459  	maxExecutionTime	"MAX_EXECUTION_TIME"
   460  	now			"NOW"
   461  	position		"POSITION"
   462  	recent			"RECENT"
   463  	std	            "STD"
   464  	stddev			"STDDEV"
   465  	stddevPop		"STDDEV_POP"
   466  	stddevSamp		"STDDEV_SAMP"
   467  	subDate			"SUBDATE"
   468  	sum			"SUM"
   469  	substring		"SUBSTRING"
   470  	timestampAdd		"TIMESTAMPADD"
   471  	timestampDiff		"TIMESTAMPDIFF"
   472  	top			"TOP"
   473  	trim			"TRIM"
   474  	variance		"VARIANCE"
   475  	varPop			"VAR_POP"
   476  	varSamp			"VAR_SAMP"
   477  
   478  	/* The following tokens belong to TiDBKeyword. */
   479  	admin		"ADMIN"
   480  	buckets		"BUCKETS"
   481  	cancel		"CANCEL"
   482  	ddl		"DDL"
   483  	drainer         "DRAINER"
   484  	jobs		"JOBS"
   485  	job		    "JOB"
   486  	pump            "PUMP"
   487  	stats		"STATS"
   488  	statsMeta       "STATS_META"
   489  	statsHistograms "STATS_HISTOGRAMS"
   490  	statsBuckets    "STATS_BUCKETS"
   491  	statsHealthy    "STATS_HEALTHY"
   492  	tidb		"TIDB"
   493  	tidbHJ		"TIDB_HJ"
   494  	tidbSMJ		"TIDB_SMJ"
   495  	tidbINLJ	"TIDB_INLJ"
   496  	restore		"RESTORE"
   497  
   498  	builtinAddDate
   499  	builtinBitAnd
   500  	builtinBitOr
   501  	builtinBitXor
   502  	builtinCast
   503  	builtinCount
   504  	builtinCurDate
   505  	builtinCurTime
   506  	builtinDateAdd
   507  	builtinDateSub
   508  	builtinExtract
   509  	builtinGroupConcat
   510  	builtinMax
   511  	builtinMin
   512  	builtinNow
   513  	builtinPosition
   514  	builtinSubDate
   515  	builtinSubstring
   516  	builtinSum
   517  	builtinSysDate
   518  	builtinStddevPop
   519  	builtinStddevSamp
   520  	builtinTrim
   521  	builtinUser
   522  	builtinVarPop
   523  	builtinVarSamp
   524  
   525  %token	<item>
   526  
   527  	/*yy:token "1.%d"   */	floatLit        "floating-point literal"
   528  	/*yy:token "1.%d"   */	decLit          "decimal literal"
   529  	/*yy:token "%d"     */	intLit          "integer literal"
   530  	/*yy:token "%x"     */	hexLit          "hexadecimal literal"
   531  	/*yy:token "%b"     */	bitLit          "bit literal"
   532  
   533  	andnot		"&^"
   534  	assignmentEq	":="
   535  	eq		"="
   536  	ge		">="
   537  	le		"<="
   538  	jss		"->"
   539  	juss		"->>"
   540  	lsh		"<<"
   541  	neq		"!="
   542  	neqSynonym	"<>"
   543  	nulleq		"<=>"
   544  	paramMarker	"?"
   545  	rsh		">>"
   546  
   547  %token not2
   548  
   549  %type	<expr>
   550  	Expression			"expression"
   551  	MaxValueOrExpression		"maxvalue or expression"
   552  	BoolPri				"boolean primary expression"
   553  	ExprOrDefault			"expression or default"
   554  	PredicateExpr			"Predicate expression factor"
   555  	SetExpr				"Set variable statement value's expression"
   556  	BitExpr				"bit expression"
   557  	SimpleExpr			"simple expression"
   558  	SimpleIdent			"Simple Identifier expression"
   559  	SumExpr				"aggregate functions"
   560  	FunctionCallGeneric		"Function call with Identifier"
   561  	FunctionCallKeyword		"Function call with keyword as function name"
   562  	FunctionCallNonKeyword		"Function call with nonkeyword as function name"
   563  	Literal				"literal value"
   564  	Variable			"User or system variable"
   565  	SystemVariable			"System defined variable name"
   566  	UserVariable			"User defined variable name"
   567  	SubSelect			"Sub Select"
   568  	StringLiteral			"text literal"
   569  	ExpressionOpt			"Optional expression"
   570  	SignedLiteral			"Literal or NumLiteral with sign"
   571  	DefaultValueExpr		"DefaultValueExpr(Now or Signed Literal)"
   572  	NowSymOptionFraction		"NowSym with optional fraction part"
   573  
   574  %type	<statement>
   575  	AdminStmt			"Check table statement or show ddl statement"
   576  	AlterTableStmt			"Alter table statement"
   577  	AlterUserStmt			"Alter user statement"
   578  	AnalyzeTableStmt		"Analyze table statement"
   579  	BeginTransactionStmt		"BEGIN TRANSACTION statement"
   580  	BinlogStmt			"Binlog base64 statement"
   581  	CommitStmt			"COMMIT statement"
   582  	CreateTableStmt			"CREATE TABLE statement"
   583  	CreateViewStmt			"CREATE VIEW  stetement"
   584  	CreateUserStmt			"CREATE User statement"
   585  	CreateRoleStmt			"CREATE Role statement"
   586  	CreateDatabaseStmt		"Create Database Statement"
   587  	CreateIndexStmt			"CREATE INDEX statement"
   588  	CreateBindingStmt		"CREATE BINDING  statement"
   589  	DoStmt				"Do statement"
   590  	DropDatabaseStmt		"DROP DATABASE statement"
   591  	DropIndexStmt			"DROP INDEX statement"
   592  	DropStatsStmt			"DROP STATS statement"
   593  	DropTableStmt			"DROP TABLE statement"
   594  	DropUserStmt			"DROP USER"
   595  	DropRoleStmt			"DROP ROLE"
   596  	DropViewStmt			"DROP VIEW statement"
   597  	DropBindingStmt		    	"DROP BINDING  statement"
   598  	DeallocateStmt			"Deallocate prepared statement"
   599  	DeleteFromStmt			"DELETE FROM statement"
   600  	EmptyStmt			"empty statement"
   601  	ExecuteStmt			"Execute statement"
   602  	ExplainStmt			"EXPLAIN statement"
   603  	ExplainableStmt			"explainable statement"
   604  	FlushStmt			"Flush statement"
   605  	GrantStmt			"Grant statement"
   606  	GrantRoleStmt			"Grant role statement"
   607  	InsertIntoStmt			"INSERT INTO statement"
   608  	KillStmt			"Kill statement"
   609  	LoadDataStmt			"Load data statement"
   610  	LoadStatsStmt			"Load statistic statement"
   611  	LockTablesStmt			"Lock tables statement"
   612  	PreparedStmt			"PreparedStmt"
   613  	SelectStmt			"SELECT statement"
   614  	RenameTableStmt         	"rename table statement"
   615  	ReplaceIntoStmt			"REPLACE INTO statement"
   616  	RevokeStmt			"Revoke statement"
   617  	RevokeRoleStmt      "Revoke role statement"
   618  	RollbackStmt			"ROLLBACK statement"
   619  	SavepointStmt			"SAVEPOINT statement"
   620  	SetStmt				"Set variable statement"
   621  	SetRoleStmt				"Set active role statement"
   622  	SetDefaultRoleStmt			"Set default statement for some user"
   623  	ShowStmt			"Show engines/databases/tables/user/columns/warnings/status statement"
   624  	Statement			"statement"
   625  	TraceStmt			"TRACE statement"
   626  	TraceableStmt			"traceable statment"
   627  	TruncateTableStmt		"TRUNCATE TABLE statement"
   628  	UnlockTablesStmt		"Unlock tables statement"
   629  	UpdateStmt			"UPDATE statement"
   630  	UnionStmt			"Union select state ment"
   631  	UseStmt				"USE statement"
   632  
   633  %type   <item>
   634  	AdminShowSlow			"Admin Show Slow statement"
   635  	AlterAlgorithm			"Alter table algorithm"
   636  	AlterTableOptionListOpt		"Alter table option list opt"
   637  	AlterTableSpec			"Alter table specification"
   638  	AlterTableSpecList		"Alter table specification list"
   639  	AnyOrAll			"Any or All for subquery"
   640  	Assignment			"assignment"
   641  	AssignmentList			"assignment list"
   642  	AssignmentListOpt		"assignment list opt"
   643  	AuthOption			"User auth option"
   644  	AuthString			"Password string value"
   645  	OptionalBraces			"optional braces"
   646  	CastType			"Cast function target type"
   647  	CharsetName			"Character set name"
   648  	ColumnDef			"table column definition"
   649  	ColumnDefList			"table column definition list"
   650  	ColumnName			"column name"
   651  	ColumnNameList			"column name list"
   652  	ColumnList			"column list"
   653  	ColumnNameListOpt		"column name list opt"
   654  	ColumnNameListOptWithBrackets 	"column name list opt with brackets"
   655  	ColumnSetValue			"insert statement set value by column name"
   656  	ColumnSetValueList		"insert statement set value by column name list"
   657  	CommitOpt           "Commit options"
   658  	CompareOp			"Compare opcode"
   659  	ColumnOption			"column definition option"
   660  	ColumnOptionList		"column definition option list"
   661  	VirtualOrStored			"indicate generated column is stored or not"
   662  	ColumnOptionListOpt		"optional column definition option list"
   663  	Constraint			"table constraint"
   664  	ConstraintElem			"table constraint element"
   665  	ConstraintKeywordOpt		"Constraint Keyword or empty"
   666  	CreateIndexStmtUnique		"CREATE INDEX optional UNIQUE clause"
   667  	CreateTableOptionListOpt	"create table option list opt"
   668  	CreateTableSelectOpt	        "Select/Union statement in CREATE TABLE ... SELECT"
   669  	DatabaseOption			"CREATE Database specification"
   670  	DatabaseOptionList		"CREATE Database specification list"
   671  	DatabaseOptionListOpt		"CREATE Database specification list opt"
   672  	DBName				"Database Name"
   673  	DistinctOpt			"Explicit distinct option"
   674  	DefaultFalseDistinctOpt		"Distinct option which defaults to false"
   675  	DefaultTrueDistinctOpt		"Distinct option which defaults to true"
   676  	BuggyDefaultFalseDistinctOpt	"Distinct option which accepts DISTINCT ALL and defaults to false"
   677  	Enclosed			"Enclosed by"
   678  	EqOpt				"= or empty"
   679  	EscapedTableRef 		"escaped table reference"
   680  	Escaped				"Escaped by"
   681  	ExpressionList			"expression list"
   682  	MaxValueOrExpressionList	"maxvalue or expression list"
   683  	ExpressionListOpt		"expression list opt"
   684  	FuncDatetimePrecListOpt	        "Function datetime precision list opt"
   685  	FuncDatetimePrecList	        "Function datetime precision list"
   686  	Field				"field expression"
   687  	Fields				"Fields clause"
   688  	FieldsTerminated		"Fields terminated by"
   689  	FieldAsName			"Field alias name"
   690  	FieldAsNameOpt			"Field alias name opt"
   691  	FieldList			"field expression list"
   692  	FlushOption			"Flush option"
   693  	PluginNameList			"Plugin Name List"
   694  	TableRefsClause			"Table references clause"
   695  	FuncDatetimePrec		"Function datetime precision"
   696  	GlobalScope			"The scope of variable"
   697  	GroupByClause			"GROUP BY clause"
   698  	HashString			"Hashed string"
   699  	HavingClause			"HAVING clause"
   700  	HandleRange			"handle range"
   701  	HandleRangeList			"handle range list"
   702  	IfExists			"If Exists"
   703  	IfNotExists			"If Not Exists"
   704  	IgnoreOptional			"IGNORE or empty"
   705  	IndexColName			"Index column name"
   706  	IndexColNameList		"List of index column name"
   707  	IndexHint			"index hint"
   708  	IndexHintList			"index hint list"
   709  	IndexHintListOpt		"index hint list opt"
   710  	IndexHintScope			"index hint scope"
   711  	IndexHintType			"index hint type"
   712  	IndexName			"index name"
   713  	IndexNameList			"index name list"
   714  	IndexOption			"Index Option"
   715  	IndexOptionList			"Index Option List or empty"
   716  	IndexType			"index type"
   717  	IndexTypeOpt			"Optional index type"
   718  	InsertValues			"Rest part of INSERT/REPLACE INTO statement"
   719  	JoinTable 			"join table"
   720  	JoinType			"join type"
   721  	KillOrKillTiDB			"Kill or Kill TiDB"
   722  	LikeEscapeOpt 			"like escape option"
   723  	LikeTableWithOrWithoutParen	"LIKE table_name or ( LIKE table_name )"
   724  	LimitClause			"LIMIT clause"
   725  	LimitOption			"Limit option could be integer or parameter marker."
   726  	Lines				"Lines clause"
   727  	LinesTerminated			"Lines terminated by"
   728  	LocalOpt			"Local opt"
   729  	LockClause         		"Alter table lock clause"
   730  	MaxNumBuckets			"Max number of buckets"
   731  	NumLiteral			"Num/Int/Float/Decimal Literal"
   732  	NoWriteToBinLogAliasOpt 	"NO_WRITE_TO_BINLOG alias LOCAL or empty"
   733  	ObjectType			"Grant statement object type"
   734  	OnDuplicateKeyUpdate		"ON DUPLICATE KEY UPDATE value list"
   735  	DuplicateOpt			"[IGNORE|REPLACE] in CREATE TABLE ... SELECT statement"
   736  	OptFull				"Full or empty"
   737  	Order				"ORDER BY clause optional collation specification"
   738  	OrderBy				"ORDER BY clause"
   739  	OrReplace			"or replace"
   740  	ByItem				"BY item"
   741  	OrderByOptional			"Optional ORDER BY clause optional"
   742  	ByList				"BY list"
   743  	QuickOptional			"QUICK or empty"
   744  	PartitionDefinition		"Partition definition"
   745  	PartitionDefinitionList 	"Partition definition list"
   746  	PartitionDefinitionListOpt	"Partition definition list option"
   747  	PartitionOpt			"Partition option"
   748  	PartitionNameList		"Partition name list"
   749  	PartitionNameListOpt    "table partition names list optional"
   750  	PartitionNumOpt			"PARTITION NUM option"
   751  	PartDefValuesOpt		"VALUES {LESS THAN {(expr | value_list) | MAXVALUE} | IN {value_list}"
   752  	PartDefOptionsOpt		"PartDefOptionList option"
   753  	PartDefOptionList		"PartDefOption list"
   754  	PartDefOption			"COMMENT [=] xxx | TABLESPACE [=] tablespace_name | ENGINE [=] xxx"
   755  	PasswordOpt			"Password option"
   756  	ColumnPosition			"Column position [First|After ColumnName]"
   757  	PrepareSQL			"Prepare statement sql string"
   758  	PriorityOpt			"Statement priority option"
   759  	PrivElem			"Privilege element"
   760  	PrivElemList			"Privilege element list"
   761  	PrivLevel			"Privilege scope"
   762  	PrivType			"Privilege type"
   763  	ReferDef			"Reference definition"
   764  	OnDeleteOpt			"optional ON DELETE clause"
   765  	OnUpdateOpt			"optional ON UPDATE clause"
   766  	OptGConcatSeparator		"optional GROUP_CONCAT SEPARATOR"
   767  	ReferOpt			"reference option"
   768  	Rolename            "Rolename"
   769  	RolenameList            "RolenameList"
   770  	RoleSpec		"Rolename and auth option"
   771  	RoleSpecList		"Rolename and auth option list"
   772  	RoleNameString      "role name string"
   773  	RowFormat			"Row format option"
   774  	RowValue			"Row value"
   775  	SelectLockOpt			"FOR UPDATE or LOCK IN SHARE MODE,"
   776  	SelectStmtCalcFoundRows		"SELECT statement optional SQL_CALC_FOUND_ROWS"
   777  	SelectStmtSQLCache		"SELECT statement optional SQL_CAHCE/SQL_NO_CACHE"
   778  	SelectStmtStraightJoin		"SELECT statement optional STRAIGHT_JOIN"
   779  	SelectStmtFieldList		"SELECT statement field list"
   780  	SelectStmtLimit			"SELECT statement optional LIMIT clause"
   781  	SelectStmtOpts			"Select statement options"
   782  	SelectStmtBasic			"SELECT statement from constant value"
   783  	SelectStmtFromDualTable			"SELECT statement from dual table"
   784  	SelectStmtFromTable			"SELECT statement from table"
   785  	SelectStmtGroup			"SELECT statement optional GROUP BY clause"
   786  	SetRoleOpt				"Set role options"
   787  	SetDefaultRoleOpt				"Set default role options"
   788  	ShowTargetFilterable    	"Show target that can be filtered by WHERE or LIKE"
   789  	ShowDatabaseNameOpt		"Show tables/columns statement database name option"
   790  	ShowTableAliasOpt       	"Show table alias option"
   791  	ShowLikeOrWhereOpt		"Show like or where clause option"
   792  	Starting			"Starting by"
   793  	StatementList			"statement list"
   794  	StatsPersistentVal		"stats_persistent value"
   795  	StringName			"string literal or identifier"
   796  	StringList 			"string list"
   797  	SubPartitionOpt			"SubPartition option"
   798  	SubPartitionNumOpt		"SubPartition NUM option"
   799  	Symbol				"Constraint Symbol"
   800  	TableAsName			"table alias name"
   801  	TableAsNameOpt 			"table alias name optional"
   802  	TableElement			"table definition element"
   803  	TableElementList		"table definition element list"
   804  	TableElementListOpt		"table definition element list optional"
   805  	TableFactor 			"table factor"
   806  	TableLock			"Table name and lock type"
   807  	TableLockList			"Table lock list"
   808  	TableName			"Table name"
   809  	TableNameList			"Table name list"
   810  	TableNameListOpt		"Table name list opt"
   811  	TableOption			"create table option"
   812  	TableOptionList			"create table option list"
   813  	TableRef 			"table reference"
   814  	TableRefs 			"table references"
   815  	TableToTable 			"rename table to table"
   816  	TableToTableList 		"rename table to table by list"
   817  
   818  	TransactionChar		"Transaction characteristic"
   819  	TransactionChars	"Transaction characteristic list"
   820  	TrimDirection		"Trim string direction"
   821  	UnionOpt		"Union Option(empty/ALL/DISTINCT)"
   822  	UnionClauseList		"Union select clause list"
   823  	UnionSelect		"Union (select) item"
   824  	Username		"Username"
   825  	UsernameList		"UsernameList"
   826  	UserSpec		"Username and auth option"
   827  	UserSpecList		"Username and auth option list"
   828  	UserVariableList	"User defined variable name list"
   829  	Values			"values"
   830  	ValuesList		"values list"
   831  	ValuesOpt		"values optional"
   832  	VariableAssignment	"set variable value"
   833  	VariableAssignmentList	"set variable value list"
   834  	ViewAlgorithm		"view algorithm"
   835  	ViewCheckOption		"view check option"
   836  	ViewDefiner		"view definer"
   837  	ViewName		"view name"
   838  	ViewFieldList		"create view statement field list"
   839  	ViewSQLSecurity		"view sql security"
   840  	WhereClause		"WHERE clause"
   841  	WhereClauseOptional	"Optional WHERE clause"
   842  	WhenClause		"When clause"
   843  	WhenClauseList		"When clause list"
   844  	WithReadLockOpt		"With Read Lock opt"
   845  	WithGrantOptionOpt	"With Grant Option opt"
   846  	ElseOpt			"Optional else clause"
   847  	Type			"Types"
   848  
   849  	OptExistingWindowName	"Optional existing WINDOW name"
   850  	OptFromFirstLast	"Optional FROM FIRST/LAST"
   851  	OptLLDefault		"Optional LEAD/LAG default"
   852  	OptLeadLagInfo		"Optional LEAD/LAG info"
   853  	OptNullTreatment	"Optional NULL treatment"
   854  	OptPartitionClause	"Optional PARTITION clause"
   855  	OptWindowOrderByClause	"Optional ORDER BY clause in WINDOW"
   856  	OptWindowFrameClause	"Optional FRAME clause in WINDOW"
   857  	OptWindowingClause	"Optional OVER clause"
   858  	WindowingClause		"OVER clause"
   859  	WindowClauseOptional	"Optional WINDOW clause"
   860  	WindowDefinitionList	"WINDOW definition list"
   861  	WindowDefinition	"WINDOW definition"
   862  	WindowFrameUnits	"WINDOW frame units"
   863  	WindowFrameBetween	"WINDOW frame between"
   864  	WindowFrameBound	"WINDOW frame bound"
   865  	WindowFrameExtent	"WINDOW frame extent"
   866  	WindowFrameStart	"WINDOW frame start"
   867  	WindowFuncCall		"WINDOW function call"
   868  	WindowName		"WINDOW name"
   869  	WindowNameOrSpec	"WINDOW name or spec"
   870  	WindowSpec		"WINDOW spec"
   871  	WindowSpecDetails	"WINDOW spec details"
   872  
   873  	BetweenOrNotOp		"Between predicate"
   874  	IsOrNotOp		"Is predicate"
   875  	InOrNotOp		"In predicate"
   876  	LikeOrNotOp		"Like predicate"
   877  	RegexpOrNotOp		"Regexp predicate"
   878  
   879  	NumericType		"Numeric types"
   880  	IntegerType		"Integer Types types"
   881  	BooleanType 		"Boolean Types types"
   882  	FixedPointType		"Exact value types"
   883  	FloatingPointType	"Approximate value types"
   884  	BitValueType		"bit value types"
   885  	StringType		"String types"
   886  	BlobType		"Blob types"
   887  	TextType		"Text types"
   888  	DateAndTimeType		"Date and Time types"
   889  
   890  	OptFieldLen		"Field length or empty"
   891  	FieldLen		"Field length"
   892  	FieldOpts		"Field type definition option list"
   893  	FieldOpt		"Field type definition option"
   894  	FloatOpt		"Floating-point type option"
   895  	Precision		"Floating-point precision option"
   896  	OptBinary		"Optional BINARY"
   897  	OptBinMod		"Optional BINARY mode"
   898  	OptCharset		"Optional Character setting"
   899  	OptCollate		"Optional Collate setting"
   900  	IgnoreLines		"Ignore num(int) lines"
   901  	NUM			"A number"
   902  	NumList			"Some numbers"
   903  	LengthNum		"Field length num(uint64)"
   904  	HintTableList		"Table list in optimizer hint"
   905  	TableOptimizerHintOpt	"Table level optimizer hint"
   906  	TableOptimizerHints	"Table level optimizer hints"
   907  	TableOptimizerHintList	"Table level optimizer hint list"
   908  
   909  %type	<ident>
   910  	AsOpt			"AS or EmptyString"
   911  	KeyOrIndex		"{KEY|INDEX}"
   912  	ColumnKeywordOpt	"Column keyword or empty"
   913  	PrimaryOpt		"Optional primary keyword"
   914  	NowSym			"CURRENT_TIMESTAMP/LOCALTIME/LOCALTIMESTAMP"
   915  	NowSymFunc		"CURRENT_TIMESTAMP/LOCALTIME/LOCALTIMESTAMP/NOW"
   916  	DefaultKwdOpt		"optional DEFAULT keyword"
   917  	DatabaseSym		"DATABASE or SCHEMA"
   918  	ExplainSym		"EXPLAIN or DESCRIBE or DESC"
   919  	RegexpSym		"REGEXP or RLIKE"
   920  	IntoOpt			"INTO or EmptyString"
   921  	ValueSym		"Value or Values"
   922  	Varchar			"{NATIONAL VARCHAR|VARCHAR|NVARCHAR}"
   923  	TimeUnit		"Time unit for 'DATE_ADD', 'DATE_SUB', 'ADDDATE', 'SUBDATE', 'EXTRACT'"
   924  	TimestampUnit		"Time unit for 'TIMESTAMPADD' and 'TIMESTAMPDIFF'"
   925  	DeallocateSym		"Deallocate or drop"
   926  	OuterOpt		"optional OUTER clause"
   927  	CrossOpt		"Cross join option"
   928  	TablesTerminalSym 	"{TABLE|TABLES}"
   929  	IsolationLevel		"Isolation level"
   930  	ShowIndexKwd		"Show index/indexs/key keyword"
   931  	DistinctKwd		"DISTINCT/DISTINCTROW keyword"
   932  	FromOrIn		"From or In"
   933  	OptTable		"Optional table keyword"
   934  	OptInteger		"Optional Integer keyword"
   935  	NationalOpt		"National option"
   936  	CharsetKw		"charset or charater set"
   937  	CommaOpt		"optional comma"
   938  	LockType		"Table locks type"
   939  	logAnd			"logical and operator"
   940  	logOr			"logical or operator"
   941  	FieldsOrColumns 	"Fields or columns"
   942  	GetFormatSelector	"{DATE|DATETIME|TIME|TIMESTAMP}"
   943  
   944  %type	<ident>
   945  	ODBCDateTimeType		"ODBC type keywords for date and time literals"
   946  	Identifier			"identifier or unreserved keyword"
   947  	NotKeywordToken			"Tokens not mysql keyword but treated specially"
   948  	UnReservedKeyword		"MySQL unreserved keywords"
   949  	TiDBKeyword			"TiDB added keywords"
   950  	FunctionNameConflict		"Built-in function call names which are conflict with keywords"
   951  	FunctionNameOptionalBraces	"Function with optional braces, all of them are reserved keywords."
   952  	FunctionNameDatetimePrecision	"Function with optional datetime precision, all of them are reserved keywords."
   953  	FunctionNameDateArith		"Date arith function call names (date_add or date_sub)"
   954  	FunctionNameDateArithMultiForms	"Date arith function call names (adddate or subdate)"
   955  
   956  %precedence empty
   957  
   958  %precedence sqlCache sqlNoCache
   959  %precedence lowerThanIntervalKeyword
   960  %precedence interval
   961  %precedence lowerThanStringLitToken
   962  %precedence stringLit
   963  %precedence lowerThanSetKeyword
   964  %precedence set
   965  %precedence lowerThanInsertValues
   966  %precedence insertValues
   967  %precedence lowerThanCreateTableSelect
   968  %precedence createTableSelect
   969  %precedence lowerThanKey
   970  %precedence key
   971  
   972  %left   join straightJoin inner cross left right full natural
   973  /* A dummy token to force the priority of TableRef production in a join. */
   974  %left   tableRefPriority
   975  %precedence lowerThanOn
   976  %precedence on using
   977  %right   assignmentEq
   978  %left 	pipes or pipesAsOr
   979  %left 	xor
   980  %left 	andand and
   981  %left 	between
   982  %precedence	lowerThanEq
   983  %left 	eq ge le neq neqSynonym '>' '<' is like in
   984  %left 	'|'
   985  %left 	'&'
   986  %left 	rsh lsh
   987  %left 	'-' '+'
   988  %left 	'*' '/' '%' div mod
   989  %left 	'^'
   990  %left 	'~' neg
   991  %right 	not not2
   992  %right	collate
   993  
   994  %precedence '('
   995  %precedence quick
   996  %precedence escape
   997  %precedence lowerThanComma
   998  %precedence ','
   999  %precedence higherThanComma
  1000  
  1001  %start	Start
  1002  
  1003  %%
  1004  
  1005  Start:
  1006  	StatementList
  1007  
  1008  /**************************************AlterTableStmt***************************************
  1009   * See https://dev.mysql.com/doc/refman/5.7/en/alter-table.html
  1010   *******************************************************************************************/
  1011  AlterTableStmt:
  1012  	"ALTER" IgnoreOptional "TABLE" TableName AlterTableSpecList
  1013  	{
  1014  		$$ = &ast.AlterTableStmt{
  1015  			Table: $4.(*ast.TableName),
  1016  			Specs: $5.([]*ast.AlterTableSpec),
  1017  		}
  1018  	}
  1019  |	"ALTER" IgnoreOptional "TABLE" TableName "ANALYZE" "PARTITION" PartitionNameList MaxNumBuckets
  1020  	{
  1021  		$$ = &ast.AnalyzeTableStmt{TableNames: []*ast.TableName{$4.(*ast.TableName)}, PartitionNames: $7.([]model.CIStr), MaxNumBuckets: $8.(uint64),}
  1022  	}
  1023  |	"ALTER" IgnoreOptional "TABLE" TableName "ANALYZE" "PARTITION" PartitionNameList "INDEX" IndexNameList MaxNumBuckets
  1024  	{
  1025  		$$ = &ast.AnalyzeTableStmt{
  1026  			TableNames: []*ast.TableName{$4.(*ast.TableName)},
  1027  			PartitionNames: $7.([]model.CIStr),
  1028  			IndexNames: $9.([]model.CIStr),
  1029  			IndexFlag: true,
  1030  			MaxNumBuckets: $10.(uint64),
  1031  		}
  1032  	}
  1033  
  1034  AlterTableSpec:
  1035  	AlterTableOptionListOpt
  1036  	{
  1037  		$$ = &ast.AlterTableSpec{
  1038  			Tp:	ast.AlterTableOption,
  1039  			Options:$1.([]*ast.TableOption),
  1040  		}
  1041  	}
  1042  |	"CONVERT" "TO" CharsetKw CharsetName OptCollate
  1043  	{
  1044  		op := &ast.AlterTableSpec{
  1045  			Tp: ast.AlterTableOption,
  1046  			Options:[]*ast.TableOption{{Tp: ast.TableOptionCharset, StrValue: $4.(string)}},
  1047  		}
  1048  		if $5 != "" {
  1049  			op.Options = append(op.Options, &ast.TableOption{Tp: ast.TableOptionCollate, StrValue: $5.(string)})
  1050  		}
  1051  		$$ = op
  1052  	}
  1053  |	"ADD" ColumnKeywordOpt ColumnDef ColumnPosition
  1054  	{
  1055  		$$ = &ast.AlterTableSpec{
  1056  			Tp: 		ast.AlterTableAddColumns,
  1057  			NewColumns:	[]*ast.ColumnDef{$3.(*ast.ColumnDef)},
  1058  			Position:	$4.(*ast.ColumnPosition),
  1059  		}
  1060  	}
  1061  |	"ADD" ColumnKeywordOpt '(' ColumnDefList ')'
  1062  	{
  1063  		$$ = &ast.AlterTableSpec{
  1064  			Tp: 		ast.AlterTableAddColumns,
  1065  			NewColumns:	$4.([]*ast.ColumnDef),
  1066  		}
  1067  	}
  1068  |	"ADD" Constraint
  1069  	{
  1070  		constraint := $2.(*ast.Constraint)
  1071  		$$ = &ast.AlterTableSpec{
  1072  			Tp: ast.AlterTableAddConstraint,
  1073  			Constraint: constraint,
  1074  		}
  1075  	}
  1076  |	"ADD" "PARTITION" PartitionDefinitionListOpt
  1077  	{
  1078  		var defs []*ast.PartitionDefinition
  1079  		if $3 != nil {
  1080  			defs = $3.([]*ast.PartitionDefinition)
  1081  		}
  1082  		$$ = &ast.AlterTableSpec{
  1083  			Tp: ast.AlterTableAddPartitions,
  1084  			PartDefinitions: defs,
  1085  		}
  1086  	}
  1087  |	"ADD" "PARTITION" "PARTITIONS" NUM
  1088  	{
  1089  		$$ = &ast.AlterTableSpec{
  1090  			Tp: ast.AlterTableAddPartitions,
  1091  			Num: getUint64FromNUM($4),
  1092  		}
  1093  	}
  1094  |	"COALESCE" "PARTITION" NUM
  1095  	{
  1096  		$$ = &ast.AlterTableSpec{
  1097  			Tp: ast.AlterTableCoalescePartitions,
  1098  			Num: getUint64FromNUM($3),
  1099  		}
  1100  	}
  1101  |	"DROP" ColumnKeywordOpt ColumnName RestrictOrCascadeOpt
  1102  	{
  1103  		$$ = &ast.AlterTableSpec{
  1104  			Tp: ast.AlterTableDropColumn,
  1105  			OldColumnName: $3.(*ast.ColumnName),
  1106  		}
  1107  	}
  1108  |	"DROP" "PRIMARY" "KEY"
  1109  	{
  1110  		$$ = &ast.AlterTableSpec{Tp: ast.AlterTableDropPrimaryKey}
  1111  	}
  1112  |	"DROP" "PARTITION" Identifier
  1113  	{
  1114  		$$ = &ast.AlterTableSpec{
  1115  			Tp: ast.AlterTableDropPartition,
  1116  			Name: $3,
  1117  		}
  1118  	}
  1119  |	"TRUNCATE" "PARTITION" Identifier
  1120  	{
  1121  		$$ = &ast.AlterTableSpec{
  1122  			Tp: ast.AlterTableTruncatePartition,
  1123  			Name: $3,
  1124  		}
  1125  	}
  1126  |	"DROP" KeyOrIndex Identifier
  1127  	{
  1128  		$$ = &ast.AlterTableSpec{
  1129  			Tp: ast.AlterTableDropIndex,
  1130  			Name: $3,
  1131  		}
  1132  	}
  1133  |	"DROP" "FOREIGN" "KEY" Symbol
  1134  	{
  1135  		$$ = &ast.AlterTableSpec{
  1136  			Tp: ast.AlterTableDropForeignKey,
  1137  			Name: $4.(string),
  1138  		}
  1139  	}
  1140  |	"DISABLE" "KEYS"
  1141  	{
  1142  		$$ = &ast.AlterTableSpec{}
  1143  	}
  1144  |	"ENABLE" "KEYS"
  1145  	{
  1146  		$$ = &ast.AlterTableSpec{}
  1147  	}
  1148  |	"MODIFY" ColumnKeywordOpt ColumnDef ColumnPosition
  1149  	{
  1150  		$$ = &ast.AlterTableSpec{
  1151  			Tp:		ast.AlterTableModifyColumn,
  1152  			NewColumns:	[]*ast.ColumnDef{$3.(*ast.ColumnDef)},
  1153  			Position:	$4.(*ast.ColumnPosition),
  1154  		}
  1155  	}
  1156  |	"CHANGE" ColumnKeywordOpt ColumnName ColumnDef ColumnPosition
  1157  	{
  1158  		$$ = &ast.AlterTableSpec{
  1159  			Tp:    		ast.AlterTableChangeColumn,
  1160  			OldColumnName:	$3.(*ast.ColumnName),
  1161  			NewColumns:	[]*ast.ColumnDef{$4.(*ast.ColumnDef)},
  1162  			Position:	$5.(*ast.ColumnPosition),
  1163  		}
  1164  	}
  1165  |	"ALTER" ColumnKeywordOpt ColumnName "SET" "DEFAULT" SignedLiteral
  1166  	{
  1167  		option := &ast.ColumnOption{Expr: $6}
  1168  		colDef := &ast.ColumnDef{
  1169  			Name: 	 $3.(*ast.ColumnName),
  1170  			Options: []*ast.ColumnOption{option},
  1171  		}
  1172  		$$ = &ast.AlterTableSpec{
  1173  			Tp:		ast.AlterTableAlterColumn,
  1174  			NewColumns:	[]*ast.ColumnDef{colDef},
  1175  		}
  1176  	}
  1177  |	"ALTER" ColumnKeywordOpt ColumnName "DROP" "DEFAULT"
  1178  	{
  1179  		colDef := &ast.ColumnDef{
  1180  			Name: 	 $3.(*ast.ColumnName),
  1181  		}
  1182  		$$ = &ast.AlterTableSpec{
  1183  			Tp:		ast.AlterTableAlterColumn,
  1184  			NewColumns:	[]*ast.ColumnDef{colDef},
  1185  		}
  1186  	}
  1187  |	"RENAME" "TO" TableName
  1188  	{
  1189  		$$ = &ast.AlterTableSpec{
  1190  			Tp:    		ast.AlterTableRenameTable,
  1191  			NewTable:      $3.(*ast.TableName),
  1192  		}
  1193  	}
  1194  |	"RENAME" TableName
  1195  	{
  1196  		$$ = &ast.AlterTableSpec{
  1197  			Tp:    		ast.AlterTableRenameTable,
  1198  			NewTable:      $2.(*ast.TableName),
  1199  		}
  1200  	}
  1201  |	"RENAME" "AS" TableName
  1202  	{
  1203  		$$ = &ast.AlterTableSpec{
  1204  			Tp:    		ast.AlterTableRenameTable,
  1205  			NewTable:      $3.(*ast.TableName),
  1206  		}
  1207  	}
  1208  |	"RENAME" KeyOrIndex Identifier "TO" Identifier
  1209  	{
  1210  		$$ = &ast.AlterTableSpec{
  1211  			Tp:    	    ast.AlterTableRenameIndex,
  1212  			FromKey:    model.NewCIStr($3),
  1213  			ToKey:      model.NewCIStr($5),
  1214  		}
  1215  	}
  1216  |	LockClause
  1217  	{
  1218  		$$ = &ast.AlterTableSpec{
  1219  			Tp:    		ast.AlterTableLock,
  1220  			LockType:   $1.(ast.LockType),
  1221  		}
  1222  	}
  1223  | "ALGORITHM" EqOpt AlterAlgorithm
  1224  	{
  1225  		// Parse it and ignore it. Just for compatibility.
  1226  		$$ = &ast.AlterTableSpec{
  1227  			Tp:    		ast.AlterTableAlgorithm,
  1228  			Algorithm:	$3.(ast.AlterAlgorithm),
  1229  		}
  1230  	}
  1231  | "FORCE"
  1232  	{
  1233  		// Parse it and ignore it. Just for compatibility.
  1234  		$$ = &ast.AlterTableSpec{
  1235  			Tp:    		ast.AlterTableForce,
  1236  		}
  1237  	}
  1238  
  1239  
  1240  AlterAlgorithm:
  1241  	"DEFAULT"
  1242  	{
  1243  		$$ = ast.AlterAlgorithmDefault
  1244  	}
  1245  | 	"COPY"
  1246  	{
  1247  		$$ = ast.AlterAlgorithmCopy
  1248  	}
  1249  | 	"INPLACE"
  1250  	{
  1251  		$$ = ast.AlterAlgorithmInplace
  1252  	}
  1253  |	"INSTANT"
  1254  	{
  1255  		$$ = ast.AlterAlgorithmInstant
  1256  	}
  1257  
  1258  
  1259  LockClauseOpt:
  1260  	{}
  1261  | 	LockClause {}
  1262  
  1263  LockClause:
  1264  	"LOCK" eq "NONE"
  1265  	{
  1266  		$$ = ast.LockTypeNone
  1267  	}
  1268  |	"LOCK" eq "DEFAULT"
  1269  	{
  1270  		$$ = ast.LockTypeDefault
  1271  	}
  1272  |	"LOCK" eq "SHARED"
  1273  	{
  1274  		$$ = ast.LockTypeShared
  1275  	}
  1276  |	"LOCK" eq "EXCLUSIVE"
  1277  	{
  1278  		$$ = ast.LockTypeExclusive
  1279  	}
  1280  
  1281  KeyOrIndex: "KEY" | "INDEX"
  1282  
  1283  
  1284  KeyOrIndexOpt:
  1285  	{}
  1286  |	KeyOrIndex
  1287  
  1288  ColumnKeywordOpt:
  1289  	{}
  1290  |	"COLUMN"
  1291  
  1292  ColumnPosition:
  1293  	{
  1294  		$$ = &ast.ColumnPosition{Tp: ast.ColumnPositionNone}
  1295  	}
  1296  |	"FIRST"
  1297  	{
  1298  		$$ = &ast.ColumnPosition{Tp: ast.ColumnPositionFirst}
  1299  	}
  1300  |	"AFTER" ColumnName
  1301  	{
  1302  		$$ = &ast.ColumnPosition{
  1303  			Tp: ast.ColumnPositionAfter,
  1304  			RelativeColumn: $2.(*ast.ColumnName),
  1305  		}
  1306  	}
  1307  
  1308  AlterTableSpecList:
  1309  	AlterTableSpec
  1310  	{
  1311  		$$ = []*ast.AlterTableSpec{$1.(*ast.AlterTableSpec)}
  1312  	}
  1313  |	AlterTableSpecList ',' AlterTableSpec
  1314  	{
  1315  		$$ = append($1.([]*ast.AlterTableSpec), $3.(*ast.AlterTableSpec))
  1316  	}
  1317  
  1318  PartitionNameList:
  1319  	Identifier
  1320  	{
  1321  		$$ = []model.CIStr{model.NewCIStr($1)}
  1322  	}
  1323  |	PartitionNameList ',' Identifier
  1324  	{
  1325  		$$ = append($1.([]model.CIStr), model.NewCIStr($3))
  1326  	}
  1327  
  1328  ConstraintKeywordOpt:
  1329  	{
  1330  		$$ = nil
  1331  	}
  1332  |	"CONSTRAINT"
  1333  	{
  1334  		$$ = nil
  1335  	}
  1336  |	"CONSTRAINT" Symbol
  1337  	{
  1338  		$$ = $2.(string)
  1339  	}
  1340  
  1341  Symbol:
  1342  	Identifier
  1343  	{
  1344  		$$ = $1
  1345  	}
  1346  
  1347  /**************************************RenameTableStmt***************************************
  1348   * See http://dev.mysql.com/doc/refman/5.7/en/rename-table.html
  1349   *
  1350   * TODO: refactor this when you are going to add full support for multiple schema changes.
  1351   * Currently it is only useful for syncer which depends heavily on tidb parser to do some dirty work.
  1352   *******************************************************************************************/
  1353  RenameTableStmt:
  1354  	"RENAME" "TABLE" TableToTableList
  1355  	{
  1356  		$$ = &ast.RenameTableStmt{
  1357  			OldTable: $3.([]*ast.TableToTable)[0].OldTable,
  1358  			NewTable: $3.([]*ast.TableToTable)[0].NewTable,
  1359  			TableToTables: $3.([]*ast.TableToTable),
  1360  		}
  1361  	}
  1362  
  1363  TableToTableList:
  1364  	TableToTable
  1365  	{
  1366  		$$ = []*ast.TableToTable{$1.(*ast.TableToTable)}
  1367  	}
  1368  |	TableToTableList ',' TableToTable
  1369  	{
  1370  		$$ = append($1.([]*ast.TableToTable), $3.(*ast.TableToTable))
  1371  	}
  1372  
  1373  TableToTable:
  1374  	TableName "TO" TableName
  1375  	{
  1376  		$$ = &ast.TableToTable{
  1377  			OldTable: $1.(*ast.TableName),
  1378  			NewTable: $3.(*ast.TableName),
  1379  		}
  1380  	}
  1381  
  1382  
  1383  /*******************************************************************************************/
  1384  
  1385  AnalyzeTableStmt:
  1386  	"ANALYZE" "TABLE" TableNameList MaxNumBuckets
  1387  	 {
  1388  		$$ = &ast.AnalyzeTableStmt{TableNames: $3.([]*ast.TableName), MaxNumBuckets: $4.(uint64)}
  1389  	 }
  1390  |	"ANALYZE" "TABLE" TableName "INDEX" IndexNameList MaxNumBuckets
  1391  	{
  1392  		$$ = &ast.AnalyzeTableStmt{TableNames: []*ast.TableName{$3.(*ast.TableName)}, IndexNames: $5.([]model.CIStr), IndexFlag: true, MaxNumBuckets: $6.(uint64)}
  1393  	}
  1394  |	"ANALYZE" "TABLE" TableName "PARTITION" PartitionNameList MaxNumBuckets
  1395  	{
  1396  		$$ = &ast.AnalyzeTableStmt{TableNames: []*ast.TableName{$3.(*ast.TableName)}, PartitionNames: $5.([]model.CIStr), MaxNumBuckets: $6.(uint64),}
  1397  	}
  1398  |	"ANALYZE" "TABLE" TableName "PARTITION" PartitionNameList "INDEX" IndexNameList MaxNumBuckets
  1399  	{
  1400  		$$ = &ast.AnalyzeTableStmt{
  1401  			TableNames: []*ast.TableName{$3.(*ast.TableName)},
  1402  			PartitionNames: $5.([]model.CIStr),
  1403  			IndexNames: $7.([]model.CIStr),
  1404  			IndexFlag: true,
  1405  			MaxNumBuckets: $8.(uint64),
  1406  		}
  1407  	}
  1408  
  1409  MaxNumBuckets:
  1410  	{
  1411  		$$ = uint64(0)
  1412  	}
  1413  |	"WITH" NUM "BUCKETS"
  1414  	{
  1415  		$$ = getUint64FromNUM($2)
  1416  	}
  1417  
  1418  /*******************************************************************************************/
  1419  Assignment:
  1420  	ColumnName eq Expression
  1421  	{
  1422  		$$ = &ast.Assignment{Column: $1.(*ast.ColumnName), Expr:$3}
  1423  	}
  1424  
  1425  AssignmentList:
  1426  	Assignment
  1427  	{
  1428  		$$ = []*ast.Assignment{$1.(*ast.Assignment)}
  1429  	}
  1430  |	AssignmentList ',' Assignment
  1431  	{
  1432  		$$ = append($1.([]*ast.Assignment), $3.(*ast.Assignment))
  1433  	}
  1434  
  1435  AssignmentListOpt:
  1436  	/* EMPTY */
  1437  	{
  1438  		$$ = []*ast.Assignment{}
  1439  	}
  1440  |	AssignmentList
  1441  
  1442  BeginTransactionStmt:
  1443  	"BEGIN"
  1444  	{
  1445  		$$ = &ast.BeginStmt{}
  1446  	}
  1447  |	"START" "TRANSACTION"
  1448  	{
  1449  		$$ = &ast.BeginStmt{}
  1450  	}
  1451  |	"START" "TRANSACTION" "WITH" "CONSISTENT" "SNAPSHOT"
  1452  	{
  1453  		$$ = &ast.BeginStmt{}
  1454  	}
  1455  
  1456  BinlogStmt:
  1457  	"BINLOG" stringLit
  1458  	{
  1459  		$$ = &ast.BinlogStmt{Str: $2}
  1460  	}
  1461  
  1462  ColumnDefList:
  1463  	ColumnDef
  1464  	{
  1465  		$$ = []*ast.ColumnDef{$1.(*ast.ColumnDef)}
  1466  	}
  1467  |	ColumnDefList ',' ColumnDef
  1468  	{
  1469  		$$ = append($1.([]*ast.ColumnDef), $3.(*ast.ColumnDef))
  1470  	}
  1471  
  1472  ColumnDef:
  1473  	ColumnName Type ColumnOptionListOpt
  1474  	{
  1475  		$$ = &ast.ColumnDef{Name: $1.(*ast.ColumnName), Tp: $2.(*types.FieldType), Options: $3.([]*ast.ColumnOption)}
  1476  	}
  1477  
  1478  ColumnName:
  1479  	Identifier
  1480  	{
  1481  		$$ = &ast.ColumnName{Name: model.NewCIStr($1)}
  1482  	}
  1483  |	Identifier '.' Identifier
  1484  	{
  1485  		$$ = &ast.ColumnName{Table: model.NewCIStr($1), Name: model.NewCIStr($3)}
  1486  	}
  1487  |	Identifier '.' Identifier '.' Identifier
  1488  	{
  1489  		$$ = &ast.ColumnName{Schema: model.NewCIStr($1), Table: model.NewCIStr($3), Name: model.NewCIStr($5)}
  1490  	}
  1491  
  1492  ColumnNameList:
  1493  	ColumnName
  1494  	{
  1495  		$$ = []*ast.ColumnName{$1.(*ast.ColumnName)}
  1496  	}
  1497  |	ColumnNameList ',' ColumnName
  1498  	{
  1499  		$$ = append($1.([]*ast.ColumnName), $3.(*ast.ColumnName))
  1500  	}
  1501  
  1502  ColumnNameListOpt:
  1503  	/* EMPTY */
  1504  	{
  1505  		$$ = []*ast.ColumnName{}
  1506  	}
  1507  |	ColumnNameList
  1508  	{
  1509  		$$ = $1.([]*ast.ColumnName)
  1510  	}
  1511  
  1512  ColumnNameListOptWithBrackets:
  1513  	/* EMPTY */
  1514  	{
  1515  		$$ = []*ast.ColumnName{}
  1516  	}
  1517  |	'(' ColumnNameListOpt ')'
  1518  	{
  1519  		$$ = $2.([]*ast.ColumnName)
  1520  	}
  1521  
  1522  CommitOpt:
  1523  	"WORK"
  1524  	{
  1525  		$$ = $1
  1526  	}
  1527  |	"WORK" "AND" "NO" "CHAIN" "NO" "RELEASE"
  1528  	{
  1529  		$$ = ""
  1530  	}
  1531  |	"WORK" "AND" "CHAIN" "NO" "RELEASE"
  1532  	{
  1533  		$$ = ""
  1534  	}
  1535  |	"WORK" "AND" "NO" "CHAIN" "RELEASE"
  1536  	{
  1537  		$$ = ""
  1538  	}
  1539  |	"WORK" "NO" "RELEASE"
  1540  	{
  1541  		$$ = ""
  1542  	}
  1543  |	"WORK" "RELEASE"
  1544  	{
  1545  		$$ = ""
  1546  	}
  1547  |	"AND" "NO" "CHAIN" "NO" "RELEASE"
  1548  	{
  1549  		$$ = ""
  1550  	}
  1551  |	"AND" "CHAIN" "NO" "RELEASE"
  1552  	{
  1553  		$$ = ""
  1554  	}
  1555  |	"AND" "NO" "CHAIN" "RELEASE"
  1556  	{
  1557  		$$ = ""
  1558  	}
  1559  |	"NO" "RELEASE"
  1560  	{
  1561  		$$ = ""
  1562  	}
  1563  |	"RELEASE"
  1564  	{
  1565  		$$ = ""
  1566  	}
  1567  
  1568  CommitStmt:
  1569  	"COMMIT"
  1570  	{
  1571  		$$ = &ast.CommitStmt{}
  1572  	}
  1573  |	"COMMIT" CommitOpt
  1574  	{
  1575  		$$ = &ast.CommitStmt{}
  1576  	}
  1577  
  1578  PrimaryOpt:
  1579  	{}
  1580  | "PRIMARY"
  1581  
  1582  ColumnOption:
  1583  	"NOT" "NULL"
  1584  	{
  1585  		$$ = &ast.ColumnOption{Tp: ast.ColumnOptionNotNull}
  1586  	}
  1587  |	"NULL"
  1588  	{
  1589  		$$ = &ast.ColumnOption{Tp: ast.ColumnOptionNull}
  1590  	}
  1591  |	"AUTO_INCREMENT"
  1592  	{
  1593  		$$ = &ast.ColumnOption{Tp: ast.ColumnOptionAutoIncrement}
  1594  	}
  1595  |	PrimaryOpt "KEY"
  1596  	{
  1597  		// KEY is normally a synonym for INDEX. The key attribute PRIMARY KEY
  1598  		// can also be specified as just KEY when given in a column definition.
  1599  		// See http://dev.mysql.com/doc/refman/5.7/en/create-table.html
  1600  		$$ = &ast.ColumnOption{Tp: ast.ColumnOptionPrimaryKey}
  1601  	}
  1602  |	"UNIQUE" %prec lowerThanKey
  1603  	{
  1604  		$$ = &ast.ColumnOption{Tp: ast.ColumnOptionUniqKey}
  1605  	}
  1606  |	"UNIQUE" "KEY"
  1607  	{
  1608  		$$ = &ast.ColumnOption{Tp: ast.ColumnOptionUniqKey}
  1609  	}
  1610  |	"DEFAULT" DefaultValueExpr
  1611  	{
  1612  		$$ = &ast.ColumnOption{Tp: ast.ColumnOptionDefaultValue, Expr: $2}
  1613  	}
  1614  |	"ON" "UPDATE" NowSymOptionFraction
  1615  	{
  1616  		nowFunc := &ast.FuncCallExpr{FnName: model.NewCIStr("CURRENT_TIMESTAMP")}
  1617  		$$ = &ast.ColumnOption{Tp: ast.ColumnOptionOnUpdate, Expr: nowFunc}
  1618  	}
  1619  |	"COMMENT" stringLit
  1620  	{
  1621  		$$ =  &ast.ColumnOption{Tp: ast.ColumnOptionComment, Expr: ast.NewValueExpr($2)}
  1622  	}
  1623  |	"CHECK" '(' Expression ')'
  1624  	{
  1625  		// See https://dev.mysql.com/doc/refman/5.7/en/create-table.html
  1626  		// The CHECK clause is parsed but ignored by all storage engines.
  1627  		$$ = &ast.ColumnOption{}
  1628  	}
  1629  |	GeneratedAlways "AS" '(' Expression ')' VirtualOrStored
  1630  	{
  1631  		startOffset := parser.startOffset(&yyS[yypt-2])
  1632  		endOffset := parser.endOffset(&yyS[yypt-1])
  1633  		expr := $4
  1634  		expr.SetText(parser.src[startOffset:endOffset])
  1635  
  1636  		$$ = &ast.ColumnOption{
  1637  			Tp: ast.ColumnOptionGenerated,
  1638  			Expr: expr,
  1639  			Stored: $6.(bool),
  1640  		}
  1641  	}
  1642  |	ReferDef
  1643  	{
  1644  		$$ = &ast.ColumnOption{
  1645  			Tp: ast.ColumnOptionReference,
  1646  			Refer: $1.(*ast.ReferenceDef),
  1647  		}
  1648  	}
  1649  
  1650  GeneratedAlways: | "GENERATED" "ALWAYS"
  1651  
  1652  VirtualOrStored:
  1653  	{
  1654  		$$ = false
  1655  	}
  1656  |	"VIRTUAL"
  1657  	{
  1658  		$$ = false
  1659  	}
  1660  |	"STORED"
  1661  	{
  1662  		$$ = true
  1663  	}
  1664  
  1665  ColumnOptionList:
  1666  	ColumnOption
  1667  	{
  1668  		$$ = []*ast.ColumnOption{$1.(*ast.ColumnOption)}
  1669  	}
  1670  |	ColumnOptionList ColumnOption
  1671  	{
  1672  		$$ = append($1.([]*ast.ColumnOption), $2.(*ast.ColumnOption))
  1673  	}
  1674  
  1675  ColumnOptionListOpt:
  1676  	{
  1677  		$$ = []*ast.ColumnOption{}
  1678  	}
  1679  |	ColumnOptionList
  1680  	{
  1681  		$$ = $1.([]*ast.ColumnOption)
  1682  	}
  1683  
  1684  ConstraintElem:
  1685  	"PRIMARY" "KEY" IndexName IndexTypeOpt '(' IndexColNameList ')' IndexOptionList
  1686  	{
  1687  		c := &ast.Constraint{
  1688  			Tp: ast.ConstraintPrimaryKey,
  1689  			Keys: $6.([]*ast.IndexColName),
  1690  		}
  1691  		if $8 != nil {
  1692  			c.Option = $8.(*ast.IndexOption)
  1693  		}
  1694  		if $4 != nil {
  1695  			if c.Option == nil {
  1696  				c.Option = &ast.IndexOption{}
  1697  			}
  1698  			c.Option.Tp = $4.(model.IndexType)
  1699  		}
  1700  		$$ = c
  1701  	}
  1702  |	"FULLTEXT" KeyOrIndexOpt IndexName '(' IndexColNameList ')' IndexOptionList
  1703  	{
  1704  		c := &ast.Constraint{
  1705  			Tp:	ast.ConstraintFulltext,
  1706  			Keys:	$5.([]*ast.IndexColName),
  1707  			Name:	$3.(string),
  1708  		}
  1709  		if $7 != nil {
  1710  			c.Option = $7.(*ast.IndexOption)
  1711  		}
  1712  		$$ = c
  1713  	}
  1714  |	KeyOrIndex IndexName IndexTypeOpt '(' IndexColNameList ')' IndexOptionList
  1715  	{
  1716  		c := &ast.Constraint{
  1717  			Tp:	ast.ConstraintIndex,
  1718  			Keys:	$5.([]*ast.IndexColName),
  1719  			Name:	$2.(string),
  1720  		}
  1721  		if $7 != nil {
  1722  			c.Option = $7.(*ast.IndexOption)
  1723  		}
  1724  		if $3 != nil {
  1725  			if c.Option == nil {
  1726  				c.Option = &ast.IndexOption{}
  1727  			}
  1728  			c.Option.Tp = $3.(model.IndexType)
  1729  		}
  1730  		$$ = c
  1731  	}
  1732  |	"UNIQUE" KeyOrIndexOpt IndexName IndexTypeOpt '(' IndexColNameList ')' IndexOptionList
  1733  	{
  1734  		c := &ast.Constraint{
  1735  			Tp:	ast.ConstraintUniq,
  1736  			Keys:	$6.([]*ast.IndexColName),
  1737  			Name:	$3.(string),
  1738  		}
  1739  		if $8 != nil {
  1740  			c.Option = $8.(*ast.IndexOption)
  1741  		}
  1742  		if $4 != nil {
  1743  			if c.Option == nil {
  1744  				c.Option = &ast.IndexOption{}
  1745  			}
  1746  			c.Option.Tp = $4.(model.IndexType)
  1747  		}
  1748  		$$ = c
  1749  	}
  1750  |	"FOREIGN" "KEY" IndexName '(' IndexColNameList ')' ReferDef
  1751  	{
  1752  		$$ = &ast.Constraint{
  1753  			Tp:	ast.ConstraintForeignKey,
  1754  			Keys:	$5.([]*ast.IndexColName),
  1755  			Name:	$3.(string),
  1756  			Refer:	$7.(*ast.ReferenceDef),
  1757  		}
  1758  	}
  1759  
  1760  ReferDef:
  1761  	"REFERENCES" TableName '(' IndexColNameList ')' OnDeleteOpt OnUpdateOpt
  1762  	{
  1763  		var onDeleteOpt *ast.OnDeleteOpt
  1764  		if $6 != nil {
  1765  			onDeleteOpt = $6.(*ast.OnDeleteOpt)
  1766  		}
  1767  		var onUpdateOpt *ast.OnUpdateOpt
  1768  		if $7 != nil {
  1769  			onUpdateOpt = $7.(*ast.OnUpdateOpt)
  1770  		}
  1771  		$$ = &ast.ReferenceDef{
  1772  			Table: $2.(*ast.TableName),
  1773  			IndexColNames: $4.([]*ast.IndexColName),
  1774  			OnDelete: onDeleteOpt,
  1775  			OnUpdate: onUpdateOpt,
  1776  		}
  1777  	}
  1778  
  1779  OnDeleteOpt:
  1780  	{
  1781  		$$ = &ast.OnDeleteOpt{}
  1782  	} %prec lowerThanOn
  1783  |	"ON" "DELETE" ReferOpt
  1784  	{
  1785  		$$ = &ast.OnDeleteOpt{ReferOpt: $3.(ast.ReferOptionType)}
  1786  	}
  1787  
  1788  OnUpdateOpt:
  1789  	{
  1790  		$$ = &ast.OnUpdateOpt{}
  1791  	} %prec lowerThanOn
  1792  |	"ON" "UPDATE" ReferOpt
  1793  	{
  1794  		$$ = &ast.OnUpdateOpt{ReferOpt: $3.(ast.ReferOptionType)}
  1795  	}
  1796  
  1797  ReferOpt:
  1798  	"RESTRICT"
  1799  	{
  1800  		$$ = ast.ReferOptionRestrict
  1801  	}
  1802  |	"CASCADE"
  1803  	{
  1804  		$$ = ast.ReferOptionCascade
  1805  	}
  1806  |	"SET" "NULL"
  1807  	{
  1808  		$$ = ast.ReferOptionSetNull
  1809  	}
  1810  |	"NO" "ACTION"
  1811  	{
  1812  		$$ = ast.ReferOptionNoAction
  1813  	}
  1814  
  1815  /*
  1816   * The DEFAULT clause specifies a default value for a column.
  1817   * With one exception, the default value must be a constant;
  1818   * it cannot be a function or an expression. This means, for example,
  1819   * that you cannot set the default for a date column to be the value of
  1820   * a function such as NOW() or CURRENT_DATE. The exception is that you
  1821   * can specify CURRENT_TIMESTAMP as the default for a TIMESTAMP or DATETIME column.
  1822   *
  1823   * See http://dev.mysql.com/doc/refman/5.7/en/create-table.html
  1824   *      https://github.com/mysql/mysql-server/blob/5.7/sql/sql_yacc.yy#L6832
  1825   */
  1826  DefaultValueExpr:
  1827  	NowSymOptionFraction | SignedLiteral
  1828  
  1829  NowSymOptionFraction:
  1830  	NowSym
  1831  	{
  1832  		$$ = &ast.FuncCallExpr{FnName: model.NewCIStr("CURRENT_TIMESTAMP")}
  1833  	}
  1834  |	NowSymFunc '(' ')'
  1835  	{
  1836  		$$ = &ast.FuncCallExpr{FnName: model.NewCIStr("CURRENT_TIMESTAMP")}
  1837  	}
  1838  |	NowSymFunc '(' NUM ')'
  1839  	{
  1840  		$$ = &ast.FuncCallExpr{FnName: model.NewCIStr("CURRENT_TIMESTAMP"), Args: []ast.ExprNode{ast.NewValueExpr($3)}}
  1841  	}
  1842  
  1843  /*
  1844  * See https://dev.mysql.com/doc/refman/5.7/en/date-and-time-functions.html#function_localtime
  1845  * TODO: Process other three keywords
  1846  */
  1847  NowSymFunc:
  1848  	"CURRENT_TIMESTAMP" | "LOCALTIME" | "LOCALTIMESTAMP" | builtinNow
  1849  NowSym:
  1850  	"CURRENT_TIMESTAMP" | "LOCALTIME" | "LOCALTIMESTAMP"
  1851  
  1852  
  1853  SignedLiteral:
  1854  	Literal
  1855  	{
  1856  		$$ = ast.NewValueExpr($1)
  1857  	}
  1858  |	'+' NumLiteral
  1859  	{
  1860  		$$ = &ast.UnaryOperationExpr{Op: opcode.Plus, V: ast.NewValueExpr($2)}
  1861  	}
  1862  |	'-' NumLiteral
  1863  	{
  1864  		$$ = &ast.UnaryOperationExpr{Op: opcode.Minus, V: ast.NewValueExpr($2)}
  1865  	}
  1866  
  1867  NumLiteral:
  1868  	intLit
  1869  |	floatLit
  1870  |	decLit
  1871  
  1872  
  1873  CreateIndexStmt:
  1874  	"CREATE" CreateIndexStmtUnique "INDEX" Identifier IndexTypeOpt "ON" TableName '(' IndexColNameList ')' IndexOptionList LockClauseOpt
  1875  	{
  1876  		var indexOption *ast.IndexOption
  1877  		if $11 != nil {
  1878  			indexOption = $11.(*ast.IndexOption)
  1879  			if indexOption.Tp == model.IndexTypeInvalid {
  1880  				if $5 != nil {
  1881  					indexOption.Tp = $5.(model.IndexType)
  1882  				}
  1883  			}
  1884  		} else {
  1885  			indexOption = &ast.IndexOption{}
  1886  			if $5 != nil {
  1887  				indexOption.Tp = $5.(model.IndexType)
  1888  			}
  1889  		}
  1890  		$$ = &ast.CreateIndexStmt{
  1891  			Unique:        $2.(bool),
  1892  			IndexName:     $4,
  1893  			Table:         $7.(*ast.TableName),
  1894  			IndexColNames: $9.([]*ast.IndexColName),
  1895  			IndexOption:   indexOption,
  1896  		}
  1897  	}
  1898  
  1899  CreateIndexStmtUnique:
  1900  	{
  1901  		$$ = false
  1902  	}
  1903  |	"UNIQUE"
  1904  	{
  1905  		$$ = true
  1906  	}
  1907  
  1908  IndexColName:
  1909  	ColumnName OptFieldLen Order
  1910  	{
  1911  		//Order is parsed but just ignored as MySQL did
  1912  		$$ = &ast.IndexColName{Column: $1.(*ast.ColumnName), Length: $2.(int)}
  1913  	}
  1914  
  1915  IndexColNameList:
  1916  	IndexColName
  1917  	{
  1918  		$$ = []*ast.IndexColName{$1.(*ast.IndexColName)}
  1919  	}
  1920  |	IndexColNameList ',' IndexColName
  1921  	{
  1922  		$$ = append($1.([]*ast.IndexColName), $3.(*ast.IndexColName))
  1923  	}
  1924  
  1925  
  1926  
  1927  /*******************************************************************
  1928   *
  1929   *  Create Database Statement
  1930   *  CREATE {DATABASE | SCHEMA} [IF NOT EXISTS] db_name
  1931   *      [create_specification] ...
  1932   *
  1933   *  create_specification:
  1934   *      [DEFAULT] CHARACTER SET [=] charset_name
  1935   *    | [DEFAULT] COLLATE [=] collation_name
  1936   *******************************************************************/
  1937  CreateDatabaseStmt:
  1938  	"CREATE" DatabaseSym IfNotExists DBName DatabaseOptionListOpt
  1939  	{
  1940  		$$ = &ast.CreateDatabaseStmt{
  1941  			IfNotExists:	$3.(bool),
  1942  			Name:		$4.(string),
  1943  			Options:	$5.([]*ast.DatabaseOption),
  1944  		}
  1945  	}
  1946  
  1947  DBName:
  1948  	Identifier
  1949  	{
  1950  		$$ = $1
  1951  	}
  1952  
  1953  DatabaseOption:
  1954  	DefaultKwdOpt CharsetKw EqOpt CharsetName
  1955  	{
  1956  		$$ = &ast.DatabaseOption{Tp: ast.DatabaseOptionCharset, Value: $4.(string)}
  1957  	}
  1958  |	DefaultKwdOpt "COLLATE" EqOpt StringName
  1959  	{
  1960  		$$ = &ast.DatabaseOption{Tp: ast.DatabaseOptionCollate, Value: $4.(string)}
  1961  	}
  1962  
  1963  DatabaseOptionListOpt:
  1964  	{
  1965  		$$ = []*ast.DatabaseOption{}
  1966  	}
  1967  |	DatabaseOptionList
  1968  
  1969  DatabaseOptionList:
  1970  	DatabaseOption
  1971  	{
  1972  		$$ = []*ast.DatabaseOption{$1.(*ast.DatabaseOption)}
  1973  	}
  1974  |	DatabaseOptionList DatabaseOption
  1975  	{
  1976  		$$ = append($1.([]*ast.DatabaseOption), $2.(*ast.DatabaseOption))
  1977  	}
  1978  
  1979  /*******************************************************************
  1980   *
  1981   *  Create Table Statement
  1982   *
  1983   *  Example:
  1984   *      CREATE TABLE Persons
  1985   *      (
  1986   *          P_Id int NOT NULL,
  1987   *          LastName varchar(255) NOT NULL,
  1988   *          FirstName varchar(255),
  1989   *          Address varchar(255),
  1990   *          City varchar(255),
  1991   *          PRIMARY KEY (P_Id)
  1992   *      )
  1993   *******************************************************************/
  1994  
  1995  CreateTableStmt:
  1996  	"CREATE" "TABLE" IfNotExists TableName TableElementListOpt CreateTableOptionListOpt PartitionOpt DuplicateOpt AsOpt CreateTableSelectOpt
  1997  	{
  1998  		stmt := $5.(*ast.CreateTableStmt)
  1999  		stmt.Table = $4.(*ast.TableName)
  2000  		stmt.IfNotExists = $3.(bool)
  2001  		stmt.Options = $6.([]*ast.TableOption)
  2002  		if $7 != nil {
  2003  			stmt.Partition = $7.(*ast.PartitionOptions)
  2004  		}
  2005  		stmt.OnDuplicate = $8.(ast.OnDuplicateCreateTableSelectType)
  2006  		stmt.Select = $10.(*ast.CreateTableStmt).Select
  2007  		$$ = stmt
  2008  	}
  2009  |	"CREATE" "TABLE" IfNotExists TableName LikeTableWithOrWithoutParen
  2010  	{
  2011  		$$ = &ast.CreateTableStmt{
  2012  			Table:          $4.(*ast.TableName),
  2013  			ReferTable:	$5.(*ast.TableName),
  2014  			IfNotExists:    $3.(bool),
  2015  		}
  2016  	}
  2017  
  2018  DefaultKwdOpt:
  2019  	{}
  2020  |	"DEFAULT"
  2021  
  2022  PartitionOpt:
  2023  	{
  2024  		$$ = nil
  2025  	}
  2026  |	"PARTITION" "BY" "KEY" '(' ColumnNameList ')' PartitionNumOpt PartitionDefinitionListOpt
  2027  	{
  2028  		$$ = nil
  2029  	}
  2030  |	"PARTITION" "BY" "HASH" '(' Expression ')' PartitionNumOpt
  2031  	{
  2032  		tmp := &ast.PartitionOptions{
  2033  			Tp: model.PartitionTypeHash,
  2034  			Expr: $5.(ast.ExprNode),
  2035  			// If you do not include a PARTITIONS clause, the number of partitions defaults to 1
  2036  			Num: 1,
  2037  		}
  2038  		if $7 != nil {
  2039  			tmp.Num = getUint64FromNUM($7)
  2040  		}
  2041  		$$ = tmp
  2042  	}
  2043  |	"PARTITION" "BY" "RANGE" '(' Expression ')' PartitionNumOpt SubPartitionOpt PartitionDefinitionListOpt
  2044  	{
  2045  		var defs []*ast.PartitionDefinition
  2046  		if $9 != nil {
  2047  			defs = $9.([]*ast.PartitionDefinition)
  2048  		}
  2049  		$$ = &ast.PartitionOptions{
  2050  			Tp:		model.PartitionTypeRange,
  2051  			Expr:		$5.(ast.ExprNode),
  2052  			Definitions:	defs,
  2053  		}
  2054  	}
  2055  |	"PARTITION" "BY" "RANGE" "COLUMNS" '(' ColumnNameList ')' PartitionNumOpt PartitionDefinitionListOpt
  2056  	{
  2057  		var defs []*ast.PartitionDefinition
  2058  		if $9 != nil {
  2059  			defs = $9.([]*ast.PartitionDefinition)
  2060  		}
  2061  		$$ = &ast.PartitionOptions{
  2062  			Tp:		model.PartitionTypeRange,
  2063  			ColumnNames:	$6.([]*ast.ColumnName),
  2064  			Definitions:	defs,
  2065  		}
  2066  	}
  2067  
  2068  SubPartitionOpt:
  2069  	{}
  2070  |	"SUBPARTITION" "BY" "HASH" '(' Expression ')' SubPartitionNumOpt
  2071  	{}
  2072  |	"SUBPARTITION" "BY" "KEY" '(' ColumnNameList ')' SubPartitionNumOpt
  2073  	{}
  2074  
  2075  SubPartitionNumOpt:
  2076  	{}
  2077  |	"SUBPARTITIONS" NUM
  2078  	{}
  2079  
  2080  PartitionNumOpt:
  2081  	{
  2082  		$$ = nil
  2083  	}
  2084  |	"PARTITIONS" NUM
  2085  	{
  2086  		$$ = $2
  2087  	}
  2088  
  2089  PartitionDefinitionListOpt:
  2090  	/* empty */ %prec lowerThanCreateTableSelect
  2091  	{
  2092  		$$ = nil
  2093  	}
  2094  |	'(' PartitionDefinitionList ')'
  2095  	{
  2096  		$$ = $2.([]*ast.PartitionDefinition)
  2097  	}
  2098  
  2099  PartitionDefinitionList:
  2100  	PartitionDefinition
  2101  	{
  2102  		$$ = []*ast.PartitionDefinition{$1.(*ast.PartitionDefinition)}
  2103  	}
  2104  |	PartitionDefinitionList ',' PartitionDefinition
  2105  	{
  2106  		$$ = append($1.([]*ast.PartitionDefinition), $3.(*ast.PartitionDefinition))
  2107  	}
  2108  
  2109  PartitionDefinition:
  2110  	"PARTITION" Identifier PartDefValuesOpt PartDefOptionsOpt
  2111  	{
  2112  		partDef := &ast.PartitionDefinition{
  2113  			Name: model.NewCIStr($2),
  2114  		}
  2115  		switch $3.(type) {
  2116  		case []ast.ExprNode:
  2117  			partDef.LessThan = $3.([]ast.ExprNode)
  2118  		case ast.ExprNode:
  2119  			partDef.LessThan = make([]ast.ExprNode, 1)
  2120  			partDef.LessThan[0] = $3.(ast.ExprNode)
  2121  		}
  2122  
  2123  		if comment, ok := $4.(string); ok {
  2124  			partDef.Comment = comment
  2125  		}
  2126  		$$ = partDef
  2127  	}
  2128  
  2129  PartDefOptionsOpt:
  2130  	{
  2131  		$$ = nil
  2132  	}
  2133  |	PartDefOptionList
  2134  	{
  2135  		$$ = $1
  2136  	}
  2137  
  2138  PartDefOptionList:
  2139  	PartDefOption
  2140  	{
  2141  		$$ = $1
  2142  	}
  2143  |	PartDefOptionList PartDefOption
  2144  	{
  2145  		if $1 != nil {
  2146  			$$ = $1
  2147  		} else {
  2148  			$$ = $2
  2149  		}
  2150  	}
  2151  
  2152  PartDefOption:
  2153  	"COMMENT" EqOpt stringLit
  2154  	{
  2155  		$$ = $3
  2156  	}
  2157  |	"ENGINE" EqOpt Identifier
  2158  	{
  2159  		$$ = nil
  2160  	}
  2161  |	"TABLESPACE" EqOpt Identifier
  2162  	{
  2163  		$$ =  nil
  2164  	}
  2165  
  2166  
  2167  PartDefValuesOpt:
  2168  	{
  2169  		$$ = nil
  2170  	}
  2171  |	"VALUES" "LESS" "THAN" "MAXVALUE"
  2172  	{
  2173  		$$ = &ast.MaxValueExpr{}
  2174  	}
  2175  |	"VALUES" "LESS" "THAN" '(' MaxValueOrExpressionList ')'
  2176  	{
  2177  		$$ = $5
  2178  	}
  2179  
  2180  DuplicateOpt:
  2181  	{
  2182  		$$ = ast.OnDuplicateCreateTableSelectError
  2183  	}
  2184  |   "IGNORE"
  2185  	{
  2186  		$$ = ast.OnDuplicateCreateTableSelectIgnore
  2187  	}
  2188  |   "REPLACE"
  2189  	{
  2190  		$$ = ast.OnDuplicateCreateTableSelectReplace
  2191  	}
  2192  
  2193  AsOpt:
  2194  	{}
  2195  |	"AS"
  2196  	{}
  2197  
  2198  CreateTableSelectOpt:
  2199  	/* empty */
  2200  	{
  2201  		$$ = &ast.CreateTableStmt{}
  2202  	}
  2203  |
  2204  	SelectStmt
  2205  	{
  2206  		$$ = &ast.CreateTableStmt{Select: $1}
  2207  	}
  2208  |
  2209  	UnionStmt
  2210  	{
  2211  		$$ = &ast.CreateTableStmt{Select: $1}
  2212  	}
  2213  |
  2214  	SubSelect %prec createTableSelect
  2215  	// TODO: We may need better solution as issue #320.
  2216  	{
  2217  		$$ = &ast.CreateTableStmt{Select: $1}
  2218  	}
  2219  
  2220  LikeTableWithOrWithoutParen:
  2221  	"LIKE" TableName
  2222  	{
  2223  		$$ = $2
  2224  	}
  2225  |
  2226  	'(' "LIKE" TableName ')'
  2227  	{
  2228  		$$ = $3
  2229  	}
  2230  
  2231  /*******************************************************************
  2232   *
  2233   *  Create View Statement
  2234   *
  2235   *  Example:
  2236   *      CREATE VIEW OR REPLACE ALGORITHM = MERGE DEFINER="root@localhost" SQL SECURITY = definer view_name (col1,col2)
  2237   *          as select Col1,Col2 from table WITH LOCAL CHECK OPTION
  2238   *******************************************************************/
  2239  CreateViewStmt:
  2240      "CREATE" OrReplace ViewAlgorithm ViewDefiner ViewSQLSecurity "VIEW" ViewName ViewFieldList "AS" SelectStmt ViewCheckOption
  2241      {
  2242  		startOffset := parser.startOffset(&yyS[yypt-1])
  2243  		selStmt := $10.(*ast.SelectStmt)
  2244  		selStmt.SetText(strings.TrimSpace(parser.src[startOffset:]))
  2245  		x := &ast.CreateViewStmt {
  2246   			OrReplace:     $2.(bool),
  2247  			ViewName:      $7.(*ast.TableName),
  2248  			Select:        selStmt,
  2249  			Algorithm:     $3.(model.ViewAlgorithm),
  2250  			Definer:       $4.(*auth.UserIdentity),
  2251  			Security:      $5.(model.ViewSecurity),
  2252  		}
  2253  		if $8 != nil{
  2254  			x.Cols = $8.([]model.CIStr)
  2255  		}
  2256  		if $11 !=nil {
  2257  		    x.CheckOption = $11.(model.ViewCheckOption)
  2258  		    endOffset := parser.startOffset(&yyS[yypt])
  2259  		    selStmt.SetText(strings.TrimSpace(parser.src[startOffset:endOffset]))
  2260  		} else {
  2261  		    x.CheckOption = model.CheckOptionCascaded
  2262  		}
  2263  		$$ = x
  2264  	}
  2265  
  2266  OrReplace:
  2267  	{
  2268  		$$ = false
  2269  	}
  2270  |	"OR" "REPLACE"
  2271  	{
  2272  		$$ = true
  2273  	}
  2274  
  2275  ViewAlgorithm:
  2276  	/* EMPTY */
  2277  	{
  2278  		$$ = model.AlgorithmUndefined
  2279  	}
  2280  |	"ALGORITHM" "=" "UNDEFINED"
  2281  	{
  2282  		$$ = model.AlgorithmUndefined
  2283  	}
  2284  |	"ALGORITHM" "=" "MERGE"
  2285  	{
  2286  		$$ = model.AlgorithmMerge
  2287  	}
  2288  |	"ALGORITHM" "=" "TEMPTABLE"
  2289  	{
  2290  		$$ = model.AlgorithmTemptable
  2291  	}
  2292  
  2293  ViewDefiner:
  2294  	/* EMPTY */
  2295  	{
  2296  		$$ = &auth.UserIdentity{CurrentUser: true}
  2297  	}
  2298  |   "DEFINER" "=" Username
  2299  	{
  2300  		$$ = $3
  2301  	}
  2302  
  2303  ViewSQLSecurity:
  2304  	/* EMPTY */
  2305  	{
  2306  		$$ = model.SecurityDefiner
  2307  	}
  2308  |   "SQL" "SECURITY" "DEFINER"
  2309  	 {
  2310  		 $$ = model.SecurityDefiner
  2311  	 }
  2312  |   "SQL" "SECURITY" "INVOKER"
  2313  	 {
  2314  		 $$ = model.SecurityInvoker
  2315  	 }
  2316  
  2317  ViewName:
  2318  	TableName
  2319  	{
  2320  		$$ = $1.(*ast.TableName)
  2321  	}
  2322  
  2323  ViewFieldList:
  2324  	/* Empty */
  2325  	{
  2326  		$$ = nil
  2327  	}
  2328  |   '(' ColumnList ')'
  2329  	{
  2330  		$$ = $2.([]model.CIStr)
  2331  	}
  2332  
  2333  ColumnList:
  2334  	Identifier
  2335  	{
  2336  		$$ = []model.CIStr{model.NewCIStr($1)}
  2337  	}
  2338  |   ColumnList ',' Identifier
  2339  	{
  2340  	$$ = append($1.([]model.CIStr), model.NewCIStr($3))
  2341  	}
  2342  
  2343  ViewCheckOption:
  2344  	/* EMPTY */
  2345  	{
  2346  		$$ = nil
  2347  	}
  2348  |   "WITH" "CASCADED" "CHECK" "OPTION"
  2349  	{
  2350  		$$ = model.CheckOptionCascaded
  2351  	}
  2352  |   "WITH" "LOCAL" "CHECK" "OPTION"
  2353  	{
  2354  		$$ = model.CheckOptionLocal
  2355  	}
  2356  
  2357  /******************************************************************
  2358   * Do statement
  2359   * See https://dev.mysql.com/doc/refman/5.7/en/do.html
  2360   ******************************************************************/
  2361  DoStmt:
  2362  	"DO" ExpressionList
  2363  	{
  2364  		$$ = &ast.DoStmt {
  2365  			Exprs: $2.([]ast.ExprNode),
  2366  		}
  2367  	}
  2368  
  2369  /*******************************************************************
  2370   *
  2371   *  Delete Statement
  2372   *
  2373   *******************************************************************/
  2374  DeleteFromStmt:
  2375  	"DELETE" TableOptimizerHints PriorityOpt QuickOptional IgnoreOptional "FROM" TableName IndexHintListOpt WhereClauseOptional OrderByOptional LimitClause
  2376  	{
  2377  		// Single Table
  2378  		tn := $7.(*ast.TableName)
  2379  		tn.IndexHints = $8.([]*ast.IndexHint)
  2380  		join := &ast.Join{Left: &ast.TableSource{Source: tn}, Right: nil}
  2381  		x := &ast.DeleteStmt{
  2382  			TableRefs: &ast.TableRefsClause{TableRefs: join},
  2383  			Priority:  $3.(mysql.PriorityEnum),
  2384  			Quick:	   $4.(bool),
  2385  			IgnoreErr: $5.(bool),
  2386  		}
  2387  		if $9 != nil {
  2388  			x.Where = $9.(ast.ExprNode)
  2389  		}
  2390  		if $10 != nil {
  2391  			x.Order = $10.(*ast.OrderByClause)
  2392  		}
  2393  		if $11 != nil {
  2394  			x.Limit = $11.(*ast.Limit)
  2395  		}
  2396  
  2397  		$$ = x
  2398  	}
  2399  |	"DELETE" TableOptimizerHints PriorityOpt QuickOptional IgnoreOptional TableNameList "FROM" TableRefs WhereClauseOptional
  2400  	{
  2401  		// Multiple Table
  2402  		x := &ast.DeleteStmt{
  2403  			Priority:	  $3.(mysql.PriorityEnum),
  2404  			Quick:		  $4.(bool),
  2405  			IgnoreErr:	  $5.(bool),
  2406  			IsMultiTable: 	  true,
  2407  			BeforeFrom:	  true,
  2408  			Tables:		  &ast.DeleteTableList{Tables: $6.([]*ast.TableName)},
  2409  			TableRefs:	  &ast.TableRefsClause{TableRefs: $8.(*ast.Join)},
  2410  		}
  2411  		if $2 != nil {
  2412  			x.TableHints = $2.([]*ast.TableOptimizerHint)
  2413  		}
  2414  		if $9 != nil {
  2415  			x.Where = $9.(ast.ExprNode)
  2416  		}
  2417  		$$ = x
  2418  	}
  2419  
  2420  |	"DELETE" TableOptimizerHints PriorityOpt QuickOptional IgnoreOptional "FROM" TableNameList "USING" TableRefs WhereClauseOptional
  2421  	{
  2422  		// Multiple Table
  2423  		x := &ast.DeleteStmt{
  2424  			Priority:	  $3.(mysql.PriorityEnum),
  2425  			Quick:		  $4.(bool),
  2426  			IgnoreErr:	  $5.(bool),
  2427  			IsMultiTable:	  true,
  2428  			Tables:		  &ast.DeleteTableList{Tables: $7.([]*ast.TableName)},
  2429  			TableRefs:	  &ast.TableRefsClause{TableRefs: $9.(*ast.Join)},
  2430  		}
  2431  		if $2 != nil {
  2432  			x.TableHints = $2.([]*ast.TableOptimizerHint)
  2433  		}
  2434  		if $10 != nil {
  2435  			x.Where = $10.(ast.ExprNode)
  2436  		}
  2437  		$$ = x
  2438  	}
  2439  
  2440  DatabaseSym:
  2441  "DATABASE"
  2442  
  2443  DropDatabaseStmt:
  2444  	"DROP" DatabaseSym IfExists DBName
  2445  	{
  2446  		$$ = &ast.DropDatabaseStmt{IfExists: $3.(bool), Name: $4.(string)}
  2447  	}
  2448  
  2449  DropIndexStmt:
  2450  	"DROP" "INDEX" IfExists Identifier "ON" TableName
  2451  	{
  2452  		$$ = &ast.DropIndexStmt{IfExists: $3.(bool), IndexName: $4, Table: $6.(*ast.TableName)}
  2453  	}
  2454  
  2455  DropTableStmt:
  2456  	"DROP" TableOrTables TableNameList RestrictOrCascadeOpt
  2457  	{
  2458  		$$ = &ast.DropTableStmt{Tables: $3.([]*ast.TableName), IsView: false}
  2459  	}
  2460  |	"DROP" TableOrTables "IF" "EXISTS" TableNameList RestrictOrCascadeOpt
  2461  	{
  2462  		$$ = &ast.DropTableStmt{IfExists: true, Tables: $5.([]*ast.TableName), IsView: false}
  2463  	}
  2464  
  2465  DropViewStmt:
  2466  	"DROP" "VIEW" TableNameList RestrictOrCascadeOpt
  2467  	{
  2468  		$$ = &ast.DropTableStmt{Tables: $3.([]*ast.TableName), IsView: true}
  2469  	}
  2470  |
  2471  	"DROP" "VIEW" "IF" "EXISTS" TableNameList RestrictOrCascadeOpt
  2472  	{
  2473  		$$ = &ast.DropTableStmt{IfExists: true, Tables: $5.([]*ast.TableName), IsView: true}
  2474  	}
  2475  
  2476  DropUserStmt:
  2477  	"DROP" "USER" UsernameList
  2478  	{
  2479  		$$ = &ast.DropUserStmt{IfExists: false, UserList: $3.([]*auth.UserIdentity)}
  2480  	}
  2481  |	"DROP" "USER" "IF" "EXISTS" UsernameList
  2482  	{
  2483  		$$ = &ast.DropUserStmt{IfExists: true, UserList: $5.([]*auth.UserIdentity)}
  2484  	}
  2485  
  2486  DropRoleStmt:
  2487  	"DROP" "ROLE" RolenameList
  2488  	{
  2489  	}
  2490  |	"DROP" "ROLE" "IF" "EXISTS" RolenameList
  2491  	{
  2492  	}
  2493  
  2494  DropStatsStmt:
  2495  	"DROP" "STATS" TableName
  2496  	{
  2497  		$$ = &ast.DropStatsStmt{Table: $3.(*ast.TableName)}
  2498  	}
  2499  
  2500  RestrictOrCascadeOpt:
  2501  	{}
  2502  |	"RESTRICT"
  2503  |	"CASCADE"
  2504  
  2505  TableOrTables:
  2506  	"TABLE"
  2507  |	"TABLES"
  2508  
  2509  EqOpt:
  2510  	{}
  2511  |	eq
  2512  
  2513  EmptyStmt:
  2514  	/* EMPTY */
  2515  	{
  2516  		$$ = nil
  2517  	}
  2518  
  2519  TraceStmt:
  2520  	"TRACE" TraceableStmt
  2521  	{
  2522  		$$ = &ast.TraceStmt{
  2523  			Stmt:	$2,
  2524  			Format: "json",
  2525  		}
  2526  		startOffset := parser.startOffset(&yyS[yypt])
  2527  		$2.SetText(string(parser.src[startOffset:]))
  2528  	}
  2529  |	"TRACE" "FORMAT" "=" stringLit TraceableStmt
  2530  	{
  2531  		$$ = &ast.TraceStmt{
  2532  			Stmt: $5,
  2533  			Format: $4,
  2534  		}
  2535  		startOffset := parser.startOffset(&yyS[yypt])
  2536  		$5.SetText(string(parser.src[startOffset:]))
  2537  	}
  2538  
  2539  ExplainSym:
  2540  "EXPLAIN" | "DESCRIBE" | "DESC"
  2541  
  2542  ExplainStmt:
  2543  	ExplainSym TableName
  2544  	{
  2545  		$$ = &ast.ExplainStmt{
  2546  			Stmt: &ast.ShowStmt{
  2547  				Tp:	ast.ShowColumns,
  2548  				Table:	$2.(*ast.TableName),
  2549  			},
  2550  		}
  2551  	}
  2552  |	ExplainSym TableName ColumnName
  2553  	{
  2554  		$$ = &ast.ExplainStmt{
  2555  			Stmt: &ast.ShowStmt{
  2556  				Tp:	ast.ShowColumns,
  2557  				Table:	$2.(*ast.TableName),
  2558  				Column:	$3.(*ast.ColumnName),
  2559  			},
  2560  		}
  2561  	}
  2562  |	ExplainSym ExplainableStmt
  2563  	{
  2564  		$$ = &ast.ExplainStmt{
  2565  			Stmt:	$2,
  2566  			Format: "row",
  2567  		}
  2568  	}
  2569  |	ExplainSym "FORMAT" "=" stringLit ExplainableStmt
  2570  	{
  2571  		$$ = &ast.ExplainStmt{
  2572  			Stmt:	$5,
  2573  			Format: $4,
  2574  		}
  2575  	}
  2576  |   ExplainSym "ANALYZE" ExplainableStmt
  2577      {
  2578          $$ = &ast.ExplainStmt {
  2579              Stmt:   $3,
  2580              Format: "row",
  2581              Analyze: true,
  2582          }
  2583      }
  2584  
  2585  LengthNum:
  2586  	NUM
  2587  	{
  2588  		$$ = getUint64FromNUM($1)
  2589  	}
  2590  
  2591  NUM:
  2592  	intLit
  2593  
  2594  Expression:
  2595  	singleAtIdentifier assignmentEq Expression %prec assignmentEq
  2596  	{
  2597  		v := $1
  2598  		v = strings.TrimPrefix(v, "@")
  2599  		$$ = &ast.VariableExpr{
  2600  				Name: 	  v,
  2601  				IsGlobal: false,
  2602  				IsSystem: false,
  2603  				Value:	  $3,
  2604  		}
  2605  	}
  2606  |	Expression logOr Expression %prec pipes
  2607  	{
  2608  		$$ = &ast.BinaryOperationExpr{Op: opcode.LogicOr, L: $1, R: $3}
  2609  	}
  2610  |	Expression "XOR" Expression %prec xor
  2611  	{
  2612  		$$ = &ast.BinaryOperationExpr{Op: opcode.LogicXor, L: $1, R: $3}
  2613  	}
  2614  |	Expression logAnd Expression %prec andand
  2615  	{
  2616  		$$ = &ast.BinaryOperationExpr{Op: opcode.LogicAnd, L: $1, R: $3}
  2617  	}
  2618  |	"NOT" Expression %prec not
  2619  	{
  2620  		expr, ok := $2.(*ast.ExistsSubqueryExpr)
  2621  		if ok {
  2622  			expr.Not = true
  2623  			$$ = $2
  2624  		} else {
  2625  			$$ = &ast.UnaryOperationExpr{Op: opcode.Not, V: $2}
  2626  		}
  2627  	}
  2628  |	BoolPri IsOrNotOp trueKwd %prec is
  2629  	{
  2630  		$$ = &ast.IsTruthExpr{Expr:$1, Not: !$2.(bool), True: int64(1)}
  2631  	}
  2632  |	BoolPri IsOrNotOp falseKwd %prec is
  2633  	{
  2634  		$$ = &ast.IsTruthExpr{Expr:$1, Not: !$2.(bool), True: int64(0)}
  2635  	}
  2636  |	BoolPri IsOrNotOp "UNKNOWN" %prec is
  2637  	{
  2638  		/* https://dev.mysql.com/doc/refman/5.7/en/comparison-operators.html#operator_is */
  2639  		$$ = &ast.IsNullExpr{Expr: $1, Not: !$2.(bool)}
  2640  	}
  2641  |	BoolPri
  2642  
  2643  MaxValueOrExpression:
  2644  	"MAXVALUE"
  2645  	{
  2646  		$$ = &ast.MaxValueExpr{}
  2647  	}
  2648  |	Expression
  2649  	{
  2650  		$$ = $1
  2651  	}
  2652  
  2653  
  2654  logOr:
  2655  	pipesAsOr
  2656  |	"OR"
  2657  
  2658  logAnd:
  2659  "&&" | "AND"
  2660  
  2661  ExpressionList:
  2662  	Expression
  2663  	{
  2664  		$$ = []ast.ExprNode{$1}
  2665  	}
  2666  |	ExpressionList ',' Expression
  2667  	{
  2668  		$$ = append($1.([]ast.ExprNode), $3)
  2669  	}
  2670  
  2671  MaxValueOrExpressionList:
  2672  	MaxValueOrExpression
  2673  	{
  2674  		$$ = []ast.ExprNode{$1}
  2675  }
  2676  |	MaxValueOrExpressionList ',' MaxValueOrExpression
  2677  {
  2678  		$$ = append($1.([]ast.ExprNode), $3)
  2679  	}
  2680  
  2681  
  2682  ExpressionListOpt:
  2683  	{
  2684  		$$ = []ast.ExprNode{}
  2685  	}
  2686  |	ExpressionList
  2687  
  2688  FuncDatetimePrecListOpt:
  2689  	{
  2690  		$$ = []ast.ExprNode{}
  2691  	}
  2692  |	FuncDatetimePrecList
  2693  	{
  2694  		$$ = $1
  2695  	}
  2696  
  2697  FuncDatetimePrecList:
  2698  	intLit
  2699  	{
  2700  		expr := ast.NewValueExpr($1)
  2701  		$$ = []ast.ExprNode{expr}
  2702  	}
  2703  
  2704  BoolPri:
  2705  	BoolPri IsOrNotOp "NULL" %prec is
  2706  	{
  2707  		$$ = &ast.IsNullExpr{Expr: $1, Not: !$2.(bool)}
  2708  	}
  2709  |	BoolPri CompareOp PredicateExpr %prec eq
  2710  	{
  2711  		$$ = &ast.BinaryOperationExpr{Op: $2.(opcode.Op), L: $1, R: $3}
  2712  	}
  2713  |	BoolPri CompareOp AnyOrAll SubSelect %prec eq
  2714  	{
  2715  		sq := $4.(*ast.SubqueryExpr)
  2716  		sq.MultiRows = true
  2717  		$$ = &ast.CompareSubqueryExpr{Op: $2.(opcode.Op), L: $1, R: sq, All: $3.(bool)}
  2718  	}
  2719  |	BoolPri CompareOp singleAtIdentifier assignmentEq PredicateExpr %prec assignmentEq
  2720  	{
  2721  		v := $3
  2722  		v = strings.TrimPrefix(v, "@")
  2723  		variable := &ast.VariableExpr{
  2724  				Name: 	  v,
  2725  				IsGlobal: false,
  2726  				IsSystem: false,
  2727  				Value:	  $5,
  2728  		}
  2729  		$$ = &ast.BinaryOperationExpr{Op: $2.(opcode.Op), L: $1, R: variable}
  2730  	}
  2731  |	PredicateExpr
  2732  
  2733  CompareOp:
  2734  	">="
  2735  	{
  2736  		$$ = opcode.GE
  2737  	}
  2738  |	'>'
  2739  	{
  2740  		$$ = opcode.GT
  2741  	}
  2742  |	"<="
  2743  	{
  2744  		$$ = opcode.LE
  2745  	}
  2746  |	'<'
  2747  	{
  2748  		$$ = opcode.LT
  2749  	}
  2750  |	"!="
  2751  	{
  2752  		$$ = opcode.NE
  2753  	}
  2754  |	"<>"
  2755  	{
  2756  		$$ = opcode.NE
  2757  	}
  2758  |	"="
  2759  	{
  2760  		$$ = opcode.EQ
  2761  	}
  2762  |	"<=>"
  2763  	{
  2764  		$$ = opcode.NullEQ
  2765  	}
  2766  
  2767  BetweenOrNotOp:
  2768  	"BETWEEN"
  2769  	{
  2770  		$$ = true
  2771  	}
  2772  |	"NOT" "BETWEEN"
  2773  	{
  2774  		$$ = false
  2775  	}
  2776  
  2777  IsOrNotOp:
  2778  	"IS"
  2779  	{
  2780  		$$ = true
  2781  	}
  2782  |	"IS" "NOT"
  2783  	{
  2784  		$$ = false
  2785  	}
  2786  
  2787  InOrNotOp:
  2788  	"IN"
  2789  	{
  2790  		$$ = true
  2791  	}
  2792  |	"NOT" "IN"
  2793  	{
  2794  		$$ = false
  2795  	}
  2796  
  2797  LikeOrNotOp:
  2798  	"LIKE"
  2799  	{
  2800  		$$ = true
  2801  	}
  2802  |	"NOT" "LIKE"
  2803  	{
  2804  		$$ = false
  2805  	}
  2806  
  2807  RegexpOrNotOp:
  2808  	RegexpSym
  2809  	{
  2810  		$$ = true
  2811  	}
  2812  |	"NOT" RegexpSym
  2813  	{
  2814  		$$ = false
  2815  	}
  2816  
  2817  AnyOrAll:
  2818  	"ANY"
  2819  	{
  2820  		$$ = false
  2821  	}
  2822  |	"SOME"
  2823  	{
  2824  		$$ = false
  2825  	}
  2826  |	"ALL"
  2827  	{
  2828  		$$ = true
  2829  	}
  2830  
  2831  PredicateExpr:
  2832  	BitExpr InOrNotOp '(' ExpressionList ')'
  2833  	{
  2834  		$$ = &ast.PatternInExpr{Expr: $1, Not: !$2.(bool), List: $4.([]ast.ExprNode)}
  2835  	}
  2836  |	BitExpr InOrNotOp SubSelect
  2837  	{
  2838  		sq := $3.(*ast.SubqueryExpr)
  2839  		sq.MultiRows = true
  2840  		$$ = &ast.PatternInExpr{Expr: $1, Not: !$2.(bool), Sel: sq}
  2841  	}
  2842  |	BitExpr BetweenOrNotOp BitExpr "AND" PredicateExpr
  2843  	{
  2844  		$$ = &ast.BetweenExpr{
  2845  			Expr:	$1,
  2846  			Left:	$3,
  2847  			Right:	$5,
  2848  			Not:	!$2.(bool),
  2849  		}
  2850  	}
  2851  |	BitExpr LikeOrNotOp SimpleExpr LikeEscapeOpt
  2852  	{
  2853  		escape := $4.(string)
  2854  		if len(escape) > 1 {
  2855  			yylex.Errorf("Incorrect arguments %s to ESCAPE", escape)
  2856  			return 1
  2857  		} else if len(escape) == 0 {
  2858  			escape = "\\"
  2859  		}
  2860  		$$ = &ast.PatternLikeExpr{
  2861  			Expr:		$1,
  2862  			Pattern:	$3,
  2863  			Not: 		!$2.(bool),
  2864  			Escape: 	escape[0],
  2865  		}
  2866  	}
  2867  |	BitExpr RegexpOrNotOp SimpleExpr
  2868  	{
  2869  		$$ = &ast.PatternRegexpExpr{Expr: $1, Pattern: $3, Not: !$2.(bool)}
  2870  	}
  2871  |	BitExpr
  2872  
  2873  RegexpSym:
  2874  "REGEXP" | "RLIKE"
  2875  
  2876  LikeEscapeOpt:
  2877  	%prec empty
  2878  	{
  2879  		$$ = "\\"
  2880  	}
  2881  |	"ESCAPE" stringLit
  2882  	{
  2883  		$$ = $2
  2884  	}
  2885  
  2886  Field:
  2887  	'*'
  2888  	{
  2889  		$$ = &ast.SelectField{WildCard: &ast.WildCardField{}}
  2890  	}
  2891  |	Identifier '.' '*'
  2892  	{
  2893  		wildCard := &ast.WildCardField{Table: model.NewCIStr($1)}
  2894  		$$ = &ast.SelectField{WildCard: wildCard}
  2895  	}
  2896  |	Identifier '.' Identifier '.' '*'
  2897  	{
  2898  		wildCard := &ast.WildCardField{Schema: model.NewCIStr($1), Table: model.NewCIStr($3)}
  2899  		$$ = &ast.SelectField{WildCard: wildCard}
  2900  	}
  2901  |	Expression FieldAsNameOpt
  2902  	{
  2903  		expr := $1
  2904  		asName := $2.(string)
  2905  		$$ = &ast.SelectField{Expr: expr, AsName: model.NewCIStr(asName)}
  2906  	}
  2907  |	'{' Identifier Expression '}' FieldAsNameOpt
  2908  	{
  2909  		/*
  2910  		* ODBC escape syntax.
  2911  		* See https://dev.mysql.com/doc/refman/5.7/en/expressions.html
  2912  		*/
  2913  		expr := $3
  2914  		asName := $5.(string)
  2915  		$$ = &ast.SelectField{Expr: expr, AsName: model.NewCIStr(asName)}
  2916  	}
  2917  
  2918  FieldAsNameOpt:
  2919  	/* EMPTY */
  2920  	{
  2921  		$$ = ""
  2922  	}
  2923  |	FieldAsName
  2924  	{
  2925  		$$ = $1
  2926  	}
  2927  
  2928  FieldAsName:
  2929  	Identifier
  2930  	{
  2931  		$$ = $1
  2932  	}
  2933  |	"AS" Identifier
  2934  	{
  2935  		$$ = $2
  2936  	}
  2937  |	stringLit
  2938  	{
  2939  		$$ = $1
  2940  	}
  2941  |	"AS" stringLit
  2942  	{
  2943  		$$ = $2
  2944  	}
  2945  
  2946  FieldList:
  2947  	Field
  2948  	{
  2949  		field := $1.(*ast.SelectField)
  2950  		field.Offset = parser.startOffset(&yyS[yypt])
  2951  		$$ = []*ast.SelectField{field}
  2952  	}
  2953  |	FieldList ',' Field
  2954  	{
  2955  
  2956  		fl := $1.([]*ast.SelectField)
  2957  		last := fl[len(fl)-1]
  2958  		if last.Expr != nil && last.AsName.O == "" {
  2959  			lastEnd := parser.endOffset(&yyS[yypt-1])
  2960  			last.SetText(parser.src[last.Offset:lastEnd])
  2961  		}
  2962  		newField := $3.(*ast.SelectField)
  2963  		newField.Offset = parser.startOffset(&yyS[yypt])
  2964  		$$ = append(fl, newField)
  2965  	}
  2966  
  2967  GroupByClause:
  2968  	"GROUP" "BY" ByList
  2969  	{
  2970  		$$ = &ast.GroupByClause{Items: $3.([]*ast.ByItem)}
  2971  	}
  2972  
  2973  HavingClause:
  2974  	{
  2975  		$$ = nil
  2976  	}
  2977  |	"HAVING" Expression
  2978  	{
  2979  		$$ = &ast.HavingClause{Expr: $2}
  2980  	}
  2981  
  2982  IfExists:
  2983  	{
  2984  		$$ = false
  2985  	}
  2986  |	"IF" "EXISTS"
  2987  	{
  2988  		$$ = true
  2989  	}
  2990  
  2991  IfNotExists:
  2992  	{
  2993  		$$ = false
  2994  	}
  2995  |	"IF" "NOT" "EXISTS"
  2996  	{
  2997  		$$ = true
  2998  	}
  2999  
  3000  
  3001  IgnoreOptional:
  3002  	{
  3003  		$$ = false
  3004  	}
  3005  |	"IGNORE"
  3006  	{
  3007  		$$ = true
  3008  	}
  3009  
  3010  IndexName:
  3011  	{
  3012  		$$ = ""
  3013  	}
  3014  |	Identifier
  3015  	{
  3016  		//"index name"
  3017  		$$ = $1
  3018  	}
  3019  
  3020  IndexOptionList:
  3021  	{
  3022  		$$ = nil
  3023  	}
  3024  |	IndexOptionList IndexOption
  3025  	{
  3026  		// Merge the options
  3027  		if $1 == nil {
  3028  			$$ = $2
  3029  		} else {
  3030  			opt1 := $1.(*ast.IndexOption)
  3031  			opt2 := $2.(*ast.IndexOption)
  3032  			if len(opt2.Comment) > 0 {
  3033  				opt1.Comment = opt2.Comment
  3034  			} else if opt2.Tp != 0 {
  3035  				opt1.Tp = opt2.Tp
  3036  			} else if opt2.KeyBlockSize > 0 {
  3037  			    opt1.KeyBlockSize = opt2.KeyBlockSize
  3038  			}
  3039  			$$ = opt1
  3040  		}
  3041  	}
  3042  
  3043  
  3044  IndexOption:
  3045  	"KEY_BLOCK_SIZE" EqOpt LengthNum
  3046  	{
  3047  		$$ = &ast.IndexOption{
  3048  			KeyBlockSize: $3.(uint64),
  3049  		}
  3050  	}
  3051  |	IndexType
  3052  	{
  3053  		$$ = &ast.IndexOption {
  3054  			Tp: $1.(model.IndexType),
  3055  		}
  3056  	}
  3057  |	"COMMENT" stringLit
  3058  	{
  3059  		$$ = &ast.IndexOption {
  3060  			Comment: $2,
  3061  		}
  3062  	}
  3063  
  3064  IndexType:
  3065  	"USING" "BTREE"
  3066  	{
  3067  		$$ = model.IndexTypeBtree
  3068  	}
  3069  |	"USING" "HASH"
  3070  	{
  3071  		$$ = model.IndexTypeHash
  3072  	}
  3073  
  3074  IndexTypeOpt:
  3075  	{
  3076  		$$ = nil
  3077  	}
  3078  |	IndexType
  3079  	{
  3080  		$$ = $1
  3081  	}
  3082  
  3083  /**********************************Identifier********************************************/
  3084  Identifier:
  3085  identifier | UnReservedKeyword | NotKeywordToken | TiDBKeyword
  3086  
  3087  UnReservedKeyword:
  3088   "ACTION" | "ASCII" | "AUTO_INCREMENT" | "AFTER" | "ALWAYS" | "AVG" | "BEGIN" | "BIT" | "BOOL" | "BOOLEAN" | "BTREE" | "BYTE" | "CLEANUP" | "CHARSET"
  3089  | "COLUMNS" | "COMMIT" | "COMPACT" | "COMPRESSED" | "CONSISTENT" | "CURRENT" | "DATA" | "DATE" %prec lowerThanStringLitToken| "DATETIME" | "DAY" | "DEALLOCATE" | "DO" | "DUPLICATE"
  3090  | "DYNAMIC"| "END" | "ENGINE" | "ENGINES" | "ENUM" | "ERRORS" | "ESCAPE" | "EXECUTE" | "FIELDS" | "FIRST" | "FIXED" | "FLUSH" | "FOLLOWING" | "FORMAT" | "FULL" |"GLOBAL"
  3091  | "HASH" | "HOUR" | "LESS" | "LOCAL" | "LAST" | "NAMES" | "OFFSET" | "PASSWORD" %prec lowerThanEq | "PREPARE" | "QUICK" | "REDUNDANT"
  3092  | "ROLE" | "ROLLBACK" | "SAVEPOINT" | "SESSION" | "SIGNED" | "SNAPSHOT" | "START" | "STATUS" | "SUBPARTITIONS" | "SUBPARTITION" | "TABLES" | "TABLESPACE" | "TEXT" | "THAN" | "TIME" %prec lowerThanStringLitToken
  3093  | "TIMESTAMP" %prec lowerThanStringLitToken | "TRACE" | "TRANSACTION" | "TRUNCATE" | "UNBOUNDED" | "UNKNOWN" | "VALUE" | "WARNINGS" | "YEAR" | "MODE"  | "WEEK"  | "ANY" | "SOME" | "USER" | "IDENTIFIED"
  3094  | "COLLATION" | "COMMENT" | "AVG_ROW_LENGTH" | "CONNECTION" | "CHECKSUM" | "COMPRESSION" | "KEY_BLOCK_SIZE" | "MASTER" | "MAX_ROWS"
  3095  | "MIN_ROWS" | "NATIONAL" | "ROW_FORMAT" | "QUARTER" | "GRANTS" | "TRIGGERS" | "DELAY_KEY_WRITE" | "ISOLATION" | "JSON"
  3096  | "REPEATABLE" | "RESPECT" | "COMMITTED" | "UNCOMMITTED" | "ONLY" | "SERIALIZABLE" | "LEVEL" | "VARIABLES" | "SQL_CACHE" | "INDEXES" | "PROCESSLIST"
  3097  | "SQL_NO_CACHE" | "DISABLE"  | "ENABLE" | "REVERSE" | "PRIVILEGES" | "NO" | "BINLOG" | "FUNCTION" | "VIEW" | "BINDING" | "BINDINGS" | "MODIFY" | "EVENTS" | "PARTITIONS"
  3098  | "NONE" | "NULLS" | "SUPER" | "EXCLUSIVE" | "STATS_PERSISTENT" | "ROW_COUNT" | "COALESCE" | "MONTH" | "PROCESS" | "PROFILES"
  3099  | "MICROSECOND" | "MINUTE" | "PLUGINS" | "PRECEDING" | "QUERY" | "QUERIES" | "SECOND" | "SEPARATOR" | "SHARE" | "SHARED" | "SLOW" | "MAX_CONNECTIONS_PER_HOUR" | "MAX_QUERIES_PER_HOUR" | "MAX_UPDATES_PER_HOUR"
  3100  | "MAX_USER_CONNECTIONS" | "REPLICATION" | "CLIENT" | "SLAVE" | "RELOAD" | "TEMPORARY" | "ROUTINE" | "EVENT" | "ALGORITHM" | "DEFINER" | "INVOKER" | "MERGE" | "TEMPTABLE" | "UNDEFINED" | "SECURITY" | "CASCADED" | "RECOVER"
  3101  
  3102  
  3103  
  3104  TiDBKeyword:
  3105  "ADMIN" | "BUCKETS" | "CANCEL" | "DDL" | "DRAINER" | "JOBS" | "JOB" | "PUMP" | "STATS" | "STATS_META" | "STATS_HISTOGRAMS" | "STATS_BUCKETS" | "STATS_HEALTHY" | "TIDB" | "TIDB_HJ" | "TIDB_SMJ" | "TIDB_INLJ" | "RESTORE"
  3106  
  3107  NotKeywordToken:
  3108   "ADDDATE" | "BIT_AND" | "BIT_OR" | "BIT_XOR" | "CAST" | "COPY" | "COUNT" | "CURTIME" | "DATE_ADD" | "DATE_SUB" | "EXTRACT" | "GET_FORMAT" | "GROUP_CONCAT"
  3109  | "INPLACE" | "INSTANT" | "INTERNAL" |"MIN" | "MAX" | "MAX_EXECUTION_TIME" | "NOW" | "RECENT" | "POSITION" | "SUBDATE" | "SUBSTRING" | "SUM"
  3110  | "STD" | "STDDEV" | "STDDEV_POP" | "STDDEV_SAMP" | "VARIANCE" | "VAR_POP" | "VAR_SAMP"
  3111  | "TIMESTAMPADD" | "TIMESTAMPDIFF" | "TOP" | "TRIM" | "NEXT_ROW_ID"
  3112  
  3113  /************************************************************************************
  3114   *
  3115   *  Insert Statements
  3116   *
  3117   *  TODO: support PARTITION
  3118   **********************************************************************************/
  3119  InsertIntoStmt:
  3120  	"INSERT" PriorityOpt IgnoreOptional IntoOpt TableName InsertValues OnDuplicateKeyUpdate
  3121  	{
  3122  		x := $6.(*ast.InsertStmt)
  3123  		x.Priority = $2.(mysql.PriorityEnum)
  3124  		x.IgnoreErr = $3.(bool)
  3125  		// Wraps many layers here so that it can be processed the same way as select statement.
  3126  		ts := &ast.TableSource{Source: $5.(*ast.TableName)}
  3127  		x.Table = &ast.TableRefsClause{TableRefs: &ast.Join{Left: ts}}
  3128  		if $7 != nil {
  3129  			x.OnDuplicate = $7.([]*ast.Assignment)
  3130  		}
  3131  		$$ = x
  3132  	}
  3133  
  3134  IntoOpt:
  3135  	{}
  3136  |	"INTO"
  3137  
  3138  InsertValues:
  3139  	'(' ColumnNameListOpt ')' ValueSym ValuesList
  3140  	{
  3141  		$$ = &ast.InsertStmt{
  3142  			Columns:   $2.([]*ast.ColumnName),
  3143  			Lists:      $5.([][]ast.ExprNode),
  3144  		}
  3145  	}
  3146  |	'(' ColumnNameListOpt ')' SelectStmt
  3147  	{
  3148  		$$ = &ast.InsertStmt{Columns: $2.([]*ast.ColumnName), Select: $4.(*ast.SelectStmt)}
  3149  	}
  3150  |	'(' ColumnNameListOpt ')' '(' SelectStmt ')'
  3151  	{
  3152  		$$ = &ast.InsertStmt{Columns: $2.([]*ast.ColumnName), Select: $5.(*ast.SelectStmt)}
  3153  	}
  3154  |	'(' ColumnNameListOpt ')' UnionStmt
  3155  	{
  3156  		$$ = &ast.InsertStmt{Columns: $2.([]*ast.ColumnName), Select: $4.(*ast.UnionStmt)}
  3157  	}
  3158  |	ValueSym ValuesList %prec insertValues
  3159  	{
  3160  		$$ = &ast.InsertStmt{Lists:  $2.([][]ast.ExprNode)}
  3161  	}
  3162  |	'(' SelectStmt ')'
  3163  	{
  3164  		$$ = &ast.InsertStmt{Select: $2.(*ast.SelectStmt)}
  3165  	}
  3166  |	SelectStmt
  3167  	{
  3168  		$$ = &ast.InsertStmt{Select: $1.(*ast.SelectStmt)}
  3169  	}
  3170  |	UnionStmt
  3171  	{
  3172  		$$ = &ast.InsertStmt{Select: $1.(*ast.UnionStmt)}
  3173  	}
  3174  |	"SET" ColumnSetValueList
  3175  	{
  3176  		$$ = &ast.InsertStmt{Setlist: $2.([]*ast.Assignment)}
  3177  	}
  3178  
  3179  ValueSym:
  3180  "VALUE" | "VALUES"
  3181  
  3182  ValuesList:
  3183  	RowValue
  3184  	{
  3185  		$$ = [][]ast.ExprNode{$1.([]ast.ExprNode)}
  3186  	}
  3187  |	ValuesList ',' RowValue
  3188  	{
  3189  		$$ = append($1.([][]ast.ExprNode), $3.([]ast.ExprNode))
  3190  	}
  3191  
  3192  RowValue:
  3193  	'(' ValuesOpt ')'
  3194  	{
  3195  		$$ = $2
  3196  	}
  3197  
  3198  ValuesOpt:
  3199  	{
  3200  		$$ = []ast.ExprNode{}
  3201  	}
  3202  |	Values
  3203  
  3204  Values:
  3205  	Values ',' ExprOrDefault
  3206  	{
  3207  		$$ = append($1.([]ast.ExprNode), $3)
  3208  	}
  3209  |	ExprOrDefault
  3210  	{
  3211  		$$ = []ast.ExprNode{$1}
  3212  	}
  3213  
  3214  ExprOrDefault:
  3215  	Expression
  3216  |	"DEFAULT"
  3217  	{
  3218  		$$ = &ast.DefaultExpr{}
  3219  	}
  3220  
  3221  ColumnSetValue:
  3222  	ColumnName eq Expression
  3223  	{
  3224  		$$ = &ast.Assignment{
  3225  			Column:	$1.(*ast.ColumnName),
  3226  			Expr:	$3,
  3227  		}
  3228  	}
  3229  
  3230  ColumnSetValueList:
  3231  	{
  3232  		$$ = []*ast.Assignment{}
  3233  	}
  3234  |	ColumnSetValue
  3235  	{
  3236  		$$ = []*ast.Assignment{$1.(*ast.Assignment)}
  3237  	}
  3238  |	ColumnSetValueList ',' ColumnSetValue
  3239  	{
  3240  		$$ = append($1.([]*ast.Assignment), $3.(*ast.Assignment))
  3241  	}
  3242  
  3243  /*
  3244   * ON DUPLICATE KEY UPDATE col_name=expr [, col_name=expr] ...
  3245   * See https://dev.mysql.com/doc/refman/5.7/en/insert-on-duplicate.html
  3246   */
  3247  OnDuplicateKeyUpdate:
  3248  	{
  3249  		$$ = nil
  3250  	}
  3251  |	"ON" "DUPLICATE" "KEY" "UPDATE" AssignmentList
  3252  	{
  3253  		$$ = $5
  3254  	}
  3255  
  3256  /***********************************Insert Statements END************************************/
  3257  
  3258  /************************************************************************************
  3259   *  Replace Statements
  3260   *  See https://dev.mysql.com/doc/refman/5.7/en/replace.html
  3261   *
  3262   *  TODO: support PARTITION
  3263   **********************************************************************************/
  3264  ReplaceIntoStmt:
  3265  	"REPLACE" PriorityOpt IntoOpt TableName InsertValues
  3266  	{
  3267  		x := $5.(*ast.InsertStmt)
  3268  		x.IsReplace = true
  3269  		x.Priority = $2.(mysql.PriorityEnum)
  3270  		ts := &ast.TableSource{Source: $4.(*ast.TableName)}
  3271  		x.Table = &ast.TableRefsClause{TableRefs: &ast.Join{Left: ts}}
  3272  		$$ = x
  3273  	}
  3274  
  3275  /***********************************Replace Statements END************************************/
  3276  
  3277  ODBCDateTimeType:
  3278  	"d"
  3279  	{
  3280  		$$ = ast.DateLiteral
  3281  	}
  3282  |	"t"
  3283  	{
  3284  		$$ = ast.TimeLiteral
  3285  	}
  3286  |	"ts"
  3287  	{
  3288  		$$ = ast.TimestampLiteral
  3289  	}
  3290  
  3291  Literal:
  3292  	"FALSE"
  3293  	{
  3294  		$$ = ast.NewValueExpr(false)
  3295  	}
  3296  |	"NULL"
  3297  	{
  3298  		$$ = ast.NewValueExpr(nil)
  3299  	}
  3300  |	"TRUE"
  3301  	{
  3302  		$$ = ast.NewValueExpr(true)
  3303  	}
  3304  |	floatLit
  3305  	{
  3306  		$$ = ast.NewValueExpr($1)
  3307  	}
  3308  |	decLit
  3309  	{
  3310  		$$ = ast.NewValueExpr($1)
  3311  	}
  3312  |	intLit
  3313  	{
  3314  		$$ = ast.NewValueExpr($1)
  3315  	}
  3316  |	StringLiteral %prec lowerThanStringLitToken
  3317  	{
  3318  		$$ = $1
  3319  	}
  3320  |	"UNDERSCORE_CHARSET" stringLit
  3321  	{
  3322  		// See https://dev.mysql.com/doc/refman/5.7/en/charset-literal.html
  3323  		co, err := mysql.GetDefaultCollation($1)
  3324  		if err != nil {
  3325  			yylex.Errorf("Get collation error for charset: %s", $1)
  3326  			return 1
  3327  		}
  3328  		expr := ast.NewValueExpr($2)
  3329  		tp := expr.GetType()
  3330  		tp.Charset = $1
  3331  		tp.Collate = co
  3332  		if tp.Collate == mysql.CollationBin {
  3333  			tp.Flag |= mysql.BinaryFlag
  3334  		}
  3335  		$$ = expr
  3336  	}
  3337  |	hexLit
  3338  	{
  3339  		$$ = ast.NewValueExpr($1)
  3340  	}
  3341  |	bitLit
  3342  	{
  3343  		$$ = ast.NewValueExpr($1)
  3344  	}
  3345  
  3346  StringLiteral:
  3347  	stringLit
  3348  	{
  3349  		expr := ast.NewValueExpr($1)
  3350  		$$ = expr
  3351  	}
  3352  |	StringLiteral stringLit
  3353  	{
  3354  		valExpr := $1.(ast.ValueExpr)
  3355  		strLit := valExpr.GetString()
  3356  		expr := ast.NewValueExpr(strLit+$2)
  3357  		// Fix #4239, use first string literal as projection name.
  3358  		if valExpr.GetProjectionOffset() >= 0 {
  3359  			expr.SetProjectionOffset(valExpr.GetProjectionOffset())
  3360  		} else {
  3361  			expr.SetProjectionOffset(len(strLit))
  3362  		}
  3363  		$$ = expr
  3364  	}
  3365  
  3366  
  3367  OrderBy:
  3368  	"ORDER" "BY" ByList
  3369  	{
  3370  		$$ = &ast.OrderByClause{Items: $3.([]*ast.ByItem)}
  3371  	}
  3372  
  3373  ByList:
  3374  	ByItem
  3375  	{
  3376  		$$ = []*ast.ByItem{$1.(*ast.ByItem)}
  3377  	}
  3378  |	ByList ',' ByItem
  3379  	{
  3380  		$$ = append($1.([]*ast.ByItem), $3.(*ast.ByItem))
  3381  	}
  3382  
  3383  ByItem:
  3384  	Expression Order
  3385  	{
  3386  		expr := $1
  3387  		valueExpr, ok := expr.(ast.ValueExpr)
  3388  		if ok {
  3389  			position, isPosition := valueExpr.GetValue().(int64)
  3390  			if isPosition {
  3391  				expr = &ast.PositionExpr{N: int(position)}
  3392  			}
  3393  		}
  3394  		$$ = &ast.ByItem{Expr: expr, Desc: $2.(bool)}
  3395  	}
  3396  
  3397  Order:
  3398  	/* EMPTY */
  3399  	{
  3400  		$$ = false // ASC by default
  3401  	}
  3402  |	"ASC"
  3403  	{
  3404  		$$ = false
  3405  	}
  3406  |	"DESC"
  3407  	{
  3408  		$$ = true
  3409  	}
  3410  
  3411  OrderByOptional:
  3412  	{
  3413  		$$ = nil
  3414  	}
  3415  |	OrderBy
  3416  	{
  3417  		$$ = $1
  3418  	}
  3419  
  3420  BitExpr:
  3421  	BitExpr '|' BitExpr %prec '|'
  3422  	{
  3423  		$$ = &ast.BinaryOperationExpr{Op: opcode.Or, L: $1, R: $3}
  3424  	}
  3425  |	BitExpr '&' BitExpr %prec '&'
  3426  	{
  3427  		$$ = &ast.BinaryOperationExpr{Op: opcode.And, L: $1, R: $3}
  3428  	}
  3429  |	BitExpr "<<" BitExpr %prec lsh
  3430  	{
  3431  		$$ = &ast.BinaryOperationExpr{Op: opcode.LeftShift, L: $1, R: $3}
  3432  	}
  3433  |	BitExpr ">>" BitExpr %prec rsh
  3434  	{
  3435  		$$ = &ast.BinaryOperationExpr{Op: opcode.RightShift, L: $1, R: $3}
  3436  	}
  3437  |	BitExpr '+' BitExpr %prec '+'
  3438  	{
  3439  		$$ = &ast.BinaryOperationExpr{Op: opcode.Plus, L: $1, R: $3}
  3440  	}
  3441  |	BitExpr '-' BitExpr %prec '-'
  3442  	{
  3443  		$$ = &ast.BinaryOperationExpr{Op: opcode.Minus, L: $1, R: $3}
  3444  	}
  3445  |	BitExpr '+' "INTERVAL" Expression TimeUnit %prec '+'
  3446  	{
  3447  		$$ = &ast.FuncCallExpr{
  3448  			FnName: model.NewCIStr("DATE_ADD"),
  3449  			Args: []ast.ExprNode{
  3450  				$1,
  3451  				$4,
  3452  				ast.NewValueExpr($5),
  3453  			},
  3454  		}
  3455  	}
  3456  |	BitExpr '-' "INTERVAL" Expression TimeUnit %prec '+'
  3457  	{
  3458  		$$ = &ast.FuncCallExpr{
  3459  			FnName: model.NewCIStr("DATE_SUB"),
  3460  			Args: []ast.ExprNode{
  3461  				$1,
  3462  				$4,
  3463  				ast.NewValueExpr($5),
  3464  			},
  3465  		}
  3466  	}
  3467  |	BitExpr '*' BitExpr %prec '*'
  3468  	{
  3469  		$$ = &ast.BinaryOperationExpr{Op: opcode.Mul, L: $1, R: $3}
  3470  	}
  3471  |	BitExpr '/' BitExpr %prec '/'
  3472  	{
  3473  		$$ = &ast.BinaryOperationExpr{Op: opcode.Div, L: $1, R: $3}
  3474  	}
  3475  |	BitExpr '%' BitExpr %prec '%'
  3476  	{
  3477  		$$ = &ast.BinaryOperationExpr{Op: opcode.Mod, L: $1, R: $3}
  3478  	}
  3479  |	BitExpr "DIV" BitExpr %prec div
  3480  	{
  3481  		$$ = &ast.BinaryOperationExpr{Op: opcode.IntDiv, L: $1, R: $3}
  3482  	}
  3483  |	BitExpr "MOD" BitExpr %prec mod
  3484  	{
  3485  		$$ = &ast.BinaryOperationExpr{Op: opcode.Mod, L: $1, R: $3}
  3486  	}
  3487  |	BitExpr '^' BitExpr
  3488  	{
  3489  		$$ = &ast.BinaryOperationExpr{Op: opcode.Xor, L: $1, R: $3}
  3490  	}
  3491  |	SimpleExpr
  3492  
  3493  SimpleIdent:
  3494  	Identifier
  3495  	{
  3496  		$$ = &ast.ColumnNameExpr{Name: &ast.ColumnName{
  3497  			Name: model.NewCIStr($1),
  3498  		}}
  3499  	}
  3500  |	Identifier '.' Identifier
  3501  	{
  3502  		$$ = &ast.ColumnNameExpr{Name: &ast.ColumnName{
  3503  			Table: model.NewCIStr($1),
  3504  			Name: model.NewCIStr($3),
  3505  		}}
  3506  	}
  3507  |	'.' Identifier '.' Identifier
  3508  	{
  3509  		$$ = &ast.ColumnNameExpr{Name: &ast.ColumnName{
  3510  			Table: model.NewCIStr($2),
  3511  			Name: model.NewCIStr($4),
  3512  		}}
  3513  	}
  3514  |	Identifier '.' Identifier '.' Identifier
  3515  	{
  3516  		$$ = &ast.ColumnNameExpr{Name: &ast.ColumnName{
  3517  			Schema: model.NewCIStr($1),
  3518  			Table: model.NewCIStr($3),
  3519  			Name: model.NewCIStr($5),
  3520  		}}
  3521  	}
  3522  
  3523  SimpleExpr:
  3524  	SimpleIdent
  3525  |	FunctionCallKeyword
  3526  |	FunctionCallNonKeyword
  3527  |	FunctionCallGeneric
  3528  |	SimpleExpr "COLLATE" StringName %prec neg
  3529  	{
  3530  		// TODO: Create a builtin function hold expr and collation. When do evaluation, convert expr result using the collation.
  3531  		$$ = $1
  3532  	}
  3533  |	WindowFuncCall
  3534  	{
  3535  		$$ = $1.(*ast.WindowFuncExpr)
  3536  	}
  3537  |	Literal
  3538  |	paramMarker
  3539  	{
  3540  		$$ = ast.NewParamMarkerExpr(yyS[yypt].offset)
  3541  	}
  3542  |	Variable
  3543  |	SumExpr
  3544  |	'!' SimpleExpr %prec neg
  3545  	{
  3546  		$$ = &ast.UnaryOperationExpr{Op: opcode.Not, V: $2}
  3547  	}
  3548  |	'~'  SimpleExpr %prec neg
  3549  	{
  3550  		$$ = &ast.UnaryOperationExpr{Op: opcode.BitNeg, V: $2}
  3551  	}
  3552  |	'-' SimpleExpr %prec neg
  3553  	{
  3554  		$$ = &ast.UnaryOperationExpr{Op: opcode.Minus, V: $2}
  3555  	}
  3556  |	'+' SimpleExpr %prec neg
  3557  	{
  3558  		$$ = &ast.UnaryOperationExpr{Op: opcode.Plus, V: $2}
  3559  	}
  3560  |	SimpleExpr pipes SimpleExpr
  3561  	{
  3562  		$$ = &ast.FuncCallExpr{FnName: model.NewCIStr(ast.Concat), Args: []ast.ExprNode{$1, $3}}
  3563  	}
  3564  |	not2 SimpleExpr %prec neg
  3565  	{
  3566  		$$ = &ast.UnaryOperationExpr{Op: opcode.Not, V: $2}
  3567  	}
  3568  |	SubSelect
  3569  |	'(' Expression ')' {
  3570  		startOffset := parser.startOffset(&yyS[yypt-1])
  3571  		endOffset := parser.endOffset(&yyS[yypt])
  3572  		expr := $2
  3573  		expr.SetText(parser.src[startOffset:endOffset])
  3574  		$$ = &ast.ParenthesesExpr{Expr: expr}
  3575  	}
  3576  |	'(' ExpressionList ',' Expression ')'
  3577  	{
  3578  		values := append($2.([]ast.ExprNode), $4)
  3579  		$$ = &ast.RowExpr{Values: values}
  3580  	}
  3581  |	"ROW" '(' ExpressionList ',' Expression ')'
  3582  	{
  3583  		values := append($3.([]ast.ExprNode), $5)
  3584  		$$ = &ast.RowExpr{Values: values}
  3585  	}
  3586  |	"EXISTS" SubSelect
  3587  	{
  3588  		sq := $2.(*ast.SubqueryExpr)
  3589  		sq.Exists = true
  3590  		$$ = &ast.ExistsSubqueryExpr{Sel: sq}
  3591  	}
  3592  |	"BINARY" SimpleExpr %prec neg
  3593  	{
  3594  		// See https://dev.mysql.com/doc/refman/5.7/en/cast-functions.html#operator_binary
  3595  		x := types.NewFieldType(mysql.TypeString)
  3596  		x.Charset = mysql.CharsetBin
  3597  		x.Collate = mysql.CharsetBin
  3598  		$$ = &ast.FuncCastExpr{
  3599  			Expr: $2,
  3600  			Tp: x,
  3601  			FunctionType: ast.CastBinaryOperator,
  3602  		}
  3603  	}
  3604  |	builtinCast '(' Expression "AS" CastType ')'
  3605   	{
  3606   		/* See https://dev.mysql.com/doc/refman/5.7/en/cast-functions.html#function_cast */
  3607   		tp := $5.(*types.FieldType)
  3608   		defaultFlen, defaultDecimal := mysql.GetDefaultFieldLengthAndDecimalForCast(tp.Tp)
  3609   		if tp.Flen == types.UnspecifiedLength {
  3610   			tp.Flen = defaultFlen
  3611   		}
  3612   		if tp.Decimal == types.UnspecifiedLength {
  3613   			tp.Decimal = defaultDecimal
  3614   		}
  3615   		$$ = &ast.FuncCastExpr{
  3616   			Expr: $3,
  3617   			Tp: tp,
  3618   			FunctionType: ast.CastFunction,
  3619   		}
  3620   	}
  3621  |	"CASE" ExpressionOpt WhenClauseList ElseOpt "END"
  3622  	{
  3623  		x := &ast.CaseExpr{WhenClauses: $3.([]*ast.WhenClause)}
  3624  		if $2 != nil {
  3625  			x.Value = $2
  3626  		}
  3627  		if $4 != nil {
  3628  			x.ElseClause = $4.(ast.ExprNode)
  3629  		}
  3630  		$$ = x
  3631  	}
  3632  |	"CONVERT" '(' Expression ',' CastType ')'
  3633  	{
  3634  		// See https://dev.mysql.com/doc/refman/5.7/en/cast-functions.html#function_convert
  3635  		tp := $5.(*types.FieldType)
  3636  		defaultFlen, defaultDecimal := mysql.GetDefaultFieldLengthAndDecimalForCast(tp.Tp)
  3637  		if tp.Flen == types.UnspecifiedLength {
  3638  			tp.Flen = defaultFlen
  3639  		}
  3640  		if tp.Decimal == types.UnspecifiedLength {
  3641  			tp.Decimal = defaultDecimal
  3642  		}
  3643  		$$ = &ast.FuncCastExpr{
  3644  			Expr: $3,
  3645  			Tp: tp,
  3646  			FunctionType: ast.CastConvertFunction,
  3647  		}
  3648  	}
  3649  |	"CONVERT" '(' Expression "USING" StringName ')'
  3650  	{
  3651  		// See https://dev.mysql.com/doc/refman/5.7/en/cast-functions.html#function_convert
  3652  		charset1 := ast.NewValueExpr($5)
  3653  		$$ = &ast.FuncCallExpr{
  3654  			FnName: model.NewCIStr($1),
  3655  			Args: []ast.ExprNode{$3, charset1},
  3656  		}
  3657  	}
  3658  |	"DEFAULT" '(' SimpleIdent ')'
  3659  	{
  3660  		$$ = &ast.DefaultExpr{Name: $3.(*ast.ColumnNameExpr).Name}
  3661  	}
  3662  |	"VALUES" '(' SimpleIdent ')' %prec lowerThanInsertValues
  3663  	{
  3664  		$$ = &ast.ValuesExpr{Column: $3.(*ast.ColumnNameExpr)}
  3665  	}
  3666  |	SimpleIdent jss stringLit
  3667  	{
  3668  	    expr := ast.NewValueExpr($3)
  3669  	    $$ = &ast.FuncCallExpr{FnName: model.NewCIStr(ast.JSONExtract), Args: []ast.ExprNode{$1, expr}}
  3670  	}
  3671  |	SimpleIdent juss stringLit
  3672  	{
  3673  	    expr := ast.NewValueExpr($3)
  3674  	    extract := &ast.FuncCallExpr{FnName: model.NewCIStr(ast.JSONExtract), Args: []ast.ExprNode{$1, expr}}
  3675  	    $$ = &ast.FuncCallExpr{FnName: model.NewCIStr(ast.JSONUnquote), Args: []ast.ExprNode{extract}}
  3676  	}
  3677  
  3678  DistinctKwd:
  3679  	"DISTINCT"
  3680  |	"DISTINCTROW"
  3681  
  3682  DistinctOpt:
  3683  	"ALL"
  3684  	{
  3685  		$$ = false
  3686  	}
  3687  |	DistinctKwd
  3688  	{
  3689  		$$ = true
  3690  	}
  3691  
  3692  DefaultFalseDistinctOpt:
  3693  	{
  3694  		$$ = false
  3695  	}
  3696  |	DistinctOpt
  3697  
  3698  DefaultTrueDistinctOpt:
  3699  	{
  3700  		$$ = true
  3701  	}
  3702  |	DistinctOpt
  3703  
  3704  BuggyDefaultFalseDistinctOpt:
  3705  	DefaultFalseDistinctOpt
  3706  |	DistinctKwd "ALL"
  3707  	{
  3708  		$$ = true
  3709  	}
  3710  
  3711  
  3712  FunctionNameConflict:
  3713  	"ASCII"
  3714  |	"CHARSET"
  3715  |	"COALESCE"
  3716  |	"COLLATION"
  3717  |	"DATE"
  3718  |	"DATABASE"
  3719  |	"DAY"
  3720  |	"HOUR"
  3721  |	"IF"
  3722  |	"INTERVAL" %prec lowerThanIntervalKeyword
  3723  |	"FORMAT"
  3724  |	"LEFT"
  3725  |	"MICROSECOND"
  3726  |	"MINUTE"
  3727  |	"MONTH"
  3728  |	builtinNow
  3729  |	"QUARTER"
  3730  |	"REPEAT"
  3731  |	"REPLACE"
  3732  |	"REVERSE"
  3733  |	"RIGHT"
  3734  |	"ROW_COUNT"
  3735  |	"SECOND"
  3736  |	"TIME"
  3737  |	"TIMESTAMP"
  3738  |	"TRUNCATE"
  3739  |	"USER"
  3740  |	"WEEK"
  3741  |	"YEAR"
  3742  
  3743  OptionalBraces:
  3744  	{} | '(' ')' {}
  3745  
  3746  FunctionNameOptionalBraces:
  3747  	"CURRENT_USER"
  3748  |	"CURRENT_DATE"
  3749  |	"UTC_DATE"
  3750  
  3751  FunctionNameDatetimePrecision:
  3752  	"CURRENT_TIME"
  3753  |	"CURRENT_TIMESTAMP"
  3754  |	"LOCALTIME"
  3755  |	"LOCALTIMESTAMP"
  3756  |	"UTC_TIME"
  3757  |	"UTC_TIMESTAMP"
  3758  
  3759  FunctionCallKeyword:
  3760  	FunctionNameConflict '(' ExpressionListOpt ')'
  3761  	{
  3762  		$$ = &ast.FuncCallExpr{FnName: model.NewCIStr($1), Args: $3.([]ast.ExprNode)}
  3763  	}
  3764  |	builtinUser '('	ExpressionListOpt ')'
  3765  	{
  3766  		$$ = &ast.FuncCallExpr{FnName: model.NewCIStr($1), Args: $3.([]ast.ExprNode)}
  3767  	}
  3768  |	FunctionNameOptionalBraces OptionalBraces
  3769  	{
  3770  		$$ = &ast.FuncCallExpr{FnName: model.NewCIStr($1)}
  3771  	}
  3772  |	builtinCurDate '(' ')'
  3773      {
  3774  		$$ = &ast.FuncCallExpr{FnName: model.NewCIStr($1)}
  3775      }
  3776  |	FunctionNameDatetimePrecision FuncDatetimePrec
  3777  	{
  3778  		args := []ast.ExprNode{}
  3779  		if $2 != nil {
  3780  			args = append(args, $2.(ast.ExprNode))
  3781  		}
  3782  		$$ = &ast.FuncCallExpr{FnName: model.NewCIStr($1), Args: args}
  3783  	}
  3784  |	"CHAR" '(' ExpressionList ')'
  3785  	{
  3786  		nilVal := ast.NewValueExpr(nil)
  3787  		args := $3.([]ast.ExprNode)
  3788  		$$ = &ast.FuncCallExpr{
  3789  			FnName: model.NewCIStr(ast.CharFunc),
  3790  			Args: append(args, nilVal),
  3791  		}
  3792  	}
  3793  |	"CHAR" '(' ExpressionList "USING" StringName ')'
  3794  	{
  3795  		charset1 := ast.NewValueExpr($5)
  3796  		args := $3.([]ast.ExprNode)
  3797  		$$ = &ast.FuncCallExpr{
  3798  			FnName: model.NewCIStr(ast.CharFunc),
  3799  			Args: append(args, charset1),
  3800  		}
  3801  	}
  3802  |	"DATE"  stringLit
  3803  	{
  3804  		expr := ast.NewValueExpr($2)
  3805  		$$ = &ast.FuncCallExpr{FnName: model.NewCIStr(ast.DateLiteral), Args: []ast.ExprNode{expr}}
  3806  	}
  3807  |	"TIME"  stringLit
  3808  	{
  3809  		expr := ast.NewValueExpr($2)
  3810  		$$ = &ast.FuncCallExpr{FnName: model.NewCIStr(ast.TimeLiteral), Args: []ast.ExprNode{expr}}
  3811  	}
  3812  |	"TIMESTAMP"  stringLit
  3813  	{
  3814  		expr := ast.NewValueExpr($2)
  3815  		$$ = &ast.FuncCallExpr{FnName: model.NewCIStr(ast.TimestampLiteral), Args: []ast.ExprNode{expr}}
  3816  	}
  3817  |	"INSERT" '(' ExpressionListOpt ')'
  3818  	{
  3819  		$$ = &ast.FuncCallExpr{FnName:model.NewCIStr(ast.InsertFunc), Args: $3.([]ast.ExprNode)}
  3820  	}
  3821  |	"MOD" '(' BitExpr ',' BitExpr ')'
  3822  	{
  3823  		$$ = &ast.BinaryOperationExpr{Op: opcode.Mod, L: $3, R: $5}
  3824  	}
  3825  |	"PASSWORD" '(' ExpressionListOpt ')'
  3826  	{
  3827  		$$ = &ast.FuncCallExpr{FnName:model.NewCIStr(ast.PasswordFunc), Args: $3.([]ast.ExprNode)}
  3828  	}
  3829  |	'{' ODBCDateTimeType stringLit '}'
  3830  	{
  3831  		// This is ODBC syntax for date and time literals.
  3832  		// See: https://dev.mysql.com/doc/refman/5.7/en/date-and-time-literals.html
  3833  		expr := ast.NewValueExpr($3)
  3834  		$$ = &ast.FuncCallExpr{FnName: model.NewCIStr($2), Args: []ast.ExprNode{expr}}
  3835  	}
  3836  
  3837  FunctionCallNonKeyword:
  3838  	builtinCurTime '(' FuncDatetimePrecListOpt ')'
  3839  	{
  3840  		$$ = &ast.FuncCallExpr{FnName: model.NewCIStr($1), Args: $3.([]ast.ExprNode)}
  3841  	}
  3842  |	builtinSysDate '(' FuncDatetimePrecListOpt ')'
  3843  	{
  3844  		$$ = &ast.FuncCallExpr{FnName: model.NewCIStr($1), Args: $3.([]ast.ExprNode)}
  3845  	}
  3846  |	FunctionNameDateArithMultiForms '(' Expression ',' Expression ')'
  3847  	{
  3848  		$$ = &ast.FuncCallExpr{
  3849  			FnName: model.NewCIStr($1),
  3850  			Args: []ast.ExprNode{
  3851  				$3,
  3852  				$5,
  3853  				ast.NewValueExpr("DAY"),
  3854  			},
  3855  		}
  3856  	}
  3857  |	FunctionNameDateArithMultiForms '(' Expression ',' "INTERVAL" Expression TimeUnit ')'
  3858  	{
  3859  		$$ = &ast.FuncCallExpr{
  3860  			FnName: model.NewCIStr($1),
  3861  			Args: []ast.ExprNode{
  3862  				$3,
  3863  				$6,
  3864  				ast.NewValueExpr($7),
  3865  			},
  3866  		}
  3867  	}
  3868  |	FunctionNameDateArith '(' Expression ',' "INTERVAL" Expression TimeUnit ')'
  3869  	{
  3870  		$$ = &ast.FuncCallExpr{
  3871  			FnName: model.NewCIStr($1),
  3872  			Args: []ast.ExprNode{
  3873  				$3,
  3874  				$6,
  3875  				ast.NewValueExpr($7),
  3876  			},
  3877  		}
  3878  	}
  3879  |	builtinExtract '(' TimeUnit "FROM" Expression ')'
  3880  	{
  3881  		timeUnit := ast.NewValueExpr($3)
  3882  		$$ = &ast.FuncCallExpr{
  3883  			FnName: model.NewCIStr($1),
  3884  			Args: []ast.ExprNode{timeUnit, $5},
  3885  		}
  3886  	}
  3887  |	"GET_FORMAT" '(' GetFormatSelector ','  Expression ')'
  3888  	{
  3889  		$$ = &ast.FuncCallExpr{
  3890  			FnName: model.NewCIStr($1),
  3891  			Args: []ast.ExprNode{ast.NewValueExpr($3), $5},
  3892  		}
  3893  	}
  3894  |	builtinPosition '(' BitExpr "IN" Expression ')'
  3895  	{
  3896  		$$ = &ast.FuncCallExpr{FnName: model.NewCIStr($1), Args: []ast.ExprNode{$3, $5}}
  3897  	}
  3898  |	builtinSubstring '(' Expression ',' Expression ')'
  3899  	{
  3900  		$$ = &ast.FuncCallExpr{
  3901  			FnName: model.NewCIStr($1),
  3902  			Args: []ast.ExprNode{$3, $5},
  3903  		}
  3904  	}
  3905  |	builtinSubstring '(' Expression "FROM" Expression ')'
  3906  	{
  3907  		$$ = &ast.FuncCallExpr{
  3908  			FnName: model.NewCIStr($1),
  3909  			Args: []ast.ExprNode{$3, $5},
  3910  		}
  3911  	}
  3912  |	builtinSubstring '(' Expression ',' Expression ',' Expression ')'
  3913  	{
  3914  		$$ = &ast.FuncCallExpr{
  3915  			FnName: model.NewCIStr($1),
  3916  			Args: []ast.ExprNode{$3, $5, $7},
  3917  		}
  3918  	}
  3919  |	builtinSubstring '(' Expression "FROM" Expression "FOR" Expression ')'
  3920  	{
  3921  		$$ = &ast.FuncCallExpr{
  3922  			FnName: model.NewCIStr($1),
  3923  			Args: []ast.ExprNode{$3, $5, $7},
  3924  		}
  3925  	}
  3926  |	"TIMESTAMPADD" '(' TimestampUnit ',' Expression ',' Expression ')'
  3927  	{
  3928  		$$ = &ast.FuncCallExpr{
  3929  			FnName: model.NewCIStr($1),
  3930  			Args: []ast.ExprNode{ast.NewValueExpr($3), $5, $7},
  3931  		}
  3932  	}
  3933  |	"TIMESTAMPDIFF" '(' TimestampUnit ',' Expression ',' Expression ')'
  3934  	{
  3935  		$$ = &ast.FuncCallExpr{
  3936  			FnName: model.NewCIStr($1),
  3937  			Args: []ast.ExprNode{ast.NewValueExpr($3), $5, $7},
  3938  		}
  3939  	}
  3940  |	builtinTrim '(' Expression ')'
  3941  	{
  3942  		$$ = &ast.FuncCallExpr{
  3943  			FnName: model.NewCIStr($1),
  3944  			Args: []ast.ExprNode{$3},
  3945  		}
  3946  	}
  3947  |	builtinTrim '(' Expression "FROM" Expression ')'
  3948  	{
  3949  		$$ = &ast.FuncCallExpr{
  3950  			FnName: model.NewCIStr($1),
  3951  			Args: []ast.ExprNode{$5, $3},
  3952  		}
  3953  	}
  3954  |	builtinTrim '(' TrimDirection "FROM" Expression ')'
  3955  	{
  3956  		nilVal := ast.NewValueExpr(nil)
  3957  		direction := ast.NewValueExpr(int($3.(ast.TrimDirectionType)))
  3958  		$$ = &ast.FuncCallExpr{
  3959  			FnName: model.NewCIStr($1),
  3960  			Args: []ast.ExprNode{$5, nilVal, direction},
  3961  		}
  3962  	}
  3963  |	builtinTrim '(' TrimDirection Expression "FROM" Expression ')'
  3964  	{
  3965  		direction := ast.NewValueExpr(int($3.(ast.TrimDirectionType)))
  3966  		$$ = &ast.FuncCallExpr{
  3967  			FnName: model.NewCIStr($1),
  3968  			Args: []ast.ExprNode{$6, $4, direction},
  3969  		}
  3970  	}
  3971  
  3972  GetFormatSelector:
  3973  	"DATE"
  3974  	{
  3975  		$$ = strings.ToUpper($1)
  3976  	}
  3977  | 	"DATETIME"
  3978  	{
  3979  		$$ = strings.ToUpper($1)
  3980  	}
  3981  |	"TIME"
  3982  	{
  3983  		$$ = strings.ToUpper($1)
  3984  	}
  3985  |	"TIMESTAMP"
  3986  	{
  3987  		$$ = strings.ToUpper($1)
  3988  	}
  3989  
  3990  
  3991  FunctionNameDateArith:
  3992  	builtinDateAdd
  3993  |	builtinDateSub
  3994  
  3995  
  3996  FunctionNameDateArithMultiForms:
  3997  	builtinAddDate
  3998  |	builtinSubDate
  3999  
  4000  
  4001  TrimDirection:
  4002  	"BOTH"
  4003  	{
  4004  		$$ = ast.TrimBoth
  4005  	}
  4006  |	"LEADING"
  4007  	{
  4008  		$$ = ast.TrimLeading
  4009  	}
  4010  |	"TRAILING"
  4011  	{
  4012  		$$ = ast.TrimTrailing
  4013  	}
  4014  
  4015  SumExpr:
  4016  	"AVG" '(' BuggyDefaultFalseDistinctOpt Expression ')'  OptWindowingClause
  4017  	{
  4018  		if $6 != nil {
  4019  			$$ = &ast.WindowFuncExpr{F: $1, Args: []ast.ExprNode{$4}, Distinct: $3.(bool), Spec: *($6.(*ast.WindowSpec)),}
  4020  		} else {
  4021  			$$ = &ast.AggregateFuncExpr{F: $1, Args: []ast.ExprNode{$4}, Distinct: $3.(bool)}
  4022  		}
  4023  	}
  4024  |	builtinBitAnd '(' Expression ')'  OptWindowingClause
  4025  	{
  4026  		if $5 != nil {
  4027  			$$ = &ast.WindowFuncExpr{F: $1, Args: []ast.ExprNode{$3}, Spec: *($5.(*ast.WindowSpec)),}
  4028  		} else {
  4029  			$$ = &ast.AggregateFuncExpr{F: $1, Args: []ast.ExprNode{$3},}
  4030  		}
  4031  	}
  4032  |	builtinBitAnd '(' "ALL" Expression ')'  OptWindowingClause
  4033  	{
  4034  		if $6 != nil {
  4035  			$$ = &ast.WindowFuncExpr{F: $1, Args: []ast.ExprNode{$4}, Spec: *($6.(*ast.WindowSpec)),}
  4036  		} else {
  4037  			$$ = &ast.AggregateFuncExpr{F: $1, Args: []ast.ExprNode{$4},}
  4038  		}
  4039  	}
  4040  |	builtinBitOr '(' Expression ')'  OptWindowingClause
  4041  	{
  4042  		if $5 != nil {
  4043  			$$ = &ast.WindowFuncExpr{F: $1, Args: []ast.ExprNode{$3}, Spec: *($5.(*ast.WindowSpec)),}
  4044  		} else {
  4045  			$$ = &ast.AggregateFuncExpr{F: $1, Args: []ast.ExprNode{$3},}
  4046  		}
  4047  	}
  4048  |	builtinBitOr '(' "ALL" Expression ')'  OptWindowingClause
  4049  	{
  4050  		if $6 != nil {
  4051  			$$ = &ast.WindowFuncExpr{F: $1, Args: []ast.ExprNode{$4}, Spec: *($6.(*ast.WindowSpec)),}
  4052  		} else {
  4053  			$$ = &ast.AggregateFuncExpr{F: $1, Args: []ast.ExprNode{$4},}
  4054  		}
  4055  	}
  4056  |	builtinBitXor '(' Expression ')'  OptWindowingClause
  4057  	{
  4058  		if $5 != nil {
  4059  			$$ = &ast.WindowFuncExpr{F: $1, Args: []ast.ExprNode{$3}, Spec: *($5.(*ast.WindowSpec)),}
  4060  		} else {
  4061  			$$ = &ast.AggregateFuncExpr{F: $1, Args: []ast.ExprNode{$3},}
  4062  		}
  4063  	}
  4064  |	builtinBitXor '(' "ALL" Expression ')'  OptWindowingClause
  4065  	{
  4066  		if $6 != nil {
  4067  			$$ = &ast.WindowFuncExpr{F: $1, Args: []ast.ExprNode{$4}, Spec: *($6.(*ast.WindowSpec)),}
  4068  		} else {
  4069  			$$ = &ast.AggregateFuncExpr{F: $1, Args: []ast.ExprNode{$4},}
  4070  		}
  4071  	}
  4072  |	builtinCount '(' DistinctKwd ExpressionList ')'
  4073  	{
  4074  		$$ = &ast.AggregateFuncExpr{F: $1, Args: $4.([]ast.ExprNode), Distinct: true}
  4075  	}
  4076  |	builtinCount '(' "ALL" Expression ')'  OptWindowingClause
  4077  	{
  4078  		if $6 != nil {
  4079  			$$ = &ast.WindowFuncExpr{F: $1, Args: []ast.ExprNode{$4}, Spec: *($6.(*ast.WindowSpec)),}
  4080  		} else {
  4081  			$$ = &ast.AggregateFuncExpr{F: $1, Args: []ast.ExprNode{$4},}
  4082  		}
  4083  	}
  4084  |	builtinCount '(' Expression ')'  OptWindowingClause
  4085  	{
  4086  		if $5 != nil {
  4087  			$$ = &ast.WindowFuncExpr{F: $1, Args: []ast.ExprNode{$3}, Spec: *($5.(*ast.WindowSpec)),}
  4088  		} else {
  4089  			$$ = &ast.AggregateFuncExpr{F: $1, Args: []ast.ExprNode{$3},}
  4090  		}
  4091  	}
  4092  |	builtinCount '(' '*' ')'  OptWindowingClause
  4093  	{
  4094  		args := []ast.ExprNode{ast.NewValueExpr(1)}
  4095  		if $5 != nil {
  4096  			$$ = &ast.WindowFuncExpr{F: $1, Args: args, Spec: *($5.(*ast.WindowSpec)),}
  4097  		} else {
  4098  			$$ = &ast.AggregateFuncExpr{F: $1, Args: args,}
  4099  		}
  4100  	}
  4101  |	builtinGroupConcat '(' BuggyDefaultFalseDistinctOpt ExpressionList OrderByOptional OptGConcatSeparator ')'
  4102  	{
  4103  		args := $4.([]ast.ExprNode)
  4104  		args = append(args, $6.(ast.ExprNode))
  4105  		$$ = &ast.AggregateFuncExpr{F: $1, Args: args, Distinct: $3.(bool)}
  4106  	}
  4107  |	builtinMax '(' BuggyDefaultFalseDistinctOpt Expression ')'  OptWindowingClause
  4108  	{
  4109  		if $6 != nil {
  4110  			$$ = &ast.WindowFuncExpr{F: $1, Args: []ast.ExprNode{$4}, Distinct: $3.(bool), Spec: *($6.(*ast.WindowSpec)),}
  4111  		} else {
  4112  			$$ = &ast.AggregateFuncExpr{F: $1, Args: []ast.ExprNode{$4}, Distinct: $3.(bool)}
  4113  		}
  4114  	}
  4115  |	builtinMin '(' BuggyDefaultFalseDistinctOpt Expression ')'  OptWindowingClause
  4116  	{
  4117  		if $6 != nil {
  4118  			$$ = &ast.WindowFuncExpr{F: $1, Args: []ast.ExprNode{$4}, Distinct: $3.(bool), Spec: *($6.(*ast.WindowSpec)),}
  4119  		} else {
  4120  			$$ = &ast.AggregateFuncExpr{F: $1, Args: []ast.ExprNode{$4}, Distinct: $3.(bool)}
  4121  		}
  4122  	}
  4123  |	builtinSum '(' BuggyDefaultFalseDistinctOpt Expression ')'  OptWindowingClause
  4124  	{
  4125  		if $6 != nil {
  4126  			$$ = &ast.WindowFuncExpr{F: $1, Args: []ast.ExprNode{$4}, Distinct: $3.(bool), Spec: *($6.(*ast.WindowSpec)),}
  4127  		} else {
  4128  			$$ = &ast.AggregateFuncExpr{F: $1, Args: []ast.ExprNode{$4}, Distinct: $3.(bool)}
  4129  		}
  4130  	}
  4131  |	builtinStddevPop '(' BuggyDefaultFalseDistinctOpt Expression ')'  OptWindowingClause
  4132  	{
  4133  		if $6 != nil {
  4134  			$$ = &ast.WindowFuncExpr{F: $1, Args: []ast.ExprNode{$4}, Distinct: $3.(bool), Spec: *($6.(*ast.WindowSpec)),}
  4135  		} else {
  4136  			$$ = &ast.AggregateFuncExpr{F: $1, Args: []ast.ExprNode{$4}, Distinct: $3.(bool)}
  4137  		}
  4138  	}
  4139  |	builtinStddevSamp '(' BuggyDefaultFalseDistinctOpt Expression ')'  OptWindowingClause
  4140  	{
  4141  		if $6 != nil {
  4142  			$$ = &ast.WindowFuncExpr{F: $1, Args: []ast.ExprNode{$4}, Distinct: $3.(bool), Spec: *($6.(*ast.WindowSpec)),}
  4143  		} else {
  4144  			$$ = &ast.AggregateFuncExpr{F: $1, Args: []ast.ExprNode{$4}, Distinct: $3.(bool)}
  4145  		}
  4146  	}
  4147  |	builtinVarPop '(' BuggyDefaultFalseDistinctOpt Expression ')'  OptWindowingClause
  4148  	{
  4149  		$$ = &ast.AggregateFuncExpr{F: ast.AggFuncVarPop, Args: []ast.ExprNode{$4}, Distinct: $3.(bool)}
  4150  	}
  4151  |	builtinVarSamp '(' BuggyDefaultFalseDistinctOpt Expression ')'  OptWindowingClause
  4152  	{
  4153  		$$ = &ast.AggregateFuncExpr{F: $1, Args: []ast.ExprNode{$4}, Distinct: $3.(bool)}
  4154  	}
  4155  
  4156  OptGConcatSeparator:
  4157          {
  4158              	$$ = ast.NewValueExpr(",")
  4159          }
  4160  | "SEPARATOR" stringLit
  4161  	{
  4162  		$$ = ast.NewValueExpr($2)
  4163  	}
  4164  
  4165  
  4166  FunctionCallGeneric:
  4167  	identifier '(' ExpressionListOpt ')'
  4168  	{
  4169  		$$ = &ast.FuncCallExpr{FnName: model.NewCIStr($1), Args: $3.([]ast.ExprNode)}
  4170  	}
  4171  
  4172  FuncDatetimePrec:
  4173  	{
  4174  		$$ = nil
  4175  	}
  4176  |	'(' ')'
  4177  	{
  4178  		$$ = nil
  4179  	}
  4180  |	'(' intLit ')'
  4181  	{
  4182  		expr := ast.NewValueExpr($2)
  4183  		$$ = expr
  4184  	}
  4185  
  4186  TimeUnit:
  4187  	"MICROSECOND"
  4188  	{
  4189  		$$ = strings.ToUpper($1)
  4190  	}
  4191  |	"SECOND"
  4192  	{
  4193  		$$ = strings.ToUpper($1)
  4194  	}
  4195  |	"MINUTE"
  4196  	{
  4197  		$$ = strings.ToUpper($1)
  4198  	}
  4199  |	"HOUR"
  4200  	{
  4201  		$$ = strings.ToUpper($1)
  4202  	}
  4203  |	"DAY"
  4204  	{
  4205  		$$ = strings.ToUpper($1)
  4206  	}
  4207  |	"WEEK"
  4208  	{
  4209  		$$ = strings.ToUpper($1)
  4210  	}
  4211  |	"MONTH"
  4212  	{
  4213  		$$ = strings.ToUpper($1)
  4214  	}
  4215  |	"QUARTER"
  4216  	{
  4217  		$$ = strings.ToUpper($1)
  4218  	}
  4219  |	"YEAR"
  4220  	{
  4221  		$$ = strings.ToUpper($1)
  4222  	}
  4223  |	"SECOND_MICROSECOND"
  4224  	{
  4225  		$$ = strings.ToUpper($1)
  4226  	}
  4227  |	"MINUTE_MICROSECOND"
  4228  	{
  4229  		$$ = strings.ToUpper($1)
  4230  	}
  4231  |	"MINUTE_SECOND"
  4232  	{
  4233  		$$ = strings.ToUpper($1)
  4234  	}
  4235  |	"HOUR_MICROSECOND"
  4236  	{
  4237  		$$ = strings.ToUpper($1)
  4238  	}
  4239  |	"HOUR_SECOND"
  4240  	{
  4241  		$$ = strings.ToUpper($1)
  4242  	}
  4243  |	"HOUR_MINUTE"
  4244  	{
  4245  		$$ = strings.ToUpper($1)
  4246  	}
  4247  |	"DAY_MICROSECOND"
  4248  	{
  4249  		$$ = strings.ToUpper($1)
  4250  	}
  4251  |	"DAY_SECOND"
  4252  	{
  4253  		$$ = strings.ToUpper($1)
  4254  	}
  4255  |	"DAY_MINUTE"
  4256  	{
  4257  		$$ = strings.ToUpper($1)
  4258  	}
  4259  |	"DAY_HOUR"
  4260  	{
  4261  		$$ = strings.ToUpper($1)
  4262  	}
  4263  |	"YEAR_MONTH"
  4264  	{
  4265  		$$ = strings.ToUpper($1)
  4266  	}
  4267  
  4268  TimestampUnit:
  4269  	"MICROSECOND"
  4270  	{
  4271  		$$ = strings.ToUpper($1)
  4272  	}
  4273  |	"SECOND"
  4274  	{
  4275  		$$ = strings.ToUpper($1)
  4276  	}
  4277  |	"MINUTE"
  4278  	{
  4279  		$$ = strings.ToUpper($1)
  4280  	}
  4281  |	"HOUR"
  4282  	{
  4283  		$$ = strings.ToUpper($1)
  4284  	}
  4285  |	"DAY"
  4286  	{
  4287  		$$ = strings.ToUpper($1)
  4288  	}
  4289  |	"WEEK"
  4290  	{
  4291  		$$ = strings.ToUpper($1)
  4292  	}
  4293  |	"MONTH"
  4294  	{
  4295  		$$ = strings.ToUpper($1)
  4296  	}
  4297  |	"QUARTER"
  4298  	{
  4299  		$$ = strings.ToUpper($1)
  4300  	}
  4301  |	"YEAR"
  4302  	{
  4303  		$$ = strings.ToUpper($1)
  4304  	}
  4305  
  4306  ExpressionOpt:
  4307  	{
  4308  		$$ = nil
  4309  	}
  4310  |	Expression
  4311  	{
  4312  		$$ = $1
  4313  	}
  4314  
  4315  WhenClauseList:
  4316  	WhenClause
  4317  	{
  4318  		$$ = []*ast.WhenClause{$1.(*ast.WhenClause)}
  4319  	}
  4320  |	WhenClauseList WhenClause
  4321  	{
  4322  		$$ = append($1.([]*ast.WhenClause), $2.(*ast.WhenClause))
  4323  	}
  4324  
  4325  WhenClause:
  4326  	"WHEN" Expression "THEN" Expression
  4327  	{
  4328  		$$ = &ast.WhenClause{
  4329  			Expr: $2,
  4330  			Result: $4,
  4331  		}
  4332  	}
  4333  
  4334  ElseOpt:
  4335  	/* empty */
  4336  	{
  4337  		$$ = nil
  4338  	}
  4339  |	"ELSE" Expression
  4340  	{
  4341  		$$ = $2
  4342  	}
  4343  
  4344  CastType:
  4345  	"BINARY" OptFieldLen
  4346  	{
  4347  		x := types.NewFieldType(mysql.TypeVarString)
  4348  		x.Flen = $2.(int)  // TODO: Flen should be the flen of expression
  4349  		if x.Flen != types.UnspecifiedLength {
  4350  			x.Tp = mysql.TypeString
  4351  		}
  4352  		x.Charset = mysql.CharsetBin
  4353  		x.Collate = mysql.CollationBin
  4354  		x.Flag |= mysql.BinaryFlag
  4355  		$$ = x
  4356  	}
  4357  |	"CHAR" OptFieldLen OptBinary
  4358  	{
  4359  		x := types.NewFieldType(mysql.TypeVarString)
  4360  		x.Flen = $2.(int)  // TODO: Flen should be the flen of expression
  4361  		x.Charset = $3.(*ast.OptBinary).Charset
  4362  		if $3.(*ast.OptBinary).IsBinary{
  4363  			x.Flag |= mysql.BinaryFlag
  4364  		}
  4365  		if x.Charset == "" {
  4366  			x.Charset = mysql.DefaultCharset
  4367  			x.Collate = mysql.DefaultCollationName
  4368  		}
  4369  		$$ = x
  4370  	}
  4371  |	"DATE"
  4372  	{
  4373  		x := types.NewFieldType(mysql.TypeDate)
  4374  		x.Charset = mysql.CharsetBin
  4375  		x.Collate = mysql.CollationBin
  4376  		x.Flag |= mysql.BinaryFlag
  4377  		$$ = x
  4378  	}
  4379  |	"DATETIME" OptFieldLen
  4380  	{
  4381  		x := types.NewFieldType(mysql.TypeDatetime)
  4382  		x.Flen, _ = mysql.GetDefaultFieldLengthAndDecimalForCast(mysql.TypeDatetime)
  4383  		x.Decimal = $2.(int)
  4384  		if x.Decimal > 0 {
  4385  			x.Flen = x.Flen + 1 + x.Decimal
  4386  		}
  4387  		x.Charset = mysql.CharsetBin
  4388  		x.Collate = mysql.CollationBin
  4389  		x.Flag |= mysql.BinaryFlag
  4390  		$$ = x
  4391  	}
  4392  |	"DECIMAL" FloatOpt
  4393  	{
  4394  		fopt := $2.(*ast.FloatOpt)
  4395  		x := types.NewFieldType(mysql.TypeNewDecimal)
  4396  		x.Flen = fopt.Flen
  4397  		x.Decimal = fopt.Decimal
  4398  		x.Charset = mysql.CharsetBin
  4399  		x.Collate = mysql.CollationBin
  4400  		x.Flag |= mysql.BinaryFlag
  4401  		$$ = x
  4402  	}
  4403  |	"TIME" OptFieldLen
  4404  	{
  4405  		x := types.NewFieldType(mysql.TypeDuration)
  4406  		x.Flen, _ = mysql.GetDefaultFieldLengthAndDecimalForCast(mysql.TypeDuration)
  4407  		x.Decimal = $2.(int)
  4408  		if x.Decimal > 0 {
  4409  			x.Flen = x.Flen + 1 + x.Decimal
  4410  		}
  4411  		x.Charset = mysql.CharsetBin
  4412  		x.Collate = mysql.CollationBin
  4413  		x.Flag |= mysql.BinaryFlag
  4414  		$$ = x
  4415  	}
  4416  |	"SIGNED" OptInteger
  4417  	{
  4418  		x := types.NewFieldType(mysql.TypeLonglong)
  4419  		x.Charset = mysql.CharsetBin
  4420  		x.Collate = mysql.CollationBin
  4421  		x.Flag |= mysql.BinaryFlag
  4422  		$$ = x
  4423  	}
  4424  |	"UNSIGNED" OptInteger
  4425  	{
  4426  		x := types.NewFieldType(mysql.TypeLonglong)
  4427  		x.Flag |= mysql.UnsignedFlag | mysql.BinaryFlag
  4428  		x.Charset = mysql.CharsetBin
  4429  		x.Collate = mysql.CollationBin
  4430  		$$ = x
  4431  	}
  4432  |	"JSON"
  4433  	{
  4434  		x := types.NewFieldType(mysql.TypeJSON)
  4435  		x.Flag |= mysql.BinaryFlag | (mysql.ParseToJSONFlag)
  4436  		x.Charset = mysql.DefaultCharset
  4437  		x.Collate = mysql.DefaultCollationName
  4438  		$$ = x
  4439  	}
  4440  
  4441  PriorityOpt:
  4442  	{
  4443  		$$ = mysql.NoPriority
  4444  	}
  4445  |	"LOW_PRIORITY"
  4446  	{
  4447  		$$ = mysql.LowPriority
  4448  	}
  4449  |	"HIGH_PRIORITY"
  4450  	{
  4451  		$$ = mysql.HighPriority
  4452  	}
  4453  |	"DELAYED"
  4454  	{
  4455  		$$ = mysql.DelayedPriority
  4456  	}
  4457  
  4458  TableName:
  4459  	Identifier
  4460  	{
  4461  		$$ = &ast.TableName{Name:model.NewCIStr($1)}
  4462  	}
  4463  |	Identifier '.' Identifier
  4464  	{
  4465  		$$ = &ast.TableName{Schema:model.NewCIStr($1),	Name:model.NewCIStr($3)}
  4466  	}
  4467  |	Identifier '.' '*'
  4468  	{
  4469  		$$ = &ast.TableName{Name:model.NewCIStr($1)}
  4470  	}
  4471  
  4472  TableNameList:
  4473  	TableName
  4474  	{
  4475  		tbl := []*ast.TableName{$1.(*ast.TableName)}
  4476  		$$ = tbl
  4477  	}
  4478  |	TableNameList ',' TableName
  4479  	{
  4480  		$$ = append($1.([]*ast.TableName), $3.(*ast.TableName))
  4481  	}
  4482  
  4483  QuickOptional:
  4484  	%prec empty
  4485  	{
  4486  		$$ = false
  4487  	}
  4488  |	"QUICK"
  4489  	{
  4490  		$$ = true
  4491  	}
  4492  
  4493  /***************************Prepared Statement Start******************************
  4494   * See https://dev.mysql.com/doc/refman/5.7/en/prepare.html
  4495   * Example:
  4496   * PREPARE stmt_name FROM 'SELECT SQRT(POW(?,2) + POW(?,2)) AS hypotenuse';
  4497   * OR
  4498   * SET @s = 'SELECT SQRT(POW(?,2) + POW(?,2)) AS hypotenuse';
  4499   * PREPARE stmt_name FROM @s;
  4500   */
  4501  
  4502  PreparedStmt:
  4503  	"PREPARE" Identifier "FROM" PrepareSQL
  4504  	{
  4505  		var sqlText string
  4506  		var sqlVar *ast.VariableExpr
  4507  		switch $4.(type) {
  4508  		case string:
  4509  			sqlText = $4.(string)
  4510  		case *ast.VariableExpr:
  4511  			sqlVar = $4.(*ast.VariableExpr)
  4512  		}
  4513  		$$ = &ast.PrepareStmt{
  4514  			Name:		$2,
  4515  			SQLText:	sqlText,
  4516  			SQLVar: 	sqlVar,
  4517  		}
  4518  	}
  4519  
  4520  PrepareSQL:
  4521  	stringLit
  4522  	{
  4523  		$$ = $1
  4524  	}
  4525  |	UserVariable
  4526  	{
  4527  		$$ = $1.(interface{})
  4528  	}
  4529  
  4530  
  4531  /*
  4532   * See https://dev.mysql.com/doc/refman/5.7/en/execute.html
  4533   * Example:
  4534   * EXECUTE stmt1 USING @a, @b;
  4535   * OR
  4536   * EXECUTE stmt1;
  4537   */
  4538  ExecuteStmt:
  4539  	"EXECUTE" Identifier
  4540  	{
  4541  		$$ = &ast.ExecuteStmt{Name: $2}
  4542  	}
  4543  |	"EXECUTE" Identifier "USING" UserVariableList
  4544  	{
  4545  		$$ = &ast.ExecuteStmt{
  4546  			Name: $2,
  4547  			UsingVars: $4.([]ast.ExprNode),
  4548  		}
  4549  	}
  4550  
  4551  UserVariableList:
  4552  	UserVariable
  4553  	{
  4554  		$$ = []ast.ExprNode{$1}
  4555  	}
  4556  |	UserVariableList ',' UserVariable
  4557  	{
  4558  		$$ = append($1.([]ast.ExprNode), $3)
  4559  	}
  4560  
  4561  /*
  4562   * See https://dev.mysql.com/doc/refman/5.0/en/deallocate-prepare.html
  4563   */
  4564  
  4565  DeallocateStmt:
  4566  	DeallocateSym "PREPARE" Identifier
  4567  	{
  4568  		$$ = &ast.DeallocateStmt{Name: $3}
  4569  	}
  4570  
  4571  DeallocateSym:
  4572  "DEALLOCATE" | "DROP"
  4573  
  4574  /****************************Prepared Statement End*******************************/
  4575  
  4576  RollbackStmt:
  4577  	"ROLLBACK"
  4578  	{
  4579  		$$ = &ast.RollbackStmt{}
  4580  	}
  4581  |	"ROLLBACK" CommitOpt
  4582  	{
  4583  		$$ = &ast.RollbackStmt{}
  4584  	}
  4585  |	"ROLLBACK" "WORK" "TO" "SAVEPOINT" StringName
  4586  	{
  4587  		$$ = &ast.RollbackStmt{Savepoint: $5.(string)}
  4588  	}
  4589  |	"ROLLBACK" "WORK" "TO" StringName
  4590  	{
  4591  		$$ = &ast.RollbackStmt{Savepoint: $4.(string)}
  4592  	}
  4593  |	"ROLLBACK" "TO" "SAVEPOINT" StringName
  4594  	{
  4595  		$$ = &ast.RollbackStmt{Savepoint: $4.(string)}
  4596  	}
  4597  |	"ROLLBACK" "TO" StringName
  4598  	{
  4599  		$$ = &ast.RollbackStmt{Savepoint: $3.(string)}
  4600  	}
  4601  
  4602  SavepointStmt:
  4603  	"SAVEPOINT" StringName
  4604  	{
  4605  		$$ = &ast.SavepointStmt{Savepoint : $2.(string)}
  4606  	}
  4607  |	"RELEASE" "SAVEPOINT" StringName
  4608      {
  4609          $$ = &ast.SavepointStmt{Savepoint : $3.(string), Release: true}
  4610      }
  4611  
  4612  SelectStmtBasic:
  4613  	"SELECT" SelectStmtOpts SelectStmtFieldList
  4614  	{
  4615  		st := &ast.SelectStmt {
  4616  			SelectStmtOpts: $2.(*ast.SelectStmtOpts),
  4617  			Distinct:      $2.(*ast.SelectStmtOpts).Distinct,
  4618  			Fields:        $3.(*ast.FieldList),
  4619  		}
  4620  		$$ = st
  4621  	}
  4622  
  4623  SelectStmtFromDualTable:
  4624  	SelectStmtBasic FromDual WhereClauseOptional
  4625  	{
  4626  		st := $1.(*ast.SelectStmt)
  4627  		lastField := st.Fields.Fields[len(st.Fields.Fields)-1]
  4628  		if lastField.Expr != nil && lastField.AsName.O == "" {
  4629  			lastEnd := yyS[yypt-1].offset-1
  4630  			lastField.SetText(parser.src[lastField.Offset:lastEnd])
  4631  		}
  4632  		if $3 != nil {
  4633  			st.Where = $3.(ast.ExprNode)
  4634  		}
  4635  	}
  4636  
  4637  SelectStmtFromTable:
  4638  	SelectStmtBasic "FROM"
  4639  	TableRefsClause WhereClauseOptional SelectStmtGroup HavingClause WindowClauseOptional
  4640  	{
  4641  		st := $1.(*ast.SelectStmt)
  4642  		st.From = $3.(*ast.TableRefsClause)
  4643  		if st.SelectStmtOpts.TableHints != nil {
  4644  			st.TableHints = st.SelectStmtOpts.TableHints
  4645  		}
  4646  		lastField := st.Fields.Fields[len(st.Fields.Fields)-1]
  4647  		if lastField.Expr != nil && lastField.AsName.O == "" {
  4648  			lastEnd := parser.endOffset(&yyS[yypt-5])
  4649  			lastField.SetText(parser.src[lastField.Offset:lastEnd])
  4650  		}
  4651  		if $4 != nil {
  4652  			st.Where = $4.(ast.ExprNode)
  4653  		}
  4654  		if $5 != nil {
  4655  			st.GroupBy = $5.(*ast.GroupByClause)
  4656  		}
  4657  		if $6 != nil {
  4658  			st.Having = $6.(*ast.HavingClause)
  4659  		}
  4660  		if $7 != nil {
  4661  		    st.WindowSpecs = ($7.([]ast.WindowSpec))
  4662  		}
  4663  		$$ = st
  4664  	}
  4665  
  4666  SelectStmt:
  4667  	SelectStmtBasic OrderByOptional SelectStmtLimit SelectLockOpt
  4668  	{
  4669  		st := $1.(*ast.SelectStmt)
  4670  		st.LockTp = $4.(ast.SelectLockType)
  4671  		lastField := st.Fields.Fields[len(st.Fields.Fields)-1]
  4672  		if lastField.Expr != nil && lastField.AsName.O == "" {
  4673  			src := parser.src
  4674  			var lastEnd int
  4675  			if $2 != nil {
  4676  				lastEnd = yyS[yypt-2].offset-1
  4677  			} else if $3 != nil {
  4678  				lastEnd = yyS[yypt-1].offset-1
  4679  			} else if $4 != ast.SelectLockNone {
  4680  				lastEnd = yyS[yypt].offset-1
  4681  			} else {
  4682  				lastEnd = len(src)
  4683  				if src[lastEnd-1] == ';' {
  4684  					lastEnd--
  4685  				}
  4686  			}
  4687  			lastField.SetText(src[lastField.Offset:lastEnd])
  4688  		}
  4689  		if $2 != nil {
  4690  			st.OrderBy = $2.(*ast.OrderByClause)
  4691  		}
  4692  		if $3 != nil {
  4693  			st.Limit = $3.(*ast.Limit)
  4694  		}
  4695  		$$ = st
  4696  	}
  4697  |	SelectStmtFromDualTable OrderByOptional SelectStmtLimit SelectLockOpt
  4698  	{
  4699  		st := $1.(*ast.SelectStmt)
  4700  		if $2 != nil {
  4701  			st.OrderBy = $2.(*ast.OrderByClause)
  4702  		}
  4703  		if $3 != nil {
  4704  			st.Limit = $3.(*ast.Limit)
  4705  		}
  4706  		st.LockTp = $4.(ast.SelectLockType)
  4707  		$$ = st
  4708  	}
  4709  |	SelectStmtFromTable OrderByOptional SelectStmtLimit SelectLockOpt
  4710  	{
  4711  		st := $1.(*ast.SelectStmt)
  4712  		st.LockTp = $4.(ast.SelectLockType)
  4713  		if $2 != nil {
  4714  			st.OrderBy = $2.(*ast.OrderByClause)
  4715  		}
  4716  		if $3 != nil {
  4717  			st.Limit = $3.(*ast.Limit)
  4718  		}
  4719  		$$ = st
  4720  	}
  4721  
  4722  FromDual:
  4723  	"FROM" "DUAL"
  4724  
  4725  WindowClauseOptional:
  4726  	{
  4727  		$$ = nil
  4728  	}
  4729  |	"WINDOW" WindowDefinitionList
  4730  	{
  4731  		$$ = $2.([]ast.WindowSpec)
  4732  	}
  4733  
  4734  WindowDefinitionList:
  4735  	WindowDefinition
  4736  	{
  4737  		$$ = []ast.WindowSpec{$1.(ast.WindowSpec)}
  4738  	}
  4739  |	WindowDefinitionList ',' WindowDefinition
  4740  	{
  4741  		$$ = append($1.([]ast.WindowSpec), $3.(ast.WindowSpec))
  4742  	}
  4743  
  4744  WindowDefinition:
  4745  	WindowName "AS" WindowSpec
  4746  	{
  4747  		var spec = $3.(ast.WindowSpec)
  4748  		spec.Name = $1.(model.CIStr)
  4749  		$$ = spec
  4750  	}
  4751  
  4752  WindowName:
  4753  	Identifier
  4754  	{
  4755  		$$ = model.NewCIStr($1)
  4756  	}
  4757  
  4758  WindowSpec:
  4759  	'(' WindowSpecDetails ')'
  4760  	{
  4761  		$$ = $2.(ast.WindowSpec)
  4762  	}
  4763  
  4764  WindowSpecDetails:
  4765  	OptExistingWindowName OptPartitionClause OptWindowOrderByClause OptWindowFrameClause
  4766  	{
  4767  		spec := ast.WindowSpec{Ref: $1.(model.CIStr),}
  4768  		if $2 != nil {
  4769  		    spec.PartitionBy = $2.(*ast.PartitionByClause)
  4770  		}
  4771  		if $3 != nil {
  4772  		    spec.OrderBy = $3.(*ast.OrderByClause)
  4773  		}
  4774  		if $4 != nil {
  4775  		    spec.Frame = $4.(*ast.FrameClause)
  4776  		}
  4777  		$$ = spec
  4778  	}
  4779  
  4780  OptExistingWindowName:
  4781  	{
  4782  		$$ = model.CIStr{}
  4783  	}
  4784  |	WindowName
  4785  	{
  4786  		$$ = $1.(model.CIStr)
  4787  	}
  4788  
  4789  OptPartitionClause:
  4790  	{
  4791  		$$ = nil
  4792  	}
  4793  |	"PARTITION" "BY" ByList
  4794  	{
  4795  		$$ = &ast.PartitionByClause{Items: $3.([]*ast.ByItem)}
  4796  	}
  4797  
  4798  OptWindowOrderByClause:
  4799  	{
  4800  		$$ = nil
  4801  	}
  4802  |	"ORDER" "BY" ByList
  4803  	{
  4804  		$$ = &ast.OrderByClause{Items: $3.([]*ast.ByItem)}
  4805  	}
  4806  
  4807  OptWindowFrameClause:
  4808  	{
  4809  		$$ = nil
  4810  	}
  4811  |	WindowFrameUnits WindowFrameExtent
  4812  	{
  4813  		$$ = &ast.FrameClause{
  4814  			Type: $1.(ast.FrameType),
  4815  			Extent: $2.(ast.FrameExtent),
  4816  		}
  4817  	}
  4818  
  4819  WindowFrameUnits:
  4820  	"ROWS"
  4821  	{
  4822  		$$ = ast.FrameType(ast.Rows)
  4823  	}
  4824  |	"RANGE"
  4825  	{
  4826  		$$ = ast.FrameType(ast.Ranges)
  4827  	}
  4828  |	"GROUPS"
  4829  	{
  4830  		$$ = ast.FrameType(ast.Groups)
  4831  	}
  4832  
  4833  WindowFrameExtent:
  4834  	WindowFrameStart
  4835  	{
  4836  		$$ = ast.FrameExtent {
  4837  			Start: $1.(ast.FrameBound),
  4838  			End: ast.FrameBound{Type: ast.CurrentRow,},
  4839  		}
  4840  	}
  4841  |	WindowFrameBetween
  4842  	{
  4843  		$$ = $1.(ast.FrameExtent)
  4844  	}
  4845  
  4846  WindowFrameStart:
  4847  	"UNBOUNDED" "PRECEDING"
  4848  	{
  4849  		$$ = ast.FrameBound{Type: ast.Preceding, UnBounded: true,}
  4850  	}
  4851  |	NumLiteral "PRECEDING"
  4852  	{
  4853  		$$ = ast.FrameBound{Type: ast.Preceding, Expr: ast.NewValueExpr($1),}
  4854  	}
  4855  |	paramMarker "PRECEDING"
  4856  	{
  4857  		$$ = ast.FrameBound{Type: ast.Preceding, Expr: ast.NewParamMarkerExpr(yyS[yypt].offset),}
  4858  	}
  4859  |	"INTERVAL" Expression TimeUnit "PRECEDING"
  4860  	{
  4861  		$$ = ast.FrameBound{Type: ast.Preceding, Expr: $2, Unit: ast.NewValueExpr($3),}
  4862  	}
  4863  |	"CURRENT" "ROW"
  4864  	{
  4865  		$$ = ast.FrameBound{Type: ast.CurrentRow,}
  4866  	}
  4867  
  4868  WindowFrameBetween:
  4869  	"BETWEEN" WindowFrameBound "AND" WindowFrameBound
  4870  	{
  4871  		$$ = ast.FrameExtent{Start: $2.(ast.FrameBound), End: $4.(ast.FrameBound),}
  4872  	}
  4873  
  4874  WindowFrameBound:
  4875  	WindowFrameStart
  4876  	{
  4877  		$$ = $1.(ast.FrameBound)
  4878  	}
  4879  |	"UNBOUNDED" "FOLLOWING"
  4880  	{
  4881  		$$ = ast.FrameBound{Type: ast.Following, UnBounded: true,}
  4882  	}
  4883  |	NumLiteral "FOLLOWING"
  4884  	{
  4885  		$$ = ast.FrameBound{Type: ast.Following, Expr: ast.NewValueExpr($1),}
  4886  	}
  4887  |	paramMarker "FOLLOWING"
  4888  	{
  4889  		$$ = ast.FrameBound{Type: ast.Following, Expr: ast.NewParamMarkerExpr(yyS[yypt].offset),}
  4890  	}
  4891  |	"INTERVAL" Expression TimeUnit "FOLLOWING"
  4892  	{
  4893  		$$ = ast.FrameBound{Type: ast.Following, Expr: $2, Unit: ast.NewValueExpr($3),}
  4894  	}
  4895  
  4896  OptWindowingClause:
  4897  	{
  4898  		$$ = nil
  4899  	}
  4900  |	WindowingClause
  4901  	{
  4902  		spec := $1.(ast.WindowSpec)
  4903  		$$ = &spec
  4904  	}
  4905  
  4906  WindowingClause:
  4907  	"OVER" WindowNameOrSpec
  4908  	{
  4909  		$$ = $2.(ast.WindowSpec)
  4910  	}
  4911  
  4912  WindowNameOrSpec:
  4913  	WindowName
  4914  	{
  4915  		$$ = ast.WindowSpec{Ref: $1.(model.CIStr)}
  4916  	}
  4917  |	WindowSpec
  4918  	{
  4919  		$$ = $1.(ast.WindowSpec)
  4920  	}
  4921  
  4922  WindowFuncCall:
  4923  	"ROW_NUMBER" '(' ')' WindowingClause
  4924  	{
  4925  		$$ = &ast.WindowFuncExpr{F: $1, Spec: $4.(ast.WindowSpec),}
  4926  	}
  4927  |	"RANK" '(' ')' WindowingClause
  4928  	{
  4929  		$$ = &ast.WindowFuncExpr{F: $1, Spec: $4.(ast.WindowSpec),}
  4930  	}
  4931  |	"DENSE_RANK" '(' ')' WindowingClause
  4932  	{
  4933  		$$ = &ast.WindowFuncExpr{F: $1, Spec: $4.(ast.WindowSpec),}
  4934  	}
  4935  |	"CUME_DIST" '(' ')' WindowingClause
  4936  	{
  4937  		$$ = &ast.WindowFuncExpr{F: $1, Spec: $4.(ast.WindowSpec),}
  4938  	}
  4939  |	"PERCENT_RANK" '(' ')' WindowingClause
  4940  	{
  4941  		$$ = &ast.WindowFuncExpr{F: $1, Spec: $4.(ast.WindowSpec),}
  4942  	}
  4943  |	"NTILE" '(' SimpleExpr ')' WindowingClause
  4944  	{
  4945  		$$ = &ast.WindowFuncExpr{F: $1, Args: []ast.ExprNode{$3}, Spec: $5.(ast.WindowSpec),}
  4946  	}
  4947  |	"LEAD" '(' Expression OptLeadLagInfo ')' OptNullTreatment WindowingClause
  4948  	{
  4949  		args := []ast.ExprNode{$3}
  4950  		if $4 != nil {
  4951  			args = append(args, $4.([]ast.ExprNode)...)
  4952  		}
  4953  		$$ = &ast.WindowFuncExpr{F: $1, Args: args, IgnoreNull: $6.(bool), Spec: $7.(ast.WindowSpec),}
  4954  	}
  4955  |	"LAG" '(' Expression OptLeadLagInfo ')' OptNullTreatment WindowingClause
  4956  	{
  4957  		args := []ast.ExprNode{$3}
  4958  		if $4 != nil {
  4959  			args = append(args, $4.([]ast.ExprNode)...)
  4960  		}
  4961  		$$ = &ast.WindowFuncExpr{F: $1, Args: args, IgnoreNull: $6.(bool), Spec: $7.(ast.WindowSpec),}
  4962  	}
  4963  |	"FIRST_VALUE" '(' Expression ')' OptNullTreatment WindowingClause
  4964  	{
  4965  		$$ = &ast.WindowFuncExpr{F: $1, Args: []ast.ExprNode{$3}, IgnoreNull: $5.(bool), Spec: $6.(ast.WindowSpec),}
  4966  	}
  4967  |	"LAST_VALUE" '(' Expression ')' OptNullTreatment WindowingClause
  4968  	{
  4969  		$$ = &ast.WindowFuncExpr{F: $1, Args: []ast.ExprNode{$3}, IgnoreNull: $5.(bool), Spec: $6.(ast.WindowSpec),}
  4970  	}
  4971  |	"NTH_VALUE" '(' Expression ',' SimpleExpr ')' OptFromFirstLast OptNullTreatment WindowingClause
  4972  	{
  4973  		$$ = &ast.WindowFuncExpr{F: $1, Args: []ast.ExprNode{$3, $5}, FromLast: $7.(bool), IgnoreNull: $8.(bool), Spec: $9.(ast.WindowSpec),}
  4974  	}
  4975  
  4976  OptLeadLagInfo:
  4977  	{
  4978  		$$ = nil
  4979  	}
  4980  |	',' NumLiteral OptLLDefault
  4981  	{
  4982  		args := []ast.ExprNode{ast.NewValueExpr($2)}
  4983  		if $3 != nil {
  4984  			args = append(args, $3.(ast.ExprNode))
  4985  		}
  4986  		$$ = args
  4987  	}
  4988  |	',' paramMarker OptLLDefault
  4989  	{
  4990  		args := []ast.ExprNode{ast.NewValueExpr($2)}
  4991  		if $3 != nil {
  4992  			args = append(args, $3.(ast.ExprNode))
  4993  		}
  4994  		$$ = args
  4995  	}
  4996  
  4997  OptLLDefault:
  4998  	{
  4999  		$$ = nil
  5000  	}
  5001  |	',' Expression
  5002  	{
  5003  		$$ = $2
  5004  	}
  5005  
  5006  OptNullTreatment:
  5007  	{
  5008  		$$ = false
  5009  	}
  5010  |	"RESPECT" "NULLS"
  5011  	{
  5012  		$$ = false
  5013  	}
  5014  |	"IGNORE" "NULLS"
  5015  	{
  5016  		$$ = true
  5017  	}
  5018  
  5019  OptFromFirstLast:
  5020  	{
  5021  		$$ = false
  5022  	}
  5023  |	"FROM" "FIRST"
  5024  	{
  5025  		$$ = false
  5026  	}
  5027  |	"FROM" "LAST"
  5028  	{
  5029  		$$ = true
  5030  	}
  5031  
  5032  TableRefsClause:
  5033  	TableRefs
  5034  	{
  5035  		$$ = &ast.TableRefsClause{TableRefs: $1.(*ast.Join)}
  5036  	}
  5037  
  5038  TableRefs:
  5039  	EscapedTableRef
  5040  	{
  5041  		if j, ok := $1.(*ast.Join); ok {
  5042  			// if $1 is Join, use it directly
  5043  			$$ = j
  5044  		} else {
  5045  			$$ = &ast.Join{Left: $1.(ast.ResultSetNode), Right: nil}
  5046  		}
  5047  	}
  5048  |	TableRefs ',' EscapedTableRef
  5049  	{
  5050  		/* from a, b is default cross join */
  5051  		$$ = &ast.Join{Left: $1.(ast.ResultSetNode), Right: $3.(ast.ResultSetNode), Tp: ast.CrossJoin}
  5052  	}
  5053  
  5054  EscapedTableRef:
  5055  	TableRef %prec lowerThanSetKeyword
  5056  	{
  5057  		$$ = $1
  5058  	}
  5059  |	'{' Identifier TableRef '}'
  5060  	{
  5061  		/*
  5062  		* ODBC escape syntax for outer join is { OJ join_table }
  5063  		* Use an Identifier for OJ
  5064  		*/
  5065  		$$ = $3
  5066  	}
  5067  
  5068  TableRef:
  5069  	TableFactor
  5070  	{
  5071  		$$ = $1
  5072  	}
  5073  |	JoinTable
  5074  	{
  5075  		$$ = $1
  5076  	}
  5077  
  5078  TableFactor:
  5079  	TableName PartitionNameListOpt TableAsNameOpt IndexHintListOpt
  5080  	{
  5081  		tn := $1.(*ast.TableName)
  5082  		tn.PartitionNames = $2.([]model.CIStr)
  5083  		tn.IndexHints = $4.([]*ast.IndexHint)
  5084  		$$ = &ast.TableSource{Source: tn, AsName: $3.(model.CIStr)}
  5085  	}
  5086  |	'(' SelectStmt ')' TableAsName
  5087  	{
  5088  		st := $2.(*ast.SelectStmt)
  5089  		endOffset := parser.endOffset(&yyS[yypt-1])
  5090  		parser.setLastSelectFieldText(st, endOffset)
  5091  		$$ = &ast.TableSource{Source: $2.(*ast.SelectStmt), AsName: $4.(model.CIStr)}
  5092  	}
  5093  |	'(' UnionStmt ')' TableAsName
  5094  	{
  5095  		$$ = &ast.TableSource{Source: $2.(*ast.UnionStmt), AsName: $4.(model.CIStr)}
  5096  	}
  5097  |	'(' TableRefs ')'
  5098  	{
  5099  		$$ = $2
  5100  	}
  5101  
  5102  PartitionNameListOpt:
  5103      /* empty */
  5104      {
  5105          $$ = []model.CIStr{}
  5106      }
  5107  |    "PARTITION" '(' PartitionNameList ')'
  5108      {
  5109          $$ = $3
  5110      }
  5111  
  5112  TableAsNameOpt:
  5113  	{
  5114  		$$ = model.CIStr{}
  5115  	}
  5116  |	TableAsName
  5117  	{
  5118  		$$ = $1
  5119  	}
  5120  
  5121  TableAsName:
  5122  	Identifier
  5123  	{
  5124  		$$ = model.NewCIStr($1)
  5125  	}
  5126  |	"AS" Identifier
  5127  	{
  5128  		$$ = model.NewCIStr($2)
  5129  	}
  5130  
  5131  IndexHintType:
  5132  	"USE" KeyOrIndex
  5133  	{
  5134  		$$ = ast.HintUse
  5135  	}
  5136  |	"IGNORE" KeyOrIndex
  5137  	{
  5138  		$$ = ast.HintIgnore
  5139  	}
  5140  |	"FORCE" KeyOrIndex
  5141  	{
  5142  		$$ = ast.HintForce
  5143  	}
  5144  
  5145  IndexHintScope:
  5146  	{
  5147  		$$ = ast.HintForScan
  5148  	}
  5149  |	"FOR" "JOIN"
  5150  	{
  5151  		$$ = ast.HintForJoin
  5152  	}
  5153  |	"FOR" "ORDER" "BY"
  5154  	{
  5155  		$$ = ast.HintForOrderBy
  5156  	}
  5157  |	"FOR" "GROUP" "BY"
  5158  	{
  5159  		$$ = ast.HintForGroupBy
  5160  	}
  5161  
  5162  
  5163  IndexHint:
  5164  	IndexHintType IndexHintScope '(' IndexNameList ')'
  5165  	{
  5166  		$$ = &ast.IndexHint{
  5167  			IndexNames:	$4.([]model.CIStr),
  5168  			HintType:	$1.(ast.IndexHintType),
  5169  			HintScope:	$2.(ast.IndexHintScope),
  5170  		}
  5171  	}
  5172  
  5173  IndexNameList:
  5174  	{
  5175  		var nameList []model.CIStr
  5176  		$$ = nameList
  5177  	}
  5178  |	Identifier
  5179  	{
  5180  		$$ = []model.CIStr{model.NewCIStr($1)}
  5181  	}
  5182  |	IndexNameList ',' Identifier
  5183  	{
  5184  		$$ = append($1.([]model.CIStr), model.NewCIStr($3))
  5185  	}
  5186  |	"PRIMARY"
  5187  	{
  5188  		$$ = []model.CIStr{model.NewCIStr($1)}
  5189  	}
  5190  
  5191  IndexHintList:
  5192  	IndexHint
  5193  	{
  5194  		$$ = []*ast.IndexHint{$1.(*ast.IndexHint)}
  5195  	}
  5196  |	IndexHintList IndexHint
  5197   	{
  5198   		$$ = append($1.([]*ast.IndexHint), $2.(*ast.IndexHint))
  5199   	}
  5200  
  5201  IndexHintListOpt:
  5202  	{
  5203  		var hintList []*ast.IndexHint
  5204  		$$ = hintList
  5205  	}
  5206  |	IndexHintList
  5207  	{
  5208  		$$ = $1
  5209  	}
  5210  
  5211  JoinTable:
  5212  	/* Use %prec to evaluate production TableRef before cross join */
  5213  	TableRef CrossOpt TableRef %prec tableRefPriority
  5214  	{
  5215  		$$ = &ast.Join{Left: $1.(ast.ResultSetNode), Right: $3.(ast.ResultSetNode), Tp: ast.CrossJoin}
  5216  	}
  5217  |	TableRef CrossOpt TableRef "ON" Expression
  5218  	{
  5219  		on := &ast.OnCondition{Expr: $5}
  5220  		$$ = &ast.Join{Left: $1.(ast.ResultSetNode), Right: $3.(ast.ResultSetNode), Tp: ast.CrossJoin, On: on}
  5221  	}
  5222  |	TableRef CrossOpt TableRef "USING" '(' ColumnNameList ')'
  5223  	{
  5224  		$$ = &ast.Join{Left: $1.(ast.ResultSetNode), Right: $3.(ast.ResultSetNode), Tp: ast.CrossJoin, Using: $6.([]*ast.ColumnName)}
  5225  	}
  5226  |	TableRef JoinType OuterOpt "JOIN" TableRef "ON" Expression
  5227  	{
  5228  		on := &ast.OnCondition{Expr: $7}
  5229  		$$ = &ast.Join{Left: $1.(ast.ResultSetNode), Right: $5.(ast.ResultSetNode), Tp: $2.(ast.JoinType), On: on}
  5230  	}
  5231  |	TableRef JoinType OuterOpt "JOIN" TableRef "USING" '(' ColumnNameList ')'
  5232  	{
  5233  		$$ = &ast.Join{Left: $1.(ast.ResultSetNode), Right: $5.(ast.ResultSetNode), Tp: $2.(ast.JoinType), Using: $8.([]*ast.ColumnName)}
  5234  	}
  5235  |	TableRef "NATURAL" "JOIN" TableRef
  5236  	{
  5237  		$$ = &ast.Join{Left: $1.(ast.ResultSetNode), Right: $4.(ast.ResultSetNode), NaturalJoin: true}
  5238  	}
  5239  |	TableRef "NATURAL" JoinType OuterOpt "JOIN" TableRef
  5240  	{
  5241  		$$ = &ast.Join{Left: $1.(ast.ResultSetNode), Right: $6.(ast.ResultSetNode), Tp: $3.(ast.JoinType), NaturalJoin: true}
  5242  	}
  5243  |	TableRef "STRAIGHT_JOIN" TableRef
  5244  	{
  5245  		$$ = &ast.Join{Left: $1.(ast.ResultSetNode), Right: $3.(ast.ResultSetNode), StraightJoin: true}
  5246  	}
  5247  |	TableRef "STRAIGHT_JOIN" TableRef "ON" Expression
  5248  	{
  5249  		on := &ast.OnCondition{Expr: $5}
  5250  		$$ = &ast.Join{Left: $1.(ast.ResultSetNode), Right: $3.(ast.ResultSetNode), StraightJoin: true, On: on}
  5251  	}
  5252  
  5253  JoinType:
  5254  	"LEFT"
  5255  	{
  5256  		$$ = ast.LeftJoin
  5257  	}
  5258  |	"RIGHT"
  5259  	{
  5260  		$$ = ast.RightJoin
  5261  	}
  5262  
  5263  OuterOpt:
  5264  	{}
  5265  |	"OUTER"
  5266  
  5267  CrossOpt:
  5268  	"JOIN"
  5269  |	"CROSS" "JOIN"
  5270  |	"INNER" "JOIN"
  5271  
  5272  
  5273  LimitClause:
  5274  	{
  5275  		$$ = nil
  5276  	}
  5277  |	"LIMIT" LimitOption
  5278  	{
  5279  		$$ = &ast.Limit{Count: $2.(ast.ValueExpr)}
  5280  	}
  5281  
  5282  LimitOption:
  5283  	LengthNum
  5284  	{
  5285  		$$ = ast.NewValueExpr($1)
  5286  	}
  5287  |	paramMarker
  5288  	{
  5289  		$$ = ast.NewParamMarkerExpr(yyS[yypt].offset)
  5290  	}
  5291  
  5292  SelectStmtLimit:
  5293  	{
  5294  		$$ = nil
  5295  	}
  5296  |	"LIMIT" LimitOption
  5297  	{
  5298  		$$ = &ast.Limit{Count: $2.(ast.ExprNode)}
  5299  	}
  5300  |	"LIMIT" LimitOption ',' LimitOption
  5301  	{
  5302  		$$ = &ast.Limit{Offset: $2.(ast.ExprNode), Count: $4.(ast.ExprNode)}
  5303  	}
  5304  |	"LIMIT" LimitOption "OFFSET" LimitOption
  5305  	{
  5306  		$$ = &ast.Limit{Offset: $4.(ast.ExprNode), Count: $2.(ast.ExprNode)}
  5307  	}
  5308  
  5309  
  5310  SelectStmtOpts:
  5311  	TableOptimizerHints DefaultFalseDistinctOpt PriorityOpt SelectStmtSQLCache SelectStmtCalcFoundRows SelectStmtStraightJoin
  5312  	{
  5313  		opt := &ast.SelectStmtOpts{}
  5314  		if $1 != nil {
  5315  			opt.TableHints = $1.([]*ast.TableOptimizerHint)
  5316  		}
  5317  		if $2 != nil {
  5318  			opt.Distinct = $2.(bool)
  5319  		}
  5320  		if $3 != nil {
  5321  			opt.Priority = $3.(mysql.PriorityEnum)
  5322  		}
  5323  		if $4 != nil {
  5324  			opt.SQLCache = $4.(bool)
  5325  		}
  5326  		if $5 != nil {
  5327  			opt.CalcFoundRows = $5.(bool)
  5328  		}
  5329  		if $6 != nil {
  5330  			opt.StraightJoin = $6.(bool)
  5331  		}
  5332  
  5333  		$$ = opt
  5334  	}
  5335  
  5336  TableOptimizerHints:
  5337  	/* empty */
  5338  	{
  5339  		$$ = nil
  5340  	}
  5341  |	hintBegin TableOptimizerHintList hintEnd
  5342  	{
  5343  		$$ = $2
  5344  	}
  5345  |	hintBegin error hintEnd
  5346  	{
  5347  		yyerrok()
  5348  		parser.lastErrorAsWarn()
  5349  		$$ = nil
  5350  	}
  5351  
  5352  HintTableList:
  5353  	Identifier
  5354  	{
  5355  		$$ = []model.CIStr{model.NewCIStr($1)}
  5356  	}
  5357  |	HintTableList ',' Identifier
  5358  	{
  5359  		$$ = append($1.([]model.CIStr), model.NewCIStr($3))
  5360  	}
  5361  
  5362  TableOptimizerHintList:
  5363  	TableOptimizerHintOpt
  5364  	{
  5365  		$$ = []*ast.TableOptimizerHint{$1.(*ast.TableOptimizerHint)}
  5366  	}
  5367  |	TableOptimizerHintList TableOptimizerHintOpt
  5368  	{
  5369  		$$ = append($1.([]*ast.TableOptimizerHint), $2.(*ast.TableOptimizerHint))
  5370  	}
  5371  
  5372  TableOptimizerHintOpt:
  5373  	tidbSMJ '(' HintTableList ')'
  5374  	{
  5375  		$$ = &ast.TableOptimizerHint{HintName: model.NewCIStr($1), Tables: $3.([]model.CIStr)}
  5376  	}
  5377  |	tidbINLJ '(' HintTableList ')'
  5378  	{
  5379  		$$ = &ast.TableOptimizerHint{HintName: model.NewCIStr($1), Tables: $3.([]model.CIStr)}
  5380  	}
  5381  |	tidbHJ '(' HintTableList ')'
  5382  	{
  5383  		$$ = &ast.TableOptimizerHint{HintName: model.NewCIStr($1), Tables: $3.([]model.CIStr)}
  5384  	}
  5385  |	maxExecutionTime '(' NUM ')'
  5386  	{
  5387  		$$ = &ast.TableOptimizerHint{HintName: model.NewCIStr($1), MaxExecutionTime: getUint64FromNUM($3)}
  5388  	}
  5389  
  5390  SelectStmtCalcFoundRows:
  5391  	{
  5392  		$$ = false
  5393  	}
  5394  |	"SQL_CALC_FOUND_ROWS"
  5395  	{
  5396  		$$ = true
  5397  	}
  5398  SelectStmtSQLCache:
  5399  	%prec empty
  5400  	{
  5401  		$$ = true
  5402  	}
  5403  |	"SQL_CACHE"
  5404  	{
  5405  		$$ = true
  5406  	}
  5407  |	"SQL_NO_CACHE"
  5408  	{
  5409  		$$ = false
  5410  	}
  5411  SelectStmtStraightJoin:
  5412  	%prec empty
  5413  	{
  5414  		$$ = false
  5415  	}
  5416  |	"STRAIGHT_JOIN"
  5417  	{
  5418  		$$ = true
  5419  	}
  5420  
  5421  SelectStmtFieldList:
  5422  	FieldList
  5423  	{
  5424  		$$ = &ast.FieldList{Fields: $1.([]*ast.SelectField)}
  5425  	}
  5426  
  5427  SelectStmtGroup:
  5428  	/* EMPTY */
  5429  	{
  5430  		$$ = nil
  5431  	}
  5432  |	GroupByClause
  5433  
  5434  // See https://dev.mysql.com/doc/refman/5.7/en/subqueries.html
  5435  SubSelect:
  5436  	'(' SelectStmt ')'
  5437  	{
  5438  		s := $2.(*ast.SelectStmt)
  5439  		endOffset := parser.endOffset(&yyS[yypt])
  5440  		parser.setLastSelectFieldText(s, endOffset)
  5441  		src := parser.src
  5442  		// See the implementation of yyParse function
  5443  		s.SetText(src[yyS[yypt-1].offset:yyS[yypt].offset])
  5444  		$$ = &ast.SubqueryExpr{Query: s}
  5445  	}
  5446  |	'(' UnionStmt ')'
  5447  	{
  5448  		s := $2.(*ast.UnionStmt)
  5449  		src := parser.src
  5450  		// See the implementation of yyParse function
  5451  		s.SetText(src[yyS[yypt-1].offset:yyS[yypt].offset])
  5452  		$$ = &ast.SubqueryExpr{Query: s}
  5453  	}
  5454  
  5455  // See https://dev.mysql.com/doc/refman/5.7/en/innodb-locking-reads.html
  5456  SelectLockOpt:
  5457  	/* empty */
  5458  	{
  5459  		$$ = ast.SelectLockNone
  5460  	}
  5461  |	"FOR" "UPDATE"
  5462  	{
  5463  		$$ = ast.SelectLockForUpdate
  5464  	}
  5465  |	"LOCK" "IN" "SHARE" "MODE"
  5466  	{
  5467  		$$ = ast.SelectLockInShareMode
  5468  	}
  5469  
  5470  // See https://dev.mysql.com/doc/refman/5.7/en/union.html
  5471  UnionStmt:
  5472  	UnionClauseList "UNION" UnionOpt SelectStmtBasic OrderByOptional SelectStmtLimit SelectLockOpt
  5473  	{
  5474  		st := $4.(*ast.SelectStmt)
  5475  		union := $1.(*ast.UnionStmt)
  5476  		st.IsAfterUnionDistinct = $3.(bool)
  5477  		lastSelect := union.SelectList.Selects[len(union.SelectList.Selects)-1]
  5478  		endOffset := parser.endOffset(&yyS[yypt-5])
  5479  		parser.setLastSelectFieldText(lastSelect, endOffset)
  5480  		union.SelectList.Selects = append(union.SelectList.Selects, st)
  5481  		if $5 != nil {
  5482  		    union.OrderBy = $5.(*ast.OrderByClause)
  5483  		}
  5484  		if $6 != nil {
  5485  		    union.Limit = $6.(*ast.Limit)
  5486  		}
  5487  		if $5 == nil && $6 == nil {
  5488  		    st.LockTp = $7.(ast.SelectLockType)
  5489  		}
  5490  		$$ = union
  5491  	}
  5492  |	UnionClauseList "UNION" UnionOpt SelectStmtFromDualTable OrderByOptional
  5493      SelectStmtLimit SelectLockOpt
  5494  	{
  5495  		st := $4.(*ast.SelectStmt)
  5496  		union := $1.(*ast.UnionStmt)
  5497  		st.IsAfterUnionDistinct = $3.(bool)
  5498  		lastSelect := union.SelectList.Selects[len(union.SelectList.Selects)-1]
  5499  		endOffset := parser.endOffset(&yyS[yypt-5])
  5500  		parser.setLastSelectFieldText(lastSelect, endOffset)
  5501  		union.SelectList.Selects = append(union.SelectList.Selects, st)
  5502  		if $5 != nil {
  5503  			union.OrderBy = $5.(*ast.OrderByClause)
  5504  		}
  5505  		if $6 != nil {
  5506  			union.Limit = $6.(*ast.Limit)
  5507  		}
  5508  		if $5 == nil && $6 == nil {
  5509  			st.LockTp = $7.(ast.SelectLockType)
  5510  		}
  5511  		$$ = union
  5512  	}
  5513  |	UnionClauseList "UNION" UnionOpt SelectStmtFromTable OrderByOptional
  5514     	SelectStmtLimit SelectLockOpt
  5515  	{
  5516  		st := $4.(*ast.SelectStmt)
  5517  		union := $1.(*ast.UnionStmt)
  5518  		st.IsAfterUnionDistinct = $3.(bool)
  5519  		lastSelect := union.SelectList.Selects[len(union.SelectList.Selects)-1]
  5520  		endOffset := parser.endOffset(&yyS[yypt-5])
  5521  		parser.setLastSelectFieldText(lastSelect, endOffset)
  5522  		union.SelectList.Selects = append(union.SelectList.Selects, st)
  5523  		if $5 != nil {
  5524  			union.OrderBy = $5.(*ast.OrderByClause)
  5525  		}
  5526  		if $6 != nil {
  5527  			union.Limit = $6.(*ast.Limit)
  5528  		}
  5529  		if $5 == nil && $6 == nil {
  5530  			st.LockTp = $7.(ast.SelectLockType)
  5531  		}
  5532  		$$ = union
  5533  	}
  5534  |	UnionClauseList "UNION" UnionOpt '(' SelectStmt ')' OrderByOptional SelectStmtLimit
  5535  	{
  5536  		union := $1.(*ast.UnionStmt)
  5537  		lastSelect := union.SelectList.Selects[len(union.SelectList.Selects)-1]
  5538  		endOffset := parser.endOffset(&yyS[yypt-6])
  5539  		parser.setLastSelectFieldText(lastSelect, endOffset)
  5540  		st := $5.(*ast.SelectStmt)
  5541  		st.IsInBraces = true
  5542  		st.IsAfterUnionDistinct = $3.(bool)
  5543  		endOffset = parser.endOffset(&yyS[yypt-2])
  5544  		parser.setLastSelectFieldText(st, endOffset)
  5545  		union.SelectList.Selects = append(union.SelectList.Selects, st)
  5546  		if $7 != nil {
  5547  			union.OrderBy = $7.(*ast.OrderByClause)
  5548  		}
  5549  		if $8 != nil {
  5550  			union.Limit = $8.(*ast.Limit)
  5551  		}
  5552  		$$ = union
  5553  	}
  5554  
  5555  UnionClauseList:
  5556  	UnionSelect
  5557  	{
  5558  		selectList := &ast.UnionSelectList{Selects: []*ast.SelectStmt{$1.(*ast.SelectStmt)}}
  5559  		$$ = &ast.UnionStmt{
  5560  			SelectList: selectList,
  5561  		}
  5562  	}
  5563  |	UnionClauseList "UNION" UnionOpt UnionSelect
  5564  	{
  5565  		union := $1.(*ast.UnionStmt)
  5566  		st := $4.(*ast.SelectStmt)
  5567  		st.IsAfterUnionDistinct = $3.(bool)
  5568  		lastSelect := union.SelectList.Selects[len(union.SelectList.Selects)-1]
  5569  		endOffset := parser.endOffset(&yyS[yypt-2])
  5570  		parser.setLastSelectFieldText(lastSelect, endOffset)
  5571  		union.SelectList.Selects = append(union.SelectList.Selects, st)
  5572  		$$ = union
  5573  	}
  5574  
  5575  UnionSelect:
  5576  	SelectStmt
  5577  	{
  5578  		$$ = $1.(interface{})
  5579  	}
  5580  |	'(' SelectStmt ')'
  5581  	{
  5582  		st := $2.(*ast.SelectStmt)
  5583  		st.IsInBraces = true
  5584  		endOffset := parser.endOffset(&yyS[yypt])
  5585  		parser.setLastSelectFieldText(st, endOffset)
  5586  		$$ = $2
  5587  	}
  5588  
  5589  UnionOpt:
  5590  DefaultTrueDistinctOpt
  5591  
  5592  
  5593  /********************Set Statement*******************************/
  5594  SetStmt:
  5595  	"SET" VariableAssignmentList
  5596  	{
  5597  		$$ = &ast.SetStmt{Variables: $2.([]*ast.VariableAssignment)}
  5598  	}
  5599  |	"SET" "PASSWORD" eq PasswordOpt
  5600  	{
  5601  		$$ = &ast.SetPwdStmt{Password: $4.(string)}
  5602  	}
  5603  |	"SET" "PASSWORD" "FOR" Username eq PasswordOpt
  5604  	{
  5605  		$$ = &ast.SetPwdStmt{User: $4.(*auth.UserIdentity), Password: $6.(string)}
  5606  	}
  5607  |	"SET" "GLOBAL" "TRANSACTION" TransactionChars
  5608  	{
  5609  		vars := $4.([]*ast.VariableAssignment)
  5610  		for _, v := range vars {
  5611  			v.IsGlobal = true
  5612  		}
  5613  		$$ = &ast.SetStmt{Variables: vars}
  5614  	}
  5615  |	"SET" "SESSION" "TRANSACTION" TransactionChars
  5616  	{
  5617  		$$ = &ast.SetStmt{Variables: $4.([]*ast.VariableAssignment)}
  5618  	}
  5619  |	"SET" "TRANSACTION" TransactionChars
  5620  	{
  5621  		assigns := $3.([]*ast.VariableAssignment)
  5622  		for i:=0; i<len(assigns); i++ {
  5623  			if assigns[i].Name == "tx_isolation" {
  5624  				// A special session variable that make setting tx_isolation take effect one time.
  5625  				assigns[i].Name = "tx_isolation_one_shot"
  5626  			}
  5627  		}
  5628  		$$ = &ast.SetStmt{Variables: assigns}
  5629  	}
  5630  
  5631  SetRoleStmt:
  5632  	"SET" "ROLE" SetRoleOpt
  5633  	{
  5634  	}
  5635  
  5636  SetDefaultRoleStmt:
  5637  	"SET" "DEFAULT" "ROLE" SetDefaultRoleOpt "TO" UsernameList
  5638  	{
  5639  	}
  5640  
  5641  SetDefaultRoleOpt:
  5642  	"NONE"
  5643  	{
  5644  	}
  5645  |	"ALL"
  5646  	{
  5647  	}
  5648  |	RolenameList
  5649  	{
  5650  	}
  5651  
  5652  SetRoleOpt:
  5653  	"ALL" "EXCEPT" RolenameList
  5654  	{
  5655  	}
  5656  |	SetDefaultRoleOpt
  5657  	{
  5658  	}
  5659  |	"DEFAULT"
  5660  	{
  5661  	}
  5662  
  5663  
  5664  TransactionChars:
  5665  	TransactionChar
  5666  	{
  5667  		if $1 != nil {
  5668  			$$ = $1
  5669  		} else {
  5670  			$$ = []*ast.VariableAssignment{}
  5671  		}
  5672  	}
  5673  |	TransactionChars ',' TransactionChar
  5674  	{
  5675  		if $3 != nil {
  5676  			varAssigns := $3.([]*ast.VariableAssignment)
  5677  			$$ = append($1.([]*ast.VariableAssignment), varAssigns...)
  5678  		} else {
  5679  			$$ = $1
  5680  		}
  5681  	}
  5682  
  5683  TransactionChar:
  5684  	"ISOLATION" "LEVEL" IsolationLevel
  5685  	{
  5686  		varAssigns := []*ast.VariableAssignment{}
  5687  		expr := ast.NewValueExpr($3)
  5688  		varAssigns = append(varAssigns, &ast.VariableAssignment{Name: "tx_isolation", Value: expr, IsSystem: true})
  5689  		$$ = varAssigns
  5690  	}
  5691  |	"READ" "WRITE"
  5692  	{
  5693  		varAssigns := []*ast.VariableAssignment{}
  5694  		expr := ast.NewValueExpr("0")
  5695  		varAssigns = append(varAssigns, &ast.VariableAssignment{Name: "tx_read_only", Value: expr, IsSystem: true})
  5696  		$$ = varAssigns
  5697  	}
  5698  |	"READ" "ONLY"
  5699  	{
  5700  		varAssigns := []*ast.VariableAssignment{}
  5701  		expr := ast.NewValueExpr("1")
  5702  		varAssigns = append(varAssigns, &ast.VariableAssignment{Name: "tx_read_only", Value: expr, IsSystem: true})
  5703  		$$ = varAssigns
  5704  	}
  5705  
  5706  IsolationLevel:
  5707  	"REPEATABLE" "READ"
  5708  	{
  5709  		$$ = ast.RepeatableRead
  5710  	}
  5711  |	"READ"	"COMMITTED"
  5712  	{
  5713  		$$ = ast.ReadCommitted
  5714  	}
  5715  |	"READ"	"UNCOMMITTED"
  5716  	{
  5717  		$$ = ast.ReadUncommitted
  5718  	}
  5719  |	"SERIALIZABLE"
  5720  	{
  5721  		$$ = ast.Serializable
  5722  	}
  5723  
  5724  SetExpr:
  5725  	"ON"
  5726  	{
  5727  		$$ = ast.NewValueExpr("ON")
  5728  	}
  5729  |	ExprOrDefault
  5730  
  5731  VariableAssignment:
  5732  	Identifier eq SetExpr
  5733  	{
  5734  		$$ = &ast.VariableAssignment{Name: $1, Value: $3, IsSystem: true}
  5735  	}
  5736  |	"GLOBAL" Identifier eq SetExpr
  5737  	{
  5738  		$$ = &ast.VariableAssignment{Name: $2, Value: $4, IsGlobal: true, IsSystem: true}
  5739  	}
  5740  |	"SESSION" Identifier eq SetExpr
  5741  	{
  5742  		$$ = &ast.VariableAssignment{Name: $2, Value: $4, IsSystem: true}
  5743  	}
  5744  |	"LOCAL" Identifier eq Expression
  5745  	{
  5746  		$$ = &ast.VariableAssignment{Name: $2, Value: $4, IsSystem: true}
  5747  	}
  5748  |	doubleAtIdentifier eq SetExpr
  5749  	{
  5750  		v := strings.ToLower($1)
  5751  		var isGlobal bool
  5752  		if strings.HasPrefix(v, "@@global.") {
  5753  			isGlobal = true
  5754  			v = strings.TrimPrefix(v, "@@global.")
  5755  		} else if strings.HasPrefix(v, "@@session.") {
  5756  			v = strings.TrimPrefix(v, "@@session.")
  5757  		} else if strings.HasPrefix(v, "@@local.") {
  5758  			v = strings.TrimPrefix(v, "@@local.")
  5759  		} else if strings.HasPrefix(v, "@@") {
  5760  			v = strings.TrimPrefix(v, "@@")
  5761  		}
  5762  		$$ = &ast.VariableAssignment{Name: v, Value: $3, IsGlobal: isGlobal, IsSystem: true}
  5763  	}
  5764  |	singleAtIdentifier eq Expression
  5765  	{
  5766  		v := $1
  5767  		v = strings.TrimPrefix(v, "@")
  5768  		$$ = &ast.VariableAssignment{Name: v, Value: $3}
  5769  	}
  5770  |	singleAtIdentifier assignmentEq Expression
  5771  	{
  5772  		v := $1
  5773  		v = strings.TrimPrefix(v, "@")
  5774  		$$ = &ast.VariableAssignment{Name: v, Value: $3}
  5775  	}
  5776  |	"NAMES" CharsetName
  5777  	{
  5778  		$$ = &ast.VariableAssignment{
  5779  			Name: ast.SetNames,
  5780  			Value: ast.NewValueExpr($2.(string)),
  5781  		}
  5782  	}
  5783  |	"NAMES" CharsetName "COLLATE" "DEFAULT"
  5784  	{
  5785  		$$ = &ast.VariableAssignment{
  5786  			Name: ast.SetNames,
  5787  			Value: ast.NewValueExpr($2.(string)),
  5788  		}
  5789  	}
  5790  |	"NAMES" CharsetName "COLLATE" StringName
  5791  	{
  5792  		$$ = &ast.VariableAssignment{
  5793  			Name: ast.SetNames,
  5794  			Value: ast.NewValueExpr($2.(string)),
  5795  			ExtendValue: ast.NewValueExpr($4.(string)),
  5796  		}
  5797  	}
  5798  |	CharsetKw CharsetName
  5799  	{
  5800  		$$ = &ast.VariableAssignment{
  5801  			Name: ast.SetNames,
  5802  			Value: ast.NewValueExpr($2.(string)),
  5803  		}
  5804  	}
  5805  
  5806  CharsetName:
  5807  	StringName
  5808  	{
  5809  		$$ = $1
  5810  	}
  5811  |	binaryType
  5812  	{
  5813  		$$ = mysql.CharsetBin
  5814  	}
  5815  
  5816  VariableAssignmentList:
  5817  	{
  5818  		$$ = []*ast.VariableAssignment{}
  5819  	}
  5820  |	VariableAssignment
  5821  	{
  5822  		$$ = []*ast.VariableAssignment{$1.(*ast.VariableAssignment)}
  5823  	}
  5824  |	VariableAssignmentList ',' VariableAssignment
  5825  	{
  5826  		$$ = append($1.([]*ast.VariableAssignment), $3.(*ast.VariableAssignment))
  5827  	}
  5828  
  5829  Variable:
  5830  	SystemVariable | UserVariable
  5831  
  5832  SystemVariable:
  5833  	doubleAtIdentifier
  5834  	{
  5835  		v := strings.ToLower($1)
  5836  		var isGlobal bool
  5837  		explicitScope := true
  5838  		if strings.HasPrefix(v, "@@global.") {
  5839  			isGlobal = true
  5840  			v = strings.TrimPrefix(v, "@@global.")
  5841  		} else if strings.HasPrefix(v, "@@session.") {
  5842  			v = strings.TrimPrefix(v, "@@session.")
  5843  		} else if strings.HasPrefix(v, "@@local.") {
  5844  			v = strings.TrimPrefix(v, "@@local.")
  5845  		} else if strings.HasPrefix(v, "@@") {
  5846  			v, explicitScope = strings.TrimPrefix(v, "@@"), false
  5847  		}
  5848  		$$ = &ast.VariableExpr{Name: v, IsGlobal: isGlobal, IsSystem: true, ExplicitScope: explicitScope}
  5849  	}
  5850  
  5851  UserVariable:
  5852  	singleAtIdentifier
  5853  	{
  5854  		v := $1
  5855  		v = strings.TrimPrefix(v, "@")
  5856  		$$ = &ast.VariableExpr{Name: v, IsGlobal: false, IsSystem: false}
  5857  	}
  5858  
  5859  Username:
  5860  	StringName
  5861  	{
  5862  		$$ = &auth.UserIdentity{Username: $1.(string), Hostname: "%"}
  5863  	}
  5864  |	StringName '@' StringName
  5865  	{
  5866  		$$ = &auth.UserIdentity{Username: $1.(string), Hostname: $3.(string)}
  5867  	}
  5868  |	StringName singleAtIdentifier
  5869  	{
  5870  		$$ = &auth.UserIdentity{Username: $1.(string), Hostname: strings.TrimPrefix($2, "@")}
  5871  	}
  5872  |	"CURRENT_USER" OptionalBraces
  5873  	{
  5874  		$$ = &auth.UserIdentity{CurrentUser: true}
  5875  	}
  5876  
  5877  UsernameList:
  5878  	Username
  5879  	{
  5880  		$$ = []*auth.UserIdentity{$1.(*auth.UserIdentity)}
  5881  	}
  5882  |	UsernameList ',' Username
  5883  	{
  5884  		$$ = append($1.([]*auth.UserIdentity), $3.(*auth.UserIdentity))
  5885  	}
  5886  
  5887  PasswordOpt:
  5888  	stringLit
  5889  	{
  5890  		$$ = $1
  5891  	}
  5892  |	"PASSWORD" '(' AuthString ')'
  5893  	{
  5894  		$$ = $3.(string)
  5895  	}
  5896  
  5897  AuthString:
  5898  	stringLit
  5899  	{
  5900  		$$ = $1
  5901  	}
  5902  
  5903  RoleNameString:
  5904  	stringLit
  5905  	{
  5906  		$$ = $1
  5907  	}
  5908  |	identifier
  5909  	{
  5910  		$$ = $1
  5911  	}
  5912  
  5913  
  5914  Rolename:
  5915      RoleNameString
  5916  	{
  5917  		$$ = &auth.RoleIdentity{Username: $1.(string), Hostname: "%"}
  5918  	}
  5919  |	StringName '@' StringName
  5920  	{
  5921  		$$ = &auth.RoleIdentity{Username: $1.(string), Hostname: $3.(string)}
  5922  	}
  5923  |	StringName singleAtIdentifier
  5924  	{
  5925  		$$ = &auth.RoleIdentity{Username: $1.(string), Hostname: strings.TrimPrefix($2, "@")}
  5926  	}
  5927  
  5928  RolenameList:
  5929  	Rolename
  5930  	{
  5931  		$$ = []*auth.RoleIdentity{$1.(*auth.RoleIdentity)}
  5932  	}
  5933  |	RolenameList ',' Rolename
  5934  	{
  5935  		$$ = append($1.([]*auth.RoleIdentity), $3.(*auth.RoleIdentity))
  5936  	}
  5937  
  5938  /****************************Admin Statement*******************************/
  5939  AdminStmt:
  5940  	"ADMIN" "SHOW" "DDL"
  5941  	{
  5942  		$$ = &ast.AdminStmt{Tp: ast.AdminShowDDL}
  5943  	}
  5944  |	"ADMIN" "SHOW" "DDL" "JOBS"
  5945  	{
  5946  		$$ = &ast.AdminStmt{Tp: ast.AdminShowDDLJobs}
  5947  	}
  5948  |	"ADMIN" "SHOW" "DDL" "JOBS" NUM
  5949  	{
  5950  		$$ = &ast.AdminStmt{
  5951  		    Tp: ast.AdminShowDDLJobs,
  5952  		    JobNumber: $5.(int64),
  5953  		}
  5954  	}
  5955  |	"ADMIN" "SHOW" TableName "NEXT_ROW_ID"
  5956  	{
  5957  		$$ = &ast.AdminStmt{
  5958  			Tp: ast.AdminShowNextRowID,
  5959  			Tables: []*ast.TableName{$3.(*ast.TableName)},
  5960  		}
  5961  	}
  5962  |	"ADMIN" "CHECK" "TABLE" TableNameList
  5963  	{
  5964  		$$ = &ast.AdminStmt{
  5965  			Tp:	ast.AdminCheckTable,
  5966  			Tables: $4.([]*ast.TableName),
  5967  		}
  5968  	}
  5969  |	"ADMIN" "CHECK" "INDEX" TableName Identifier
  5970  	{
  5971  		$$ = &ast.AdminStmt{
  5972  			Tp: ast.AdminCheckIndex,
  5973  			Tables: []*ast.TableName{$4.(*ast.TableName)},
  5974  			Index: string($5),
  5975  		}
  5976  	}
  5977  |	"ADMIN" "RECOVER" "INDEX" TableName Identifier
  5978  	{
  5979  		$$ = &ast.AdminStmt{
  5980  			Tp: ast.AdminRecoverIndex,
  5981  			Tables: []*ast.TableName{$4.(*ast.TableName)},
  5982  			Index: string($5),
  5983  		}
  5984  	}
  5985  |	"ADMIN" "RESTORE" "TABLE" "BY" "JOB" NUM
  5986  	{
  5987  		$$ = &ast.AdminStmt{
  5988  			Tp: ast.AdminRestoreTable,
  5989  			JobIDs: []int64{$6.(int64)},
  5990  		}
  5991  	}
  5992  |	"ADMIN" "RESTORE" "TABLE" TableName
  5993  	{
  5994  		$$ = &ast.AdminStmt{
  5995  			Tp: ast.AdminRestoreTable,
  5996  			Tables: []*ast.TableName{$4.(*ast.TableName)},
  5997  		}
  5998  	}
  5999  |	"ADMIN" "RESTORE" "TABLE" TableName NUM
  6000  	{
  6001  		$$ = &ast.AdminStmt{
  6002  			Tp: ast.AdminRestoreTable,
  6003  			Tables: []*ast.TableName{$4.(*ast.TableName)},
  6004  			JobNumber: $5.(int64),
  6005  		}
  6006  	}
  6007  |	"ADMIN" "CLEANUP" "INDEX" TableName Identifier
  6008  	{
  6009  		$$ = &ast.AdminStmt{
  6010  			Tp: ast.AdminCleanupIndex,
  6011  			Tables: []*ast.TableName{$4.(*ast.TableName)},
  6012  			Index: string($5),
  6013  		}
  6014  	}
  6015  |	"ADMIN" "CHECK" "INDEX" TableName Identifier HandleRangeList
  6016  	{
  6017  		$$ = &ast.AdminStmt{
  6018  			Tp: ast.AdminCheckIndexRange,
  6019  			Tables:	[]*ast.TableName{$4.(*ast.TableName)},
  6020  			Index: string($5),
  6021  			HandleRanges: $6.([]ast.HandleRange),
  6022  		}
  6023  	}
  6024  |	"ADMIN" "CHECKSUM" "TABLE" TableNameList
  6025  	{
  6026  		$$ = &ast.AdminStmt{
  6027  			Tp: ast.AdminChecksumTable,
  6028  			Tables: $4.([]*ast.TableName),
  6029  		}
  6030  	}
  6031  |	"ADMIN" "CANCEL" "DDL" "JOBS" NumList
  6032  	{
  6033  		$$ = &ast.AdminStmt{
  6034  			Tp: ast.AdminCancelDDLJobs,
  6035  			JobIDs: $5.([]int64),
  6036  		}
  6037  	}
  6038  |	"ADMIN" "SHOW" "DDL" "JOB" "QUERIES" NumList
  6039  	{
  6040  		$$ = &ast.AdminStmt{
  6041  			Tp: ast.AdminShowDDLJobQueries,
  6042  			JobIDs: $6.([]int64),
  6043  		}
  6044  	}
  6045  |	"ADMIN" "SHOW" "SLOW" AdminShowSlow
  6046  	{
  6047  		$$ = &ast.AdminStmt{
  6048  			Tp: ast.AdminShowSlow,
  6049  			ShowSlow: $4.(*ast.ShowSlow),
  6050  		}
  6051  	}
  6052  
  6053  AdminShowSlow:
  6054  	"RECENT" NUM
  6055  	{
  6056  		$$ = &ast.ShowSlow{
  6057  			Tp: ast.ShowSlowRecent,
  6058  			Count: getUint64FromNUM($2),
  6059  		}
  6060  	}
  6061  |	"TOP" NUM
  6062  	{
  6063  		$$ = &ast.ShowSlow{
  6064  			Tp: ast.ShowSlowTop,
  6065  			Kind: ast.ShowSlowKindDefault,
  6066  			Count: getUint64FromNUM($2),
  6067  		}
  6068  	}
  6069  |	"TOP" "INTERNAL" NUM
  6070  	{
  6071  		$$ = &ast.ShowSlow{
  6072  			Tp: ast.ShowSlowTop,
  6073  			Kind: ast.ShowSlowKindInternal,
  6074  			Count: getUint64FromNUM($3),
  6075  		}
  6076  	}
  6077  |	"TOP" "ALL" NUM
  6078  	{
  6079  		$$ = &ast.ShowSlow{
  6080  			Tp: ast.ShowSlowTop,
  6081  			Kind: ast.ShowSlowKindAll,
  6082  			Count: getUint64FromNUM($3),
  6083  		}
  6084  	}
  6085  
  6086  HandleRangeList:
  6087  	HandleRange
  6088  	{
  6089  		$$ = []ast.HandleRange{$1.(ast.HandleRange)}
  6090  	}
  6091  |	HandleRangeList ',' HandleRange
  6092  	{
  6093  		$$ = append($1.([]ast.HandleRange), $3.(ast.HandleRange))
  6094  	}
  6095  
  6096  HandleRange:
  6097  	'(' NUM ',' NUM ')'
  6098  	{
  6099  		$$ = ast.HandleRange{Begin: $2.(int64), End: $4.(int64)}
  6100  	}
  6101  
  6102  
  6103  NumList:
  6104         NUM
  6105         {
  6106  	        $$ = []int64{$1.(int64)}
  6107         }
  6108  |
  6109         NumList ',' NUM
  6110         {
  6111  	        $$ = append($1.([]int64), $3.(int64))
  6112         }
  6113  
  6114  /****************************Show Statement*******************************/
  6115  ShowStmt:
  6116  	"SHOW" ShowTargetFilterable ShowLikeOrWhereOpt
  6117  	{
  6118  		stmt := $2.(*ast.ShowStmt)
  6119  		if $3 != nil {
  6120  			if x, ok := $3.(*ast.PatternLikeExpr); ok && x.Expr == nil {
  6121  				stmt.Pattern = x
  6122  			} else {
  6123  				stmt.Where = $3.(ast.ExprNode)
  6124  			}
  6125  		}
  6126  		$$ = stmt
  6127  	}
  6128  |	"SHOW" "CREATE" "TABLE" TableName
  6129  	{
  6130  		$$ = &ast.ShowStmt{
  6131  			Tp:	ast.ShowCreateTable,
  6132  			Table:	$4.(*ast.TableName),
  6133  		}
  6134  	}
  6135  |	"SHOW" "CREATE" "VIEW" TableName
  6136  	{
  6137  		$$ = &ast.ShowStmt{
  6138  			Tp:	ast.ShowCreateView,
  6139  			Table:	$4.(*ast.TableName),
  6140  		}
  6141  	}
  6142  |	"SHOW" "CREATE" "DATABASE" IfNotExists DBName
  6143  	{
  6144  		$$ = &ast.ShowStmt{
  6145  			Tp:	ast.ShowCreateDatabase,
  6146  			IfNotExists: $4.(bool),
  6147  			DBName:	$5.(string),
  6148  		}
  6149  	}
  6150  |	"SHOW" "CREATE" "USER" Username
  6151          {
  6152                  // See https://dev.mysql.com/doc/refman/5.7/en/show-create-user.html
  6153                  $$ = &ast.ShowStmt{
  6154                          Tp:	ast.ShowCreateUser,
  6155                          User:	$4.(*auth.UserIdentity),
  6156                  }
  6157          }
  6158  |	"SHOW" "GRANTS"
  6159  	{
  6160  		// See https://dev.mysql.com/doc/refman/5.7/en/show-grants.html
  6161  		$$ = &ast.ShowStmt{Tp: ast.ShowGrants}
  6162  	}
  6163  |	"SHOW" "GRANTS" "FOR" Username
  6164  	{
  6165  		// See https://dev.mysql.com/doc/refman/5.7/en/show-grants.html
  6166  		$$ = &ast.ShowStmt{
  6167  			Tp:	ast.ShowGrants,
  6168  			User:	$4.(*auth.UserIdentity),
  6169  		}
  6170  	}
  6171  |	"SHOW" "MASTER" "STATUS"
  6172  	{
  6173  		$$ = &ast.ShowStmt{
  6174  			Tp:	ast.ShowMasterStatus,
  6175  		}
  6176  	}
  6177  |	"SHOW" OptFull "PROCESSLIST"
  6178  	{
  6179  		$$ = &ast.ShowStmt{
  6180  			Tp: ast.ShowProcessList,
  6181  			Full:	$2.(bool),
  6182  		}
  6183  	}
  6184  |	"SHOW" "STATS_META" ShowLikeOrWhereOpt
  6185  	{
  6186  		stmt := &ast.ShowStmt{
  6187  			Tp: ast.ShowStatsMeta,
  6188  		}
  6189  		if $3 != nil {
  6190  			if x, ok := $3.(*ast.PatternLikeExpr); ok && x.Expr == nil {
  6191  				stmt.Pattern = x
  6192  			} else {
  6193  				stmt.Where = $3.(ast.ExprNode)
  6194  			}
  6195  		}
  6196  		$$ = stmt
  6197  	}
  6198  |	"SHOW" "STATS_HISTOGRAMS" ShowLikeOrWhereOpt
  6199  	{
  6200  		stmt := &ast.ShowStmt{
  6201  			Tp: ast.ShowStatsHistograms,
  6202  		}
  6203  		if $3 != nil {
  6204  			if x, ok := $3.(*ast.PatternLikeExpr); ok && x.Expr == nil {
  6205  				stmt.Pattern = x
  6206  			} else {
  6207  				stmt.Where = $3.(ast.ExprNode)
  6208  			}
  6209  		}
  6210  		$$ = stmt
  6211  	}
  6212  |	"SHOW" "STATS_BUCKETS" ShowLikeOrWhereOpt
  6213  	{
  6214  		stmt := &ast.ShowStmt{
  6215  			Tp: ast.ShowStatsBuckets,
  6216  		}
  6217  		if $3 != nil {
  6218  			if x, ok := $3.(*ast.PatternLikeExpr); ok && x.Expr == nil {
  6219  				stmt.Pattern = x
  6220  			} else {
  6221  				stmt.Where = $3.(ast.ExprNode)
  6222  			}
  6223  		}
  6224  		$$ = stmt
  6225  	}
  6226  |	"SHOW" "STATS_HEALTHY" ShowLikeOrWhereOpt
  6227  	{
  6228  		stmt := &ast.ShowStmt{
  6229  			Tp: ast.ShowStatsHealthy,
  6230  		}
  6231  		if $3 != nil {
  6232  			if x, ok := $3.(*ast.PatternLikeExpr); ok && x.Expr == nil {
  6233  				stmt.Pattern = x
  6234  			} else {
  6235  				stmt.Where = $3.(ast.ExprNode)
  6236  			}
  6237  		}
  6238  		$$ = stmt
  6239  	}
  6240  |	"SHOW" "PROFILES"
  6241  	{
  6242  		$$ = &ast.ShowStmt{
  6243  			Tp: ast.ShowProfiles,
  6244  		}
  6245  	}
  6246  |	"SHOW" "PRIVILEGES"
  6247  	{
  6248  		$$ = &ast.ShowStmt{
  6249  			Tp: ast.ShowPrivileges,
  6250  		}
  6251  	}
  6252  
  6253  ShowIndexKwd:
  6254  	"INDEX"
  6255  |	"INDEXES"
  6256  |	"KEYS"
  6257  
  6258  FromOrIn:
  6259  "FROM" | "IN"
  6260  
  6261  ShowTargetFilterable:
  6262  	"ENGINES"
  6263  	{
  6264  		$$ = &ast.ShowStmt{Tp: ast.ShowEngines}
  6265  	}
  6266  |	"DATABASES"
  6267  	{
  6268  		$$ = &ast.ShowStmt{Tp: ast.ShowDatabases}
  6269  	}
  6270  |	CharsetKw
  6271  	{
  6272  		$$ = &ast.ShowStmt{Tp: ast.ShowCharset}
  6273  	}
  6274  |	OptFull "TABLES" ShowDatabaseNameOpt
  6275  	{
  6276  		$$ = &ast.ShowStmt{
  6277  			Tp:	ast.ShowTables,
  6278  			DBName:	$3.(string),
  6279  			Full:	$1.(bool),
  6280  		}
  6281  	}
  6282  |	"TABLE" "STATUS" ShowDatabaseNameOpt
  6283  	{
  6284  		$$ = &ast.ShowStmt{
  6285  			Tp:	ast.ShowTableStatus,
  6286  			DBName:	$3.(string),
  6287  		}
  6288  	}
  6289  |	ShowIndexKwd FromOrIn TableName
  6290  	{
  6291          $$ = &ast.ShowStmt{
  6292              Tp: ast.ShowIndex,
  6293              Table: $3.(*ast.TableName),
  6294  		}
  6295  	}
  6296  |	ShowIndexKwd FromOrIn Identifier FromOrIn Identifier
  6297  	{
  6298          show := &ast.ShowStmt{
  6299              Tp: ast.ShowIndex,
  6300              Table: &ast.TableName{Name:model.NewCIStr($3), Schema: model.NewCIStr($5)},
  6301  		}
  6302          $$ = show
  6303  	}
  6304  |	OptFull "COLUMNS" ShowTableAliasOpt ShowDatabaseNameOpt
  6305  	{
  6306  		$$ = &ast.ShowStmt{
  6307  			Tp:     ast.ShowColumns,
  6308  			Table:	$3.(*ast.TableName),
  6309  			DBName:	$4.(string),
  6310  			Full:	$1.(bool),
  6311  		}
  6312  	}
  6313  |	OptFull "FIELDS" ShowTableAliasOpt ShowDatabaseNameOpt
  6314  	{
  6315  		// SHOW FIELDS is a synonym for SHOW COLUMNS.
  6316  		$$ = &ast.ShowStmt{
  6317  			Tp:     ast.ShowColumns,
  6318  			Table:	$3.(*ast.TableName),
  6319  			DBName:	$4.(string),
  6320  			Full:	$1.(bool),
  6321  		}
  6322  	}
  6323  |	"WARNINGS"
  6324  	{
  6325  		$$ = &ast.ShowStmt{Tp: ast.ShowWarnings}
  6326  	}
  6327  |	"ERRORS"
  6328  	{
  6329  		$$ = &ast.ShowStmt{Tp: ast.ShowErrors}
  6330  	}
  6331  |	GlobalScope "VARIABLES"
  6332  	{
  6333  		$$ = &ast.ShowStmt{
  6334  			Tp: ast.ShowVariables,
  6335  			GlobalScope: $1.(bool),
  6336  		}
  6337  	}
  6338  |	GlobalScope "STATUS"
  6339  	{
  6340  		$$ = &ast.ShowStmt{
  6341  			Tp: ast.ShowStatus,
  6342  			GlobalScope: $1.(bool),
  6343  		}
  6344  	}
  6345  |	GlobalScope "BINDINGS"
  6346  	{
  6347  		$$ = &ast.ShowStmt{
  6348  			Tp: ast.ShowBindings,
  6349  			GlobalScope: $1.(bool),
  6350  		}
  6351  	}
  6352  |	"COLLATION"
  6353  	{
  6354  		$$ = &ast.ShowStmt{
  6355  			Tp: 	ast.ShowCollation,
  6356  		}
  6357  	}
  6358  |	"TRIGGERS" ShowDatabaseNameOpt
  6359  	{
  6360  		$$ = &ast.ShowStmt{
  6361  			Tp:	ast.ShowTriggers,
  6362  			DBName:	$2.(string),
  6363  		}
  6364  	}
  6365  |	"PROCEDURE" "STATUS"
  6366  	{
  6367  		$$ = &ast.ShowStmt {
  6368  			Tp: ast.ShowProcedureStatus,
  6369  		}
  6370  	}
  6371  |	"PUMP" "STATUS"
  6372  	{
  6373  		$$ = &ast.ShowStmt {
  6374  			Tp: ast.ShowPumpStatus,
  6375  		}
  6376  	}
  6377  |	"DRAINER" "STATUS"
  6378  	{
  6379  		$$ = &ast.ShowStmt {
  6380  			Tp: ast.ShowDrainerStatus,
  6381  		}
  6382  	}
  6383  |	"FUNCTION" "STATUS"
  6384  	{
  6385  		// This statement is similar to SHOW PROCEDURE STATUS but for stored functions.
  6386  		// See http://dev.mysql.com/doc/refman/5.7/en/show-function-status.html
  6387  		// We do not support neither stored functions nor stored procedures.
  6388  		// So we reuse show procedure status process logic.
  6389  		$$ = &ast.ShowStmt {
  6390  			Tp: ast.ShowProcedureStatus,
  6391  		}
  6392  	}
  6393  |	"EVENTS" ShowDatabaseNameOpt
  6394  	{
  6395  		$$ = &ast.ShowStmt{
  6396  			Tp:	ast.ShowEvents,
  6397  			DBName:	$2.(string),
  6398  		}
  6399  	}
  6400  |	"PLUGINS"
  6401  	{
  6402  		$$ = &ast.ShowStmt{
  6403  			Tp: 	ast.ShowPlugins,
  6404  		}
  6405  	}
  6406  ShowLikeOrWhereOpt:
  6407  	{
  6408  		$$ = nil
  6409  	}
  6410  |	"LIKE" SimpleExpr
  6411  	{
  6412  		$$ = &ast.PatternLikeExpr{
  6413  			Pattern: $2,
  6414  			Escape: '\\',
  6415  		}
  6416  	}
  6417  |	"WHERE" Expression
  6418  	{
  6419  		$$ = $2
  6420  	}
  6421  
  6422  GlobalScope:
  6423  	{
  6424  		$$ = false
  6425  	}
  6426  |	"GLOBAL"
  6427  	{
  6428  		$$ = true
  6429  	}
  6430  |	"SESSION"
  6431  	{
  6432  		$$ = false
  6433  	}
  6434  
  6435  OptFull:
  6436  	{
  6437  		$$ = false
  6438  	}
  6439  |	"FULL"
  6440  	{
  6441  		$$ = true
  6442  	}
  6443  
  6444  ShowDatabaseNameOpt:
  6445  	{
  6446  		$$ = ""
  6447  	}
  6448  |	FromOrIn DBName
  6449  	{
  6450  		$$ = $2.(string)
  6451  	}
  6452  
  6453  ShowTableAliasOpt:
  6454  	FromOrIn TableName
  6455  	{
  6456  		$$ = $2.(*ast.TableName)
  6457  	}
  6458  
  6459  FlushStmt:
  6460  	"FLUSH" NoWriteToBinLogAliasOpt FlushOption
  6461  	{
  6462  		tmp := $3.(*ast.FlushStmt)
  6463  		tmp.NoWriteToBinLog = $2.(bool)
  6464  		$$ = tmp
  6465  	}
  6466  
  6467  PluginNameList:
  6468  	Identifier
  6469  	{
  6470  		$$ = []string{$1}
  6471  	}
  6472  |	PluginNameList ',' Identifier
  6473  	{
  6474  		$$ = append($1.([]string), $3)
  6475  	}
  6476  
  6477  FlushOption:
  6478  	"PRIVILEGES"
  6479  	{
  6480  		$$ = &ast.FlushStmt{
  6481  			Tp: ast.FlushPrivileges,
  6482  		}
  6483  	}
  6484  |	"STATUS"
  6485  	{
  6486  		$$ = &ast.FlushStmt{
  6487  			Tp: ast.FlushStatus,
  6488  		}
  6489  	}
  6490  |	"TIDB" "PLUGINS" PluginNameList
  6491  	{
  6492  		$$ = &ast.FlushStmt{
  6493  			Tp: ast.FlushTiDBPlugin,
  6494  			Plugins: $3.([]string),
  6495  		}
  6496  	}
  6497  |	TableOrTables TableNameListOpt WithReadLockOpt
  6498  	{
  6499  		$$ = &ast.FlushStmt{
  6500  			Tp: ast.FlushTables,
  6501  			Tables: $2.([]*ast.TableName),
  6502  			ReadLock: $3.(bool),
  6503  		}
  6504  	}
  6505  
  6506  NoWriteToBinLogAliasOpt:
  6507  	{
  6508  		$$ = false
  6509  	}
  6510  |	"NO_WRITE_TO_BINLOG"
  6511  	{
  6512  		$$ = true
  6513  	}
  6514  |	"LOCAL"
  6515  	{
  6516  		$$ = true
  6517  	}
  6518  
  6519  TableNameListOpt:
  6520  	%prec empty
  6521  	{
  6522  		$$ = []*ast.TableName{}
  6523  	}
  6524  |	TableNameList
  6525  	{
  6526  		$$ = $1
  6527  	}
  6528  
  6529  WithReadLockOpt:
  6530  	{
  6531  		$$ = false
  6532  	}
  6533  |	"WITH" "READ" "LOCK"
  6534  	{
  6535  		$$ = true
  6536  	}
  6537  
  6538  Statement:
  6539  	EmptyStmt
  6540  |	AdminStmt
  6541  |	AlterTableStmt
  6542  |	AlterUserStmt
  6543  |	AnalyzeTableStmt
  6544  |	BeginTransactionStmt
  6545  |	BinlogStmt
  6546  |	CommitStmt
  6547  |	DeallocateStmt
  6548  |	DeleteFromStmt
  6549  |	ExecuteStmt
  6550  |	ExplainStmt
  6551  |	CreateDatabaseStmt
  6552  |	CreateIndexStmt
  6553  |	CreateTableStmt
  6554  |	CreateViewStmt
  6555  |	CreateUserStmt
  6556  |	CreateRoleStmt
  6557  |	CreateBindingStmt
  6558  |	DoStmt
  6559  |	DropDatabaseStmt
  6560  |	DropIndexStmt
  6561  |	DropTableStmt
  6562  |	DropViewStmt
  6563  |	DropUserStmt
  6564  |	DropRoleStmt
  6565  |	DropStatsStmt
  6566  |	DropBindingStmt
  6567  |	FlushStmt
  6568  |	GrantStmt
  6569  |	GrantRoleStmt
  6570  |	InsertIntoStmt
  6571  |	KillStmt
  6572  |	LoadDataStmt
  6573  |	LoadStatsStmt
  6574  |	PreparedStmt
  6575  |	RollbackStmt
  6576  |	RenameTableStmt
  6577  |	ReplaceIntoStmt
  6578  |	RevokeStmt
  6579  |	RevokeRoleStmt
  6580  |	SavepointStmt
  6581  |	SelectStmt
  6582  |	UnionStmt
  6583  |	SetStmt
  6584  |	SetRoleStmt
  6585  |	SetDefaultRoleStmt
  6586  |	ShowStmt
  6587  |	SubSelect
  6588  	{
  6589  		// `(select 1)`; is a valid select statement
  6590  		// TODO: This is used to fix issue #320. There may be a better solution.
  6591  		$$ = $1.(*ast.SubqueryExpr).Query.(ast.StmtNode)
  6592  	}
  6593  |	TraceStmt
  6594  |	TruncateTableStmt
  6595  |	UpdateStmt
  6596  |	UseStmt
  6597  |	UnlockTablesStmt
  6598  |	LockTablesStmt
  6599  
  6600  TraceableStmt:
  6601  	SelectStmt
  6602  |	DeleteFromStmt
  6603  |	UpdateStmt
  6604  |	InsertIntoStmt
  6605  |	ReplaceIntoStmt
  6606  |	UnionStmt
  6607  
  6608  ExplainableStmt:
  6609  	SelectStmt
  6610  |	DeleteFromStmt
  6611  |	UpdateStmt
  6612  |	InsertIntoStmt
  6613  |	ReplaceIntoStmt
  6614  |	UnionStmt
  6615  
  6616  StatementList:
  6617  	Statement
  6618  	{
  6619  		if $1 != nil {
  6620  			s := $1
  6621  			if lexer, ok := yylex.(stmtTexter); ok {
  6622  				s.SetText(lexer.stmtText())
  6623  			}
  6624  			parser.result = append(parser.result, s)
  6625  		}
  6626  	}
  6627  |	StatementList ';' Statement
  6628  	{
  6629  		if $3 != nil {
  6630  			s := $3
  6631  			if lexer, ok := yylex.(stmtTexter); ok {
  6632  				s.SetText(lexer.stmtText())
  6633  			}
  6634  			parser.result = append(parser.result, s)
  6635  		}
  6636  	}
  6637  
  6638  Constraint:
  6639  	ConstraintKeywordOpt ConstraintElem
  6640  	{
  6641  		cst := $2.(*ast.Constraint)
  6642  		if $1 != nil {
  6643  			cst.Name = $1.(string)
  6644  		}
  6645  		$$ = cst
  6646  	}
  6647  
  6648  TableElement:
  6649  	ColumnDef
  6650  	{
  6651  		$$ = $1.(*ast.ColumnDef)
  6652  	}
  6653  |	Constraint
  6654  	{
  6655  		$$ = $1.(*ast.Constraint)
  6656  	}
  6657  |	"CHECK" '(' Expression ')'
  6658  	{
  6659  		/* Nothing to do now */
  6660  		$$ = nil
  6661  	}
  6662  
  6663  TableElementList:
  6664  	TableElement
  6665  	{
  6666  		if $1 != nil {
  6667  			$$ = []interface{}{$1.(interface{})}
  6668  		} else {
  6669  			$$ = []interface{}{}
  6670  		}
  6671  	}
  6672  |	TableElementList ',' TableElement
  6673  	{
  6674  		if $3 != nil {
  6675  			$$ = append($1.([]interface{}), $3)
  6676  		} else {
  6677  			$$ = $1
  6678  		}
  6679  	}
  6680  
  6681  TableElementListOpt:
  6682  	/* empty */ %prec lowerThanCreateTableSelect
  6683  	{
  6684  		var columnDefs []*ast.ColumnDef
  6685  		var constraints []*ast.Constraint
  6686  		$$ = &ast.CreateTableStmt{
  6687  			Cols:           columnDefs,
  6688  			Constraints:    constraints,
  6689  		}
  6690  	}
  6691  |
  6692  	'(' TableElementList ')'
  6693  	{
  6694  		tes := $2.([]interface {})
  6695  		var columnDefs []*ast.ColumnDef
  6696  		var constraints []*ast.Constraint
  6697  		for _, te := range tes {
  6698  			switch te := te.(type) {
  6699  			case *ast.ColumnDef:
  6700  				columnDefs = append(columnDefs, te)
  6701  			case *ast.Constraint:
  6702  				constraints = append(constraints, te)
  6703  			}
  6704  		}
  6705  		$$ = &ast.CreateTableStmt{
  6706  			Cols:           columnDefs,
  6707  			Constraints:    constraints,
  6708  		}
  6709  	}
  6710  
  6711  TableOption:
  6712  	"ENGINE" StringName
  6713  	{
  6714  		$$ = &ast.TableOption{Tp: ast.TableOptionEngine, StrValue: $2.(string)}
  6715  	}
  6716  |	"ENGINE" eq StringName
  6717  	{
  6718  		$$ = &ast.TableOption{Tp: ast.TableOptionEngine, StrValue: $3.(string)}
  6719  	}
  6720  |	DefaultKwdOpt CharsetKw EqOpt CharsetName
  6721  	{
  6722  		$$ = &ast.TableOption{Tp: ast.TableOptionCharset, StrValue: $4.(string)}
  6723  	}
  6724  |	DefaultKwdOpt "COLLATE" EqOpt StringName
  6725  	{
  6726  		$$ = &ast.TableOption{Tp: ast.TableOptionCollate, StrValue: $4.(string)}
  6727  	}
  6728  |	"AUTO_INCREMENT" EqOpt LengthNum
  6729  	{
  6730  		$$ = &ast.TableOption{Tp: ast.TableOptionAutoIncrement, UintValue: $3.(uint64)}
  6731  	}
  6732  |	"COMMENT" EqOpt stringLit
  6733  	{
  6734  		$$ = &ast.TableOption{Tp: ast.TableOptionComment, StrValue: $3}
  6735  	}
  6736  |	"AVG_ROW_LENGTH" EqOpt LengthNum
  6737  	{
  6738  		$$ = &ast.TableOption{Tp: ast.TableOptionAvgRowLength, UintValue: $3.(uint64)}
  6739  	}
  6740  |	"CONNECTION" EqOpt stringLit
  6741  	{
  6742  		$$ = &ast.TableOption{Tp: ast.TableOptionConnection, StrValue: $3}
  6743  	}
  6744  |	"CHECKSUM" EqOpt LengthNum
  6745  	{
  6746  		$$ = &ast.TableOption{Tp: ast.TableOptionCheckSum, UintValue: $3.(uint64)}
  6747  	}
  6748  |	"PASSWORD" EqOpt stringLit
  6749  	{
  6750  		$$ = &ast.TableOption{Tp: ast.TableOptionPassword, StrValue: $3}
  6751  	}
  6752  |	"COMPRESSION" EqOpt stringLit
  6753  	{
  6754  		$$ = &ast.TableOption{Tp: ast.TableOptionCompression, StrValue: $3}
  6755  	}
  6756  |	"KEY_BLOCK_SIZE" EqOpt LengthNum
  6757  	{
  6758  		$$ = &ast.TableOption{Tp: ast.TableOptionKeyBlockSize, UintValue: $3.(uint64)}
  6759  	}
  6760  |	"MAX_ROWS" EqOpt LengthNum
  6761  	{
  6762  		$$ = &ast.TableOption{Tp: ast.TableOptionMaxRows, UintValue: $3.(uint64)}
  6763  	}
  6764  |	"MIN_ROWS" EqOpt LengthNum
  6765  	{
  6766  		$$ = &ast.TableOption{Tp: ast.TableOptionMinRows, UintValue: $3.(uint64)}
  6767  	}
  6768  |	"DELAY_KEY_WRITE" EqOpt LengthNum
  6769  	{
  6770  		$$ = &ast.TableOption{Tp: ast.TableOptionDelayKeyWrite, UintValue: $3.(uint64)}
  6771  	}
  6772  |	RowFormat
  6773  	{
  6774  		$$ = &ast.TableOption{Tp: ast.TableOptionRowFormat, UintValue: $1.(uint64)}
  6775  	}
  6776  |	"STATS_PERSISTENT" EqOpt StatsPersistentVal
  6777  	{
  6778  		$$ = &ast.TableOption{Tp: ast.TableOptionStatsPersistent}
  6779  	}
  6780  |	"SHARD_ROW_ID_BITS" EqOpt LengthNum
  6781  	{
  6782  		$$ = &ast.TableOption{Tp: ast.TableOptionShardRowID, UintValue: $3.(uint64)}
  6783  	}
  6784  |	"PACK_KEYS" EqOpt StatsPersistentVal
  6785  	{
  6786  		// Parse it but will ignore it.
  6787  		$$ = &ast.TableOption{Tp: ast.TableOptionPackKeys}
  6788  	}
  6789  
  6790  StatsPersistentVal:
  6791  	"DEFAULT"
  6792  	{}
  6793  |	LengthNum
  6794  	{}
  6795  
  6796  AlterTableOptionListOpt:
  6797  	{
  6798  		$$ = []*ast.TableOption{}
  6799  	}
  6800  |	TableOptionList %prec higherThanComma
  6801  
  6802  CreateTableOptionListOpt:
  6803  	/* empty */ %prec lowerThanCreateTableSelect
  6804  	{
  6805  		$$ = []*ast.TableOption{}
  6806  	}
  6807  |	TableOptionList %prec lowerThanComma
  6808  
  6809  TableOptionList:
  6810  	TableOption
  6811  	{
  6812  		$$ = []*ast.TableOption{$1.(*ast.TableOption)}
  6813  	}
  6814  |	TableOptionList TableOption
  6815  	{
  6816  		$$ = append($1.([]*ast.TableOption), $2.(*ast.TableOption))
  6817  	}
  6818  |	TableOptionList ','  TableOption
  6819  	{
  6820  		$$ = append($1.([]*ast.TableOption), $3.(*ast.TableOption))
  6821  	}
  6822  
  6823  OptTable:
  6824  	{}
  6825  |	"TABLE"
  6826  
  6827  TruncateTableStmt:
  6828  	"TRUNCATE" OptTable TableName
  6829  	{
  6830  		$$ = &ast.TruncateTableStmt{Table: $3.(*ast.TableName)}
  6831  	}
  6832  
  6833  RowFormat:
  6834  	 "ROW_FORMAT" EqOpt "DEFAULT"
  6835  	{
  6836  		$$ = ast.RowFormatDefault
  6837  	}
  6838  |	"ROW_FORMAT" EqOpt "DYNAMIC"
  6839  	{
  6840  		$$ = ast.RowFormatDynamic
  6841  	}
  6842  |	"ROW_FORMAT" EqOpt "FIXED"
  6843  	{
  6844  		$$ = ast.RowFormatFixed
  6845  	}
  6846  |	"ROW_FORMAT" EqOpt "COMPRESSED"
  6847  	{
  6848  		$$ = ast.RowFormatCompressed
  6849  	}
  6850  |	"ROW_FORMAT" EqOpt "REDUNDANT"
  6851  	{
  6852  		$$ = ast.RowFormatRedundant
  6853  	}
  6854  |	"ROW_FORMAT" EqOpt "COMPACT"
  6855  	{
  6856  		$$ = ast.RowFormatCompact
  6857  	}
  6858  
  6859  /*************************************Type Begin***************************************/
  6860  Type:
  6861  	NumericType
  6862  	{
  6863  		$$ = $1
  6864  	}
  6865  |	StringType
  6866  	{
  6867  		$$ = $1
  6868  	}
  6869  |	DateAndTimeType
  6870  	{
  6871  		$$ = $1
  6872  	}
  6873  
  6874  NumericType:
  6875  	IntegerType OptFieldLen FieldOpts
  6876  	{
  6877  		// TODO: check flen 0
  6878  		x := types.NewFieldType($1.(byte))
  6879  		x.Flen = $2.(int)
  6880  		for _, o := range $3.([]*ast.TypeOpt) {
  6881  			if o.IsUnsigned {
  6882  				x.Flag |= mysql.UnsignedFlag
  6883  			}
  6884  			if o.IsZerofill {
  6885  				x.Flag |= mysql.ZerofillFlag
  6886  			}
  6887  		}
  6888  		$$ = x
  6889  	}
  6890  |	BooleanType FieldOpts
  6891  	{
  6892  		// TODO: check flen 0
  6893  		x := types.NewFieldType($1.(byte))
  6894  		x.Flen = 1
  6895  		for _, o := range $2.([]*ast.TypeOpt) {
  6896  			if o.IsUnsigned {
  6897  				x.Flag |= mysql.UnsignedFlag
  6898  			}
  6899  			if o.IsZerofill {
  6900  				x.Flag |= mysql.ZerofillFlag
  6901  			}
  6902  		}
  6903  		$$ = x
  6904  	}
  6905  |	FixedPointType FloatOpt FieldOpts
  6906  	{
  6907  		fopt := $2.(*ast.FloatOpt)
  6908  		x := types.NewFieldType($1.(byte))
  6909  		x.Flen = fopt.Flen
  6910  		x.Decimal = fopt.Decimal
  6911  		for _, o := range $3.([]*ast.TypeOpt) {
  6912  			if o.IsUnsigned {
  6913  				x.Flag |= mysql.UnsignedFlag
  6914  			}
  6915  			if o.IsZerofill {
  6916  				x.Flag |= mysql.ZerofillFlag
  6917  			}
  6918  		}
  6919  		$$ = x
  6920  	}
  6921  |	FloatingPointType FloatOpt FieldOpts
  6922  	{
  6923  		fopt := $2.(*ast.FloatOpt)
  6924  		x := types.NewFieldType($1.(byte))
  6925  		x.Flen = fopt.Flen
  6926  		if x.Tp == mysql.TypeFloat {
  6927  			if x.Flen > 24 {
  6928  				x.Tp = mysql.TypeDouble
  6929  			}
  6930  		}
  6931  		x.Decimal = fopt.Decimal
  6932  		for _, o := range $3.([]*ast.TypeOpt) {
  6933  			if o.IsUnsigned {
  6934  				x.Flag |= mysql.UnsignedFlag
  6935  			}
  6936  			if o.IsZerofill {
  6937  				x.Flag |= mysql.ZerofillFlag
  6938  			}
  6939  		}
  6940  		$$ = x
  6941  	}
  6942  |	BitValueType OptFieldLen
  6943  	{
  6944  		x := types.NewFieldType($1.(byte))
  6945  		x.Flen = $2.(int)
  6946  		if x.Flen == types.UnspecifiedLength || x.Flen == 0 {
  6947  			x.Flen = 1
  6948  		} else if x.Flen > 64 {
  6949  			yylex.Errorf("invalid field length %d for bit type, must in [1, 64]", x.Flen)
  6950  		}
  6951  		$$ = x
  6952  	}
  6953  
  6954  IntegerType:
  6955  	"TINYINT"
  6956  	{
  6957  		$$ = mysql.TypeTiny
  6958  	}
  6959  |	"SMALLINT"
  6960  	{
  6961  		$$ = mysql.TypeShort
  6962  	}
  6963  |	"MEDIUMINT"
  6964  	{
  6965  		$$ = mysql.TypeInt24
  6966  	}
  6967  |	"INT"
  6968  	{
  6969  		$$ = mysql.TypeLong
  6970  	}
  6971  |	"INT1"
  6972  	{
  6973  		$$ = mysql.TypeTiny
  6974  	}
  6975  | 	"INT2"
  6976  	{
  6977  		$$ = mysql.TypeShort
  6978  	}
  6979  | 	"INT3"
  6980  	{
  6981  		$$ = mysql.TypeInt24
  6982  	}
  6983  |	"INT4"
  6984  	{
  6985  		$$ = mysql.TypeLong
  6986  	}
  6987  |	"INT8"
  6988  	{
  6989  		$$ = mysql.TypeLonglong
  6990  	}
  6991  |	"INTEGER"
  6992  	{
  6993  		$$ = mysql.TypeLong
  6994  	}
  6995  |	"BIGINT"
  6996  	{
  6997  		$$ = mysql.TypeLonglong
  6998  	}
  6999  
  7000  
  7001  BooleanType:
  7002  	"BOOL"
  7003  	{
  7004  		$$ = mysql.TypeTiny
  7005  	}
  7006  |	"BOOLEAN"
  7007  	{
  7008  		$$ = mysql.TypeTiny
  7009  	}
  7010  
  7011  OptInteger:
  7012  	{}
  7013  |	"INTEGER"
  7014  |	"INT"
  7015  
  7016  FixedPointType:
  7017  	"DECIMAL"
  7018  	{
  7019  		$$ = mysql.TypeNewDecimal
  7020  	}
  7021  |	"NUMERIC"
  7022  	{
  7023  		$$ = mysql.TypeNewDecimal
  7024  	}
  7025  
  7026  FloatingPointType:
  7027  	"FLOAT"
  7028  	{
  7029  		$$ = mysql.TypeFloat
  7030  	}
  7031  |	"REAL"
  7032  	{
  7033  	    if parser.lexer.GetSQLMode().HasRealAsFloatMode() {
  7034  		    $$ = mysql.TypeFloat
  7035  	    } else {
  7036  		    $$ = mysql.TypeDouble
  7037  	    }
  7038  	}
  7039  |	"DOUBLE"
  7040  	{
  7041  		$$ = mysql.TypeDouble
  7042  	}
  7043  |	"DOUBLE" "PRECISION"
  7044  	{
  7045  		$$ = mysql.TypeDouble
  7046  	}
  7047  
  7048  BitValueType:
  7049  	"BIT"
  7050  	{
  7051  		$$ = mysql.TypeBit
  7052  	}
  7053  
  7054  StringType:
  7055  	NationalOpt "CHAR" FieldLen OptBinary OptCollate
  7056  	{
  7057  		x := types.NewFieldType(mysql.TypeString)
  7058  		x.Flen = $3.(int)
  7059  		x.Charset = $4.(*ast.OptBinary).Charset
  7060  		x.Collate = $5.(string)
  7061  		if $4.(*ast.OptBinary).IsBinary {
  7062  			x.Flag |= mysql.BinaryFlag
  7063  		}
  7064  		$$ = x
  7065  	}
  7066  |	NationalOpt "CHAR" OptBinary OptCollate
  7067  	{
  7068  		x := types.NewFieldType(mysql.TypeString)
  7069  		x.Charset = $3.(*ast.OptBinary).Charset
  7070  		x.Collate = $4.(string)
  7071  		if $3.(*ast.OptBinary).IsBinary {
  7072  			x.Flag |= mysql.BinaryFlag
  7073  		}
  7074  		$$ = x
  7075  	}
  7076  |	"NATIONAL" "CHARACTER" FieldLen OptBinary OptCollate
  7077  	{
  7078  		x := types.NewFieldType(mysql.TypeString)
  7079  		x.Flen = $3.(int)
  7080  		x.Charset = $4.(*ast.OptBinary).Charset
  7081  		x.Collate = $5.(string)
  7082  		if $4.(*ast.OptBinary).IsBinary {
  7083  			x.Flag |= mysql.BinaryFlag
  7084  		}
  7085  		$$ = x
  7086  	}
  7087  |	Varchar FieldLen OptBinary OptCollate
  7088  	{
  7089  		x := types.NewFieldType(mysql.TypeVarchar)
  7090  		x.Flen = $2.(int)
  7091  		x.Charset = $3.(*ast.OptBinary).Charset
  7092  		x.Collate = $4.(string)
  7093  		if $3.(*ast.OptBinary).IsBinary {
  7094  			x.Flag |= mysql.BinaryFlag
  7095  		}
  7096  		$$ = x
  7097  	}
  7098  |	"BINARY" OptFieldLen
  7099  	{
  7100  		x := types.NewFieldType(mysql.TypeString)
  7101  		x.Flen = $2.(int)
  7102  		x.Charset = mysql.CharsetBin
  7103  		x.Collate = mysql.CharsetBin
  7104  		x.Flag |= mysql.BinaryFlag
  7105  		$$ = x
  7106  	}
  7107  |	"VARBINARY" FieldLen
  7108  	{
  7109  		x := types.NewFieldType(mysql.TypeVarchar)
  7110  		x.Flen = $2.(int)
  7111  		x.Charset = mysql.CharsetBin
  7112  		x.Collate = mysql.CharsetBin
  7113  		x.Flag |= mysql.BinaryFlag
  7114  		$$ = x
  7115  	}
  7116  |	BlobType
  7117  	{
  7118  		x := $1.(*types.FieldType)
  7119  		x.Charset = mysql.CharsetBin
  7120  		x.Collate = mysql.CharsetBin
  7121  		x.Flag |= mysql.BinaryFlag
  7122  		$$ = $1.(*types.FieldType)
  7123  	}
  7124  |	TextType OptBinary OptCollate
  7125  	{
  7126  		x := $1.(*types.FieldType)
  7127  		x.Charset = $2.(*ast.OptBinary).Charset
  7128  		x.Collate = $3.(string)
  7129  		if $2.(*ast.OptBinary).IsBinary {
  7130  			x.Flag |= mysql.BinaryFlag
  7131  		}
  7132  		$$ = x
  7133  	}
  7134  |	"ENUM" '(' StringList ')' OptCharset OptCollate
  7135  	{
  7136  		x := types.NewFieldType(mysql.TypeEnum)
  7137  		x.Elems = $3.([]string)
  7138  		x.Charset = $5.(string)
  7139  		x.Collate = $6.(string)
  7140  		$$ = x
  7141  	}
  7142  |	"SET" '(' StringList ')' OptCharset OptCollate
  7143  	{
  7144  		x := types.NewFieldType(mysql.TypeSet)
  7145  		x.Elems = $3.([]string)
  7146  		x.Charset = $5.(string)
  7147  		x.Collate = $6.(string)
  7148  		$$ = x
  7149  	}
  7150  |	"JSON"
  7151  	{
  7152  		x := types.NewFieldType(mysql.TypeJSON)
  7153  		x.Decimal = 0
  7154  		x.Charset = mysql.CharsetBin
  7155  		x.Collate = mysql.CollationBin
  7156  		$$ = x
  7157  	}
  7158  
  7159  NationalOpt:
  7160  	{}
  7161  |	"NATIONAL"
  7162  
  7163  Varchar:
  7164  "NATIONAL" "VARCHAR"
  7165  | "VARCHAR"
  7166  | "NVARCHAR"
  7167  
  7168  
  7169  BlobType:
  7170  	"TINYBLOB"
  7171  	{
  7172  		x := types.NewFieldType(mysql.TypeTinyBlob)
  7173  		$$ = x
  7174  	}
  7175  |	"BLOB" OptFieldLen
  7176  	{
  7177  		x := types.NewFieldType(mysql.TypeBlob)
  7178  		x.Flen = $2.(int)
  7179  		$$ = x
  7180  	}
  7181  |	"MEDIUMBLOB"
  7182  	{
  7183  		x := types.NewFieldType(mysql.TypeMediumBlob)
  7184  		$$ = x
  7185  	}
  7186  |	"LONGBLOB"
  7187  	{
  7188  		x := types.NewFieldType(mysql.TypeLongBlob)
  7189  		$$ = x
  7190  	}
  7191  
  7192  TextType:
  7193  	"TINYTEXT"
  7194  	{
  7195  		x := types.NewFieldType(mysql.TypeTinyBlob)
  7196  		$$ = x
  7197  
  7198  	}
  7199  |	"TEXT" OptFieldLen
  7200  	{
  7201  		x := types.NewFieldType(mysql.TypeBlob)
  7202  		x.Flen = $2.(int)
  7203  		$$ = x
  7204  	}
  7205  |	"MEDIUMTEXT"
  7206  	{
  7207  		x := types.NewFieldType(mysql.TypeMediumBlob)
  7208  		$$ = x
  7209  	}
  7210  |	"LONGTEXT"
  7211  	{
  7212  		x := types.NewFieldType(mysql.TypeLongBlob)
  7213  		$$ = x
  7214  	}
  7215  |	"LONG" "VARCHAR"
  7216  	{
  7217  		x := types.NewFieldType(mysql.TypeMediumBlob)
  7218  		$$ = x
  7219  	}
  7220  
  7221  
  7222  DateAndTimeType:
  7223  	"DATE"
  7224  	{
  7225  		x := types.NewFieldType(mysql.TypeDate)
  7226  		$$ = x
  7227  	}
  7228  |	"DATETIME" OptFieldLen
  7229  	{
  7230  		x := types.NewFieldType(mysql.TypeDatetime)
  7231  		x.Flen = mysql.MaxDatetimeWidthNoFsp
  7232  		x.Decimal = $2.(int)
  7233  		if x.Decimal > 0 {
  7234  			x.Flen = x.Flen + 1 + x.Decimal
  7235  		}
  7236  		$$ = x
  7237  	}
  7238  |	"TIMESTAMP" OptFieldLen
  7239  	{
  7240  		x := types.NewFieldType(mysql.TypeTimestamp)
  7241  		x.Flen = mysql.MaxDatetimeWidthNoFsp
  7242  		x.Decimal = $2.(int)
  7243  		if x.Decimal > 0 {
  7244  			x.Flen = x.Flen + 1 + x.Decimal
  7245  		}
  7246  		$$ = x
  7247  	}
  7248  |	"TIME" OptFieldLen
  7249  	{
  7250  		x := types.NewFieldType(mysql.TypeDuration)
  7251  		x.Flen = mysql.MaxDurationWidthNoFsp
  7252  		x.Decimal = $2.(int)
  7253  		if x.Decimal > 0 {
  7254  			x.Flen = x.Flen + 1 + x.Decimal
  7255  		}
  7256  		$$ = x
  7257  	}
  7258  |	"YEAR" OptFieldLen FieldOpts
  7259  	{
  7260  		x := types.NewFieldType(mysql.TypeYear)
  7261  		x.Flen = $2.(int)
  7262  		if x.Flen != types.UnspecifiedLength && x.Flen != 4 {
  7263  			yylex.Errorf("Supports only YEAR or YEAR(4) column.")
  7264  			return -1
  7265  		}
  7266  		$$ = x
  7267  	}
  7268  
  7269  FieldLen:
  7270  	'(' LengthNum ')'
  7271  	{
  7272  		$$ = int($2.(uint64))
  7273  	}
  7274  
  7275  OptFieldLen:
  7276  	{
  7277  		$$ = types.UnspecifiedLength
  7278  	}
  7279  |	FieldLen
  7280  	{
  7281  		$$ = $1.(int)
  7282  	}
  7283  
  7284  FieldOpt:
  7285  	"UNSIGNED"
  7286  	{
  7287  		$$ = &ast.TypeOpt{IsUnsigned: true}
  7288  	}
  7289  |	"SIGNED"
  7290  	{
  7291  		$$ = &ast.TypeOpt{IsUnsigned: false}
  7292  	}
  7293  |	"ZEROFILL"
  7294  	{
  7295  		$$ = &ast.TypeOpt{IsZerofill: true, IsUnsigned: true}
  7296  	}
  7297  
  7298  FieldOpts:
  7299  	{
  7300  		$$ = []*ast.TypeOpt{}
  7301  	}
  7302  |	FieldOpts FieldOpt
  7303  	{
  7304  		$$ = append($1.([]*ast.TypeOpt), $2.(*ast.TypeOpt))
  7305  	}
  7306  
  7307  FloatOpt:
  7308  	{
  7309  		$$ = &ast.FloatOpt{Flen: types.UnspecifiedLength, Decimal: types.UnspecifiedLength}
  7310  	}
  7311  |	FieldLen
  7312  	{
  7313  		$$ = &ast.FloatOpt{Flen: $1.(int), Decimal: types.UnspecifiedLength}
  7314  	}
  7315  |	Precision
  7316  	{
  7317  		$$ = $1.(*ast.FloatOpt)
  7318  	}
  7319  
  7320  Precision:
  7321  	'(' LengthNum ',' LengthNum ')'
  7322  	{
  7323  		$$ = &ast.FloatOpt{Flen: int($2.(uint64)), Decimal: int($4.(uint64))}
  7324  	}
  7325  
  7326  OptBinMod:
  7327  	{
  7328  		$$ = false
  7329  	}
  7330  |	"BINARY"
  7331  	{
  7332  		$$ = true
  7333  	}
  7334  
  7335  OptBinary:
  7336  	{
  7337  		$$ = &ast.OptBinary{
  7338  			IsBinary: false,
  7339  			Charset:  "",
  7340  		}
  7341  	}
  7342  |	"BINARY" OptCharset
  7343  	{
  7344  		$$ = &ast.OptBinary{
  7345  			IsBinary: true,
  7346  			Charset:  $2.(string),
  7347  		}
  7348  	}
  7349  |	CharsetKw CharsetName OptBinMod
  7350  	{
  7351  		$$ = &ast.OptBinary{
  7352  			IsBinary: $3.(bool),
  7353  			Charset:  $2.(string),
  7354  		}
  7355  	}
  7356  
  7357  OptCharset:
  7358  	{
  7359  		$$ = ""
  7360  	}
  7361  |	CharsetKw CharsetName
  7362  	{
  7363  		$$ = $2.(string)
  7364  	}
  7365  
  7366  CharsetKw:
  7367  	"CHARACTER" "SET"
  7368  |	"CHARSET"
  7369  
  7370  OptCollate:
  7371  	{
  7372  		$$ = ""
  7373  	}
  7374  |	"COLLATE" StringName
  7375  	{
  7376  		$$ = $2.(string)
  7377  	}
  7378  
  7379  StringList:
  7380  	stringLit
  7381  	{
  7382  		$$ = []string{$1}
  7383  	}
  7384  |	StringList ',' stringLit
  7385  	{
  7386  		$$ = append($1.([]string), $3)
  7387  	}
  7388  
  7389  StringName:
  7390  	stringLit
  7391  	{
  7392  		$$ = $1
  7393  	}
  7394  |	Identifier
  7395  	{
  7396  		$$ = $1
  7397  	}
  7398  
  7399  /***********************************************************************************
  7400   * Update Statement
  7401   * See https://dev.mysql.com/doc/refman/5.7/en/update.html
  7402   ***********************************************************************************/
  7403  UpdateStmt:
  7404  	"UPDATE" TableOptimizerHints PriorityOpt IgnoreOptional TableRef "SET" AssignmentList WhereClauseOptional OrderByOptional LimitClause
  7405  	{
  7406  		var refs *ast.Join
  7407  		if x, ok := $5.(*ast.Join); ok {
  7408  			refs = x
  7409  		} else {
  7410  			refs = &ast.Join{Left: $5.(ast.ResultSetNode)}
  7411  		}
  7412  		st := &ast.UpdateStmt{
  7413  			Priority:  $3.(mysql.PriorityEnum),
  7414  			TableRefs: &ast.TableRefsClause{TableRefs: refs},
  7415  			List:	   $7.([]*ast.Assignment),
  7416  			IgnoreErr: $4.(bool),
  7417  		}
  7418  		if $2 != nil {
  7419  			st.TableHints = $2.([]*ast.TableOptimizerHint)
  7420  		}
  7421  		if $8 != nil {
  7422  			st.Where = $8.(ast.ExprNode)
  7423  		}
  7424  		if $9 != nil {
  7425  			st.Order = $9.(*ast.OrderByClause)
  7426  		}
  7427  		if $10 != nil {
  7428  			st.Limit = $10.(*ast.Limit)
  7429  		}
  7430  		$$ = st
  7431  	}
  7432  |	"UPDATE" TableOptimizerHints PriorityOpt IgnoreOptional TableRefs "SET" AssignmentList WhereClauseOptional
  7433  	{
  7434  		st := &ast.UpdateStmt{
  7435  			Priority:  $3.(mysql.PriorityEnum),
  7436  			TableRefs: &ast.TableRefsClause{TableRefs: $5.(*ast.Join)},
  7437  			List:	   $7.([]*ast.Assignment),
  7438  			IgnoreErr: $4.(bool),
  7439  		}
  7440  		if $2 != nil {
  7441  			st.TableHints = $2.([]*ast.TableOptimizerHint)
  7442  		}
  7443  		if $8 != nil {
  7444  			st.Where = $8.(ast.ExprNode)
  7445  		}
  7446  		$$ = st
  7447  	}
  7448  
  7449  UseStmt:
  7450  	"USE" DBName
  7451  	{
  7452  		$$ = &ast.UseStmt{DBName: $2.(string)}
  7453  	}
  7454  
  7455  WhereClause:
  7456  	"WHERE" Expression
  7457  	{
  7458  		$$ = $2
  7459  	}
  7460  
  7461  WhereClauseOptional:
  7462  	{
  7463  		$$ = nil
  7464  	}
  7465  |	WhereClause
  7466  	{
  7467  		$$ = $1
  7468  	}
  7469  
  7470  CommaOpt:
  7471  	{}
  7472  |	','
  7473  	{}
  7474  
  7475  /************************************************************************************
  7476   *  Account Management Statements
  7477   *  https://dev.mysql.com/doc/refman/5.7/en/account-management-sql.html
  7478   ************************************************************************************/
  7479  CreateUserStmt:
  7480  	"CREATE" "USER" IfNotExists UserSpecList
  7481  	{
  7482   		// See https://dev.mysql.com/doc/refman/5.7/en/create-user.html
  7483  		$$ = &ast.CreateUserStmt{
  7484  			IsCreateRole: false,
  7485  			IfNotExists: $3.(bool),
  7486  			Specs: $4.([]*ast.UserSpec),
  7487  		}
  7488  	}
  7489  
  7490  CreateRoleStmt:
  7491      "CREATE" "ROLE" IfNotExists RoleSpecList
  7492  	{
  7493  		// See https://dev.mysql.com/doc/refman/8.0/en/create-role.html
  7494  		$$ = &ast.CreateUserStmt{
  7495  			IsCreateRole: true,
  7496  			IfNotExists: $3.(bool),
  7497  			Specs: $4.([]*ast.UserSpec),
  7498  		}
  7499  	}
  7500  
  7501  /* See http://dev.mysql.com/doc/refman/5.7/en/alter-user.html */
  7502  AlterUserStmt:
  7503  	"ALTER" "USER" IfExists UserSpecList
  7504  	{
  7505  		$$ = &ast.AlterUserStmt{
  7506  			IfExists: $3.(bool),
  7507  			Specs: $4.([]*ast.UserSpec),
  7508  		}
  7509  	}
  7510  | 	"ALTER" "USER" IfExists "USER" '(' ')' "IDENTIFIED" "BY" AuthString
  7511  	{
  7512  		auth := &ast.AuthOption {
  7513  			AuthString: $9.(string),
  7514  			ByAuthString: true,
  7515  		}
  7516  		$$ = &ast.AlterUserStmt{
  7517  			IfExists: $3.(bool),
  7518  			CurrentAuth: auth,
  7519  		}
  7520  	}
  7521  
  7522  UserSpec:
  7523  	Username AuthOption
  7524  	{
  7525  		userSpec := &ast.UserSpec{
  7526  			User: $1.(*auth.UserIdentity),
  7527  		}
  7528  		if $2 != nil {
  7529  			userSpec.AuthOpt = $2.(*ast.AuthOption)
  7530  		}
  7531  		$$ = userSpec
  7532  	}
  7533  
  7534  UserSpecList:
  7535  	UserSpec
  7536  	{
  7537  		$$ = []*ast.UserSpec{$1.(*ast.UserSpec)}
  7538  	}
  7539  |	UserSpecList ',' UserSpec
  7540  	{
  7541  		$$ = append($1.([]*ast.UserSpec), $3.(*ast.UserSpec))
  7542  	}
  7543  
  7544  AuthOption:
  7545  	{
  7546  		$$ = nil
  7547  	}
  7548  |	"IDENTIFIED" "BY" AuthString
  7549  	{
  7550  		$$ = &ast.AuthOption {
  7551  			AuthString: $3.(string),
  7552  			ByAuthString: true,
  7553  		}
  7554  	}
  7555  |	"IDENTIFIED" "WITH" StringName
  7556  	{
  7557  		$$ = nil
  7558  	}
  7559  |	"IDENTIFIED" "WITH" StringName "BY" AuthString
  7560  	{
  7561  		$$ = &ast.AuthOption {
  7562  			AuthString: $5.(string),
  7563  			ByAuthString: true,
  7564  		}
  7565  	}
  7566  |	"IDENTIFIED" "WITH" StringName "AS" HashString
  7567  	{
  7568  		$$ = &ast.AuthOption{
  7569  			HashString: $5.(string),
  7570  		}
  7571  	}
  7572  |	"IDENTIFIED" "BY" "PASSWORD" HashString
  7573  	{
  7574  		$$ = &ast.AuthOption{
  7575  			HashString: $4.(string),
  7576  		}
  7577  	}
  7578  
  7579  HashString:
  7580  	stringLit
  7581  	{
  7582  		$$ = $1
  7583  	}
  7584  
  7585  RoleSpec:
  7586  	Rolename
  7587  	{
  7588  		role := $1.(*auth.RoleIdentity)
  7589  		roleSpec := &ast.UserSpec{
  7590  			User: &auth.UserIdentity {
  7591  				Username: role.Username,
  7592  				Hostname: role.Hostname,
  7593  			},
  7594  			IsRole: true,
  7595  		}
  7596  		$$ = roleSpec
  7597  	}
  7598  
  7599  RoleSpecList:
  7600  	RoleSpec
  7601  	{
  7602  		$$ = []*ast.UserSpec{$1.(*ast.UserSpec)}
  7603  	}
  7604  |	RoleSpecList ',' RoleSpec
  7605  	{
  7606  		$$ = append($1.([]*ast.UserSpec), $3.(*ast.UserSpec))
  7607  	}
  7608  
  7609  /*******************************************************************
  7610   *
  7611   *  Create Binding Statement
  7612   *
  7613   *  Example:
  7614   *      CREATE GLOBAL BINDING FOR select Col1,Col2 from table USING select Col1,Col2 from table use index(Col1)
  7615   *******************************************************************/
  7616  CreateBindingStmt:
  7617  	"CREATE" GlobalScope "BINDING" "FOR" SelectStmt "USING" SelectStmt
  7618      	{
  7619  		startOffset := parser.startOffset(&yyS[yypt-2])
  7620          	endOffset := parser.startOffset(&yyS[yypt-1])
  7621          	selStmt := $5.(*ast.SelectStmt)
  7622          	selStmt.SetText(strings.TrimSpace(parser.src[startOffset:endOffset]))
  7623  
  7624  		startOffset = parser.startOffset(&yyS[yypt])
  7625  		hintedSelStmt := $7.(*ast.SelectStmt)
  7626  		hintedSelStmt.SetText(strings.TrimSpace(parser.src[startOffset:]))
  7627  
  7628  		x := &ast.CreateBindingStmt {
  7629  			OriginSel:  selStmt,
  7630  			HintedSel:  hintedSelStmt,
  7631  			GlobalScope: $2.(bool),
  7632  		}
  7633  
  7634  		$$ = x
  7635  	}
  7636  /*******************************************************************
  7637   *
  7638   *  Drop Binding Statement
  7639   *
  7640   *  Example:
  7641   *      DROP GLOBAL BINDING FOR select Col1,Col2 from table
  7642   *******************************************************************/
  7643  DropBindingStmt:
  7644  	"DROP" GlobalScope "BINDING" "FOR" SelectStmt
  7645  	{
  7646  		startOffset := parser.startOffset(&yyS[yypt])
  7647  		selStmt := $5.(*ast.SelectStmt)
  7648  		selStmt.SetText(strings.TrimSpace(parser.src[startOffset:]))
  7649  
  7650  		x := &ast.DropBindingStmt {
  7651  			OriginSel:  selStmt,
  7652  			GlobalScope: $2.(bool),
  7653  		}
  7654  
  7655  		$$ = x
  7656  	}
  7657  
  7658  /*************************************************************************************
  7659   * Grant statement
  7660   * See https://dev.mysql.com/doc/refman/5.7/en/grant.html
  7661   *************************************************************************************/
  7662  GrantStmt:
  7663  	 "GRANT" PrivElemList "ON" ObjectType PrivLevel "TO" UserSpecList WithGrantOptionOpt
  7664  	 {
  7665  		$$ = &ast.GrantStmt{
  7666  			Privs: $2.([]*ast.PrivElem),
  7667  			ObjectType: $4.(ast.ObjectTypeType),
  7668  			Level: $5.(*ast.GrantLevel),
  7669  			Users: $7.([]*ast.UserSpec),
  7670  			WithGrant: $8.(bool),
  7671  		}
  7672  	 }
  7673  
  7674  GrantRoleStmt:
  7675  	 "GRANT" RolenameList "TO" UsernameList
  7676  	 {
  7677  	 }
  7678  
  7679  WithGrantOptionOpt:
  7680  	{
  7681  		$$ = false
  7682  	}
  7683  |	"WITH" "GRANT" "OPTION"
  7684  	{
  7685  		$$ = true
  7686  	}
  7687  |	"WITH" "MAX_QUERIES_PER_HOUR" NUM
  7688  	{
  7689  		$$ = false
  7690  	}
  7691  |	"WITH" "MAX_UPDATES_PER_HOUR" NUM
  7692  	{
  7693  		$$ = false
  7694  	}
  7695  |	"WITH" "MAX_CONNECTIONS_PER_HOUR" NUM
  7696  	{
  7697  		$$ = false
  7698  	}
  7699  |	"WITH" "MAX_USER_CONNECTIONS" NUM
  7700  	{
  7701  		$$ = false
  7702  	}
  7703  
  7704  PrivElem:
  7705  	PrivType
  7706  	{
  7707  		$$ = &ast.PrivElem{
  7708  			Priv: $1.(mysql.PrivilegeType),
  7709  		}
  7710  	}
  7711  |	PrivType '(' ColumnNameList ')'
  7712  	{
  7713  		$$ = &ast.PrivElem{
  7714  			Priv: $1.(mysql.PrivilegeType),
  7715  			Cols: $3.([]*ast.ColumnName),
  7716  		}
  7717  	}
  7718  
  7719  PrivElemList:
  7720  	PrivElem
  7721  	{
  7722  		$$ = []*ast.PrivElem{$1.(*ast.PrivElem)}
  7723  	}
  7724  |	PrivElemList ',' PrivElem
  7725  	{
  7726  		$$ = append($1.([]*ast.PrivElem), $3.(*ast.PrivElem))
  7727  	}
  7728  
  7729  PrivType:
  7730  	"ALL"
  7731  	{
  7732  		$$ = mysql.AllPriv
  7733  	}
  7734  |	"ALL" "PRIVILEGES"
  7735  	{
  7736  		$$ = mysql.AllPriv
  7737  	}
  7738  |	"ALTER"
  7739  	{
  7740  		$$ = mysql.AlterPriv
  7741  	}
  7742  |	"CREATE"
  7743  	{
  7744  		$$ = mysql.CreatePriv
  7745  	}
  7746  |	"CREATE" "USER"
  7747  	{
  7748  		$$ = mysql.CreateUserPriv
  7749  	}
  7750  |	"TRIGGER"
  7751  	{
  7752  		$$ = mysql.TriggerPriv
  7753  	}
  7754  |	"DELETE"
  7755  	{
  7756  		$$ = mysql.DeletePriv
  7757  	}
  7758  |	"DROP"
  7759  	{
  7760  		$$ = mysql.DropPriv
  7761  	}
  7762  |	"PROCESS"
  7763  	{
  7764  		$$ = mysql.ProcessPriv
  7765  	}
  7766  |	"EXECUTE"
  7767  	{
  7768  		$$ = mysql.ExecutePriv
  7769  	}
  7770  |	"INDEX"
  7771  	{
  7772  		$$ = mysql.IndexPriv
  7773  	}
  7774  |	"INSERT"
  7775  	{
  7776  		$$ = mysql.InsertPriv
  7777  	}
  7778  |	"SELECT"
  7779  	{
  7780  		$$ = mysql.SelectPriv
  7781  	}
  7782  |	"SUPER"
  7783  	{
  7784  		$$ = mysql.SuperPriv
  7785  	}
  7786  |	"SHOW" "DATABASES"
  7787  	{
  7788  		$$ = mysql.ShowDBPriv
  7789  	}
  7790  |	"UPDATE"
  7791  	{
  7792  		$$ = mysql.UpdatePriv
  7793  	}
  7794  |	"GRANT" "OPTION"
  7795  	{
  7796  		$$ = mysql.GrantPriv
  7797  	}
  7798  |	"REFERENCES"
  7799  	{
  7800  		$$ = mysql.ReferencesPriv
  7801  	}
  7802  |	"REPLICATION" "SLAVE"
  7803  	{
  7804  		$$ = mysql.PrivilegeType(0)
  7805  	}
  7806  |	"REPLICATION" "CLIENT"
  7807  	{
  7808  		$$ = mysql.PrivilegeType(0)
  7809  	}
  7810  |	"USAGE"
  7811  	{
  7812  		$$ = mysql.PrivilegeType(0)
  7813  	}
  7814  |	"RELOAD"
  7815  	{
  7816  		$$ = mysql.PrivilegeType(0)
  7817  	}
  7818  |	"CREATE" "TEMPORARY" "TABLES"
  7819  	{
  7820  		$$ = mysql.PrivilegeType(0)
  7821  	}
  7822  |	"LOCK" "TABLES"
  7823  	{
  7824  		$$ = mysql.PrivilegeType(0)
  7825  	}
  7826  |	"CREATE" "VIEW"
  7827  	{
  7828  		$$ = mysql.CreateViewPriv
  7829  	}
  7830  |	"SHOW" "VIEW"
  7831  	{
  7832  		$$ = mysql.ShowViewPriv
  7833  	}
  7834  |	"CREATE" "ROLE"
  7835  	{
  7836  		$$ = mysql.CreateRolePriv
  7837  	}
  7838  |	"DROP" "ROLE"
  7839  	{
  7840  		$$ = mysql.DropRolePriv
  7841  	}
  7842  |	"CREATE" "ROUTINE"
  7843  	{
  7844  		$$ = mysql.PrivilegeType(0)
  7845  	}
  7846  |	"ALTER" "ROUTINE"
  7847  	{
  7848  		$$ = mysql.PrivilegeType(0)
  7849  	}
  7850  |	"EVENT"
  7851  	{
  7852  		$$ = mysql.PrivilegeType(0)
  7853  	}
  7854  
  7855  ObjectType:
  7856  	{
  7857  		$$ = ast.ObjectTypeNone
  7858  	}
  7859  |	"TABLE"
  7860  	{
  7861  		$$ = ast.ObjectTypeTable
  7862  	}
  7863  
  7864  PrivLevel:
  7865  	'*'
  7866  	{
  7867  		$$ = &ast.GrantLevel {
  7868  			Level: ast.GrantLevelDB,
  7869  		}
  7870  	}
  7871  |	'*' '.' '*'
  7872  	{
  7873  		$$ = &ast.GrantLevel {
  7874  			Level: ast.GrantLevelGlobal,
  7875  		}
  7876  	}
  7877  | 	Identifier '.' '*'
  7878  	{
  7879  		$$ = &ast.GrantLevel {
  7880  			Level: ast.GrantLevelDB,
  7881  			DBName: $1,
  7882  		}
  7883  	}
  7884  |	Identifier '.' Identifier
  7885  	{
  7886  		$$ = &ast.GrantLevel {
  7887  			Level: ast.GrantLevelTable,
  7888  			DBName: $1,
  7889  			TableName: $3,
  7890  		}
  7891  	}
  7892  |	Identifier
  7893  	{
  7894  		$$ = &ast.GrantLevel {
  7895  			Level: ast.GrantLevelTable,
  7896  			TableName: $1,
  7897  		}
  7898  	}
  7899  
  7900  /**************************************RevokeStmt*******************************************
  7901   * See https://dev.mysql.com/doc/refman/5.7/en/revoke.html
  7902   *******************************************************************************************/
  7903  RevokeStmt:
  7904  	 "REVOKE" PrivElemList "ON" ObjectType PrivLevel "FROM" UserSpecList
  7905  	 {
  7906  		$$ = &ast.RevokeStmt{
  7907  			Privs: $2.([]*ast.PrivElem),
  7908  			ObjectType: $4.(ast.ObjectTypeType),
  7909  			Level: $5.(*ast.GrantLevel),
  7910  			Users: $7.([]*ast.UserSpec),
  7911  		}
  7912  	 }
  7913  
  7914  RevokeRoleStmt:
  7915  	 "REVOKE" RolenameList "FROM" UsernameList
  7916  	 {
  7917  	 }
  7918  
  7919  /**************************************LoadDataStmt*****************************************
  7920   * See https://dev.mysql.com/doc/refman/5.7/en/load-data.html
  7921   *******************************************************************************************/
  7922  LoadDataStmt:
  7923  	"LOAD" "DATA" LocalOpt "INFILE" stringLit "INTO" "TABLE" TableName CharsetOpt Fields Lines IgnoreLines ColumnNameListOptWithBrackets
  7924  	{
  7925  		x := &ast.LoadDataStmt{
  7926  			Path:       $5,
  7927  			Table:      $8.(*ast.TableName),
  7928  			Columns:    $13.([]*ast.ColumnName),
  7929  			IgnoreLines:$12.(uint64),
  7930  		}
  7931  		if $3 != nil {
  7932  			x.IsLocal = true
  7933  		}
  7934  		if $10 != nil {
  7935  			x.FieldsInfo = $10.(*ast.FieldsClause)
  7936  		}
  7937  		if $11 != nil {
  7938  			x.LinesInfo = $11.(*ast.LinesClause)
  7939  		}
  7940  		$$ = x
  7941  	}
  7942  
  7943  IgnoreLines:
  7944      {
  7945          $$ = uint64(0)
  7946      }
  7947  |   "IGNORE" NUM "LINES"
  7948      {
  7949          $$ = getUint64FromNUM($2)
  7950      }
  7951  
  7952  CharsetOpt:
  7953  	{}
  7954  |	"CHARACTER" "SET" CharsetName
  7955  
  7956  LocalOpt:
  7957  	{
  7958  		$$ = nil
  7959  	}
  7960  |	"LOCAL"
  7961  	{
  7962  		$$ = $1
  7963  	}
  7964  
  7965  Fields:
  7966       	{
  7967  		escape := "\\"
  7968  		$$ = &ast.FieldsClause{
  7969  			Terminated: "\t",
  7970  			Escaped:    escape[0],
  7971  		}
  7972  	}
  7973  |	FieldsOrColumns FieldsTerminated Enclosed Escaped
  7974  	{
  7975  		escape := $4.(string)
  7976  		if escape != "\\" && len(escape) > 1 {
  7977  			yylex.Errorf("Incorrect arguments %s to ESCAPE", escape)
  7978  			return 1
  7979  		}
  7980  		var enclosed byte
  7981  		str := $3.(string)
  7982  		if len(str) > 1 {
  7983  			yylex.Errorf("Incorrect arguments %s to ENCLOSED", escape)
  7984  			return 1
  7985  		}else if len(str) != 0 {
  7986  			enclosed = str[0]
  7987  		}
  7988  		var escaped byte
  7989  		if len(escape) > 0 {
  7990  			escaped = escape[0]
  7991  		}
  7992  		$$ = &ast.FieldsClause{
  7993  			Terminated: $2.(string),
  7994  			Enclosed:   enclosed,
  7995  			Escaped:    escaped,
  7996  		}
  7997  	}
  7998  
  7999  FieldsOrColumns:
  8000  "FIELDS" | "COLUMNS"
  8001  
  8002  FieldsTerminated:
  8003  	{
  8004  		$$ = "\t"
  8005  	}
  8006  |	"TERMINATED" "BY" stringLit
  8007  	{
  8008  		$$ = $3
  8009  	}
  8010  
  8011  Enclosed:
  8012  	{
  8013  		$$ = ""
  8014  	}
  8015  |	"OPTIONALLY" "ENCLOSED" "BY" stringLit
  8016  	{
  8017  		$$ = $4
  8018  	}
  8019  |	"ENCLOSED" "BY" stringLit
  8020  	{
  8021  		$$ = $3
  8022  	}
  8023  
  8024  Escaped:
  8025  	{
  8026  		$$ = "\\"
  8027  	}
  8028  |	"ESCAPED" "BY" stringLit
  8029  	{
  8030  		$$ = $3
  8031  	}
  8032  
  8033  Lines:
  8034  	{
  8035  		$$ = &ast.LinesClause{Terminated: "\n"}
  8036  	}
  8037  |	"LINES" Starting LinesTerminated
  8038  	{
  8039  		$$ = &ast.LinesClause{Starting: $2.(string), Terminated: $3.(string)}
  8040  	}
  8041  
  8042  Starting:
  8043  	{
  8044  		$$ = ""
  8045  	}
  8046  |	"STARTING" "BY" stringLit
  8047  	{
  8048  		$$ = $3
  8049  	}
  8050  
  8051  LinesTerminated:
  8052  	{
  8053  		$$ = "\n"
  8054  	}
  8055  |	"TERMINATED" "BY" stringLit
  8056  	{
  8057  		$$ = $3
  8058  	}
  8059  
  8060  
  8061  /*********************************************************************
  8062   * Lock/Unlock Tables
  8063   * See http://dev.mysql.com/doc/refman/5.7/en/lock-tables.html
  8064   * All the statement leaves empty. This is used to prevent mysqldump error.
  8065   *********************************************************************/
  8066  
  8067  UnlockTablesStmt:
  8068  	"UNLOCK" TablesTerminalSym {}
  8069  
  8070  LockTablesStmt:
  8071  	"LOCK" TablesTerminalSym TableLockList
  8072  	{}
  8073  
  8074  TablesTerminalSym:
  8075  	"TABLES"
  8076  |	"TABLE"
  8077  
  8078  TableLock:
  8079  	TableName LockType
  8080  
  8081  LockType:
  8082  	"READ"
  8083  |	"READ" "LOCAL"
  8084  |	"WRITE"
  8085  
  8086  TableLockList:
  8087  	TableLock
  8088  |	TableLockList ',' TableLock
  8089  
  8090  
  8091  /********************************************************************
  8092   * Kill Statement
  8093   * See https://dev.mysql.com/doc/refman/5.7/en/kill.html
  8094   *******************************************************************/
  8095  
  8096  KillStmt:
  8097  	KillOrKillTiDB NUM
  8098  	{
  8099  		$$ = &ast.KillStmt{
  8100  			ConnectionID: getUint64FromNUM($2),
  8101  			TiDBExtension: $1.(bool),
  8102  		}
  8103  	}
  8104  |	KillOrKillTiDB "CONNECTION" NUM
  8105  	{
  8106  		$$ = &ast.KillStmt{
  8107  			ConnectionID: getUint64FromNUM($3),
  8108  			TiDBExtension: $1.(bool),
  8109  		}
  8110  	}
  8111  |	KillOrKillTiDB "QUERY" NUM
  8112  	{
  8113  		$$ = &ast.KillStmt{
  8114  			ConnectionID: getUint64FromNUM($3),
  8115  			Query: true,
  8116  			TiDBExtension: $1.(bool),
  8117  		}
  8118  	}
  8119  
  8120  KillOrKillTiDB:
  8121  	"KILL"
  8122  	{
  8123  		$$ = false
  8124  	}
  8125  /* KILL TIDB is a special grammar extension in TiDB, it can be used only when
  8126     the client connect to TiDB directly, not proxied under LVS. */
  8127  |	"KILL" "TIDB"
  8128  	{
  8129  		$$ = true
  8130  	}
  8131  
  8132  /*******************************************************************************************/
  8133  
  8134  LoadStatsStmt:
  8135  	"LOAD" "STATS" stringLit
  8136  	{
  8137  		$$ = &ast.LoadStatsStmt{
  8138  			Path:       $3,
  8139  		}
  8140  	}
  8141  
  8142  %%