]> review.fuel-infra Code Review - packages/trusty/mysql-wsrep-5.6.git/blob
3fbf246e142c482be15489c0b6e3cef0c595f0f3
[packages/trusty/mysql-wsrep-5.6.git] /
1 /*
2  *  Copyright (c) 2008, 2011, Oracle and/or its affiliates. All rights reserved.
3  *
4  *  This program is free software; you can redistribute it and/or modify
5  *  it under the terms of the GNU General Public License as published by
6  *  the Free Software Foundation; version 2 of the License.
7  *
8  *  This program is distributed in the hope that it will be useful,
9  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
10  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11  *  GNU General Public License for more details.
12  *
13  *  You should have received a copy of the GNU General Public License
14  *  along with this program; if not, write to the Free Software
15  *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301  USA
16  */
17
18 parser grammar MySQL51Parser; 
19
20 options {
21         output=AST;
22         tokenVocab=MySQL51Lexer;
23         superClass=MySQLParser;
24 }
25
26 import MySQL51Functions;
27
28 tokens {
29 SELECT;
30 SELECT_EXPR;
31 UNARY_MINUS;
32 UNARY_PLUS;
33 OPTIONS;
34 FUNC;
35 DIRECTION;
36 ALIAS;
37 FIELD;
38 SUBSELECT;
39 COMMA_JOIN;
40 COLUMNS;
41 INSERT_VALUES;
42 INDEX_HINTS;
43 ROLLBACK_POINT; /* rollback to savepoint */
44 /* token types for the various CREATE statements */
45 CREATE_TABLE;
46 /* helper tokens for column definitions  */
47 NOT_NULL;
48 DEFINITION;
49 DEFINITIONS;
50 COUNT_STAR;
51 }
52
53 @header{
54 package com.mysql.clusterj.jdbc.antlr;
55 }
56
57 statement_list
58         :       stmts+=statement (SEMI stmts+=statement)* SEMI*
59                 -> $stmts+
60         ;
61
62 statement
63         :       (       select
64                 |       do_stmt
65                 |       show_stmt
66                 |       explain_stmt
67                 |       insert
68                 |       update
69                 |       delete
70                 |       transaction
71                 |       create_table
72                 |       COMMENT_RULE
73                 )
74         ;
75
76 // $< DML
77
78 do_stmt :       DO exprList             -> ^(DO exprList)
79         ;
80
81 show_stmt
82   : (SHOW -> ^(SHOW))
83     ( AUTHORS     -> ^($show_stmt ^(AUTHORS))
84     | BINLOG EVENTS (IN logName=STRING)? (FROM NUMBER)? limit?  -> ^($show_stmt ^(BINLOG $logName? NUMBER? limit?))
85     | CHARACTER SET like_or_where?  -> ^($show_stmt ^(CHARACTER like_or_where?))
86     | COLLATION like_or_where?    -> ^($show_stmt ^(COLLATION like_or_where?))
87     | FULL? COLUMNS (FROM|IN) simple_table_ref_no_alias ((FROM|IN) ident)? like_or_where? -> ^($show_stmt ^(COLUMNS FULL? simple_table_ref_no_alias ident? like_or_where?))
88     | CONTRIBUTORS  -> ^($show_stmt ^(CONTRIBUTORS))
89     | CREATE DATABASE ident -> ^($show_stmt ^(CREATE DATABASE ident))
90     | CREATE EVENT ident    -> ^($show_stmt ^(CREATE EVENT ident))
91     | CREATE FUNCTION ident -> ^($show_stmt ^(CREATE FUNCTION ident))
92     | CREATE PROCEDURE ident  -> ^($show_stmt ^(CREATE PROCEDURE ident))
93     | CREATE TABLE simple_table_ref_no_alias  -> ^($show_stmt ^(CREATE TABLE simple_table_ref_no_alias))
94     | CREATE TRIGGER ident  -> ^($show_stmt ^(CREATE TRIGGER ident))
95     | CREATE VIEW ident   -> ^($show_stmt ^(CREATE VIEW ident))
96     | DATABASES like_or_where?  -> ^($show_stmt ^(DATABASES like_or_where?))
97     | ENGINE (INNODB | ident) (what=STATUS | what=MUTEX) // have to add INNODB token, because of SHOW INNODB STATUS :(
98                     -> ^($show_stmt ^(ENGINE INNODB? ident? $what))
99     | STORAGE? ENGINES    -> ^($show_stmt ^(ENGINES))
100     | ERRORS limit?     -> ^($show_stmt ^(ERRORS limit?))
101     | FULL? EVENTS      -> ^($show_stmt ^(EVENTS FULL?))
102     | FUNCTION CODE ident   -> ^($show_stmt ^(CODE FUNCTION ident))
103     | FUNCTION STATUS like_or_where?  -> ^($show_stmt ^(STATUS FUNCTION like_or_where?))
104     | GRANTS FOR
105         ( whom=USER_HOST
106         | whom=CURRENT_USER
107         | whom=CURRENT_USER LPAREN RPAREN
108         )         -> ^($show_stmt ^(GRANTS $whom))
109     | INDEX_SYM FROM simple_table_ref_no_alias ((FROM|IN) ident)? -> ^($show_stmt ^(INDEX_SYM simple_table_ref_no_alias ident?))
110     | INNODB STATUS   -> ^($show_stmt ^(ENGINE INNODB STATUS))
111     | OPEN TABLES ((FROM|IN) ident)? like_or_where? -> ^($show_stmt ^(OPEN ident? like_or_where?))
112     | PLUGINS     -> ^($show_stmt ^(PLUGINS))
113     | PROCEDURE CODE ident      -> ^($show_stmt ^(CODE PROCEDURE ident))
114     | PROCEDURE STATUS like_or_where? -> ^($show_stmt ^(STATUS PROCEDURE ident))
115     | PRIVILEGES      -> ^($show_stmt ^(PRIVILEGES))
116     | FULL? PROCESSLIST -> ^($show_stmt ^(PROCESSLIST FULL?))
117     | PROFILE show_profile_types (FOR QUERY NUMBER)? limit? -> ^($show_stmt ^(PROFILE show_profile_types NUMBER? limit?))
118     | PROFILES    -> ^($show_stmt ^(PROFILES))
119     | SCHEDULER STATUS  -> ^($show_stmt ^(STATUS SCHEDULER))
120     | optScopeModifier STATUS like_or_where?  -> ^($show_stmt ^(STATUS optScopeModifier? like_or_where?))
121     | TABLE STATUS ((FROM|IN) ident)? like_or_where?      -> ^($show_stmt  ^(STATUS TABLE ident? like_or_where?))
122     | TABLES ((FROM|IN) ident)? like_or_where?          -> ^($show_stmt ^(TABLES ident? like_or_where?))
123     | TRIGGERS ((FROM|IN) ident)? like_or_where?        -> ^($show_stmt ^(TRIGGERS ident? like_or_where?))
124     | optScopeModifier VARIABLES like_or_where?   -> ^($show_stmt ^(VARIABLES optScopeModifier? like_or_where?))
125     | WARNINGS limit?   -> ^($show_stmt ^(WARNINGS limit?))
126     )
127   ;
128   
129 optScopeModifier
130   : GLOBAL    -> GLOBAL
131   | SESSION   -> SESSION
132   | l=LOCAL   -> SESSION[$l]
133   | /* empty, defaults to SESSION */ -> SESSION
134   ;
135
136 show_profile_types
137   : ALL
138   | BLOCK IO
139   | CONTEXT SWITCHES
140   | CPU
141   | IPC
142   | MEMORY
143   | PAGE FAULTS
144   | SOURCE
145   | SWAPS
146   ;
147
148 like_or_where
149   : // behold, this is a special LIKE...does not allow expressions on the RHS
150     LIKE string_or_placeholder   -> ^(LIKE string_or_placeholder)
151   | WHERE expr    -> ^(WHERE expr)
152   ;
153   
154 explain_stmt
155   : EXPLAIN select -> ^(EXPLAIN select)
156   ;
157
158 select
159 @init {
160 boolean seenUnion = false;
161 }
162         :       select_paren
163                 (UNION (mod=ALL | mod=DISTINCT)? union_selects+=select_paren {seenUnion=true;})*
164                         -> {seenUnion}? ^(UNION $mod? select_paren $union_selects+)
165                         -> select_paren
166         ;
167
168 select_paren
169         :       LPAREN select_paren RPAREN      -> select_paren
170         |       select_inner                            -> select_inner
171         ;
172         
173 select_inner
174         :       SELECT (options{k=1;}:select_options)*
175                 exprs+=select_expr (COMMA exprs+=select_expr)*
176                 (
177             (FROM table_references)
178             (WHERE where=where_condition)?
179             group_by?
180             (HAVING having=where_condition)?
181             order_by?
182             limit?
183             // these procedures are not "SQL-SPs" but C++ ones. very unlikely that we'll see them.
184             (PROCEDURE procId=ident procArgs=parenOptExprList)?
185             /* TODO: what is allowed in the "STRING" below? probably not N'foobar' etc. */
186             ((  INTO OUTFILE file=STRING opts=infile_options_helper
187                 |       INTO DUMPFILE file=STRING
188                 |       INTO vars+=variable (COMMA vars+=variable)*
189                 )       
190             )?
191             (forUpdate=FOR UPDATE | lock=LOCK IN SHARE MODE)?
192         |   order_by
193             limit?
194         |   limit
195                 )?
196                 -> ^(SELECT<com.mysql.clusterj.jdbc.antlr.node.SelectNode>
197                                 ^(OPTIONS select_options*)?
198                                 ^(COLUMNS $exprs+)
199                                 ^(FROM table_references)?
200                                 ^(WHERE<com.mysql.clusterj.jdbc.antlr.node.WhereNode> $where)?
201                                 group_by?
202                                 ^(HAVING $having)?
203                                 order_by?
204                                 limit?
205                                 FOR?
206                                 LOCK?
207                         )
208         ;
209
210 infile_options_helper
211         :       (       (COLUMNS|FIELDS)
212                         (TERMINATED BY fieldTerm=STRING)?
213                         (optEnclosed=OPTIONALLY? ENCLOSED BY fieldEncl=STRING)?                 /* TODO: STRING here is one character, really */
214                         (ESCAPED BY fieldEsc=STRING)?                                                                   /* TODO: STRING here is one character, really */
215                 )?
216                 (       LINES
217                         (STARTING BY linesStart=STRING)?
218                         (TERMINATED BY linesTerm=STRING)?
219                 )?
220         ;
221         
222 variable
223         :       SESSION_VARIABLE
224         |       GLOBAL_VARIABLE
225         ;
226
227 limit
228         :       LIMIT
229                         (       ((offset=number_or_placeholder COMMA)? lim=number_or_placeholder)       
230                         |       (lim=number_or_placeholder offsetForm=OFFSET offset=number_or_placeholder)
231                         )
232                 -> ^(LIMIT $lim $offset? $offsetForm?)
233         ;
234
235 string_or_placeholder
236         :       STRING
237         |       VALUE_PLACEHOLDER
238         ;
239
240 number_or_placeholder
241         :       NUMBER
242         |       VALUE_PLACEHOLDER
243         ;
244
245 text_string
246         :       STRING
247         |       BINARY_VALUE
248         |       HEXA_VALUE
249         ;
250
251 group_by
252         :       GROUP BY 
253                         elements+=order_group_by_elements (COMMA elements+=order_group_by_elements )*
254                 (rollup=WITH ROLLUP)?
255                 -> ^(GROUP $elements+ $rollup?)
256         ;
257
258 order_by
259         :       ORDER BY
260                         elements+=order_group_by_elements (COMMA elements+=order_group_by_elements )*
261                 -> ^(ORDER $elements+)
262         ;
263         
264 order_group_by_elements
265         :       expr 
266                 (       asc=ASC                                         -> ^(DIRECTION[$asc] expr)
267                 |       desc=DESC                                       -> ^(DIRECTION[$desc] expr)
268                 |       /* implicit ASC */                      -> ^(DIRECTION["ASC"] expr)
269                 )
270         ;
271
272 select_options
273         :       ALL
274         |       DISTINCT
275         |       DISTINCTROW
276         |       HIGH_PRIORITY
277         |       STRAIGHT_JOIN
278         |       SQL_SMALL_RESULT
279         |       SQL_BIG_RESULT
280 // the following cause parser warnings
281 //      |       SQL_BUFFER_RESULT
282 //      |       SQL_CACHE
283 //      |       SQL_NO_CACHE
284         |       SQL_CALC_FOUND_ROWS
285         ;
286         
287 select_expr
288         :       expr (AS? ident)?               -> ^(SELECT_EXPR expr ^(ALIAS ident)?)
289         |       star=MULT                               -> ^(SELECT_EXPR $star)
290         ;
291 /*      catch[RecognitionException re] {
292            Object errorNode = (Object)adaptor.errorNode(input, retval.start, input.LT(-1), re);
293            Object root_1 = (Object)adaptor.nil();
294      root_1 = (Object)adaptor.becomeRoot((Object)adaptor.create(SELECT_EXPR, "SELECT_EXPR"), root_1);
295      adaptor.addChild(root_1, errorNode);
296      adaptor.addChild(root_0, root_1);
297      retval.tree = (Object)adaptor.rulePostProcessing(root_0);
298         }
299 */
300 table_references returns [int table_count]
301 scope {
302 int count;
303 }
304 @init {
305 $table_references::count = 0;
306 }
307 @after {
308 $table_references.table_count = $table_references::count;
309 }
310         :       (       t1=table_ref                    -> $t1)
311                 (       COMMA t2=table_ref              -> ^(COMMA_JOIN[$COMMA] $table_references $t2)
312                 )*
313         ;
314
315 /* left factored to get rid of the recursion */
316 table_ref
317         :       (t1=table_factor -> $t1 )
318                 (
319                         (LEFT|RIGHT)=>(ltype=LEFT|ltype=RIGHT) outer=OUTER? JOIN t3=table_ref lrjoinCond=join_condition_either 
320                                 -> ^($ltype {$tree} $t3 $lrjoinCond $outer?)
321 // join condition is not optional here
322                 |       (type=INNER|type=CROSS)? JOIN t2=table_factor cond1=join_condition_either 
323                                 -> ^(JOIN {$tree} $t2 $cond1? $type?)
324                 |       (       type=STRAIGHT_JOIN t2=table_factor 
325                                 (       (join_condition_on)=> cond2=join_condition_on   -> ^($type {$tree} $t2 $cond2)
326                                 |                                                       -> ^($type {$tree} $t2)
327                                 )
328                         )
329                 |       (NATURAL)=> NATURAL ((type=LEFT|type=RIGHT) outer=OUTER?)? JOIN t2=table_factor -> ^(NATURAL $type? {$tree} $t2 $outer?)
330                 )*
331         ;
332         
333 table_factor
334         :       simple_table_ref_alias index_hint_list? {$table_references::count++;} -> ^(TABLE simple_table_ref_alias index_hint_list?)
335         |       LPAREN select_inner RPAREN AS? ident            {$table_references::count++;} -> ^(SUBSELECT select_inner ^(ALIAS ident))
336     |   LPAREN table_ref {$table_references::count++;} (COMMA table_ref {$table_references::count++;} )* RPAREN   -> ^(TABLE table_ref+)
337         /* ident in the following should really by 'OJ', but the parser accepts any identifier in its place */
338         |       LCURLY ident t1=table_ref LEFT OUTER JOIN t2=table_ref join_condition_on RCURLY 
339                         -> ^(ident $t1 $t2 join_condition_on)
340         |       DUAL                                                            -> ^(DUAL)
341         ;
342
343 join_condition_on
344         :       ON where_condition              -> ^(ON where_condition)
345         ;
346
347 join_condition_either
348         :       join_condition_on
349         |       USING LPAREN fields+=ident (COMMA fields+=ident)* RPAREN                -> ^(USING $fields+)
350         ;
351
352 simple_table_ref_no_alias
353         :       first=ident (DOT second=ident)?         -> $first $second?
354         ;
355
356 simple_table_ref_alias
357         :       first=ident (DOT second=ident)? table_alias?            -> $first $second? table_alias?
358         ;
359
360 table_alias
361         :       AS? alias=ident -> ^(ALIAS $alias)
362         ;
363
364 field_name
365 @init {
366 int i = 0;
367 boolean seenStar = false;
368 }
369         :       ident
370                 ({seenStar == false}?=> 
371                   (DOT 
372                     ({seenStar == false}? (ident | star=MULT {seenStar = true;}) {++i <= 2}?)
373                   )*
374                 )
375                 -> ^(FIELD ident+ $star?)
376 //      |       (DOT)=>DOT column=field_name_column     -> ^(FIELD $column)
377         ;
378
379 /* list all keywords that can also be used as an identifier
380    This list is taken from the 5.1 YACC grammar 
381 */
382
383 ident
384         :       
385         (       tok=ASCII
386         |       tok=BACKUP
387         |       tok=BEGIN
388         |       tok=BYTE
389         |       tok=CACHE
390         |       tok=CHARSET
391         |       tok=CHECKSUM
392         |       tok=CLOSE
393         |       tok=COMMENT
394         |       tok=COMMIT
395         |       tok=CONTAINS
396         |       tok=DEALLOCATE
397         |       tok=DO
398         |       tok=END
399         |       tok=EXECUTE
400         |       tok=FLUSH
401         |       tok=GROUP
402         |       tok=HANDLER
403         |       tok=HELP
404         |       tok=HOST
405         |       tok=INSTALL
406         |       tok=LABEL
407         |       tok=LANGUAGE
408         |       tok=NO
409         |       tok=OPEN
410         |       tok=OPTIONS
411         |       tok=OWNER
412         |       tok=PARSER
413         |       tok=PARTITION
414         |       tok=PORT
415         |       tok=PREPARE
416         |       tok=REMOVE
417         |       tok=REPAIR
418         |       tok=RESET
419         |       tok=RESTORE
420         |       tok=ROLLBACK
421         |       tok=SAVEPOINT
422         |       tok=SECURITY
423         |       tok=SERVER
424         |       tok=SIGNED
425         |       tok=SOCKET
426         |       tok=SLAVE
427         |       tok=SONAME
428         |       tok=START
429         |       tok=STOP
430         |       tok=TRUNCATE
431         |       tok=UNICODE
432         |       tok=UNINSTALL
433         |       tok=WRAPPER
434         |       tok=XA
435         |       tok=UPGRADE
436         )       -> ID[$tok]
437         |       ident_sp_label  -> {$ident_sp_label.tree}
438         ;
439
440 ident_sp_label
441         :               
442         (       tok=ID!
443         |       tok=ACTION!
444         |       tok=ADDDATE!
445         |       tok=AFTER!
446         |       tok=AGAINST!
447         |       tok=AGGREGATE!
448         |       tok=ALGORITHM!
449         |       tok=ANY!
450         |       tok=AT!
451         |       tok=AUTHORS!
452         |       tok=AUTO_INCREMENT!
453         |       tok=AUTOEXTEND_SIZE!
454         |       tok=AVG_ROW_LENGTH!
455         |       tok=AVG!
456         |       tok=BINLOG!
457         |       tok=BIT!
458         |       tok=BLOCK!
459         |       tok=BOOL!
460         |       tok=BOOLEAN!
461         |       tok=BTREE!
462         |       tok=CASCADED!
463         |       tok=CHAIN!
464         |       tok=CHANGED!
465         |       tok=CIPHER!
466         |       tok=CLIENT!
467         |       tok=COALESCE!
468         |       tok=CODE!
469         |       tok=COLLATION!
470         |       tok=COLUMNS!
471         |       tok=FIELDS!
472         |       tok=COMMITTED!
473         |       tok=COMPACT!
474         |       tok=COMPLETION!
475         |       tok=COMPRESSED!
476         |       tok=CONCURRENT!
477         |       tok=CONNECTION!
478         |       tok=CONSISTENT!
479         |       tok=CONTEXT!
480         |       tok=CONTRIBUTORS!
481         |       tok=CPU!
482         |       tok=CUBE!
483         |       tok=DATA!
484         |       tok=DATAFILE!
485         |       tok=DATETIME!
486         |       tok=DATE!
487         |       tok=DAY!
488         |       tok=DEFINER!
489         |       tok=DELAY_KEY_WRITE!
490         |       tok=DES_KEY_FILE!
491         |       tok=DIRECTORY!
492         |       tok=DISABLE!
493         |       tok=DISCARD!
494         |       tok=DISK!
495         |       tok=DUMPFILE!
496         |       tok=DUPLICATE!
497         |       tok=DYNAMIC!
498         |       tok=ENDS!
499         |       tok=ENUM!
500         |       tok=ENGINE!
501         |       tok=ENGINES!
502         |       tok=ERRORS!
503         |       tok=ESCAPE!
504         |       tok=EVENT!
505         |       tok=EVENTS!
506         |       tok=EVERY!
507         |       tok=EXPANSION!
508         |       tok=EXTENDED!
509         |       tok=EXTENT_SIZE!
510         |       tok=FAULTS!
511         |       tok=FAST!
512         |       tok=FOUND!
513         |       tok=ENABLE!
514         |       tok=FULL!
515         |       tok=FILE!
516         |       tok=FIRST!
517         |       tok=FIXED!
518         |       tok=FRAC_SECOND!
519         |       tok=GEOMETRY!
520         |       tok=GEOMETRYCOLLECTION!
521         |       tok=GET_FORMAT!
522         |       tok=GRANTS!
523         |       tok=GLOBAL!
524         |       tok=HASH!
525         |       tok=HOSTS!
526         |       tok=HOUR!
527         |       tok=IDENTIFIED!
528         |       tok=INVOKER!
529         |       tok=IMPORT!
530         |       tok=INDEXES!
531         |       tok=INITIAL_SIZE!
532         |       tok=IO!
533         |       tok=IPC!
534         |       tok=ISOLATION!
535         |       tok=ISSUER!
536         |       tok=INNOBASE!
537         |       tok=INSERT_METHOD!
538         |       tok=KEY_BLOCK_SIZE!
539         |       tok=LAST!
540         |       tok=LEAVES!
541         |       tok=LESS!
542         |       tok=LEVEL!
543         |       tok=LINESTRING!
544         |       tok=LIST!
545         |       tok=LOCAL!
546         |       tok=LOCKS!
547         |       tok=LOGFILE!
548         |       tok=LOGS!
549         |       tok=MAX_ROWS!
550         |       tok=MASTER!
551         |       tok=MASTER_HOST!
552         |       tok=MASTER_PORT!
553         |       tok=MASTER_LOG_FILE!
554         |       tok=MASTER_LOG_POS!
555         |       tok=MASTER_USER!
556         |       tok=MASTER_PASSWORD!
557         |       tok=MASTER_SERVER_ID!
558         |       tok=MASTER_CONNECT_RETRY!
559         |       tok=MASTER_SSL!
560         |       tok=MASTER_SSL_CA!
561         |       tok=MASTER_SSL_CAPATH!
562         |       tok=MASTER_SSL_CERT!
563         |       tok=MASTER_SSL_CIPHER!
564         |       tok=MASTER_SSL_KEY!
565         |       tok=MAX_CONNECTIONS_PER_HOUR!
566         |       tok=MAX_QUERIES_PER_HOUR!
567         |       tok=MAX_SIZE!
568         |       tok=MAX_UPDATES_PER_HOUR!
569         |       tok=MAX_USER_CONNECTIONS!
570         |       tok=MAX_VALUE!
571         |       tok=MEDIUM!
572         |       tok=MEMORY!
573         |       tok=MERGE!
574         |       tok=MICROSECOND!
575         |       tok=MIGRATE!
576         |       tok=MINUTE!
577         |       tok=MIN_ROWS!
578         |       tok=MODIFY!
579         |       tok=MODE!
580         |       tok=MONTH!
581         |       tok=MULTILINESTRING!
582         |       tok=MULTIPOINT!
583         |       tok=MULTIPOLYGON!
584         |       tok=MUTEX!
585         |       tok=NAME!
586         |       tok=NAMES!
587         |       tok=NATIONAL!
588         |       tok=NCHAR!
589         |       tok=NDBCLUSTER!
590         |       tok=NEXT!
591         |       tok=NEW!
592         |       tok=NO_WAIT!
593         |       tok=NODEGROUP!
594         |       tok=NONE!
595         |       tok=NVARCHAR!
596         |       tok=OFFSET!
597         |       tok=OLD_PASSWORD!
598         |       tok=ONE_SHOT!
599         |       tok=ONE!
600         |       tok=PACK_KEYS!
601         |       tok=PAGE!
602         |       tok=PARTIAL!
603         |       tok=PARTITIONING!
604         |       tok=PARTITIONS!
605         |       tok=PASSWORD!
606         |       tok=PHASE!
607         |       tok=PLUGIN!
608         |       tok=PLUGINS!
609         |       tok=POINT!
610         |       tok=POLYGON!
611         |       tok=PRESERVE!
612         |       tok=PREV!
613         |       tok=PRIVILEGES!
614         |       tok=PROCESS!
615         |       tok=PROCESSLIST!
616         |       tok=PROFILE!
617         |       tok=PROFILES!
618         |       tok=QUARTER!
619         |       tok=QUERY!
620         |       tok=QUICK!
621         |       tok=REBUILD!
622         |       tok=RECOVER!
623         |       tok=REDO_BUFFER_SIZE!
624         |       tok=REDOFILE!
625         |       tok=REDUNDANT!
626         |       tok=RELAY_LOG_FILE!
627         |       tok=RELAY_LOG_POS!
628         |       tok=RELAY_THREAD!
629         |       tok=RELOAD!
630         |       tok=REORGANIZE!
631         |       tok=REPEATABLE!
632         |       tok=REPLICATION!
633         |       tok=RESOURCES!
634         |       tok=RESUME!
635         |       tok=RETURNS!
636         |       tok=ROLLUP!
637         |       tok=ROUTINE!
638         |       tok=ROWS!
639         |       tok=ROW_FORMAT!
640         |       tok=ROW!
641         |       tok=RTREE!
642         |       tok=SCHEDULE!
643         |       tok=SECOND!
644         |       tok=SERIAL!
645         |       tok=SERIALIZABLE!
646         |       tok=SESSION!
647         |       tok=SIMPLE!
648         |       tok=SHARE!
649         |       tok=SHUTDOWN!
650         |       tok=SNAPSHOT!
651         |       tok=SOUNDS!
652         |       tok=SOURCE!
653         |       tok=SQL_CACHE!
654         |       tok=SQL_BUFFER_RESULT!
655         |       tok=SQL_NO_CACHE!
656         |       tok=SQL_THREAD!
657         |       tok=STARTS!
658         |       tok=STATUS!
659         |       tok=STORAGE!
660         |       tok=STRING_KEYWORD!
661         |       tok=SUBDATE!
662         |       tok=SUBJECT!
663         |       tok=SUBPARTITION!
664         |       tok=SUBPARTITIONS!
665         |       tok=SUPER!
666         |       tok=SUSPEND!
667         |       tok=SWAPS!
668         |       tok=SWITCHES!
669         |       tok=TABLES!
670         |       tok=TABLESPACE!
671         |       tok=TEMPORARY!
672         |       tok=TEMPTABLE!
673         |       tok=TEXT!
674         |       tok=THAN!
675         |       tok=TRANSACTION!
676         |       tok=TRANSACTIONAL!
677         |       tok=TRIGGERS!
678         |       tok=TIMESTAMP!
679         |       tok=TIMESTAMP_ADD!
680         |       tok=TIMESTAMP_DIFF!
681         |       tok=TIME!
682         |       tok=TYPES!
683         |       tok=TYPE!
684         |       tok=UDF_RETURNS!
685         |       tok=FUNCTION!
686         |       tok=UNCOMMITTED!
687         |       tok=UNDEFINED!
688         |       tok=UNDO_BUFFER_SIZE!
689         |       tok=UNDOFILE!
690         |       tok=UNKNOWN!
691         |       tok=UNTIL!
692         |       tok=USER!
693         |       tok=USE_FRM!
694         |       tok=VARIABLES!
695         |       tok=VIEW!
696         |       tok=VALUE!
697         |       tok=WARNINGS!
698         |       tok=WAIT!
699         |       tok=WEEK!
700         |       tok=WORK!
701         |       tok=X509!
702         |       tok=YEAR!
703         )       
704         {
705                 adaptor.addChild(root_0, (Object)adaptor.create(ID, $tok));
706         }
707         ;
708
709 index_hint_list
710         :       index_hint (COMMA index_hint)*          -> ^(INDEX_HINTS index_hint+)
711         ;
712
713 index_hint
714 scope {
715 boolean namesOptional;
716 }
717 @init {
718 $index_hint::namesOptional = false;
719 }
720         :       USE {$index_hint::namesOptional = true;} index_hint_rest                -> ^(USE index_hint_rest)
721         |       IGNORE {$index_hint::namesOptional = false;} index_hint_rest    -> ^(IGNORE index_hint_rest)
722         |       FORCE {$index_hint::namesOptional = false;} index_hint_rest     -> ^(FORCE index_hint_rest)
723         ;
724
725 index_hint_rest
726         :       (name=INDEX|name=KEY) (FOR (usage=JOIN | usage=ORDER BY | usage=GROUP BY))?
727                 LPAREN
728                 ( {$index_hint::namesOptional == true}?=> (names+=ident (COMMA names+=ident)*)?
729                 | names+=ident (COMMA names+=ident)* 
730                 )
731                 RPAREN
732                 -> $name ^(LPAREN $names?) $usage?
733         ;
734 // $<Expressions
735
736 exprList
737         :       e+=expr (COMMA e+=expr)*        -> $e+
738         ;
739
740 parenExpr
741         :       LPAREN expr RPAREN      -> ^(LPAREN<com.mysql.clusterj.jdbc.antlr.node.ParensNode> expr)
742         ;
743         
744 parenExprList
745         :       LPAREN exprList RPAREN  -> ^(LPAREN exprList)
746         ;
747         
748 parenOptExprList
749         :       LPAREN e+=exprList? RPAREN      -> ^(LPAREN $e*)
750         ;
751
752 expr
753         :       lhs=assignOrExpr (op=ASSIGN^ rhs=expr)?
754         ;
755
756 assignOrExpr
757         :       lhs=assignXORExpr ((op+=LOGICAL_OR^ | op+=OR<com.mysql.clusterj.jdbc.antlr.node.OrNode>^) rhs+=assignXORExpr)*
758         ;
759
760 assignXORExpr
761         :       lhs=assignAndExpr (op+=XOR^ rhs+=assignAndExpr)*
762         ;
763
764 assignAndExpr
765         :       lhs=assignNotExpr (( op+=LOGICAL_AND^ | op+=AND<com.mysql.clusterj.jdbc.antlr.node.AndNode>^ ) rhs+=assignNotExpr)*
766         ;
767
768 assignNotExpr
769         :       lhs=equalityExpr
770         |       op+=NOT<com.mysql.clusterj.jdbc.antlr.node.NotNode>^ rhs+=equalityExpr
771         ;
772
773 equalityExpr
774         :       bitwiseOrExpr
775                 (op+=equalityOperator^ ((subselect_in_expr_rhs)=> subselect_in_expr_rhs | bitwiseOrExpr))*                                                                              
776         ;
777
778 subselect_in_expr_rhs
779         :       (mod=ANY | mod=SOME | mod=ALL) LPAREN select RPAREN     -> ^(SUBSELECT $mod select)
780         ;
781         
782 subselect
783         :       LPAREN select_inner RPAREN      -> ^(SUBSELECT select_inner)
784         ;
785
786 isOperator
787         :       IS NOT? (value2=NULL | value2=FALSE | value2=TRUE | value2=UNKNOWN)     -> ^(IS NOT? $value2)
788         ;
789
790 equalityOperator
791         :       (       value=EQUALS<com.mysql.clusterj.jdbc.antlr.node.EqualsNode>
792                 |       value=NOT_EQUAL
793                 |       value=LESS_THAN<com.mysql.clusterj.jdbc.antlr.node.LessThanNode>
794                 |       value=LESS_THAN_EQUAL<com.mysql.clusterj.jdbc.antlr.node.LessEqualsNode>
795                 |       value=GREATER_THAN<com.mysql.clusterj.jdbc.antlr.node.GreaterThanNode>          
796                 |       value=GREATER_THAN_EQUAL<com.mysql.clusterj.jdbc.antlr.node.GreaterEqualsNode>
797                 |       value=NULL_SAFE_NOT_EQUAL
798                 |       value=REGEXP
799                 |       value=CASE
800                 |       value=WHEN
801                 |       value=THEN
802                 |       value=ELSE
803                 )
804         ;
805
806 bitwiseOrExpr
807     : lhs=bitwiseAndExpr 
808     ( (op+=BITWISE_OR^ rhs+=bitwiseAndExpr)+
809 // force compiler to always recognize NOT IN regardless of whatever follows
810     | (((NOT^)? IN^)=>(NOT^)? IN^ (parenExprList | subselect))
811     | LIKE^ unaryExpr (ESCAPE STRING)?  // STRING must be empty or one character long (or be "\\" if not in sql_mode NO_BACKSLASH_ESCAPES)
812     | isOperator^
813     | ((NOT^)? BETWEEN^)=> (NOT<com.mysql.clusterj.jdbc.antlr.node.NotNode>^)? (BETWEEN<com.mysql.clusterj.jdbc.antlr.node.BetweenNode>^ unaryExpr AND! unaryExpr )
814     )?
815     ;
816
817 bitwiseAndExpr
818         :       lhs=shiftExpr (op+=BITWISE_AND^ rhs+=shiftExpr)*
819         ;
820
821 shiftExpr
822         :       lhs=additiveExpr ((op+=LEFT_SHIFT^ | op+=RIGHT_SHIFT^) rhs+=additiveExpr)*
823         ;
824
825 /* this is ugly because of INTERVAL:
826    As rightmost in an expression, it has the highest precendence.
827    Otherwise it must be followed by PLUS|MINUS.
828    TODO: It cannot be on the left of a MINUS, because that expression makes no sense.
829 */
830 additiveExpr
831 // force any PLUS or MINUS to be binary not unary for this rule
832     :   lhs=multiplicativeExpr ((PLUS|MINUS)=>(op+=PLUS^|op+=MINUS^) rhs+=multiplicativeExpr)*
833         ;
834
835 multOperator
836         :       value=MULT
837         |       value=DIVISION
838         |       value=DIV
839         |       value=MODULO
840         ;
841
842 multiplicativeExpr
843         :       lhs=bitwiseXORExpr (op+=multOperator^ rhs+=bitwiseXORExpr)*
844         ;
845
846 bitwiseXORExpr
847         :       lhs=unaryExpr (op+=BITWISE_XOR^ rhs+=unaryExpr)*
848         ;
849
850 unaryExpr
851         :       op=MINUS lhs=unaryExpr  -> ^(UNARY_MINUS[$op] $lhs)
852         |       op=PLUS lhs=unaryExpr   -> ^(UNARY_PLUS[$op] $lhs)
853         |       op=BITWISE_INVERSION lhs=unaryExpr -> ^(BITWISE_INVERSION $lhs)
854         |       lhsUnaryNot=unaryNotExpr        -> unaryNotExpr
855         ;
856         
857 unaryNotExpr
858         :       op=NOT_OP lhs=unaryNotExpr      -> ^(NOT_OP $lhs)
859         |       lhsBin=binaryCollateExpr        -> binaryCollateExpr
860         ;
861
862 binaryCollateExpr
863         :       op=BINARY lhs=binaryCollateExpr         -> ^(BINARY $lhs)
864         |       op=COLLATE lhs=binaryCollateExpr        -> ^(COLLATE $lhs)
865         |       intervalExpr
866         ;
867
868 /* INTERVAL can bind extremely closely, if used as the rightmost subexpr of an expression, otherwise it is in additiveExpr 
869    the validating predicate disallows its usage all by itself (can't select just an interval, it must be used in an additive expr)
870    defer checking that to a semantic tree phase.
871 */
872 intervalExpr
873         :       (INTERVAL ~(LPAREN))=> INTERVAL expr timeUnit {input.LA(1) == PLUS || input.LA(1) == MINUS}? -> ^(INTERVAL expr timeUnit)
874         |       lhsPrim=primary -> primary
875         ;
876         
877 primary
878         :       lhsParen=parenExpr -> parenExpr
879         |       lhsLit=literal  -> literal
880         |       subselect       -> subselect
881         |       EXISTS subselect -> ^(EXISTS subselect)
882         // TODO: add missing primary expressions, like ROW, DEFAULT etc.
883         ;
884
885 literal
886         :       value=STRING
887         |       value=NUMBER
888         |       value=GLOBAL_VARIABLE
889         |       value=SESSION_VARIABLE
890         |       value=VALUE_PLACEHOLDER<com.mysql.clusterj.jdbc.antlr.node.PlaceholderNode>
891         |       value=BINARY_VALUE
892         |       value=HEXA_VALUE
893         |       value=NULL
894         |       value=TRUE
895         |       value=FALSE
896         |       (functionCall)=>functionCall
897         |       field_name
898         ;
899 // $>
900
901 cast_data_type
902         :       BINARY (LPAREN NUMBER RPAREN)?
903         |       CHAR (LPAREN NUMBER RPAREN)?
904         |       DATE
905         |       DATETIME
906         |       TIME
907         |       DECIMAL (LPAREN num1=NUMBER COMMA num2=NUMBER RPAREN)?
908         |       SIGNED INTEGER?
909         |       UNSIGNED INTEGER?
910         ;
911         
912 timeUnit
913         :       MICROSECOND
914         |       SECOND
915         |       MINUTE
916         |       HOUR
917         |       DAY
918         |       WEEK
919         |       MONTH
920         |       QUARTER
921         |       YEAR
922         |       SECOND_MICROSECOND
923         |       MINUTE_MICROSECOND
924         |       MINUTE_SECOND
925         |       HOUR_MICROSECOND
926         |       HOUR_SECOND
927         |       HOUR_MINUTE
928         |       DAY_MICROSECOND
929         |       DAY_SECOND
930         |       DAY_MINUTE
931         |       DAY_HOUR
932         |       YEAR_MONTH
933         ;
934
935 /* TODO: add the SQL_TSI_ prefix versions */
936 timestampUnit
937         :       FRAC_SECOND | MICROSECOND
938         |       SECOND
939         |       MINUTE
940         |       HOUR
941         |       DAY
942         |       WEEK
943         |       MONTH
944         |       QUARTER
945         |       YEAR
946         ;
947         
948 where_condition
949         :       expr
950         ;
951
952 // $< Transactions
953
954 /* generates bogus warning about RELEASE */
955 transaction
956         // general trx statements
957         :       (       BEGIN  WORK?                                                                            -> ^(BEGIN WORK?)
958                 |       START TRANSACTION (WITH CONSISTENT SNAPSHOT)?           -> ^(START SNAPSHOT?)
959                 )
960         |       COMMIT WORK?
961                 (AND NO? CHAIN)?
962                 (NO? RELEASE)?                                                                                  -> ^(COMMIT ^(CHAIN NO?)? ^(RELEASE NO?)?)
963         |       ROLLBACK WORK?
964                 (AND NO? CHAIN)?
965                 (NO? RELEASE)?                                                                                  -> ^(ROLLBACK ^(CHAIN NO?)? ^(RELEASE NO?)?)
966         // NUMBER must be (0 | 1), no grammar checks done at this point, TODO check AUTOCOMMIT vs keywords/identifiers
967 //      |       SET AUTOCOMMIT EQUALS NUMBER                    
968         |       SET 
969                 (       txnScope=GLOBAL 
970                 |       txnScope=SESSION 
971                 )?
972                 TRANSACTION ISOLATION LEVEL
973                 (       READ UNCOMMITTED                        -> ^(ISOLATION UNCOMMITTED $txnScope)
974                 |       READ COMMITTED                          -> ^(ISOLATION COMMITTED $txnScope)     
975                 |       REPEATABLE READ                         -> ^(ISOLATION REPEATABLE $txnScope)
976                 |       SERIALIZABLE                            -> ^(ISOLATION SERIALIZABLE $txnScope)  
977                 )
978         |       savepoint
979         |       lockTables
980         //      TODO support for XA transactions is missing
981         ;
982
983 // savepoint handling
984 savepoint
985         :       RELEASE? SAVEPOINT ident                                -> ^(SAVEPOINT ident RELEASE?)
986         |       ROLLBACK WORK? TO SAVEPOINT? ident              -> ^(ROLLBACK_POINT ident)
987         ;
988
989 // $> Transactions
990
991 // $< Insert
992
993 insert
994         :       INSERT (opt=LOW_PRIORITY | opt=DELAYED | opt=HIGH_PRIORITY)?
995                 IGNORE? INTO?
996                 table=simple_table_ref_no_alias
997                 (       insert_columns
998                 |       set_columns
999                 |       select
1000                 )
1001                 on_dup_key?
1002                 -> ^(INSERT<com.mysql.clusterj.jdbc.antlr.node.InsertNode> IGNORE? INTO? $opt? ^(TABLE $table)
1003                         /* the following three lines are really alts as they cannot appear at the same time */
1004                         insert_columns?
1005                         set_columns?
1006                         select?
1007                         on_dup_key?)
1008         ;
1009
1010 insert_columns
1011         :       (LPAREN column_name_list? RPAREN)?
1012                 (VALUE|VALUES) LPAREN val+=insert_default_or_expression (COMMA val+=insert_default_or_expression)* RPAREN
1013                         -> ^(INSERT_VALUES column_name_list? ^(VALUES[] $val+))
1014         ;
1015
1016 insert_default_or_expression
1017         :       DEFAULT
1018         |       expr
1019         ;
1020         
1021 set_columns
1022         :       SET column_assignment (COMMA column_assignment)*        -> ^(SET column_assignment+)
1023         ;
1024
1025 on_dup_key
1026         :       ON DUPLICATE KEY UPDATE
1027                 column_assignment (COMMA column_assignment)*    -> ^(DUPLICATE column_assignment+)
1028         ;
1029
1030 column_assignment
1031         :       field_name EQUALS 
1032                 (       DEFAULT                 -> ^(EQUALS field_name DEFAULT)
1033                 |       expr                    -> ^(EQUALS field_name expr)
1034                 )
1035         ;
1036         
1037 column_name_list
1038         :       field_name (COMMA field_name)*  -> ^(COLUMNS field_name+)
1039         ;
1040 // $> Insert
1041
1042 // $< Update
1043
1044 update
1045         :       UPDATE LOW_PRIORITY? IGNORE?
1046                 table=table_references                  // this must be table_references because the mysql parser allows an alias here, even for single table updates (unlike DELETE)
1047                 set=set_columns
1048                 (WHERE where_condition)?
1049                 /* these options are only valid if we update one table */
1050                 ({$table.table_count==1}?=> 
1051                         order_by?
1052                         (LIMIT NUMBER)? 
1053                 )?
1054                 -> ^(UPDATE LOW_PRIORITY? IGNORE? $table $set ^(WHERE where_condition)? order_by? ^(LIMIT NUMBER)?)
1055         ;
1056
1057
1058 // $> Update
1059
1060 // $< Delete
1061
1062 /* both multi table delete trees are basically identical. The FROM and USING nodes are just in there to differentiate between the syntax used, in order to format it correctly
1063    the AST drops potential .* suffixes for the table names, as they are simply syntactic sugar.
1064 */
1065 delete
1066 @init {
1067 boolean multiTableDelete = false;
1068 }
1069         :       DELETE
1070 // opts+=QUICK causes parser warnings
1071                 (options{k=1;}: opts+=LOW_PRIORITY | opts+=IGNORE)*             // the yacc parser accepts any combination and any number of these modifiers, so we do, too.
1072                 (       FROM 
1073                         t+=simple_table_ref_no_alias (DOT MULT {multiTableDelete = true;} )? (COMMA t+=simple_table_ref_no_alias (DOT MULT)? {multiTableDelete = true;} )*
1074                         (USING tr=table_references {multiTableDelete = true;})?
1075                         (WHERE where_condition)?
1076                         ({multiTableDelete == false}?=>
1077                                 order_by?
1078                                 (LIMIT NUMBER)?
1079                         )?
1080                                 -> {multiTableDelete}? ^(DELETE<com.mysql.clusterj.jdbc.antlr.node.DeleteNode> ^(OPTIONS $opts+)? ^(TABLE $t)+ ^(USING $tr) ^(WHERE<com.mysql.clusterj.jdbc.antlr.node.WhereNode> where_condition)?)
1081                                 -> ^(DELETE<com.mysql.clusterj.jdbc.antlr.node.DeleteNode> ^(OPTIONS $opts+)? ^(TABLE $t) ^(WHERE<com.mysql.clusterj.jdbc.antlr.node.WhereNode> where_condition)? order_by? ^(LIMIT NUMBER)?)
1082                                                                  
1083                 |       t+=simple_table_ref_no_alias (DOT MULT)? (COMMA t+=simple_table_ref_no_alias (DOT MULT)?)*
1084                         FROM tr=table_references
1085                         (WHERE where_condition)?                        -> ^(DELETE ^(OPTIONS $opts+)? ^(TABLE $t)+ ^(FROM $tr) ^(WHERE<com.mysql.clusterj.jdbc.antlr.node.WhereNode> where_condition)?)
1086                 )
1087         ;
1088
1089 // $> Delete
1090
1091 // $< Lock tables
1092
1093 lockTables
1094         :       LOCK TABLES tables+=lock_table_ref (COMMA tables+=lock_table_ref)*      -> ^(LOCK $tables)
1095         |       UNLOCK TABLES                                                                                                           -> ^(UNLOCK TABLES)
1096         ;
1097
1098 lock_table_ref
1099         :       simple_table_ref_alias
1100                 (       READ  (LOCAL )?                                 -> ^(READ simple_table_ref_alias LOCAL?)
1101                 |       (LOW_PRIORITY )? WRITE                  -> ^(WRITE simple_table_ref_alias LOW_PRIORITY?)
1102                 )
1103         ;
1104
1105 // $> Lock tables
1106
1107 // $> DML
1108
1109 // $< DDL
1110
1111 // $< Create Table
1112
1113 create_table
1114         :       CREATE (TEMPORARY )? TABLE
1115                 (IF NOT EXISTS )?
1116                 tableName=simple_table_ref_no_alias
1117                 LPAREN create+=create_definition (COMMA create+=create_definition)* RPAREN
1118                 -> ^(CREATE_TABLE
1119                                 TEMPORARY?
1120                                 EXISTS?
1121                                 simple_table_ref_no_alias
1122                                 ^(DEFINITIONS $create+)
1123                         )
1124         ;
1125
1126 create_definition
1127         :       colName=ident column_definition -> ^(DEFINITION $colName column_definition)
1128         ;
1129         
1130 // $> Create Table
1131
1132 column_definition
1133
1134         :       data_type
1135                 (notSym=NOT NULL | nullSym=NULL)?
1136                 (DEFAULT literal)?              // TODO check whether literal covers all the legal values
1137                 autoInc=AUTO_INCREMENT?
1138                 (UNIQUE uniqueKey=KEY? | PRIMARY? generalKey=KEY)?
1139                 (COMMENT STRING)?
1140                 (reference_definition )?
1141                 // TODO the following two are NDB specific, skipping for now.
1142 //              (COLUMN_FORMAT (FIXED|DYNAMIC|DEFAULT))?
1143 //              (STORAGE (DISK|MEMORY))?
1144                 -> ^(TYPE data_type
1145                                 $notSym?
1146                                 ($nullSym)?
1147                                 ^(DEFAULT literal)?
1148                                 ($autoInc)?
1149                                 UNIQUE? PRIMARY? KEY?
1150                         )
1151         ;
1152
1153 data_type
1154         :       BIT 
1155                 ( LPAREN NUMBER  RPAREN )?
1156         |       (       TINYINT         
1157                 |       SMALLINT        
1158                 |       MEDIUMINT       
1159                 |       INT                     
1160                 |       INTEGER         
1161                 |       BIGINT          
1162                 )
1163                 (LPAREN NUMBER  RPAREN)?
1164                 (SIGNED | UNSIGNED )?
1165                 (ZEROFILL )?
1166         |       (       REAL            
1167                 |       DOUBLE          
1168                 |       FLOAT           
1169                 |       DECIMAL         
1170                 |       NUMERIC         
1171                 )
1172                 (LPAREN num1=NUMBER COMMA num2=NUMBER RPAREN )?
1173                 (SIGNED | UNSIGNED )?
1174                 (ZEROFILL )?
1175         |       DATE            
1176         |       TIME            
1177         |       TIMESTAMP       
1178         |       DATETIME        
1179         |       YEAR            
1180         |       TINYBLOB        
1181         |       BLOB            
1182         |       MEDIUMBLOB      
1183         |       LONGBLOB        
1184         |       (       CHAR    
1185                 |       VARCHAR 
1186                 )
1187                 LPAREN NUMBER  RPAREN
1188                 (charset )?
1189                 (collate )?
1190         |       (       BINARY          
1191                 |       VARBINARY       
1192                 )
1193                 LPAREN NUMBER  RPAREN
1194         |       (       TINYTEXT        
1195                 |       TEXT            
1196                 |       MEDIUMTEXT      
1197                 |       LONGTEXT        
1198                 )
1199                 (BINARY )?
1200                 (charset )?
1201                 (collate )?
1202         |       (       ENUM    
1203                 |       SET             
1204                 )
1205                 LPAREN values+=STRING (COMMA values+=STRING)* RPAREN 
1206                 (charset )?
1207                 (collate )?
1208         ;
1209
1210 charset
1211         :       CHARACTER SET
1212                 (       ID 
1213                 |       STRING 
1214                 )
1215         ;
1216
1217 collate
1218         :       COLLATE 
1219                 (       ID 
1220                 |       STRING 
1221                 )
1222         ;
1223         
1224 reference_definition
1225         :       RESTRICT        
1226         |       CASCADE         
1227         |       SET NULL        
1228         |       NO ACTION       
1229         ;
1230 // $> DDL