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.dialect.oracle;
25
26 import static org.modeshape.sequencer.ddl.StandardDdlLexicon.CREATE_VIEW_QUERY_EXPRESSION;
27 import static org.modeshape.sequencer.ddl.StandardDdlLexicon.DROP_BEHAVIOR;
28 import static org.modeshape.sequencer.ddl.StandardDdlLexicon.DROP_OPTION_TYPE;
29 import static org.modeshape.sequencer.ddl.StandardDdlLexicon.NEW_NAME;
30 import static org.modeshape.sequencer.ddl.StandardDdlLexicon.TYPE_ALTER_TABLE_STATEMENT;
31 import static org.modeshape.sequencer.ddl.StandardDdlLexicon.TYPE_COLUMN_REFERENCE;
32 import static org.modeshape.sequencer.ddl.StandardDdlLexicon.TYPE_CREATE_VIEW_STATEMENT;
33 import static org.modeshape.sequencer.ddl.StandardDdlLexicon.TYPE_DROP_COLUMN_DEFINITION;
34 import static org.modeshape.sequencer.ddl.StandardDdlLexicon.TYPE_DROP_TABLE_CONSTRAINT_DEFINITION;
35 import static org.modeshape.sequencer.ddl.StandardDdlLexicon.TYPE_DROP_TABLE_STATEMENT;
36 import static org.modeshape.sequencer.ddl.StandardDdlLexicon.TYPE_GRANT_STATEMENT;
37 import static org.modeshape.sequencer.ddl.StandardDdlLexicon.TYPE_UNKNOWN_STATEMENT;
38 import static org.modeshape.sequencer.ddl.dialect.oracle.OracleDdlLexicon.*;
39 import java.util.ArrayList;
40 import java.util.List;
41 import org.modeshape.common.text.ParsingException;
42 import org.modeshape.common.util.CheckArg;
43 import org.modeshape.graph.property.Name;
44 import org.modeshape.sequencer.ddl.DdlParserProblem;
45 import org.modeshape.sequencer.ddl.DdlSequencerI18n;
46 import org.modeshape.sequencer.ddl.DdlTokenStream;
47 import org.modeshape.sequencer.ddl.StandardDdlLexicon;
48 import org.modeshape.sequencer.ddl.StandardDdlParser;
49 import org.modeshape.sequencer.ddl.DdlTokenStream.DdlTokenizer;
50 import org.modeshape.sequencer.ddl.datatype.DataType;
51 import org.modeshape.sequencer.ddl.datatype.DataTypeParser;
52 import org.modeshape.sequencer.ddl.node.AstNode;
53
54
55
56
57 public class OracleDdlParser extends StandardDdlParser
58 implements OracleDdlConstants, OracleDdlConstants.OracleStatementStartPhrases {
59 private final String parserId = "ORACLE";
60
61 static List<String[]> oracleDataTypeStrings = new ArrayList<String[]>();
62
63 public OracleDdlParser() {
64 super();
65
66 setDatatypeParser(new OracleDataTypeParser());
67 initialize();
68 }
69
70 private void initialize() {
71 setTerminator(DEFAULT_TERMINATOR);
72
73 setDoUseTerminator(true);
74
75 oracleDataTypeStrings.addAll(OracleDataTypes.CUSTOM_DATATYPE_START_PHRASES);
76 }
77
78
79
80
81
82
83 @Override
84 public String getId() {
85 return this.parserId;
86 }
87
88
89
90
91
92
93 @Override
94 public String[] getIdentifyingKeywords() {
95 return new String[] {getId(), "spool.log"};
96 }
97
98
99
100
101
102
103 @Override
104 protected void initializeTokenStream( DdlTokenStream tokens ) {
105 super.initializeTokenStream(tokens);
106 tokens.registerKeyWords(CUSTOM_KEYWORDS);
107 tokens.registerKeyWords(OracleDataTypes.CUSTOM_DATATYPE_START_WORDS);
108 tokens.registerStatementStartPhrase(ALTER_PHRASES);
109 tokens.registerStatementStartPhrase(CREATE_PHRASES);
110 tokens.registerStatementStartPhrase(DROP_PHRASES);
111 tokens.registerStatementStartPhrase(MISC_PHRASES);
112 tokens.registerStatementStartPhrase(SET_PHRASES);
113 }
114
115 @Override
116 protected void rewrite( DdlTokenStream tokens,
117 AstNode rootNode ) {
118 assert tokens != null;
119 assert rootNode != null;
120
121
122
123
124
125 List<AstNode> copyOfNodes = new ArrayList<AstNode>(rootNode.getChildren());
126
127 AstNode complexNode = null;
128
129 for (AstNode child : copyOfNodes) {
130
131 if ((complexNode != null && nodeFactory().hasMixinType(child, TYPE_UNKNOWN_STATEMENT))
132 || (complexNode != null && nodeFactory().hasMixinType(child, TYPE_BACKSLASH_TERMINATOR))) {
133 mergeNodes(tokens, complexNode, child);
134 rootNode.removeChild(child);
135 } else {
136 complexNode = null;
137 }
138
139 if (nodeFactory().hasMixinType(child, TYPE_CREATE_FUNCTION_STATEMENT)
140 || nodeFactory().hasMixinType(child, TYPE_CREATE_TRIGGER_STATEMENT)
141 || nodeFactory().hasMixinType(child, TYPE_CREATE_LIBRARY_STATEMENT)
142 || nodeFactory().hasMixinType(child, TYPE_CREATE_PACKAGE_STATEMENT)
143 || nodeFactory().hasMixinType(child, TYPE_CREATE_PROCEDURE_STATEMENT)) {
144 complexNode = child;
145 }
146 }
147
148
149
150
151 super.rewrite(tokens, rootNode);
152
153
154
155
156
157 copyOfNodes = new ArrayList<AstNode>(rootNode.getChildren());
158 boolean foundComplexNode = false;
159 complexNode = null;
160 for (AstNode child : copyOfNodes) {
161 if (matchesComplexNode(child)) {
162 foundComplexNode = true;
163 complexNode = child;
164 } else if (foundComplexNode) {
165 if (complexNode != null && nodeFactory().hasMixinType(child, TYPE_UNKNOWN_STATEMENT)) {
166 mergeNodes(tokens, complexNode, child);
167 rootNode.removeChild(child);
168 } else {
169 foundComplexNode = false;
170 complexNode = null;
171 }
172 }
173 }
174 }
175
176 private boolean matchesComplexNode( AstNode node ) {
177 assert node != null;
178
179 for (Name mixin : COMPLEX_STMT_TYPES) {
180 if (nodeFactory().hasMixinType(node, mixin)) {
181 return true;
182 }
183 }
184
185 return false;
186 }
187
188
189
190
191
192
193
194 @Override
195 public AstNode handleUnknownToken( DdlTokenStream tokens,
196 String tokenValue ) throws ParsingException {
197 if (tokenValue.equals("/")) {
198 return nodeFactory().node("backslashTerminator", getRootNode(), TYPE_BACKSLASH_TERMINATOR);
199 }
200
201 return null;
202 }
203
204
205
206
207
208
209
210 @Override
211 protected AstNode parseCreateSchemaStatement( DdlTokenStream tokens,
212 AstNode parentNode ) throws ParsingException {
213 assert tokens != null;
214 assert parentNode != null;
215
216 return super.parseCreateSchemaStatement(tokens, parentNode);
217 }
218
219
220
221
222
223
224
225 @Override
226 protected AstNode parseCustomStatement( DdlTokenStream tokens,
227 AstNode parentNode ) throws ParsingException {
228 assert tokens != null;
229 assert parentNode != null;
230
231 AstNode result = null;
232
233 if (tokens.matches(STMT_COMMENT_ON)) {
234 result = parseCommentStatement(tokens, parentNode);
235 } else if (tokens.matches(STMT_ANALYZE)) {
236 return parseStatement(tokens, STMT_ANALYZE, parentNode, TYPE_ANALYZE_STATEMENT);
237 } else if (tokens.matches(STMT_ASSOCIATE_STATISTICS)) {
238 return parseStatement(tokens, STMT_ASSOCIATE_STATISTICS, parentNode, TYPE_ASSOCIATE_STATISTICS_STATEMENT);
239 } else if (tokens.matches(STMT_AUDIT)) {
240 return parseStatement(tokens, STMT_AUDIT, parentNode, TYPE_AUDIT_STATEMENT);
241 } else if (tokens.matches(STMT_COMMIT_FORCE) || tokens.matches(STMT_COMMIT_WORK) || tokens.matches(STMT_COMMIT_WRITE)) {
242 return parseStatement(tokens, STMT_COMMIT, parentNode, TYPE_COMMIT_STATEMENT);
243 } else if (tokens.matches(STMT_DISASSOCIATE_STATISTICS)) {
244 return parseStatement(tokens, STMT_DISASSOCIATE_STATISTICS, parentNode, TYPE_DISASSOCIATE_STATISTICS_STATEMENT);
245 } else if (tokens.matches(STMT_EXPLAIN_PLAN)) {
246 return parseStatement(tokens, STMT_EXPLAIN_PLAN, parentNode, TYPE_EXPLAIN_PLAN_STATEMENT);
247 } else if (tokens.matches(STMT_FLASHBACK)) {
248 return parseStatement(tokens, STMT_FLASHBACK, parentNode, TYPE_FLASHBACK_STATEMENT);
249 } else if (tokens.matches(STMT_LOCK_TABLE)) {
250 return parseStatement(tokens, STMT_LOCK_TABLE, parentNode, TYPE_LOCK_TABLE_STATEMENT);
251 } else if (tokens.matches(STMT_MERGE)) {
252 return parseStatement(tokens, STMT_MERGE, parentNode, TYPE_MERGE_STATEMENT);
253 } else if (tokens.matches(STMT_NOAUDIT)) {
254 return parseStatement(tokens, STMT_NOAUDIT, parentNode, TYPE_NOAUDIT_STATEMENT);
255 } else if (tokens.matches(STMT_PURGE)) {
256 return parseStatement(tokens, STMT_PURGE, parentNode, TYPE_PURGE_STATEMENT);
257 } else if (tokens.matches(STMT_RENAME)) {
258 return parseStatement(tokens, STMT_RENAME, parentNode, TYPE_RENAME_STATEMENT);
259 } else if (tokens.matches(STMT_ROLLBACK)) {
260 return parseStatement(tokens, STMT_ROLLBACK, parentNode, TYPE_ROLLBACK_STATEMENT);
261 } else if (tokens.matches(STMT_ROLLBACK_WORK)) {
262 return parseStatement(tokens, STMT_ROLLBACK_WORK, parentNode, TYPE_ROLLBACK_STATEMENT);
263 } else if (tokens.matches(STMT_ROLLBACK_TO_SAVEPOINT)) {
264 return parseStatement(tokens, STMT_ROLLBACK_TO_SAVEPOINT, parentNode, TYPE_ROLLBACK_STATEMENT);
265 } else if (tokens.matches(STMT_SAVEPOINT)) {
266 return parseStatement(tokens, STMT_SAVEPOINT, parentNode, TYPE_SAVEPOINT_STATEMENT);
267 } else if (tokens.matches(STMT_TRUNCATE)) {
268 return parseStatement(tokens, STMT_TRUNCATE, parentNode, TYPE_TRUNCATE_STATEMENT);
269 }
270
271 if (result == null) {
272 result = super.parseCustomStatement(tokens, parentNode);
273 }
274 return result;
275 }
276
277 @Override
278 protected AstNode parseCreateStatement( DdlTokenStream tokens,
279 AstNode parentNode ) throws ParsingException {
280 assert tokens != null;
281 assert parentNode != null;
282
283 if (tokens.matches(STMT_CREATE_INDEX) || tokens.matches(STMT_CREATE_UNIQUE_INDEX)
284 || tokens.matches(STMT_CREATE_BITMAP_INDEX)) {
285 return parseCreateIndex(tokens, parentNode);
286 } else if (tokens.matches(STMT_CREATE_CLUSTER)) {
287 return parseCreateClusterStatement(tokens, parentNode);
288 } else if (tokens.matches(STMT_CREATE_CONTEXT)) {
289 return parseStatement(tokens, STMT_CREATE_CONTEXT, parentNode, TYPE_CREATE_CONTEXT_STATEMENT);
290 } else if (tokens.matches(STMT_CREATE_CONTROLFILE)) {
291 return parseStatement(tokens, STMT_CREATE_CONTROLFILE, parentNode, TYPE_CREATE_CONTROLFILE_STATEMENT);
292 } else if (tokens.matches(STMT_CREATE_DATABASE)) {
293 return parseStatement(tokens, STMT_CREATE_DATABASE, parentNode, TYPE_CREATE_DATABASE_STATEMENT);
294 } else if (tokens.matches(STMT_CREATE_PUBLIC_DATABASE)) {
295 return parseStatement(tokens, STMT_CREATE_PUBLIC_DATABASE, parentNode, TYPE_CREATE_DATABASE_STATEMENT);
296 } else if (tokens.matches(STMT_CREATE_DIMENSION)) {
297 return parseCreateDimensionStatement(tokens, parentNode);
298 } else if (tokens.matches(STMT_CREATE_DIRECTORY)) {
299 return parseStatement(tokens, STMT_CREATE_DIRECTORY, parentNode, TYPE_CREATE_DIRECTORY_STATEMENT);
300 } else if (tokens.matches(STMT_CREATE_OR_REPLACE_DIRECTORY)) {
301 return parseStatement(tokens, STMT_CREATE_OR_REPLACE_DIRECTORY, parentNode, TYPE_CREATE_DIRECTORY_STATEMENT);
302 } else if (tokens.matches(STMT_CREATE_DISKGROUP)) {
303 return parseStatement(tokens, STMT_CREATE_DISKGROUP, parentNode, TYPE_CREATE_DISKGROUP_STATEMENT);
304 } else if (tokens.matches(STMT_CREATE_FUNCTION)) {
305
306 return parseCreateFunctionStatement(tokens, parentNode);
307 } else if (tokens.matches(STMT_CREATE_OR_REPLACE_FUNCTION)) {
308
309 return parseCreateFunctionStatement(tokens, parentNode);
310 } else if (tokens.matches(STMT_CREATE_INDEXTYPE)) {
311 return parseStatement(tokens, STMT_CREATE_INDEXTYPE, parentNode, TYPE_CREATE_INDEXTYPE_STATEMENT);
312 } else if (tokens.matches(STMT_CREATE_JAVA)) {
313 return parseCreateJavaStatement(tokens, parentNode);
314 } else if (tokens.matches(STMT_CREATE_LIBRARY)) {
315
316 return parseStatement(tokens, STMT_CREATE_LIBRARY, parentNode, TYPE_CREATE_LIBRARY_STATEMENT);
317 } else if (tokens.matches(STMT_CREATE_OR_REPLACE_LIBRARY)) {
318
319 return parseStatement(tokens, STMT_CREATE_OR_REPLACE_LIBRARY, parentNode, TYPE_CREATE_LIBRARY_STATEMENT);
320 } else if (tokens.matches(STMT_CREATE_MATERIALIZED_VIEW)) {
321 return parseMaterializedViewStatement(tokens, parentNode);
322 } else if (tokens.matches(STMT_CREATE_OPERATOR)) {
323 return parseStatement(tokens, STMT_CREATE_OPERATOR, parentNode, TYPE_CREATE_OPERATOR_STATEMENT);
324 } else if (tokens.matches(STMT_CREATE_OUTLINE)) {
325 return parseStatement(tokens, STMT_CREATE_OUTLINE, parentNode, TYPE_CREATE_OUTLINE_STATEMENT);
326 } else if (tokens.matches(STMT_CREATE_OR_REPLACE_OUTLINE)) {
327 return parseStatement(tokens, STMT_CREATE_OR_REPLACE_OUTLINE, parentNode, TYPE_CREATE_OUTLINE_STATEMENT);
328 } else if (tokens.matches(STMT_CREATE_PACKAGE)) {
329
330 return parseStatement(tokens, STMT_CREATE_PACKAGE, parentNode, TYPE_CREATE_PACKAGE_STATEMENT);
331 } else if (tokens.matches(STMT_CREATE_OR_REPLACE_PACKAGE)) {
332
333 return parseStatement(tokens, STMT_CREATE_OR_REPLACE_PACKAGE, parentNode, TYPE_CREATE_PACKAGE_STATEMENT);
334 } else if (tokens.matches(STMT_CREATE_PFILE)) {
335 return parseStatement(tokens, STMT_CREATE_PFILE, parentNode, TYPE_CREATE_PFILE_STATEMENT);
336 } else if (tokens.matches(STMT_CREATE_PROCEDURE)) {
337
338 return parseCreateProcedureStatement(tokens, parentNode);
339 } else if (tokens.matches(STMT_CREATE_OR_REPLACE_PROCEDURE)) {
340
341 return parseCreateProcedureStatement(tokens, parentNode);
342 } else if (tokens.matches(STMT_CREATE_PROFILE)) {
343 return parseStatement(tokens, STMT_CREATE_PROFILE, parentNode, TYPE_CREATE_PROFILE_STATEMENT);
344 } else if (tokens.matches(STMT_CREATE_ROLE)) {
345 return parseStatement(tokens, STMT_CREATE_ROLE, parentNode, TYPE_CREATE_ROLE_STATEMENT);
346 } else if (tokens.matches(STMT_CREATE_ROLLBACK)) {
347 return parseStatement(tokens, STMT_CREATE_ROLLBACK, parentNode, TYPE_CREATE_ROLLBACK_STATEMENT);
348 } else if (tokens.matches(STMT_CREATE_PUBLIC_ROLLBACK)) {
349 return parseStatement(tokens, STMT_CREATE_PUBLIC_ROLLBACK, parentNode, TYPE_CREATE_ROLLBACK_STATEMENT);
350 } else if (tokens.matches(STMT_CREATE_SEQUENCE)) {
351 return parseStatement(tokens, STMT_CREATE_SEQUENCE, parentNode, TYPE_CREATE_SEQUENCE_STATEMENT);
352 } else if (tokens.matches(STMT_CREATE_SPFILE)) {
353 return parseStatement(tokens, STMT_CREATE_SPFILE, parentNode, TYPE_CREATE_SPFILE_STATEMENT);
354 } else if (tokens.matches(STMT_CREATE_SYNONYM)) {
355 return parseStatement(tokens, STMT_CREATE_SYNONYM, parentNode, TYPE_CREATE_SYNONYM_STATEMENT);
356 } else if (tokens.matches(STMT_CREATE_OR_REPLACE_SYNONYM)) {
357 return parseStatement(tokens, STMT_CREATE_OR_REPLACE_SYNONYM, parentNode, TYPE_CREATE_SYNONYM_STATEMENT);
358 } else if (tokens.matches(STMT_CREATE_OR_REPLACE_PUBLIC_SYNONYM)) {
359 return parseStatement(tokens, STMT_CREATE_OR_REPLACE_PUBLIC_SYNONYM, parentNode, TYPE_CREATE_SYNONYM_STATEMENT);
360 } else if (tokens.matches(STMT_CREATE_PUBLIC_SYNONYM)) {
361 return parseStatement(tokens, STMT_CREATE_PUBLIC_SYNONYM, parentNode, TYPE_CREATE_SYNONYM_STATEMENT);
362 } else if (tokens.matches(STMT_CREATE_TABLESPACE)) {
363 return parseStatement(tokens, STMT_CREATE_TABLESPACE, parentNode, TYPE_CREATE_TABLESPACE_STATEMENT);
364 } else if (tokens.matches(STMT_CREATE_TRIGGER)) {
365
366 return parseSlashedStatement(tokens, STMT_CREATE_TRIGGER, parentNode, TYPE_CREATE_TRIGGER_STATEMENT);
367 } else if (tokens.matches(STMT_CREATE_OR_REPLACE_TRIGGER)) {
368
369 return parseSlashedStatement(tokens, STMT_CREATE_OR_REPLACE_TRIGGER, parentNode, TYPE_CREATE_TRIGGER_STATEMENT);
370 } else if (tokens.matches(STMT_CREATE_TYPE)) {
371 return parseStatement(tokens, STMT_CREATE_TYPE, parentNode, TYPE_CREATE_TYPE_STATEMENT);
372 } else if (tokens.matches(STMT_CREATE_OR_REPLACE_TYPE)) {
373 return parseStatement(tokens, STMT_CREATE_OR_REPLACE_TYPE, parentNode, TYPE_CREATE_TYPE_STATEMENT);
374 } else if (tokens.matches(STMT_CREATE_USER)) {
375 return parseStatement(tokens, STMT_CREATE_USER, parentNode, TYPE_CREATE_USER_STATEMENT);
376 }
377
378 return super.parseCreateStatement(tokens, parentNode);
379 }
380
381 private AstNode parseCreateClusterStatement( DdlTokenStream tokens,
382 AstNode parentNode ) throws ParsingException {
383 markStartOfStatement(tokens);
384 tokens.consume(STMT_CREATE_CLUSTER);
385 String name = parseName(tokens);
386
387 AstNode node = nodeFactory().node(name, parentNode, TYPE_CREATE_CLUSTER_STATEMENT);
388
389 parseUntilTerminator(tokens);
390
391 markEndOfStatement(tokens, node);
392
393 return node;
394 }
395
396 private AstNode parseCreateDimensionStatement( DdlTokenStream tokens,
397 AstNode parentNode ) throws ParsingException {
398 markStartOfStatement(tokens);
399 tokens.consume(STMT_CREATE_DIMENSION);
400 String name = parseName(tokens);
401
402 AstNode node = nodeFactory().node(name, parentNode, TYPE_CREATE_DIMENSION_STATEMENT);
403
404 parseUntilTerminator(tokens);
405
406 markEndOfStatement(tokens, node);
407
408 return node;
409 }
410
411
412
413
414
415
416
417
418
419 protected AstNode parseCreateFunctionStatement( DdlTokenStream tokens,
420 AstNode parentNode ) throws ParsingException {
421 assert tokens != null;
422 assert parentNode != null;
423
424 markStartOfStatement(tokens);
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445 boolean isReplace = tokens.canConsume(STMT_CREATE_OR_REPLACE_FUNCTION);
446
447 tokens.canConsume(STMT_CREATE_FUNCTION);
448
449 String name = parseName(tokens);
450
451 AstNode node = nodeFactory().node(name, parentNode, TYPE_CREATE_FUNCTION_STATEMENT);
452
453 if (isReplace) {
454
455 }
456
457 boolean ok = parseParameters(tokens, node);
458
459 if (ok) {
460 if (tokens.canConsume("RETURN")) {
461 DataType dType = getDatatypeParser().parse(tokens);
462 if (dType != null) {
463 getDatatypeParser().setPropertiesOnNode(node, dType);
464 }
465 }
466 }
467
468 parseUntilFwdSlash(tokens, false);
469
470 tokens.canConsume("/");
471
472 markEndOfStatement(tokens, node);
473
474 return node;
475 }
476
477
478
479
480
481
482
483
484
485 protected AstNode parseCreateProcedureStatement( DdlTokenStream tokens,
486 AstNode parentNode ) throws ParsingException {
487 assert tokens != null;
488 assert parentNode != null;
489
490 markStartOfStatement(tokens);
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512 boolean isReplace = tokens.canConsume(STMT_CREATE_OR_REPLACE_PROCEDURE);
513
514 tokens.canConsume(STMT_CREATE_PROCEDURE);
515
516 String name = parseName(tokens);
517
518 AstNode node = nodeFactory().node(name, parentNode, TYPE_CREATE_PROCEDURE_STATEMENT);
519
520 if (isReplace) {
521
522 }
523
524 boolean ok = parseParameters(tokens, node);
525
526 if (ok) {
527 if (tokens.canConsume("AUTHID")) {
528 if (tokens.canConsume("CURRENT_USER")) {
529 node.setProperty(AUTHID_VALUE, "AUTHID CURRENT_USER");
530 } else {
531 tokens.consume("DEFINER");
532 node.setProperty(AUTHID_VALUE, "DEFINER");
533 }
534 }
535 }
536
537 parseUntilFwdSlash(tokens, false);
538
539 tokens.canConsume("/");
540
541 markEndOfStatement(tokens, node);
542
543 return node;
544 }
545
546 private boolean parseParameters( DdlTokenStream tokens,
547 AstNode procedureNode ) throws ParsingException {
548 assert tokens != null;
549 assert procedureNode != null;
550
551
552
553
554
555
556
557
558 tokens.consume(L_PAREN);
559
560 while (!tokens.canConsume(R_PAREN)) {
561
562 String paramName = parseName(tokens);
563 String inOutStr = null;
564 if (tokens.matches("IN")) {
565 if (tokens.canConsume("IN", "OUT")) {
566 if (tokens.canConsume("NOCOPY")) {
567 inOutStr = "IN OUT NOCOPY";
568 } else {
569 inOutStr = "IN OUT";
570 }
571 } else {
572 tokens.consume("IN");
573 inOutStr = "IN";
574 }
575
576 } else if (tokens.matches("OUT")) {
577 if (tokens.canConsume("OUT", "NOCOPY")) {
578 inOutStr = "OUT NOCOPY";
579 } else {
580 tokens.consume("OUT");
581 inOutStr = "OUT";
582 }
583 }
584
585 DataType datatype = getDatatypeParser().parse(tokens);
586 AstNode paramNode = nodeFactory().node(paramName, procedureNode, TYPE_FUNCTION_PARAMETER);
587 if (datatype != null) {
588 getDatatypeParser().setPropertiesOnNode(paramNode, datatype);
589 }
590
591 if (tokens.matchesAnyOf(":=", "DEFAULT") || !tokens.matchesAnyOf(COMMA, R_PAREN)) {
592 String msg = DdlSequencerI18n.unsupportedProcedureParameterDeclaration.text(procedureNode.getProperty(StandardDdlLexicon.NAME));
593 DdlParserProblem problem = new DdlParserProblem(Problems.WARNING, getCurrentMarkedPosition(), msg);
594 addProblem(problem, procedureNode);
595 return false;
596 }
597
598 if (inOutStr != null) {
599 paramNode.setProperty(IN_OUT_NO_COPY, inOutStr);
600 }
601
602 tokens.canConsume(COMMA);
603 }
604
605 return true;
606 }
607
608
609
610
611
612
613
614
615
616 protected AstNode parseMaterializedViewStatement( DdlTokenStream tokens,
617 AstNode parentNode ) throws ParsingException {
618 assert tokens != null;
619 assert parentNode != null;
620
621 markStartOfStatement(tokens);
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645 boolean isLog = tokens.canConsume(STMT_CREATE_MATERIALIZED_VEIW_LOG);
646
647 tokens.canConsume(STMT_CREATE_MATERIALIZED_VIEW);
648
649 String name = parseName(tokens);
650
651 AstNode node = null;
652
653 if (isLog) {
654 node = nodeFactory().node(name, parentNode, TYPE_CREATE_MATERIALIZED_VIEW_LOG_STATEMENT);
655 } else {
656 node = nodeFactory().node(name, parentNode, TYPE_CREATE_MATERIALIZED_VIEW_STATEMENT);
657 }
658
659 parseUntilTerminator(tokens);
660
661 markEndOfStatement(tokens, node);
662
663 return node;
664 }
665
666 @Override
667 protected AstNode parseGrantStatement( DdlTokenStream tokens,
668 AstNode parentNode ) throws ParsingException {
669 CheckArg.isNotNull(tokens, "tokens");
670 CheckArg.isNotNull(parentNode, "parentNode");
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694 AstNode node = null;
695
696
697 markStartOfStatement(tokens);
698
699 tokens.consume(GRANT);
700 String name = GRANT;
701
702 tokens.consume();
703
704 node = nodeFactory().node(name, parentNode, TYPE_GRANT_STATEMENT);
705
706 while (tokens.hasNext()
707 && !isTerminator(tokens)
708 && (!tokens.matches(DdlTokenizer.STATEMENT_KEY) || (tokens.matches(DdlTokenizer.STATEMENT_KEY) && tokens.matches("GRANT",
709 "OPTION")))) {
710 tokens.consume();
711 }
712
713 markEndOfStatement(tokens, node);
714
715 return node;
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831 }
832
833
834
835
836
837
838
839 @Override
840 protected AstNode parseRevokeStatement( DdlTokenStream tokens,
841 AstNode parentNode ) throws ParsingException {
842 return parseStatement(tokens, STMT_REVOKE, parentNode, TYPE_REVOKE_STATEMENT);
843 }
844
845 @Override
846 protected AstNode parseAlterTableStatement( DdlTokenStream tokens,
847 AstNode parentNode ) throws ParsingException {
848 assert tokens != null;
849 assert parentNode != null;
850
851 if (tokens.matches("ALTER", "TABLE", DdlTokenStream.ANY_VALUE, "ADD")) {
852
853
854
855
856
857 markStartOfStatement(tokens);
858
859 tokens.consume(ALTER, TABLE);
860
861 String tableName = parseName(tokens);
862
863 AstNode alterTableNode = nodeFactory().node(tableName, parentNode, TYPE_ALTER_TABLE_STATEMENT);
864
865 tokens.consume("ADD");
866
867
868
869 if (isTableConstraint(tokens)) {
870 parseTableConstraint(tokens, alterTableNode, true);
871 } else {
872
873 if (tokens.matches(L_PAREN, "REF")) {
874
875 tokens.consume(L_PAREN, "REF", L_PAREN);
876 parseName(tokens);
877 tokens.consume(R_PAREN, "WITH", "ROWID", R_PAREN);
878
879 } else if (tokens.matches(L_PAREN, "SCOPE")) {
880
881 tokens.consume(L_PAREN, "SCOPE", "FOR", L_PAREN);
882 parseName(tokens);
883 tokens.consume(R_PAREN, "IS");
884 parseName(tokens);
885 tokens.consume(R_PAREN);
886 } else if (tokens.matches(L_PAREN)) {
887 parseColumns(tokens, alterTableNode, true);
888 } else {
889
890 parseSingleTerminatedColumnDefinition(tokens, alterTableNode, true);
891 }
892 }
893
894 parseUntilTerminator(tokens);
895
896 markEndOfStatement(tokens, alterTableNode);
897
898 return alterTableNode;
899 } else if (tokens.matches("ALTER", "TABLE", DdlTokenStream.ANY_VALUE, "DROP")) {
900 markStartOfStatement(tokens);
901
902 tokens.consume(ALTER, TABLE);
903
904 String tableName = parseName(tokens);
905
906 AstNode alterTableNode = nodeFactory().node(tableName, parentNode, TYPE_ALTER_TABLE_STATEMENT);
907
908 tokens.consume(DROP);
909
910 if (tokens.canConsume("CONSTRAINT")) {
911 String constraintName = parseName(tokens);
912
913 AstNode constraintNode = nodeFactory().node(constraintName, alterTableNode, TYPE_DROP_TABLE_CONSTRAINT_DEFINITION);
914
915 if (tokens.canConsume(DropBehavior.CASCADE)) {
916 constraintNode.setProperty(DROP_BEHAVIOR, DropBehavior.CASCADE);
917 } else if (tokens.canConsume(DropBehavior.RESTRICT)) {
918 constraintNode.setProperty(DROP_BEHAVIOR, DropBehavior.RESTRICT);
919 }
920 } else if (tokens.canConsume("COLUMN")) {
921
922
923
924 String columnName = parseName(tokens);
925
926 AstNode columnNode = nodeFactory().node(columnName, alterTableNode, TYPE_DROP_COLUMN_DEFINITION);
927
928 if (tokens.canConsume(DropBehavior.CASCADE)) {
929 columnNode.setProperty(DROP_BEHAVIOR, DropBehavior.CASCADE);
930 } else if (tokens.canConsume(DropBehavior.RESTRICT)) {
931 columnNode.setProperty(DROP_BEHAVIOR, DropBehavior.RESTRICT);
932 }
933 } else {
934 parseUntilTerminator(tokens);
935 }
936
937 markEndOfStatement(tokens, alterTableNode);
938
939 return alterTableNode;
940 } else if (tokens.matches("ALTER", "TABLE", DdlTokenStream.ANY_VALUE, "RENAME")) {
941
942
943
944 markStartOfStatement(tokens);
945
946 tokens.consume(ALTER, TABLE);
947
948 String oldName = parseName(tokens);
949 AstNode alterTableNode = nodeFactory().node(oldName, parentNode, TYPE_ALTER_TABLE_STATEMENT);
950
951 if (tokens.canConsume("RENAME", "TO")) {
952 String newName = parseName(tokens);
953 alterTableNode.setProperty(NEW_NAME, newName);
954
955 parseUntilTerminator(tokens);
956
957 } else if (tokens.canConsume("RENAME", "COLUMN")) {
958 String oldColumnName = parseName(tokens);
959 tokens.consume("TO");
960 String newColumnName = parseName(tokens);
961
962 parseUntilTerminator(tokens);
963
964 AstNode renameColumnNode = nodeFactory().node(oldColumnName, alterTableNode, TYPE_RENAME_COLUMN);
965 renameColumnNode.setProperty(NEW_NAME, newColumnName);
966
967 } else if (tokens.canConsume("RENAME", "CONSTRAINT")) {
968 String oldConstraintName = parseName(tokens);
969 tokens.consume("TO");
970 String newConstraintName = parseName(tokens);
971
972 parseUntilTerminator(tokens);
973
974 AstNode renameColumnNode = nodeFactory().node(oldConstraintName, alterTableNode, TYPE_RENAME_CONSTRAINT);
975 renameColumnNode.setProperty(NEW_NAME, newConstraintName);
976 }
977
978 markEndOfStatement(tokens, alterTableNode);
979
980 return alterTableNode;
981 } else if (tokens.matches("ALTER", "TABLE", DdlTokenStream.ANY_VALUE, "MODIFY")) {
982
983 }
984
985 return super.parseAlterTableStatement(tokens, parentNode);
986 }
987
988 @Override
989 protected AstNode parseAlterStatement( DdlTokenStream tokens,
990 AstNode parentNode ) throws ParsingException {
991 assert tokens != null;
992 assert parentNode != null;
993
994 if (tokens.matches(ALTER, TABLE)) {
995 return parseAlterTableStatement(tokens, parentNode);
996 } else if (tokens.matches(STMT_ALTER_CLUSTER)) {
997 return parseStatement(tokens, STMT_ALTER_CLUSTER, parentNode, TYPE_ALTER_CLUSTER_STATEMENT);
998 } else if (tokens.matches(STMT_ALTER_DATABASE)) {
999
1000
1001 markStartOfStatement(tokens);
1002 tokens.consume(STMT_ALTER_DATABASE);
1003 AstNode result = nodeFactory().node("database", parentNode, TYPE_ALTER_DATABASE_STATEMENT);
1004 tokens.canConsume("RENAME");
1005 parseUntilTerminator(tokens);
1006 markEndOfStatement(tokens, result);
1007 return result;
1008 } else if (tokens.matches(STMT_ALTER_DIMENSION)) {
1009 return parseStatement(tokens, STMT_ALTER_DIMENSION, parentNode, TYPE_ALTER_DIMENSION_STATEMENT);
1010 } else if (tokens.matches(STMT_ALTER_DISKGROUP)) {
1011 return parseStatement(tokens, STMT_ALTER_DISKGROUP, parentNode, TYPE_ALTER_DISKGROUP_STATEMENT);
1012 } else if (tokens.matches(STMT_ALTER_FUNCTION)) {
1013 return parseStatement(tokens, STMT_ALTER_FUNCTION, parentNode, TYPE_ALTER_FUNCTION_STATEMENT);
1014 } else if (tokens.matches(STMT_ALTER_INDEX)) {
1015
1016
1017 markStartOfStatement(tokens);
1018 tokens.consume(ALTER, INDEX);
1019 String indexName = parseName(tokens);
1020 AstNode result = nodeFactory().node(indexName, parentNode, TYPE_ALTER_INDEX_STATEMENT);
1021 tokens.canConsume("RENAME");
1022 parseUntilTerminator(tokens);
1023 markEndOfStatement(tokens, result);
1024 return result;
1025 } else if (tokens.matches(STMT_ALTER_INDEXTYPE)) {
1026 return parseStatement(tokens, STMT_ALTER_INDEXTYPE, parentNode, TYPE_ALTER_INDEXTYPE_STATEMENT);
1027 } else if (tokens.matches(STMT_ALTER_JAVA)) {
1028 return parseStatement(tokens, STMT_ALTER_JAVA, parentNode, TYPE_ALTER_JAVA_STATEMENT);
1029 } else if (tokens.matches(STMT_ALTER_MATERIALIZED)) {
1030 return parseStatement(tokens, STMT_ALTER_MATERIALIZED, parentNode, TYPE_ALTER_MATERIALIZED_STATEMENT);
1031 } else if (tokens.matches(STMT_ALTER_OPERATOR)) {
1032 return parseStatement(tokens, STMT_ALTER_OPERATOR, parentNode, TYPE_ALTER_OPERATOR_STATEMENT);
1033 } else if (tokens.matches(STMT_ALTER_OUTLINE)) {
1034 return parseStatement(tokens, STMT_ALTER_OUTLINE, parentNode, TYPE_ALTER_OUTLINE_STATEMENT);
1035 } else if (tokens.matches(STMT_ALTER_PACKAGE)) {
1036 return parseStatement(tokens, STMT_ALTER_PACKAGE, parentNode, TYPE_ALTER_PACKAGE_STATEMENT);
1037 } else if (tokens.matches(STMT_ALTER_PROCEDURE)) {
1038 return parseStatement(tokens, STMT_ALTER_PROCEDURE, parentNode, TYPE_ALTER_PROCEDURE_STATEMENT);
1039 } else if (tokens.matches(STMT_ALTER_PROFILE)) {
1040 return parseStatement(tokens, STMT_ALTER_PROFILE, parentNode, TYPE_ALTER_PROFILE_STATEMENT);
1041 } else if (tokens.matches(STMT_ALTER_RESOURCE)) {
1042 return parseStatement(tokens, STMT_ALTER_RESOURCE, parentNode, TYPE_ALTER_RESOURCE_STATEMENT);
1043 } else if (tokens.matches(STMT_ALTER_ROLE)) {
1044 return parseStatement(tokens, STMT_ALTER_ROLE, parentNode, TYPE_ALTER_ROLE_STATEMENT);
1045 } else if (tokens.matches(STMT_ALTER_ROLLBACK)) {
1046 return parseStatement(tokens, STMT_ALTER_ROLLBACK, parentNode, TYPE_ALTER_ROLLBACK_STATEMENT);
1047 } else if (tokens.matches(STMT_ALTER_SEQUENCE)) {
1048 return parseStatement(tokens, STMT_ALTER_SEQUENCE, parentNode, TYPE_ALTER_SEQUENCE_STATEMENT);
1049 } else if (tokens.matches(STMT_ALTER_SESSION)) {
1050 return parseStatement(tokens, STMT_ALTER_SESSION, parentNode, TYPE_ALTER_SESSION_STATEMENT);
1051 } else if (tokens.matches(STMT_ALTER_SYSTEM)) {
1052 return parseStatement(tokens, STMT_ALTER_SYSTEM, parentNode, TYPE_ALTER_SYSTEM_STATEMENT);
1053 } else if (tokens.matches(STMT_ALTER_TABLESPACE)) {
1054 return parseStatement(tokens, STMT_ALTER_TABLESPACE, parentNode, TYPE_ALTER_TABLESPACE_STATEMENT);
1055 } else if (tokens.matches(STMT_ALTER_TRIGGER)) {
1056 return parseStatement(tokens, STMT_ALTER_TRIGGER, parentNode, TYPE_ALTER_TRIGGER_STATEMENT);
1057 } else if (tokens.matches(STMT_ALTER_TYPE)) {
1058 return parseStatement(tokens, STMT_ALTER_TYPE, parentNode, TYPE_ALTER_TYPE_STATEMENT);
1059 } else if (tokens.matches(STMT_ALTER_USER)) {
1060
1061
1062 markStartOfStatement(tokens);
1063 tokens.consume(STMT_ALTER_USER);
1064 String name = parseName(tokens);
1065 AstNode result = nodeFactory().node(name, parentNode, TYPE_ALTER_USER_STATEMENT);
1066 tokens.canConsume("GRANT");
1067 parseUntilTerminator(tokens);
1068 markEndOfStatement(tokens, result);
1069 return result;
1070 } else if (tokens.matches(STMT_ALTER_VIEW)) {
1071 return parseStatement(tokens, STMT_ALTER_VIEW, parentNode, TYPE_ALTER_VIEW_STATEMENT);
1072 }
1073
1074 return super.parseAlterStatement(tokens, parentNode);
1075 }
1076
1077
1078
1079
1080
1081
1082
1083 @Override
1084 protected AstNode parseCreateViewStatement( DdlTokenStream tokens,
1085 AstNode parentNode ) throws ParsingException {
1086 assert tokens != null;
1087 assert parentNode != null;
1088
1089 markStartOfStatement(tokens);
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108 String stmtType = "CREATE";
1109 tokens.consume("CREATE");
1110 if (tokens.canConsume("OR", "REPLACE")) {
1111 stmtType = stmtType + SPACE + "OR REPLACE";
1112 } else if (tokens.canConsume("NO", "FORCE")) {
1113 stmtType = stmtType + SPACE + "NO FORCE";
1114 } else if (tokens.canConsume("FORCE")) {
1115 stmtType = stmtType + SPACE + "FORCE";
1116 }
1117
1118 tokens.consume("VIEW");
1119 stmtType = stmtType + SPACE + "VIEW";
1120
1121 String name = parseName(tokens);
1122
1123 AstNode createViewNode = nodeFactory().node(name, parentNode, TYPE_CREATE_VIEW_STATEMENT);
1124
1125
1126 parseColumnNameList(tokens, createViewNode, TYPE_COLUMN_REFERENCE);
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151 if (tokens.matches("OF")) {
1152 do {
1153 tokens.consume();
1154 } while (!tokens.matches("AS"));
1155 }
1156
1157 tokens.consume("AS");
1158
1159 String queryExpression = parseUntilTerminator(tokens);
1160
1161 createViewNode.setProperty(CREATE_VIEW_QUERY_EXPRESSION, queryExpression);
1162
1163 markEndOfStatement(tokens, createViewNode);
1164
1165 return createViewNode;
1166 }
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176 private AstNode parseCreateIndex( DdlTokenStream tokens,
1177 AstNode parentNode ) throws ParsingException {
1178 assert tokens != null;
1179 assert parentNode != null;
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215 return parseStatement(tokens, STMT_CREATE_INDEX, parentNode, TYPE_CREATE_INDEX_STATEMENT);
1216 }
1217
1218 private AstNode parseCommentStatement( DdlTokenStream tokens,
1219 AstNode parentNode ) throws ParsingException {
1220 assert tokens != null;
1221 assert parentNode != null;
1222
1223 markStartOfStatement(tokens);
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241 tokens.consume("COMMENT");
1242 tokens.consume("ON");
1243 String obj = tokens.consume();
1244 String objName = parseName(tokens);
1245
1246
1247 String commentString = null;
1248
1249 tokens.consume("IS");
1250 if (tokens.matches("NULL")) {
1251 tokens.consume("NULL");
1252 commentString = "NULL";
1253 } else {
1254 commentString = parseUntilTerminator(tokens).trim();
1255 }
1256
1257 AstNode commentNode = nodeFactory().node(objName, parentNode, TYPE_COMMENT_ON_STATEMENT);
1258 commentNode.setProperty(OracleDdlLexicon.COMMENT, commentString);
1259 commentNode.setProperty(OracleDdlLexicon.TARGET_OBJECT_TYPE, obj);
1260
1261 markEndOfStatement(tokens, commentNode);
1262
1263 return commentNode;
1264 }
1265
1266 @Override
1267 protected AstNode parseSetStatement( DdlTokenStream tokens,
1268 AstNode parentNode ) throws ParsingException {
1269 assert tokens != null;
1270 assert parentNode != null;
1271
1272 if (tokens.matches(STMT_SET_CONSTRAINT)) {
1273 return parseStatement(tokens, STMT_SET_CONSTRAINT, parentNode, TYPE_SET_CONSTRAINT_STATEMENT);
1274 } else if (tokens.matches(STMT_SET_CONSTRAINTS)) {
1275 return parseStatement(tokens, STMT_SET_CONSTRAINTS, parentNode, TYPE_SET_CONSTRAINTS_STATEMENT);
1276 } else if (tokens.matches(STMT_SET_ROLE)) {
1277 return parseStatement(tokens, STMT_SET_ROLE, parentNode, TYPE_SET_ROLE_STATEMENT);
1278 } else if (tokens.matches(STMT_SET_TRANSACTION)) {
1279 return parseStatement(tokens, STMT_SET_TRANSACTION, parentNode, TYPE_SET_TRANSACTION_STATEMENT);
1280 }
1281
1282 return super.parseSetStatement(tokens, parentNode);
1283 }
1284
1285 @Override
1286 protected AstNode parseDropStatement( DdlTokenStream tokens,
1287 AstNode parentNode ) throws ParsingException {
1288 assert tokens != null;
1289 assert parentNode != null;
1290
1291 AstNode dropNode = null;
1292
1293 if (tokens.matches(StatementStartPhrases.STMT_DROP_TABLE)) {
1294 markStartOfStatement(tokens);
1295
1296
1297
1298 tokens.consume(DROP, TABLE);
1299
1300 String name = parseName(tokens);
1301 dropNode = nodeFactory().node(name, parentNode, TYPE_DROP_TABLE_STATEMENT);
1302
1303 dropNode.setProperty(DROP_OPTION_TYPE, "TABLE");
1304
1305 if (tokens.matchesAnyOf("CASCADE", "RESTRICT")) {
1306 StringBuffer sb = new StringBuffer();
1307
1308 if (tokens.canConsume("CASCADE")) {
1309 sb.append("CASCADE");
1310 tokens.consume("CONSTRAINTS");
1311 sb.append(SPACE).append("CONSTRAINTS");
1312 AstNode optionNode = nodeFactory().node("OPTION", dropNode, StandardDdlLexicon.DROP_OPTION_TYPE);
1313 optionNode.setProperty(StandardDdlLexicon.NAME, "CASCADE OR RESTRICT");
1314 optionNode.setProperty(StandardDdlLexicon.VALUE, sb.toString());
1315 } else {
1316 tokens.consume("RESTRICT");
1317 sb.append("RESTRICT");
1318 tokens.consume("CONSTRAINTS");
1319 sb.append(SPACE).append("CONSTRAINTS");
1320 AstNode optionNode = nodeFactory().node("OPTION", dropNode, StandardDdlLexicon.DROP_OPTION_TYPE);
1321 optionNode.setProperty(StandardDdlLexicon.NAME, "CASCADE OR RESTRICT");
1322 optionNode.setProperty(StandardDdlLexicon.VALUE, sb.toString());
1323 }
1324
1325 }
1326
1327 if (tokens.canConsume("PURGE")) {
1328 AstNode optionNode = nodeFactory().node("OPTION", dropNode, StandardDdlLexicon.DROP_OPTION_TYPE);
1329 optionNode.setProperty(StandardDdlLexicon.NAME, "PURGE");
1330 optionNode.setProperty(StandardDdlLexicon.VALUE, "PURGE");
1331 }
1332
1333 markEndOfStatement(tokens, dropNode);
1334
1335 return dropNode;
1336 } else if (tokens.matches(STMT_DROP_CLUSTER)) {
1337 return parseStatement(tokens, STMT_DROP_CLUSTER, parentNode, TYPE_DROP_CLUSTER_STATEMENT);
1338 } else if (tokens.matches(STMT_DROP_CONTEXT)) {
1339 return parseStatement(tokens, STMT_DROP_CONTEXT, parentNode, TYPE_DROP_CONTEXT_STATEMENT);
1340 } else if (tokens.matches(STMT_DROP_DATABASE)) {
1341 return parseStatement(tokens, STMT_DROP_DATABASE, parentNode, TYPE_DROP_DATABASE_STATEMENT);
1342 } else if (tokens.matches(STMT_DROP_PUBLIC_DATABASE)) {
1343 return parseStatement(tokens, STMT_DROP_PUBLIC_DATABASE, parentNode, TYPE_DROP_DATABASE_STATEMENT);
1344 } else if (tokens.matches(STMT_DROP_DIMENSION)) {
1345 return parseStatement(tokens, STMT_DROP_DIMENSION, parentNode, TYPE_DROP_DIMENSION_STATEMENT);
1346 } else if (tokens.matches(STMT_DROP_DIRECTORY)) {
1347 return parseStatement(tokens, STMT_DROP_DIRECTORY, parentNode, TYPE_DROP_DIRECTORY_STATEMENT);
1348 } else if (tokens.matches(STMT_DROP_DISKGROUP)) {
1349 return parseStatement(tokens, STMT_DROP_DISKGROUP, parentNode, TYPE_DROP_DISKGROUP_STATEMENT);
1350 } else if (tokens.matches(STMT_DROP_FUNCTION)) {
1351 return parseStatement(tokens, STMT_DROP_FUNCTION, parentNode, TYPE_DROP_FUNCTION_STATEMENT);
1352 } else if (tokens.matches(STMT_DROP_INDEX)) {
1353 return parseStatement(tokens, STMT_DROP_INDEX, parentNode, TYPE_DROP_INDEX_STATEMENT);
1354 } else if (tokens.matches(STMT_DROP_INDEXTYPE)) {
1355 return parseStatement(tokens, STMT_DROP_INDEXTYPE, parentNode, TYPE_DROP_INDEXTYPE_STATEMENT);
1356 } else if (tokens.matches(STMT_DROP_JAVA)) {
1357 return parseStatement(tokens, STMT_DROP_JAVA, parentNode, TYPE_DROP_JAVA_STATEMENT);
1358 } else if (tokens.matches(STMT_DROP_LIBRARY)) {
1359 return parseStatement(tokens, STMT_DROP_LIBRARY, parentNode, TYPE_DROP_LIBRARY_STATEMENT);
1360 } else if (tokens.matches(STMT_DROP_MATERIALIZED)) {
1361 return parseStatement(tokens, STMT_DROP_MATERIALIZED, parentNode, TYPE_DROP_MATERIALIZED_STATEMENT);
1362 } else if (tokens.matches(STMT_DROP_OPERATOR)) {
1363 return parseStatement(tokens, STMT_DROP_OPERATOR, parentNode, TYPE_DROP_OPERATOR_STATEMENT);
1364 } else if (tokens.matches(STMT_DROP_OUTLINE)) {
1365 return parseStatement(tokens, STMT_DROP_OUTLINE, parentNode, TYPE_DROP_OUTLINE_STATEMENT);
1366 } else if (tokens.matches(STMT_DROP_PACKAGE)) {
1367 return parseStatement(tokens, STMT_DROP_PACKAGE, parentNode, TYPE_DROP_PACKAGE_STATEMENT);
1368 } else if (tokens.matches(STMT_DROP_PROCEDURE)) {
1369 return parseStatement(tokens, STMT_DROP_PROCEDURE, parentNode, TYPE_DROP_PROCEDURE_STATEMENT);
1370 } else if (tokens.matches(STMT_DROP_PROFILE)) {
1371 return parseStatement(tokens, STMT_DROP_PROFILE, parentNode, TYPE_DROP_PROFILE_STATEMENT);
1372 } else if (tokens.matches(STMT_DROP_ROLE)) {
1373 return parseStatement(tokens, STMT_DROP_ROLE, parentNode, TYPE_DROP_ROLE_STATEMENT);
1374 } else if (tokens.matches(STMT_DROP_ROLLBACK)) {
1375 return parseStatement(tokens, STMT_DROP_ROLLBACK, parentNode, TYPE_DROP_ROLLBACK_STATEMENT);
1376 } else if (tokens.matches(STMT_DROP_SEQUENCE)) {
1377 return parseStatement(tokens, STMT_DROP_SEQUENCE, parentNode, TYPE_DROP_SEQUENCE_STATEMENT);
1378 } else if (tokens.matches(STMT_DROP_SYNONYM)) {
1379 return parseStatement(tokens, STMT_DROP_SYNONYM, parentNode, TYPE_DROP_SYNONYM_STATEMENT);
1380 } else if (tokens.matches(STMT_DROP_PUBLIC_SYNONYM)) {
1381 return parseStatement(tokens, STMT_DROP_PUBLIC_SYNONYM, parentNode, TYPE_DROP_SYNONYM_STATEMENT);
1382 } else if (tokens.matches(STMT_DROP_TABLESPACE)) {
1383 return parseStatement(tokens, STMT_DROP_TABLESPACE, parentNode, TYPE_DROP_TABLESPACE_STATEMENT);
1384 } else if (tokens.matches(STMT_DROP_TRIGGER)) {
1385 return parseStatement(tokens, STMT_DROP_TRIGGER, parentNode, TYPE_DROP_TRIGGER_STATEMENT);
1386 } else if (tokens.matches(STMT_DROP_TYPE)) {
1387 return parseStatement(tokens, STMT_DROP_TYPE, parentNode, TYPE_DROP_TYPE_STATEMENT);
1388 } else if (tokens.matches(STMT_DROP_USER)) {
1389 return parseStatement(tokens, STMT_DROP_USER, parentNode, TYPE_DROP_USER_STATEMENT);
1390 }
1391
1392 return super.parseDropStatement(tokens, parentNode);
1393 }
1394
1395 private AstNode parseCreateJavaStatement( DdlTokenStream tokens,
1396 AstNode parentNode ) throws ParsingException {
1397 assert tokens != null;
1398 assert parentNode != null;
1399
1400 markStartOfStatement(tokens);
1401 tokens.consume(STMT_CREATE_JAVA);
1402 AstNode result = nodeFactory().node(getStatementTypeName(STMT_CREATE_JAVA), parentNode, TYPE_CREATE_JAVA_STATEMENT);
1403
1404
1405
1406
1407
1408
1409 int iParen = 0;
1410
1411 while (tokens.hasNext()) {
1412 if (tokens.matches('{')) {
1413 iParen++;
1414 } else if (tokens.matches('}')) {
1415 iParen--;
1416 }
1417 tokens.consume();
1418
1419 if (isTerminator(tokens) && iParen == 0) {
1420 break;
1421 }
1422 }
1423
1424 markEndOfStatement(tokens, result);
1425
1426 return result;
1427 }
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437 protected void parseColumns( DdlTokenStream tokens,
1438 AstNode tableNode,
1439 boolean isAlterTable ) throws ParsingException {
1440 assert tokens != null;
1441 assert tableNode != null;
1442
1443
1444
1445
1446
1447 String tableElementString = getTableElementsString(tokens, false);
1448
1449 DdlTokenStream localTokens = new DdlTokenStream(tableElementString, DdlTokenStream.ddlTokenizer(false), false);
1450
1451 localTokens.start();
1452
1453 StringBuffer unusedTokensSB = new StringBuffer();
1454
1455 do {
1456 if (isColumnDefinitionStart(localTokens)) {
1457 parseColumnDefinition(localTokens, tableNode, true);
1458 } else {
1459
1460
1461 while (localTokens.hasNext() && !localTokens.matches(COMMA)) {
1462 unusedTokensSB.append(SPACE).append(localTokens.consume());
1463 }
1464 }
1465 } while (localTokens.canConsume(COMMA));
1466
1467 if (unusedTokensSB.length() > 0) {
1468 String msg = DdlSequencerI18n.unusedTokensParsingColumnDefinition.text(tableNode.getProperty(StandardDdlLexicon.NAME));
1469 DdlParserProblem problem = new DdlParserProblem(Problems.WARNING, getCurrentMarkedPosition(), msg);
1470 problem.setUnusedSource(unusedTokensSB.toString());
1471 addProblem(problem, tableNode);
1472 }
1473 }
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484 protected AstNode parseSlashedStatement( DdlTokenStream tokens,
1485 String[] stmt_start_phrase,
1486 AstNode parentNode,
1487 Name mixinType ) {
1488 assert tokens != null;
1489 assert stmt_start_phrase != null && stmt_start_phrase.length > 0;
1490 assert parentNode != null;
1491
1492 markStartOfStatement(tokens);
1493 tokens.consume(stmt_start_phrase);
1494 AstNode result = nodeFactory().node(getStatementTypeName(stmt_start_phrase), parentNode, mixinType);
1495
1496 parseUntilFwdSlash(tokens, false);
1497
1498 consumeSlash(tokens);
1499
1500 markEndOfStatement(tokens, result);
1501
1502 return result;
1503 }
1504
1505
1506
1507
1508
1509
1510
1511
1512
1513
1514 private String parseUntilFwdSlash( DdlTokenStream tokens,
1515 boolean stopAtStatementStart ) throws ParsingException {
1516 StringBuffer sb = new StringBuffer();
1517 if (stopAtStatementStart) {
1518 while (tokens.hasNext()
1519
1520 && !tokens.matches(DdlTokenizer.STATEMENT_KEY) && !tokens.matches('/')) {
1521
1522
1523 sb.append(SPACE).append(tokens.consume());
1524 }
1525 } else {
1526 while (tokens.hasNext() && !isFwdSlashedStatement(tokens) && !tokens.matches('/')) {
1527
1528 sb.append(SPACE).append(tokens.consume());
1529 }
1530 }
1531 return sb.toString();
1532 }
1533
1534 private boolean isFwdSlashedStatement( DdlTokenStream tokens ) throws ParsingException {
1535 for (int i = 0; i < SLASHED_STMT_PHRASES.length; i++) {
1536 if (tokens.matches(SLASHED_STMT_PHRASES[i])) {
1537 return true;
1538 }
1539 }
1540
1541 return false;
1542 }
1543
1544 private void consumeSlash( DdlTokenStream tokens ) throws ParsingException {
1545 tokens.canConsume("/");
1546 }
1547
1548
1549
1550
1551
1552
1553 @Override
1554 protected Name[] getValidSchemaChildTypes() {
1555 return VALID_SCHEMA_CHILD_STMTS;
1556 }
1557
1558
1559
1560
1561
1562
1563
1564
1565 class OracleDataTypeParser extends DataTypeParser {
1566
1567
1568
1569
1570
1571 @Override
1572 protected DataType parseCustomType( DdlTokenStream tokens ) throws ParsingException {
1573 DataType dataType = null;
1574 String typeName = null;
1575
1576 if (tokens.matches(OracleDataTypes.DTYPE_BINARY_FLOAT)) {
1577 dataType = new DataType();
1578 typeName = consume(tokens, dataType, true, OracleDataTypes.DTYPE_BINARY_FLOAT);
1579 dataType.setName(typeName);
1580 } else if (tokens.matches(OracleDataTypes.DTYPE_BINARY_DOUBLE)) {
1581 dataType = new DataType();
1582 typeName = consume(tokens, dataType, true, OracleDataTypes.DTYPE_BINARY_DOUBLE);
1583 dataType.setName(typeName);
1584 } else if (tokens.matches(OracleDataTypes.DTYPE_LONG)) {
1585 dataType = new DataType();
1586 typeName = consume(tokens, dataType, true, OracleDataTypes.DTYPE_LONG);
1587 dataType.setName(typeName);
1588 } else if (tokens.matches(OracleDataTypes.DTYPE_LONG_RAW)) {
1589 dataType = new DataType();
1590 typeName = consume(tokens, dataType, true, OracleDataTypes.DTYPE_LONG_RAW);
1591 dataType.setName(typeName);
1592 } else if (tokens.matches(OracleDataTypes.DTYPE_BLOB)) {
1593 dataType = new DataType();
1594 typeName = consume(tokens, dataType, true, OracleDataTypes.DTYPE_BLOB);
1595 dataType.setName(typeName);
1596 } else if (tokens.matches(OracleDataTypes.DTYPE_CLOB)) {
1597 dataType = new DataType();
1598 typeName = consume(tokens, dataType, true, OracleDataTypes.DTYPE_CLOB);
1599 dataType.setName(typeName);
1600 } else if (tokens.matches(OracleDataTypes.DTYPE_NCLOB)) {
1601 dataType = new DataType();
1602 typeName = consume(tokens, dataType, true, OracleDataTypes.DTYPE_NCLOB);
1603 dataType.setName(typeName);
1604 } else if (tokens.matches(OracleDataTypes.DTYPE_BFILE)) {
1605 dataType = new DataType();
1606 typeName = consume(tokens, dataType, true, OracleDataTypes.DTYPE_BFILE);
1607 dataType.setName(typeName);
1608 } else if (tokens.matches(OracleDataTypes.DTYPE_VARCHAR2)) {
1609 dataType = new DataType();
1610
1611 typeName = consume(tokens, dataType, true, OracleDataTypes.DTYPE_VARCHAR2);
1612 consume(tokens, dataType, false, L_PAREN);
1613 long length = parseLong(tokens, dataType);
1614 canConsume(tokens, dataType, true, "BYTE");
1615 canConsume(tokens, dataType, true, "CHAR");
1616 consume(tokens, dataType, false, R_PAREN);
1617 dataType.setName(typeName);
1618 dataType.setLength(length);
1619 } else if (tokens.matches(OracleDataTypes.DTYPE_RAW)) {
1620 dataType = new DataType();
1621 typeName = consume(tokens, dataType, true, OracleDataTypes.DTYPE_RAW);
1622 long length = parseBracketedLong(tokens, dataType);
1623 dataType.setName(typeName);
1624 dataType.setLength(length);
1625 } else if (tokens.matches(OracleDataTypes.DTYPE_NVARCHAR2)) {
1626 dataType = new DataType();
1627 typeName = consume(tokens, dataType, true, OracleDataTypes.DTYPE_NVARCHAR2);
1628 long length = parseBracketedLong(tokens, dataType);
1629 dataType.setName(typeName);
1630 dataType.setLength(length);
1631 } else if (tokens.matches(OracleDataTypes.DTYPE_NUMBER)) {
1632 dataType = new DataType();
1633 typeName = consume(tokens, dataType, true, OracleDataTypes.DTYPE_NUMBER);
1634 int precision = 0;
1635 int scale = 0;
1636 if (tokens.matches(L_PAREN)) {
1637 consume(tokens, dataType, false, L_PAREN);
1638 precision = (int)parseLong(tokens, dataType);
1639 if (canConsume(tokens, dataType, false, COMMA)) {
1640 scale = (int)parseLong(tokens, dataType);
1641 } else {
1642 scale = getDefaultScale();
1643 }
1644 consume(tokens, dataType, false, R_PAREN);
1645 } else {
1646 precision = getDefaultPrecision();
1647 scale = getDefaultScale();
1648 }
1649 dataType.setName(typeName);
1650 dataType.setPrecision(precision);
1651 dataType.setScale(scale);
1652 } else if (tokens.matches(OracleDataTypes.DTYPE_INTERVAL_YEAR)) {
1653
1654
1655 } else if (tokens.matches(OracleDataTypes.DTYPE_INTERVAL_DAY)) {
1656
1657 }
1658
1659 if (dataType == null) {
1660 dataType = super.parseCustomType(tokens);
1661 }
1662
1663 return dataType;
1664 }
1665
1666
1667
1668
1669
1670
1671
1672 @Override
1673 protected DataType parseCharStringType( DdlTokenStream tokens ) throws ParsingException {
1674 DataType dataType = null;
1675
1676 if (tokens.matches(OracleDataTypes.DTYPE_CHAR_ORACLE)) {
1677 dataType = new DataType();
1678 String typeName = consume(tokens, dataType, true, OracleDataTypes.DTYPE_CHAR_ORACLE);
1679 consume(tokens, dataType, false, L_PAREN);
1680 long length = parseLong(tokens, dataType);
1681 canConsume(tokens, dataType, true, "BYTE");
1682 canConsume(tokens, dataType, true, "CHAR");
1683 consume(tokens, dataType, false, R_PAREN);
1684 dataType.setName(typeName);
1685 dataType.setLength(length);
1686 } else {
1687 dataType = super.parseCharStringType(tokens);
1688 }
1689
1690 return dataType;
1691 }
1692
1693
1694
1695
1696
1697
1698 @Override
1699 protected boolean isCustomDataType( DdlTokenStream tokens ) throws ParsingException {
1700 for (String[] stmt : oracleDataTypeStrings) {
1701 if (tokens.matches(stmt)) return true;
1702 }
1703
1704 return false;
1705 }
1706
1707 }
1708
1709
1710
1711
1712
1713
1714 @Override
1715 protected List<String> getCustomDataTypeStartWords() {
1716 return OracleDataTypes.CUSTOM_DATATYPE_START_WORDS;
1717 }
1718 }