1 package org.modeshape.sequencer.ddl.dialect.mysql;
2
3 import static org.modeshape.sequencer.ddl.StandardDdlLexicon.DDL_EXPRESSION;
4 import static org.modeshape.sequencer.ddl.StandardDdlLexicon.DDL_ORIGINAL_EXPRESSION;
5 import static org.modeshape.sequencer.ddl.StandardDdlLexicon.DDL_START_CHAR_INDEX;
6 import static org.modeshape.sequencer.ddl.StandardDdlLexicon.DDL_START_COLUMN_NUMBER;
7 import static org.modeshape.sequencer.ddl.StandardDdlLexicon.DDL_START_LINE_NUMBER;
8 import static org.modeshape.sequencer.ddl.StandardDdlLexicon.NEW_NAME;
9 import static org.modeshape.sequencer.ddl.dialect.mysql.MySqlDdlLexicon.TYPE_ALTER_ALGORITHM_STATEMENT;
10 import static org.modeshape.sequencer.ddl.dialect.mysql.MySqlDdlLexicon.TYPE_ALTER_DATABASE_STATEMENT;
11 import static org.modeshape.sequencer.ddl.dialect.mysql.MySqlDdlLexicon.TYPE_ALTER_DEFINER_STATEMENT;
12 import static org.modeshape.sequencer.ddl.dialect.mysql.MySqlDdlLexicon.TYPE_ALTER_EVENT_STATEMENT;
13 import static org.modeshape.sequencer.ddl.dialect.mysql.MySqlDdlLexicon.TYPE_ALTER_FUNCTION_STATEMENT;
14 import static org.modeshape.sequencer.ddl.dialect.mysql.MySqlDdlLexicon.TYPE_ALTER_LOGFILE_GROUP_STATEMENT;
15 import static org.modeshape.sequencer.ddl.dialect.mysql.MySqlDdlLexicon.TYPE_ALTER_PROCEDURE_STATEMENT;
16 import static org.modeshape.sequencer.ddl.dialect.mysql.MySqlDdlLexicon.TYPE_ALTER_SCHEMA_STATEMENT;
17 import static org.modeshape.sequencer.ddl.dialect.mysql.MySqlDdlLexicon.TYPE_ALTER_SERVER_STATEMENT;
18 import static org.modeshape.sequencer.ddl.dialect.mysql.MySqlDdlLexicon.TYPE_ALTER_TABLESPACE_STATEMENT;
19 import static org.modeshape.sequencer.ddl.dialect.mysql.MySqlDdlLexicon.TYPE_ALTER_VIEW_STATEMENT;
20 import static org.modeshape.sequencer.ddl.dialect.mysql.MySqlDdlLexicon.TYPE_CREATE_DEFINER_STATEMENT;
21 import static org.modeshape.sequencer.ddl.dialect.mysql.MySqlDdlLexicon.TYPE_CREATE_EVENT_STATEMENT;
22 import static org.modeshape.sequencer.ddl.dialect.mysql.MySqlDdlLexicon.TYPE_CREATE_FUNCTION_STATEMENT;
23 import static org.modeshape.sequencer.ddl.dialect.mysql.MySqlDdlLexicon.TYPE_CREATE_INDEX_STATEMENT;
24 import static org.modeshape.sequencer.ddl.dialect.mysql.MySqlDdlLexicon.TYPE_CREATE_PROCEDURE_STATEMENT;
25 import static org.modeshape.sequencer.ddl.dialect.mysql.MySqlDdlLexicon.TYPE_CREATE_SERVER_STATEMENT;
26 import static org.modeshape.sequencer.ddl.dialect.mysql.MySqlDdlLexicon.TYPE_CREATE_TABLESPACE_STATEMENT;
27 import static org.modeshape.sequencer.ddl.dialect.mysql.MySqlDdlLexicon.TYPE_CREATE_TRIGGER_STATEMENT;
28 import static org.modeshape.sequencer.ddl.dialect.mysql.MySqlDdlLexicon.TYPE_DROP_DATABASE_STATEMENT;
29 import static org.modeshape.sequencer.ddl.dialect.mysql.MySqlDdlLexicon.TYPE_DROP_EVENT_STATEMENT;
30 import static org.modeshape.sequencer.ddl.dialect.mysql.MySqlDdlLexicon.TYPE_DROP_FUNCTION_STATEMENT;
31 import static org.modeshape.sequencer.ddl.dialect.mysql.MySqlDdlLexicon.TYPE_DROP_INDEX_STATEMENT;
32 import static org.modeshape.sequencer.ddl.dialect.mysql.MySqlDdlLexicon.TYPE_DROP_LOGFILE_GROUP_STATEMENT;
33 import static org.modeshape.sequencer.ddl.dialect.mysql.MySqlDdlLexicon.TYPE_DROP_PROCEDURE_STATEMENT;
34 import static org.modeshape.sequencer.ddl.dialect.mysql.MySqlDdlLexicon.TYPE_DROP_SERVER_STATEMENT;
35 import static org.modeshape.sequencer.ddl.dialect.mysql.MySqlDdlLexicon.TYPE_DROP_TABLESPACE_STATEMENT;
36 import static org.modeshape.sequencer.ddl.dialect.mysql.MySqlDdlLexicon.TYPE_DROP_TRIGGER_STATEMENT;
37 import static org.modeshape.sequencer.ddl.dialect.mysql.MySqlDdlLexicon.TYPE_RENAME_DATABASE_STATEMENT;
38 import static org.modeshape.sequencer.ddl.dialect.mysql.MySqlDdlLexicon.TYPE_RENAME_SCHEMA_STATEMENT;
39 import static org.modeshape.sequencer.ddl.dialect.mysql.MySqlDdlLexicon.TYPE_RENAME_TABLE_STATEMENT;
40 import java.util.ArrayList;
41 import java.util.List;
42 import org.modeshape.common.text.ParsingException;
43 import org.modeshape.sequencer.ddl.DdlTokenStream;
44 import org.modeshape.sequencer.ddl.StandardDdlParser;
45 import org.modeshape.sequencer.ddl.datatype.DataType;
46 import org.modeshape.sequencer.ddl.datatype.DataTypeParser;
47 import org.modeshape.sequencer.ddl.node.AstNode;
48
49
50
51
52 public class MySqlDdlParser extends StandardDdlParser implements MySqlDdlConstants, MySqlDdlConstants.MySqlStatementStartPhrases {
53 private final String parserId = "MYSQL";
54
55 static List<String[]> mysqlDataTypeStrings = new ArrayList<String[]>();
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199 private static final String TERMINATOR = DEFAULT_TERMINATOR;
200
201 public MySqlDdlParser() {
202 initialize();
203 }
204
205
206
207
208
209
210 @Override
211 public String getId() {
212 return this.parserId;
213 }
214
215 private void initialize() {
216 setDatatypeParser(new MySqlDataTypeParser());
217
218 setDoUseTerminator(true);
219
220 setTerminator(TERMINATOR);
221
222 mysqlDataTypeStrings.addAll(MySqlDataTypes.CUSTOM_DATATYPE_START_PHRASES);
223 }
224
225
226
227
228
229
230 @Override
231 protected void initializeTokenStream( DdlTokenStream tokens ) {
232 super.initializeTokenStream(tokens);
233 tokens.registerKeyWords(CUSTOM_KEYWORDS);
234 tokens.registerKeyWords(MySqlDataTypes.CUSTOM_DATATYPE_START_WORDS);
235 tokens.registerStatementStartPhrase(ALTER_PHRASES);
236 tokens.registerStatementStartPhrase(CREATE_PHRASES);
237 tokens.registerStatementStartPhrase(DROP_PHRASES);
238 tokens.registerStatementStartPhrase(MISC_PHRASES);
239 }
240
241
242
243
244
245
246
247 @Override
248 protected AstNode parseCreateStatement( DdlTokenStream tokens,
249 AstNode parentNode ) throws ParsingException {
250 assert tokens != null;
251 assert parentNode != null;
252
253 if (tokens.matches(STMT_CREATE_INDEX)) {
254 return parseStatement(tokens, MySqlStatementStartPhrases.STMT_CREATE_INDEX, parentNode, TYPE_CREATE_INDEX_STATEMENT);
255 } else if (tokens.matches(STMT_CREATE_UNIQUE_INDEX)) {
256 return parseStatement(tokens,
257 MySqlStatementStartPhrases.STMT_CREATE_UNIQUE_INDEX,
258 parentNode,
259 TYPE_CREATE_INDEX_STATEMENT);
260 } else if (tokens.matches(STMT_CREATE_FUNCTION)) {
261 return parseStatement(tokens,
262 MySqlStatementStartPhrases.STMT_CREATE_FUNCTION,
263 parentNode,
264 TYPE_CREATE_FUNCTION_STATEMENT);
265 } else if (tokens.matches(STMT_CREATE_PROCEDURE)) {
266 return parseStatement(tokens,
267 MySqlStatementStartPhrases.STMT_CREATE_PROCEDURE,
268 parentNode,
269 TYPE_CREATE_PROCEDURE_STATEMENT);
270 } else if (tokens.matches(STMT_CREATE_SERVER)) {
271 return parseStatement(tokens, MySqlStatementStartPhrases.STMT_CREATE_SERVER, parentNode, TYPE_CREATE_SERVER_STATEMENT);
272 } else if (tokens.matches(STMT_CREATE_TRIGGER)) {
273 return parseStatement(tokens,
274 MySqlStatementStartPhrases.STMT_CREATE_TRIGGER,
275 parentNode,
276 TYPE_CREATE_TRIGGER_STATEMENT);
277 } else if (tokens.matches(STMT_CREATE_EVENT)) {
278 return parseStatement(tokens, MySqlStatementStartPhrases.STMT_CREATE_EVENT, parentNode, TYPE_CREATE_EVENT_STATEMENT);
279 } else if (tokens.matches(STMT_CREATE_TABLESPACE)) {
280 return parseStatement(tokens,
281 MySqlStatementStartPhrases.STMT_CREATE_TABLESPACE,
282 parentNode,
283 TYPE_CREATE_TABLESPACE_STATEMENT);
284 } else if (tokens.matches(STMT_CREATE_DEFINER)) {
285 return parseStatement(tokens,
286 MySqlStatementStartPhrases.STMT_CREATE_DEFINER,
287 parentNode,
288 TYPE_CREATE_DEFINER_STATEMENT);
289 }
290
291 return super.parseCreateStatement(tokens, parentNode);
292 }
293
294
295
296
297
298
299
300 @Override
301 protected AstNode parseAlterStatement( DdlTokenStream tokens,
302 AstNode parentNode ) throws ParsingException {
303 assert tokens != null;
304 assert parentNode != null;
305
306 if (tokens.matches(STMT_ALTER_ALGORITHM)) {
307 return parseStatement(tokens, STMT_ALTER_ALGORITHM, parentNode, TYPE_ALTER_ALGORITHM_STATEMENT);
308 } else if (tokens.matches(STMT_ALTER_DATABASE)) {
309 return parseStatement(tokens, STMT_ALTER_DATABASE, parentNode, TYPE_ALTER_DATABASE_STATEMENT);
310 } else if (tokens.matches(STMT_ALTER_DEFINER)) {
311 return parseStatement(tokens, STMT_ALTER_DEFINER, parentNode, TYPE_ALTER_DEFINER_STATEMENT);
312 } else if (tokens.matches(STMT_ALTER_EVENT)) {
313 return parseStatement(tokens, STMT_ALTER_EVENT, parentNode, TYPE_ALTER_EVENT_STATEMENT);
314 } else if (tokens.matches(STMT_ALTER_FUNCTION)) {
315 return parseStatement(tokens, STMT_ALTER_FUNCTION, parentNode, TYPE_ALTER_FUNCTION_STATEMENT);
316 } else if (tokens.matches(STMT_ALTER_LOGFILE_GROUP)) {
317 return parseStatement(tokens, STMT_ALTER_LOGFILE_GROUP, parentNode, TYPE_ALTER_LOGFILE_GROUP_STATEMENT);
318 } else if (tokens.matches(STMT_ALTER_PROCEDURE)) {
319 return parseStatement(tokens, STMT_ALTER_PROCEDURE, parentNode, TYPE_ALTER_PROCEDURE_STATEMENT);
320 } else if (tokens.matches(STMT_ALTER_SCHEMA)) {
321 return parseStatement(tokens, STMT_ALTER_SCHEMA, parentNode, TYPE_ALTER_SCHEMA_STATEMENT);
322 } else if (tokens.matches(STMT_ALTER_SERVER)) {
323 return parseStatement(tokens, STMT_ALTER_SERVER, parentNode, TYPE_ALTER_SERVER_STATEMENT);
324 } else if (tokens.matches(STMT_ALTER_TABLESPACE)) {
325 return parseStatement(tokens, STMT_ALTER_TABLESPACE, parentNode, TYPE_ALTER_TABLESPACE_STATEMENT);
326 } else if (tokens.matches(STMT_ALTER_SQL_SECURITY)) {
327 return parseStatement(tokens, STMT_ALTER_SQL_SECURITY, parentNode, TYPE_ALTER_VIEW_STATEMENT);
328 } else if (tokens.matches(STMT_ALTER_IGNORE_TABLE) || tokens.matches(STMT_ALTER_ONLINE_TABLE)
329 || tokens.matches(STMT_ALTER_ONLINE_IGNORE_TABLE) || tokens.matches(STMT_ALTER_OFFLINE_TABLE)
330 || tokens.matches(STMT_ALTER_OFFLINE_IGNORE_TABLE)) {
331 return parseAlterTableStatement(tokens, parentNode);
332 }
333
334 return super.parseAlterStatement(tokens, parentNode);
335 }
336
337
338
339
340
341
342
343 @Override
344 protected AstNode parseAlterTableStatement( DdlTokenStream tokens,
345 AstNode parentNode ) throws ParsingException {
346 assert tokens != null;
347 assert parentNode != null;
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405 return super.parseAlterTableStatement(tokens, parentNode);
406 }
407
408
409
410
411
412
413
414 @Override
415 protected AstNode parseCustomStatement( DdlTokenStream tokens,
416 AstNode parentNode ) throws ParsingException {
417 assert tokens != null;
418 assert parentNode != null;
419
420 if (tokens.matches(STMT_RENAME_DATABASE)) {
421 markStartOfStatement(tokens);
422
423
424 tokens.consume(STMT_RENAME_DATABASE);
425 String oldName = parseName(tokens);
426 tokens.consume("TO");
427 AstNode node = nodeFactory().node(oldName, parentNode, TYPE_RENAME_DATABASE_STATEMENT);
428 String newName = parseName(tokens);
429 node.setProperty(NEW_NAME, newName);
430
431 markEndOfStatement(tokens, node);
432 return node;
433 } else if (tokens.matches(STMT_RENAME_SCHEMA)) {
434 markStartOfStatement(tokens);
435
436
437 tokens.consume(STMT_RENAME_SCHEMA);
438 String oldName = parseName(tokens);
439 tokens.consume("TO");
440 AstNode node = nodeFactory().node(oldName, parentNode, TYPE_RENAME_SCHEMA_STATEMENT);
441 String newName = parseName(tokens);
442 node.setProperty(NEW_NAME, newName);
443
444 markEndOfStatement(tokens, node);
445 return node;
446 } else if (tokens.matches(STMT_RENAME_TABLE)) {
447 markStartOfStatement(tokens);
448
449
450
451
452 tokens.consume(STMT_RENAME_TABLE);
453
454 String oldName = parseName(tokens);
455 tokens.consume("TO");
456 String newName = parseName(tokens);
457
458 AstNode node = nodeFactory().node(oldName, parentNode, TYPE_RENAME_TABLE_STATEMENT);
459 node.setProperty(NEW_NAME, newName);
460
461
462 if (!tokens.matches(COMMA)) {
463 markEndOfStatement(tokens, node);
464 return node;
465 }
466
467
468
469
470 List<AstNode> nodes = new ArrayList<AstNode>();
471 nodes.add(node);
472
473 while (tokens.matches(COMMA)) {
474 tokens.consume(COMMA);
475 oldName = parseName(tokens);
476 tokens.consume("TO");
477 newName = parseName(tokens);
478 node = nodeFactory().node(oldName, parentNode, TYPE_RENAME_TABLE_STATEMENT);
479 node.setProperty(NEW_NAME, newName);
480 nodes.add(node);
481 }
482
483 markEndOfStatement(tokens, nodes.get(0));
484
485 String originalExpression = (String)nodes.get(0).getProperty(DDL_EXPRESSION).getFirstValue();
486 Object startLineNumber = nodes.get(0).getProperty(DDL_START_LINE_NUMBER).getFirstValue();
487 Object startColumnNumber = nodes.get(0).getProperty(DDL_START_COLUMN_NUMBER).getFirstValue();
488 Object startCharIndex = nodes.get(0).getProperty(DDL_START_CHAR_INDEX).getFirstValue();
489
490 for (AstNode nextNode : nodes) {
491 oldName = nextNode.getName().getString();
492 newName = (String)nextNode.getProperty(NEW_NAME).getFirstValue();
493 String express = "RENAME TABLE" + SPACE + oldName + SPACE + "TO" + SPACE + newName + SEMICOLON;
494 nextNode.setProperty(DDL_EXPRESSION, express);
495 nextNode.setProperty(DDL_ORIGINAL_EXPRESSION, originalExpression);
496 nextNode.setProperty(DDL_START_LINE_NUMBER, startLineNumber);
497 nextNode.setProperty(DDL_START_COLUMN_NUMBER, startColumnNumber);
498 nextNode.setProperty(DDL_START_CHAR_INDEX, startCharIndex);
499 }
500
501 return nodes.get(0);
502 }
503
504 return super.parseCustomStatement(tokens, parentNode);
505 }
506
507
508
509
510
511
512
513 @Override
514 protected AstNode parseDropStatement( DdlTokenStream tokens,
515 AstNode parentNode ) throws ParsingException {
516 assert tokens != null;
517 assert parentNode != null;
518
519 if (tokens.matches(STMT_DROP_DATABASE)) {
520 return parseStatement(tokens, STMT_DROP_DATABASE, parentNode, TYPE_DROP_DATABASE_STATEMENT);
521 } else if (tokens.matches(STMT_DROP_EVENT)) {
522 return parseStatement(tokens, STMT_DROP_EVENT, parentNode, TYPE_DROP_EVENT_STATEMENT);
523 } else if (tokens.matches(STMT_DROP_FUNCTION)) {
524 return parseStatement(tokens, STMT_DROP_FUNCTION, parentNode, TYPE_DROP_FUNCTION_STATEMENT);
525 } else if (tokens.matches(STMT_DROP_INDEX)) {
526 return parseStatement(tokens, STMT_DROP_INDEX, parentNode, TYPE_DROP_INDEX_STATEMENT);
527 } else if (tokens.matches(STMT_DROP_OFFLINE_INDEX)) {
528 return parseStatement(tokens, STMT_DROP_OFFLINE_INDEX, parentNode, TYPE_DROP_INDEX_STATEMENT);
529 } else if (tokens.matches(STMT_DROP_ONLINE_INDEX)) {
530 return parseStatement(tokens, STMT_DROP_ONLINE_INDEX, parentNode, TYPE_DROP_INDEX_STATEMENT);
531 } else if (tokens.matches(STMT_DROP_LOGFILE_GROUP)) {
532 return parseStatement(tokens, STMT_DROP_LOGFILE_GROUP, parentNode, TYPE_DROP_LOGFILE_GROUP_STATEMENT);
533 } else if (tokens.matches(STMT_DROP_PROCEDURE)) {
534 return parseStatement(tokens, STMT_DROP_PROCEDURE, parentNode, TYPE_DROP_PROCEDURE_STATEMENT);
535 } else if (tokens.matches(STMT_DROP_SERVER)) {
536 return parseStatement(tokens, STMT_DROP_SERVER, parentNode, TYPE_DROP_SERVER_STATEMENT);
537 } else if (tokens.matches(STMT_DROP_TABLESPACE)) {
538 return parseStatement(tokens, STMT_DROP_TABLESPACE, parentNode, TYPE_DROP_TABLESPACE_STATEMENT);
539 } else if (tokens.matches(STMT_DROP_TRIGGER)) {
540 return parseStatement(tokens, STMT_DROP_TRIGGER, parentNode, TYPE_DROP_TRIGGER_STATEMENT);
541 }
542
543 return super.parseDropStatement(tokens, parentNode);
544 }
545
546
547
548
549
550
551 @Override
552 protected List<String> getCustomDataTypeStartWords() {
553 return MySqlDataTypes.CUSTOM_DATATYPE_START_WORDS;
554 }
555
556
557
558 class MySqlDataTypeParser extends DataTypeParser implements MySqlDdlConstants.MySqlDataTypes {
559
560
561
562
563
564
565
566
567
568 @Override
569 protected boolean isCustomDataType( DdlTokenStream tokens ) throws ParsingException {
570
571
572 for (String[] stmts : mysqlDataTypeStrings) {
573 if (tokens.matches(stmts)) return true;
574 }
575 return super.isCustomDataType(tokens);
576 }
577
578 @Override
579 protected DataType parseApproxNumericType( DdlTokenStream tokens ) throws ParsingException {
580 DataType dType = super.parseApproxNumericType(tokens);
581 tokens.canConsume("UNSIGNED");
582 tokens.canConsume("ZEROFILL");
583 tokens.canConsume("UNSIGNED");
584 return dType;
585 }
586
587 @Override
588 protected DataType parseBitStringType( DdlTokenStream tokens ) throws ParsingException {
589 return super.parseBitStringType(tokens);
590 }
591
592 @Override
593 protected DataType parseCharStringType( DdlTokenStream tokens ) throws ParsingException {
594 DataType result = super.parseCharStringType(tokens);
595
596 tokens.canConsume("FOR", "BIT", "DATA");
597
598 return result;
599 }
600
601 @Override
602 protected DataType parseCustomType( DdlTokenStream tokens ) throws ParsingException {
603 DataType dataType = null;
604
605 if (tokens.matches(DTYPE_FIXED) || tokens.matches(DTYPE_DOUBLE)) {
606 dataType = new DataType();
607 String typeName = tokens.consume();
608 dataType.setName(typeName);
609
610 int precision = 0;
611 int scale = 0;
612
613 if (tokens.matches(L_PAREN)) {
614 consume(tokens, dataType, false, L_PAREN);
615 precision = (int)parseLong(tokens, dataType);
616 if (tokens.canConsume(COMMA)) {
617 scale = (int)parseLong(tokens, dataType);
618 } else {
619 scale = getDefaultScale();
620 }
621 tokens.consume(R_PAREN);
622 } else {
623 precision = getDefaultPrecision();
624 scale = getDefaultScale();
625 }
626 dataType.setPrecision(precision);
627 dataType.setScale(scale);
628 } else if (tokens.matches(DTYPE_MEDIUMBLOB) || tokens.matches(DTYPE_LONGBLOB) || tokens.matches(DTYPE_BLOB)
629 || tokens.matches(DTYPE_TINYBLOB) || tokens.matches(DTYPE_YEAR) || tokens.matches(DTYPE_DATETIME)
630 || tokens.matches(DTYPE_BOOLEAN) || tokens.matches(DTYPE_BOOL)) {
631 String typeName = tokens.consume();
632 dataType = new DataType(typeName);
633 } else if (tokens.matches(DTYPE_MEDIUMINT) || tokens.matches(DTYPE_TINYINT) || tokens.matches(DTYPE_VARBINARY)
634 || tokens.matches(DTYPE_BINARY) || tokens.matches(DTYPE_BIGINT)) {
635 String typeName = tokens.consume();
636 dataType = new DataType(typeName);
637 long length = getDefaultLength();
638 if (tokens.matches(L_PAREN)) {
639 length = parseBracketedLong(tokens, dataType);
640 }
641 dataType.setLength(length);
642 } else if (tokens.matches(DTYPE_NATIONAL_VARCHAR)) {
643 String typeName = getStatementTypeName(DTYPE_NATIONAL_VARCHAR);
644 dataType = new DataType(typeName);
645 tokens.consume(DTYPE_NATIONAL_VARCHAR);
646 long length = getDefaultLength();
647 if (tokens.matches(L_PAREN)) {
648 length = parseBracketedLong(tokens, dataType);
649 }
650 dataType.setLength(length);
651 } else if (tokens.matches(DTYPE_MEDIUMTEXT) || tokens.matches(DTYPE_TEXT) || tokens.matches(DTYPE_LONGTEXT)
652 || tokens.matches(DTYPE_TINYTEXT)) {
653 String typeName = tokens.consume();
654 dataType = new DataType(typeName);
655 tokens.canConsume("BINARY");
656 tokens.canConsume("COLLATE", DdlTokenStream.ANY_VALUE);
657 tokens.canConsume("CHARACTER", "SET", DdlTokenStream.ANY_VALUE);
658 tokens.canConsume("COLLATE", DdlTokenStream.ANY_VALUE);
659 } else if (tokens.matches(DTYPE_SET)) {
660
661 String typeName = tokens.consume();
662 dataType = new DataType(typeName);
663
664 tokens.consume(L_PAREN);
665 do {
666 tokens.consume();
667 } while (tokens.canConsume(COMMA));
668 tokens.consume(R_PAREN);
669
670 tokens.canConsume("COLLATE", DdlTokenStream.ANY_VALUE);
671 tokens.canConsume("CHARACTER", "SET", DdlTokenStream.ANY_VALUE);
672 tokens.canConsume("COLLATE", DdlTokenStream.ANY_VALUE);
673 } else if (tokens.matches(DTYPE_ENUM)) {
674
675 String typeName = tokens.consume();
676 dataType = new DataType(typeName);
677
678 tokens.consume(L_PAREN);
679 do {
680 tokens.consume();
681 } while (tokens.canConsume(COMMA));
682 tokens.consume(R_PAREN);
683
684 tokens.canConsume("COLLATE", DdlTokenStream.ANY_VALUE);
685 tokens.canConsume("CHARACTER", "SET", DdlTokenStream.ANY_VALUE);
686 tokens.canConsume("COLLATE", DdlTokenStream.ANY_VALUE);
687 }
688
689 if (dataType == null) {
690 dataType = super.parseCustomType(tokens);
691 }
692
693
694
695 tokens.canConsume("UNSIGNED");
696 tokens.canConsume("ZEROFILL");
697 tokens.canConsume("UNSIGNED");
698
699 return dataType;
700 }
701
702 @Override
703 protected DataType parseDateTimeType( DdlTokenStream tokens ) throws ParsingException {
704 return super.parseDateTimeType(tokens);
705 }
706
707 @Override
708 protected DataType parseExactNumericType( DdlTokenStream tokens ) throws ParsingException {
709 DataType dType = super.parseExactNumericType(tokens);
710 tokens.canConsume("UNSIGNED");
711 tokens.canConsume("ZEROFILL");
712 tokens.canConsume("UNSIGNED");
713 return dType;
714 }
715
716 }
717
718 }