1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24 package org.modeshape.sequencer.ddl.datatype;
25
26 import static org.modeshape.sequencer.ddl.StandardDdlLexicon.DATATYPE_LENGTH;
27 import static org.modeshape.sequencer.ddl.StandardDdlLexicon.DATATYPE_NAME;
28 import static org.modeshape.sequencer.ddl.StandardDdlLexicon.DATATYPE_PRECISION;
29 import static org.modeshape.sequencer.ddl.StandardDdlLexicon.DATATYPE_SCALE;
30 import java.math.BigInteger;
31 import java.util.ArrayList;
32 import java.util.List;
33 import org.modeshape.common.text.ParsingException;
34 import org.modeshape.sequencer.ddl.DdlConstants;
35 import org.modeshape.sequencer.ddl.DdlTokenStream;
36 import org.modeshape.sequencer.ddl.node.AstNode;
37
38
39
40
41 public class DataTypeParser implements DdlConstants {
42 private static List<String[]> basicCharStringTypes = new ArrayList<String[]>();
43 private static List<String[]> basicNationalCharStringTypes = new ArrayList<String[]>();
44 private static List<String[]> basicBitStringTypes = new ArrayList<String[]>();
45 private static List<String[]> basicExactNumericTypes = new ArrayList<String[]>();
46 private static List<String[]> basicApproxNumericStringTypes = new ArrayList<String[]>();
47 private static List<String[]> basicDateTimeTypes = new ArrayList<String[]>();
48 private static List<String[]> basicMiscTypes = new ArrayList<String[]>();
49
50 private int defaultLength = 255;
51 private int defaultPrecision = 0;
52 private int defaultScale = 0;
53
54 public DataTypeParser() {
55 super();
56
57 initialize();
58 }
59
60 private void initialize() {
61
62 basicCharStringTypes.add(DataTypes.DTYPE_CHARACTER);
63 basicCharStringTypes.add(DataTypes.DTYPE_CHAR);
64 basicCharStringTypes.add(DataTypes.DTYPE_CHARACTER_VARYING);
65 basicCharStringTypes.add(DataTypes.DTYPE_CHAR_VARYING);
66 basicCharStringTypes.add(DataTypes.DTYPE_VARCHAR);
67
68 basicNationalCharStringTypes.add(DataTypes.DTYPE_NCHAR);
69 basicNationalCharStringTypes.add(DataTypes.DTYPE_NATIONAL_CHARACTER);
70 basicNationalCharStringTypes.add(DataTypes.DTYPE_NATIONAL_CHARACTER_VARYING);
71 basicNationalCharStringTypes.add(DataTypes.DTYPE_NATIONAL_CHAR);
72 basicNationalCharStringTypes.add(DataTypes.DTYPE_NATIONAL_CHAR_VARYING);
73 basicNationalCharStringTypes.add(DataTypes.DTYPE_NCHAR_VARYING);
74
75 basicBitStringTypes.add(DataTypes.DTYPE_BIT);
76 basicBitStringTypes.add(DataTypes.DTYPE_BIT_VARYING);
77
78 basicExactNumericTypes.add(DataTypes.DTYPE_NUMERIC);
79 basicExactNumericTypes.add(DataTypes.DTYPE_DEC);
80 basicExactNumericTypes.add(DataTypes.DTYPE_DECIMAL);
81 basicExactNumericTypes.add(DataTypes.DTYPE_INTEGER);
82 basicExactNumericTypes.add(DataTypes.DTYPE_INT);
83 basicExactNumericTypes.add(DataTypes.DTYPE_SMALLINT);
84
85 basicApproxNumericStringTypes.add(DataTypes.DTYPE_FLOAT);
86 basicApproxNumericStringTypes.add(DataTypes.DTYPE_REAL);
87 basicApproxNumericStringTypes.add(DataTypes.DTYPE_DOUBLE_PRECISION);
88
89 basicDateTimeTypes.add(DataTypes.DTYPE_DATE);
90 basicDateTimeTypes.add(DataTypes.DTYPE_TIME);
91 basicDateTimeTypes.add(DataTypes.DTYPE_TIMESTAMP);
92
93 basicMiscTypes.add(DataTypes.DTYPE_INTERVAL);
94
95 }
96
97
98
99
100
101
102
103
104 public final boolean isDatatype( DdlTokenStream tokens ) throws ParsingException {
105
106
107 for (String[] stmts : basicCharStringTypes) {
108 if (tokens.matches(stmts)) return true;
109 }
110
111 for (String[] stmts : basicNationalCharStringTypes) {
112 if (tokens.matches(stmts)) return true;
113 }
114
115 for (String[] stmts : basicBitStringTypes) {
116 if (tokens.matches(stmts)) return true;
117 }
118
119 for (String[] stmts : basicExactNumericTypes) {
120 if (tokens.matches(stmts)) return true;
121 }
122
123 for (String[] stmts : basicApproxNumericStringTypes) {
124 if (tokens.matches(stmts)) return true;
125 }
126
127 for (String[] stmts : basicDateTimeTypes) {
128 if (tokens.matches(stmts)) return true;
129 }
130
131 for (String[] stmts : basicMiscTypes) {
132 if (tokens.matches(stmts)) return true;
133 }
134
135
136 return isCustomDataType(tokens);
137 }
138
139
140
141
142
143
144
145
146
147 private boolean isDatatype( DdlTokenStream tokens,
148 int type ) throws ParsingException {
149
150
151 switch (type) {
152 case DataTypes.DTYPE_CODE_CHAR_STRING: {
153 for (String[] stmts : basicCharStringTypes) {
154 if (tokens.matches(stmts)) return true;
155 }
156 }
157 break;
158 case DataTypes.DTYPE_CODE_NCHAR_STRING: {
159 for (String[] stmts : basicNationalCharStringTypes) {
160 if (tokens.matches(stmts)) return true;
161 }
162 }
163 break;
164 case DataTypes.DTYPE_CODE_BIT_STRING: {
165 for (String[] stmts : basicBitStringTypes) {
166 if (tokens.matches(stmts)) return true;
167 }
168 }
169 break;
170 case DataTypes.DTYPE_CODE_EXACT_NUMERIC: {
171 for (String[] stmts : basicExactNumericTypes) {
172 if (tokens.matches(stmts)) return true;
173 }
174 }
175 break;
176 case DataTypes.DTYPE_CODE_APROX_NUMERIC: {
177 for (String[] stmts : basicApproxNumericStringTypes) {
178 if (tokens.matches(stmts)) return true;
179 }
180 }
181 break;
182 case DataTypes.DTYPE_CODE_DATE_TIME: {
183 for (String[] stmts : basicDateTimeTypes) {
184 if (tokens.matches(stmts)) return true;
185 }
186 }
187 break;
188 case DataTypes.DTYPE_CODE_MISC: {
189 for (String[] stmts : basicMiscTypes) {
190 if (tokens.matches(stmts)) return true;
191 }
192 }
193 break;
194 }
195
196 return false;
197 }
198
199
200
201
202
203
204
205
206
207 protected boolean isCustomDataType( DdlTokenStream tokens ) throws ParsingException {
208 return false;
209 }
210
211
212
213
214
215
216
217
218
219 public DataType parse( DdlTokenStream tokens ) throws ParsingException {
220 DataType result = null;
221
222 if (isDatatype(tokens, DataTypes.DTYPE_CODE_CHAR_STRING)) {
223 result = parseCharStringType(tokens);
224 } else if (isDatatype(tokens, DataTypes.DTYPE_CODE_NCHAR_STRING)) {
225 result = parseNationalCharStringType(tokens);
226 } else if (isDatatype(tokens, DataTypes.DTYPE_CODE_BIT_STRING)) {
227 result = parseBitStringType(tokens);
228 } else if (isDatatype(tokens, DataTypes.DTYPE_CODE_EXACT_NUMERIC)) {
229 result = parseExactNumericType(tokens);
230 } else if (isDatatype(tokens, DataTypes.DTYPE_CODE_APROX_NUMERIC)) {
231 result = parseApproxNumericType(tokens);
232 } else if (isDatatype(tokens, DataTypes.DTYPE_CODE_DATE_TIME)) {
233 result = parseDateTimeType(tokens);
234 } else if (isDatatype(tokens, DataTypes.DTYPE_CODE_MISC)) {
235 result = parseMiscellaneousType(tokens);
236 } else {
237 result = parseCustomType(tokens);
238 }
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280 if (tokens.canConsume('[')) {
281 if (!tokens.canConsume(']')) {
282
283 tokens.consume();
284 tokens.consume(']');
285 }
286
287 if (tokens.canConsume('[')) {
288 if (!tokens.canConsume(']')) {
289
290 tokens.consume();
291 tokens.consume(']');
292 }
293 }
294 }
295
296 return result;
297 }
298
299
300
301
302
303
304
305
306
307
308 protected DataType parseCharStringType( DdlTokenStream tokens ) throws ParsingException {
309 DataType dataType = null;
310 String typeName = null;
311
312 if (tokens.matches(DataTypes.DTYPE_VARCHAR)) {
313 typeName = getStatementTypeName(DataTypes.DTYPE_VARCHAR);
314 dataType = new DataType(typeName);
315 consume(tokens, dataType, false, DataTypes.DTYPE_VARCHAR);
316 int length = parseBracketedInteger(tokens, dataType);
317 dataType.setLength(length);
318 } else if (tokens.matches(DataTypes.DTYPE_CHAR_VARYING)) {
319 typeName = getStatementTypeName(DataTypes.DTYPE_CHAR_VARYING);
320 dataType = new DataType(typeName);
321 consume(tokens, dataType, false, DataTypes.DTYPE_CHAR_VARYING);
322 int length = parseBracketedInteger(tokens, dataType);
323 dataType.setLength(length);
324 } else if (tokens.matches(DataTypes.DTYPE_CHARACTER_VARYING)) {
325 typeName = getStatementTypeName(DataTypes.DTYPE_CHARACTER_VARYING);
326 dataType = new DataType(typeName);
327 consume(tokens, dataType, false, DataTypes.DTYPE_CHARACTER_VARYING);
328 int length = parseBracketedInteger(tokens, dataType);
329 dataType.setLength(length);
330 } else if (tokens.matches(DataTypes.DTYPE_CHAR) || tokens.matches(DataTypes.DTYPE_CHARACTER)) {
331 dataType = new DataType();
332 typeName = consume(tokens, dataType, false);
333 dataType.setName(typeName);
334 int length = getDefaultLength();
335 if (tokens.matches(L_PAREN)) {
336 length = parseBracketedInteger(tokens, dataType);
337 }
338 dataType.setLength(length);
339 }
340
341 return dataType;
342 }
343
344
345
346
347
348
349
350
351
352
353
354 protected DataType parseNationalCharStringType( DdlTokenStream tokens ) throws ParsingException {
355 DataType dataType = null;
356 String typeName = null;
357
358 if (tokens.matches(DataTypes.DTYPE_NCHAR_VARYING)) {
359 typeName = getStatementTypeName(DataTypes.DTYPE_NCHAR_VARYING);
360 dataType = new DataType(typeName);
361 consume(tokens, dataType, false, DataTypes.DTYPE_NCHAR_VARYING);
362 int length = parseBracketedInteger(tokens, dataType);
363
364 dataType.setLength(length);
365 } else if (tokens.matches(DataTypes.DTYPE_NATIONAL_CHAR_VARYING)) {
366 typeName = getStatementTypeName(DataTypes.DTYPE_NATIONAL_CHAR_VARYING);
367 dataType = new DataType(typeName);
368 consume(tokens, dataType, false, DataTypes.DTYPE_NATIONAL_CHAR_VARYING);
369 int length = parseBracketedInteger(tokens, dataType);
370
371 dataType.setLength(length);
372 } else if (tokens.matches(DataTypes.DTYPE_NATIONAL_CHARACTER_VARYING)) {
373 typeName = getStatementTypeName(DataTypes.DTYPE_NATIONAL_CHARACTER_VARYING);
374 dataType = new DataType(typeName);
375 consume(tokens, dataType, false, DataTypes.DTYPE_NATIONAL_CHARACTER_VARYING);
376 int length = parseBracketedInteger(tokens, dataType);
377
378 dataType.setLength(length);
379 } else if (tokens.matches(DataTypes.DTYPE_NCHAR)) {
380 typeName = getStatementTypeName(DataTypes.DTYPE_NCHAR);
381 dataType = new DataType(typeName);
382 consume(tokens, dataType, false, DataTypes.DTYPE_NCHAR);
383 int length = getDefaultLength();
384 if (tokens.matches(L_PAREN)) {
385 length = parseBracketedInteger(tokens, dataType);
386 }
387 dataType.setLength(length);
388 } else if (tokens.matches(DataTypes.DTYPE_NATIONAL_CHAR)) {
389 typeName = getStatementTypeName(DataTypes.DTYPE_NATIONAL_CHAR);
390 dataType = new DataType(typeName);
391 consume(tokens, dataType, false, DataTypes.DTYPE_NATIONAL_CHAR);
392 int length = getDefaultLength();
393 if (tokens.matches(L_PAREN)) {
394 length = parseBracketedInteger(tokens, dataType);
395 }
396 dataType.setLength(length);
397 } else if (tokens.matches(DataTypes.DTYPE_NATIONAL_CHARACTER)) {
398 typeName = getStatementTypeName(DataTypes.DTYPE_NATIONAL_CHARACTER);
399 dataType = new DataType(typeName);
400 consume(tokens, dataType, false, DataTypes.DTYPE_NATIONAL_CHARACTER);
401 int length = getDefaultLength();
402 if (tokens.matches(L_PAREN)) {
403 length = parseBracketedInteger(tokens, dataType);
404 }
405 dataType.setLength(length);
406 }
407
408 return dataType;
409 }
410
411
412
413
414
415
416
417
418
419 protected DataType parseBitStringType( DdlTokenStream tokens ) throws ParsingException {
420 DataType dataType = null;
421 String typeName = null;
422
423 if (tokens.matches(DataTypes.DTYPE_BIT_VARYING)) {
424 typeName = getStatementTypeName(DataTypes.DTYPE_BIT_VARYING);
425 dataType = new DataType(typeName);
426 consume(tokens, dataType, false, DataTypes.DTYPE_BIT_VARYING);
427 int length = parseBracketedInteger(tokens, dataType);
428
429 dataType.setLength(length);
430 } else if (tokens.matches(DataTypes.DTYPE_BIT)) {
431 typeName = getStatementTypeName(DataTypes.DTYPE_BIT);
432 dataType = new DataType(typeName);
433 consume(tokens, dataType, false, DataTypes.DTYPE_BIT);
434 int length = getDefaultLength();
435 if (tokens.matches(L_PAREN)) {
436 length = parseBracketedInteger(tokens, dataType);
437 }
438 dataType.setLength(length);
439 }
440
441 return dataType;
442 }
443
444
445
446
447
448
449
450
451
452
453 protected DataType parseExactNumericType( DdlTokenStream tokens ) throws ParsingException {
454 DataType dataType = null;
455 String typeName = null;
456
457 if (tokens.matchesAnyOf("INTEGER", "INT", "SMALLINT")) {
458 dataType = new DataType();
459 typeName = consume(tokens, dataType, false);
460 dataType.setName(typeName);
461 } else if (tokens.matchesAnyOf("NUMERIC", "DECIMAL", "DEC")) {
462 dataType = new DataType();
463 typeName = consume(tokens, dataType, false);
464 dataType.setName(typeName);
465
466 int precision = 0;
467 int scale = 0;
468
469 if (tokens.matches(L_PAREN)) {
470 consume(tokens, dataType, false, L_PAREN);
471 precision = parseInteger(tokens, dataType);
472 if (canConsume(tokens, dataType, false, COMMA)) {
473 scale = parseInteger(tokens, dataType);
474 } else {
475 scale = getDefaultScale();
476 }
477 consume(tokens, dataType, false, R_PAREN);
478 } else {
479 precision = getDefaultPrecision();
480 scale = getDefaultScale();
481 }
482 dataType.setPrecision(precision);
483 dataType.setScale(scale);
484 }
485
486 return dataType;
487 }
488
489
490
491
492
493
494
495
496
497 protected DataType parseApproxNumericType( DdlTokenStream tokens ) throws ParsingException {
498 DataType dataType = null;
499 String typeName = null;
500
501 if (tokens.matches(DataTypes.DTYPE_REAL)) {
502 dataType = new DataType();
503 typeName = consume(tokens, dataType, false, DataTypes.DTYPE_REAL);
504 dataType.setName(typeName);
505 } else if (tokens.matches(DataTypes.DTYPE_DOUBLE_PRECISION)) {
506 dataType = new DataType();
507 typeName = consume(tokens, dataType, false, DataTypes.DTYPE_DOUBLE_PRECISION);
508 dataType.setName(typeName);
509 } else if (tokens.matches(DataTypes.DTYPE_FLOAT)) {
510 dataType = new DataType();
511 typeName = consume(tokens, dataType, false, DataTypes.DTYPE_FLOAT);
512 dataType.setName(typeName);
513 int precision = 0;
514 if (tokens.matches(L_PAREN)) {
515 precision = parseBracketedInteger(tokens, dataType);
516 }
517 dataType.setPrecision(precision);
518 }
519
520 return dataType;
521 }
522
523
524
525
526
527
528
529
530
531 protected DataType parseDateTimeType( DdlTokenStream tokens ) throws ParsingException {
532 DataType dataType = null;
533 String typeName = null;
534
535 if (tokens.matches(DataTypes.DTYPE_DATE)) {
536 dataType = new DataType();
537 typeName = consume(tokens, dataType, false, DataTypes.DTYPE_DATE);
538 dataType.setName(typeName);
539 } else if (tokens.matches(DataTypes.DTYPE_TIME)) {
540 dataType = new DataType();
541 typeName = consume(tokens, dataType, false, DataTypes.DTYPE_TIME);
542 dataType.setName(typeName);
543
544 int precision = 0;
545 if (tokens.matches(L_PAREN)) {
546 precision = parseBracketedInteger(tokens, dataType);
547 }
548 dataType.setPrecision(precision);
549
550 canConsume(tokens, dataType, true, "WITH", "TIME", "ZONE");
551 } else if (tokens.matches(DataTypes.DTYPE_TIMESTAMP)) {
552 dataType = new DataType();
553 typeName = consume(tokens, dataType, false, DataTypes.DTYPE_TIMESTAMP);
554 dataType.setName(typeName);
555
556 int precision = 0;
557 if (tokens.matches(L_PAREN)) {
558 precision = parseBracketedInteger(tokens, dataType);
559 }
560 dataType.setPrecision(precision);
561
562 canConsume(tokens, dataType, true, "WITH", "TIME", "ZONE");
563 }
564
565 return dataType;
566 }
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581 protected DataType parseMiscellaneousType( DdlTokenStream tokens ) throws ParsingException {
582 DataType dataType = null;
583 String typeName = null;
584
585 if (tokens.matches(DataTypes.DTYPE_INTERVAL)) {
586 dataType = new DataType();
587 typeName = consume(tokens, dataType, false, DataTypes.DTYPE_INTERVAL);
588 dataType.setName(typeName);
589
590
591
592
593
594
595
596 if (tokens.matchesAnyOf("YEAR", "MONTH", "DAY", "HOUR", "MINUTE")) {
597
598 consume(tokens, dataType, true);
599
600 if (canConsume(tokens, dataType, true, "TO")) {
601
602
603 consume(tokens, dataType, true);
604 } else if (tokens.matches(L_PAREN, DdlTokenStream.ANY_VALUE, R_PAREN)) {
605
606 consume(tokens, dataType, true, L_PAREN);
607 consume(tokens, dataType, true);
608 consume(tokens, dataType, true, R_PAREN);
609 } else {
610 System.out.println(" WARNING: PROBLEM parsing INTERVAL data type. Check your DDL for incomplete statement.");
611 }
612 } else if (canConsume(tokens, dataType, true, "SECOND")) {
613
614 if (canConsume(tokens, dataType, true, L_PAREN)) {
615
616 consume(tokens, dataType, true);
617 if (canConsume(tokens, dataType, true, COMMA)) {
618 consume(tokens, dataType, true);
619 }
620 canConsume(tokens, dataType, true, R_PAREN);
621 } else {
622 System.out.println(" WARNING: PROBLEM parsing INTERVAL data type. Check your DDL for incomplete statement.");
623 }
624 } else {
625 System.out.println(" WARNING: PROBLEM parsing INTERVAL data type. Check your DDL for incomplete statement.");
626 }
627 }
628
629 return dataType;
630 }
631
632
633
634
635
636
637
638
639 protected DataType parseCustomType( DdlTokenStream tokens ) throws ParsingException {
640 return null;
641 }
642
643
644
645
646 public int getDefaultLength() {
647 return defaultLength;
648 }
649
650
651
652
653 public void setDefaultLength( int defaultLength ) {
654 this.defaultLength = defaultLength;
655 }
656
657
658
659
660 public int getDefaultPrecision() {
661 return defaultPrecision;
662 }
663
664
665
666
667 public void setDefaultPrecision( int defaultPrecision ) {
668 this.defaultPrecision = defaultPrecision;
669 }
670
671
672
673
674 public int getDefaultScale() {
675 return defaultScale;
676 }
677
678
679
680
681 public void setDefaultScale( int defaultScale ) {
682 this.defaultScale = defaultScale;
683 }
684
685
686
687
688
689
690
691
692 protected int parseInteger( DdlTokenStream tokens,
693 DataType dataType ) {
694 String value = consume(tokens, dataType, false);
695
696 if (isKMGInteger(value)) {
697 value = value.substring(0, value.length() - 1);
698 }
699
700 return new BigInteger(value).intValue();
701 }
702
703
704
705
706
707
708
709
710 protected int parseBracketedInteger( DdlTokenStream tokens,
711 DataType dataType ) {
712 consume(tokens, dataType, false, L_PAREN);
713 int length = parseInteger(tokens, dataType);
714 consume(tokens, dataType, false, R_PAREN);
715
716 return length;
717 }
718
719
720
721
722
723
724
725
726 protected boolean isKMGInteger( String value ) {
727 return (value.endsWith("M") || value.endsWith("K") || value.endsWith("G"));
728 }
729
730
731
732
733
734
735
736
737 protected int parseInteger( String value ) {
738 if (isKMGInteger(value)) {
739 value = value.substring(0, value.length() - 1);
740 }
741
742 return new BigInteger(value).intValue();
743 }
744
745
746
747
748
749
750
751 protected String getKMG( String value ) {
752 if (value.endsWith("M")) return "M";
753 if (value.endsWith("K")) return "K";
754 if (value.endsWith("G")) return "G";
755
756 return null;
757 }
758
759
760
761
762
763
764
765
766 protected String consume( DdlTokenStream tokens,
767 DataType dataType,
768 boolean addSpacePrefix ) throws ParsingException {
769 String value = tokens.consume();
770
771 dataType.appendSource(addSpacePrefix, value);
772
773 return value;
774 }
775
776
777
778
779
780
781
782
783
784 protected String consume( DdlTokenStream tokens,
785 DataType dataType,
786 boolean addSpacePrefix,
787 String str ) throws ParsingException {
788 tokens.consume(str);
789
790 dataType.appendSource(addSpacePrefix, str);
791
792 return str;
793 }
794
795
796
797
798
799
800
801
802
803
804 protected String consume( DdlTokenStream tokens,
805 DataType dataType,
806 boolean addSpacePrefix,
807 String initialStr,
808 String... additionalStrs ) throws ParsingException {
809 tokens.consume(initialStr, additionalStrs);
810 StringBuffer value = new StringBuffer(initialStr);
811 dataType.appendSource(addSpacePrefix, initialStr);
812
813 for (String str : additionalStrs) {
814 value.append(SPACE).append(str);
815 dataType.appendSource(addSpacePrefix, str);
816 }
817
818 return value.toString();
819 }
820
821 protected String consume( DdlTokenStream tokens,
822 DataType dataType,
823 boolean addSpacePrefix,
824 String[] additionalStrs ) throws ParsingException {
825
826 tokens.consume(additionalStrs);
827
828 StringBuffer value = new StringBuffer(100);
829
830 int i = 0;
831
832 for (String str : additionalStrs) {
833 if (i == 0) {
834 value.append(str);
835 } else {
836 value.append(SPACE).append(str);
837 }
838 dataType.appendSource(addSpacePrefix, str);
839 i++;
840 }
841
842 return value.toString();
843 }
844
845
846
847
848
849
850
851
852
853
854 protected boolean canConsume( DdlTokenStream tokens,
855 DataType dataType,
856 boolean addSpacePrefix,
857 String initialStr,
858 String... additionalStrs ) throws ParsingException {
859 if (tokens.canConsume(initialStr, additionalStrs)) {
860 dataType.appendSource(addSpacePrefix, initialStr);
861
862 for (String str : additionalStrs) {
863 dataType.appendSource(addSpacePrefix, str);
864 }
865 return true;
866 }
867
868 return false;
869 }
870
871
872
873
874
875
876
877
878
879 protected boolean canConsume( DdlTokenStream tokens,
880 DataType dataType,
881 boolean addSpacePrefix,
882 String[] additionalStrs ) throws ParsingException {
883 if (tokens.canConsume(additionalStrs)) {
884
885 for (String str : additionalStrs) {
886 dataType.appendSource(addSpacePrefix, str);
887 }
888 return true;
889 }
890
891 return false;
892 }
893
894
895
896
897
898
899
900
901
902 protected boolean canConsume( DdlTokenStream tokens,
903 DataType dataType,
904 boolean addSpacePrefix,
905 int type ) throws ParsingException {
906 if (tokens.matches(type)) {
907 dataType.appendSource(addSpacePrefix, tokens.consume());
908 return true;
909 }
910
911 return false;
912 }
913
914
915
916
917
918
919
920
921
922
923 protected boolean canConsumeAnyOf( DdlTokenStream tokens,
924 DataType dataType,
925 boolean addSpacePrefix,
926 String initialStr,
927 String... additionalStrs ) throws ParsingException {
928 if (tokens.canConsume(initialStr)) {
929 dataType.appendSource(addSpacePrefix, initialStr);
930 return true;
931 }
932 for (String str : additionalStrs) {
933 dataType.appendSource(addSpacePrefix, str);
934 return true;
935 }
936
937 return false;
938 }
939
940
941
942
943
944 public String getStatementTypeName( String[] stmtPhrase ) {
945 StringBuffer sb = new StringBuffer(100);
946 for (int i = 0; i < stmtPhrase.length; i++) {
947 if (i == 0) {
948 sb.append(stmtPhrase[0]);
949 } else {
950 sb.append(SPACE).append(stmtPhrase[i]);
951 }
952 }
953
954 return sb.toString();
955 }
956
957 public void setPropertiesOnNode( AstNode columnNode,
958 DataType datatype ) {
959 columnNode.setProperty(DATATYPE_NAME, datatype.getName());
960 if (datatype.getLength() >= 0) {
961 columnNode.setProperty(DATATYPE_LENGTH, datatype.getLength());
962 }
963 if (datatype.getPrecision() >= 0) {
964 columnNode.setProperty(DATATYPE_PRECISION, datatype.getPrecision());
965 }
966 if (datatype.getScale() >= 0) {
967 columnNode.setProperty(DATATYPE_SCALE, datatype.getScale());
968 }
969 }
970 }