View Javadoc
1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one or more
3    * contributor license agreements.  See the NOTICE file distributed with
4    * this work for additional information regarding copyright ownership.
5    * The ASF licenses this file to You under the Apache License, Version 2.0
6    * (the "License"); you may not use this file except in compliance with
7    * the License.  You may obtain a copy of the License at
8    *
9    *     http://www.apache.org/licenses/LICENSE-2.0
10   *
11   * Unless required by applicable law or agreed to in writing, software
12   * distributed under the License is distributed on an "AS IS" BASIS,
13   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14   * See the License for the specific language governing permissions and
15   * limitations under the License.
16   */
17  
18  package org.apache.shardingsphere.sql.parser.oracle.visitor.statement;
19  
20  import lombok.Getter;
21  import org.antlr.v4.runtime.ParserRuleContext;
22  import org.antlr.v4.runtime.Token;
23  import org.antlr.v4.runtime.misc.Interval;
24  import org.antlr.v4.runtime.tree.TerminalNode;
25  import org.apache.shardingsphere.infra.database.core.metadata.database.enums.NullsOrderType;
26  import org.apache.shardingsphere.sql.parser.api.ASTNode;
27  import org.apache.shardingsphere.sql.parser.autogen.OracleStatementBaseVisitor;
28  import org.apache.shardingsphere.sql.parser.autogen.OracleStatementParser.AggregationFunctionContext;
29  import org.apache.shardingsphere.sql.parser.autogen.OracleStatementParser.AnalyticFunctionContext;
30  import org.apache.shardingsphere.sql.parser.autogen.OracleStatementParser.ApproxRankContext;
31  import org.apache.shardingsphere.sql.parser.autogen.OracleStatementParser.BitExprContext;
32  import org.apache.shardingsphere.sql.parser.autogen.OracleStatementParser.BitValueLiteralsContext;
33  import org.apache.shardingsphere.sql.parser.autogen.OracleStatementParser.BooleanLiteralsContext;
34  import org.apache.shardingsphere.sql.parser.autogen.OracleStatementParser.BooleanPrimaryContext;
35  import org.apache.shardingsphere.sql.parser.autogen.OracleStatementParser.CaseExpressionContext;
36  import org.apache.shardingsphere.sql.parser.autogen.OracleStatementParser.CaseWhenContext;
37  import org.apache.shardingsphere.sql.parser.autogen.OracleStatementParser.CastFunctionContext;
38  import org.apache.shardingsphere.sql.parser.autogen.OracleStatementParser.CharFunctionContext;
39  import org.apache.shardingsphere.sql.parser.autogen.OracleStatementParser.ColumnNameContext;
40  import org.apache.shardingsphere.sql.parser.autogen.OracleStatementParser.ColumnNamesContext;
41  import org.apache.shardingsphere.sql.parser.autogen.OracleStatementParser.ConstraintNameContext;
42  import org.apache.shardingsphere.sql.parser.autogen.OracleStatementParser.CursorFunctionContext;
43  import org.apache.shardingsphere.sql.parser.autogen.OracleStatementParser.DataTypeContext;
44  import org.apache.shardingsphere.sql.parser.autogen.OracleStatementParser.DataTypeLengthContext;
45  import org.apache.shardingsphere.sql.parser.autogen.OracleStatementParser.DataTypeNameContext;
46  import org.apache.shardingsphere.sql.parser.autogen.OracleStatementParser.DateTimeLiteralsContext;
47  import org.apache.shardingsphere.sql.parser.autogen.OracleStatementParser.DatetimeExprContext;
48  import org.apache.shardingsphere.sql.parser.autogen.OracleStatementParser.ExprContext;
49  import org.apache.shardingsphere.sql.parser.autogen.OracleStatementParser.ExprListContext;
50  import org.apache.shardingsphere.sql.parser.autogen.OracleStatementParser.ExtractFunctionContext;
51  import org.apache.shardingsphere.sql.parser.autogen.OracleStatementParser.FeatureFunctionContext;
52  import org.apache.shardingsphere.sql.parser.autogen.OracleStatementParser.FirstOrLastValueFunctionContext;
53  import org.apache.shardingsphere.sql.parser.autogen.OracleStatementParser.FormatFunctionContext;
54  import org.apache.shardingsphere.sql.parser.autogen.OracleStatementParser.FunctionCallContext;
55  import org.apache.shardingsphere.sql.parser.autogen.OracleStatementParser.FunctionContext;
56  import org.apache.shardingsphere.sql.parser.autogen.OracleStatementParser.HexadecimalLiteralsContext;
57  import org.apache.shardingsphere.sql.parser.autogen.OracleStatementParser.IdentifierContext;
58  import org.apache.shardingsphere.sql.parser.autogen.OracleStatementParser.IndexNameContext;
59  import org.apache.shardingsphere.sql.parser.autogen.OracleStatementParser.IndexTypeNameContext;
60  import org.apache.shardingsphere.sql.parser.autogen.OracleStatementParser.IntervalDayToSecondExpressionContext;
61  import org.apache.shardingsphere.sql.parser.autogen.OracleStatementParser.IntervalExpressionContext;
62  import org.apache.shardingsphere.sql.parser.autogen.OracleStatementParser.IntervalYearToMonthExpressionContext;
63  import org.apache.shardingsphere.sql.parser.autogen.OracleStatementParser.LiteralsContext;
64  import org.apache.shardingsphere.sql.parser.autogen.OracleStatementParser.NullValueLiteralsContext;
65  import org.apache.shardingsphere.sql.parser.autogen.OracleStatementParser.NumberLiteralsContext;
66  import org.apache.shardingsphere.sql.parser.autogen.OracleStatementParser.OrderByClauseContext;
67  import org.apache.shardingsphere.sql.parser.autogen.OracleStatementParser.OrderByItemContext;
68  import org.apache.shardingsphere.sql.parser.autogen.OracleStatementParser.OwnerContext;
69  import org.apache.shardingsphere.sql.parser.autogen.OracleStatementParser.PackageNameContext;
70  import org.apache.shardingsphere.sql.parser.autogen.OracleStatementParser.ParameterMarkerContext;
71  import org.apache.shardingsphere.sql.parser.autogen.OracleStatementParser.PredicateContext;
72  import org.apache.shardingsphere.sql.parser.autogen.OracleStatementParser.PrivateExprOfDbContext;
73  import org.apache.shardingsphere.sql.parser.autogen.OracleStatementParser.RegularFunctionContext;
74  import org.apache.shardingsphere.sql.parser.autogen.OracleStatementParser.SchemaNameContext;
75  import org.apache.shardingsphere.sql.parser.autogen.OracleStatementParser.SetFunctionContext;
76  import org.apache.shardingsphere.sql.parser.autogen.OracleStatementParser.SimpleExprContext;
77  import org.apache.shardingsphere.sql.parser.autogen.OracleStatementParser.SpecialFunctionContext;
78  import org.apache.shardingsphere.sql.parser.autogen.OracleStatementParser.StringLiteralsContext;
79  import org.apache.shardingsphere.sql.parser.autogen.OracleStatementParser.SynonymNameContext;
80  import org.apache.shardingsphere.sql.parser.autogen.OracleStatementParser.TableNameContext;
81  import org.apache.shardingsphere.sql.parser.autogen.OracleStatementParser.TableNamesContext;
82  import org.apache.shardingsphere.sql.parser.autogen.OracleStatementParser.ToDateFunctionContext;
83  import org.apache.shardingsphere.sql.parser.autogen.OracleStatementParser.TranslateFunctionContext;
84  import org.apache.shardingsphere.sql.parser.autogen.OracleStatementParser.TrimFunctionContext;
85  import org.apache.shardingsphere.sql.parser.autogen.OracleStatementParser.TypeNameContext;
86  import org.apache.shardingsphere.sql.parser.autogen.OracleStatementParser.UnreservedWordContext;
87  import org.apache.shardingsphere.sql.parser.autogen.OracleStatementParser.ViewNameContext;
88  import org.apache.shardingsphere.sql.parser.autogen.OracleStatementParser.WmConcatFunctionContext;
89  import org.apache.shardingsphere.sql.parser.autogen.OracleStatementParser.XmlAggFunctionContext;
90  import org.apache.shardingsphere.sql.parser.autogen.OracleStatementParser.XmlCdataFunctionContext;
91  import org.apache.shardingsphere.sql.parser.autogen.OracleStatementParser.XmlColattvalFunctionContext;
92  import org.apache.shardingsphere.sql.parser.autogen.OracleStatementParser.XmlElementFunctionContext;
93  import org.apache.shardingsphere.sql.parser.autogen.OracleStatementParser.XmlExistsFunctionContext;
94  import org.apache.shardingsphere.sql.parser.autogen.OracleStatementParser.XmlForestFunctionContext;
95  import org.apache.shardingsphere.sql.parser.autogen.OracleStatementParser.XmlFunctionContext;
96  import org.apache.shardingsphere.sql.parser.autogen.OracleStatementParser.XmlIsSchemaValidFunctionContext;
97  import org.apache.shardingsphere.sql.parser.autogen.OracleStatementParser.XmlNamespaceStringAsIdentifierContext;
98  import org.apache.shardingsphere.sql.parser.autogen.OracleStatementParser.XmlNamespacesClauseContext;
99  import org.apache.shardingsphere.sql.parser.autogen.OracleStatementParser.XmlParseFunctionContext;
100 import org.apache.shardingsphere.sql.parser.autogen.OracleStatementParser.XmlPiFunctionContext;
101 import org.apache.shardingsphere.sql.parser.autogen.OracleStatementParser.XmlQueryFunctionContext;
102 import org.apache.shardingsphere.sql.parser.autogen.OracleStatementParser.XmlRootFunctionContext;
103 import org.apache.shardingsphere.sql.parser.autogen.OracleStatementParser.XmlSerializeFunctionContext;
104 import org.apache.shardingsphere.sql.parser.autogen.OracleStatementParser.XmlTableColumnContext;
105 import org.apache.shardingsphere.sql.parser.autogen.OracleStatementParser.XmlTableFunctionContext;
106 import org.apache.shardingsphere.sql.parser.autogen.OracleStatementParser.XmlTableOptionsContext;
107 import org.apache.shardingsphere.sql.parser.sql.common.enums.AggregationType;
108 import org.apache.shardingsphere.sql.parser.sql.common.enums.OrderDirection;
109 import org.apache.shardingsphere.sql.parser.sql.common.enums.ParameterMarkerType;
110 import org.apache.shardingsphere.sql.parser.sql.common.enums.SequenceFunction;
111 import org.apache.shardingsphere.sql.parser.sql.common.segment.ddl.constraint.ConstraintSegment;
112 import org.apache.shardingsphere.sql.parser.sql.common.segment.ddl.index.IndexNameSegment;
113 import org.apache.shardingsphere.sql.parser.sql.common.segment.ddl.index.IndexSegment;
114 import org.apache.shardingsphere.sql.parser.sql.common.segment.ddl.index.IndexTypeSegment;
115 import org.apache.shardingsphere.sql.parser.sql.common.segment.ddl.packages.PackageSegment;
116 import org.apache.shardingsphere.sql.parser.sql.common.segment.ddl.type.TypeSegment;
117 import org.apache.shardingsphere.sql.parser.sql.common.segment.dml.column.ColumnSegment;
118 import org.apache.shardingsphere.sql.parser.sql.common.segment.dml.expr.BetweenExpression;
119 import org.apache.shardingsphere.sql.parser.sql.common.segment.dml.expr.BinaryOperationExpression;
120 import org.apache.shardingsphere.sql.parser.sql.common.segment.dml.expr.CaseWhenExpression;
121 import org.apache.shardingsphere.sql.parser.sql.common.segment.dml.expr.ExpressionSegment;
122 import org.apache.shardingsphere.sql.parser.sql.common.segment.dml.expr.FunctionSegment;
123 import org.apache.shardingsphere.sql.parser.sql.common.segment.dml.expr.InExpression;
124 import org.apache.shardingsphere.sql.parser.sql.common.segment.dml.expr.ListExpression;
125 import org.apache.shardingsphere.sql.parser.sql.common.segment.dml.expr.NotExpression;
126 import org.apache.shardingsphere.sql.parser.sql.common.segment.dml.expr.complex.CommonExpressionSegment;
127 import org.apache.shardingsphere.sql.parser.sql.common.segment.dml.expr.simple.LiteralExpressionSegment;
128 import org.apache.shardingsphere.sql.parser.sql.common.segment.dml.expr.simple.ParameterMarkerExpressionSegment;
129 import org.apache.shardingsphere.sql.parser.sql.common.segment.dml.expr.subquery.SubqueryExpressionSegment;
130 import org.apache.shardingsphere.sql.parser.sql.common.segment.dml.expr.subquery.SubquerySegment;
131 import org.apache.shardingsphere.sql.parser.sql.common.segment.dml.item.AggregationDistinctProjectionSegment;
132 import org.apache.shardingsphere.sql.parser.sql.common.segment.dml.item.AggregationProjectionSegment;
133 import org.apache.shardingsphere.sql.parser.sql.common.segment.dml.item.ExpressionProjectionSegment;
134 import org.apache.shardingsphere.sql.parser.sql.common.segment.dml.item.IntervalExpressionProjection;
135 import org.apache.shardingsphere.sql.parser.sql.common.segment.dml.order.OrderBySegment;
136 import org.apache.shardingsphere.sql.parser.sql.common.segment.dml.order.item.ColumnOrderByItemSegment;
137 import org.apache.shardingsphere.sql.parser.sql.common.segment.dml.order.item.ExpressionOrderByItemSegment;
138 import org.apache.shardingsphere.sql.parser.sql.common.segment.dml.order.item.IndexOrderByItemSegment;
139 import org.apache.shardingsphere.sql.parser.sql.common.segment.dml.order.item.OrderByItemSegment;
140 import org.apache.shardingsphere.sql.parser.sql.common.segment.generic.DataTypeLengthSegment;
141 import org.apache.shardingsphere.sql.parser.sql.common.segment.generic.DataTypeSegment;
142 import org.apache.shardingsphere.sql.parser.sql.common.segment.generic.OwnerSegment;
143 import org.apache.shardingsphere.sql.parser.sql.common.segment.generic.ParameterMarkerSegment;
144 import org.apache.shardingsphere.sql.parser.sql.common.segment.generic.table.SimpleTableSegment;
145 import org.apache.shardingsphere.sql.parser.sql.common.segment.generic.table.TableNameSegment;
146 import org.apache.shardingsphere.sql.parser.sql.common.statement.SQLStatement;
147 import org.apache.shardingsphere.sql.parser.sql.common.util.SQLUtils;
148 import org.apache.shardingsphere.sql.parser.sql.common.value.collection.CollectionValue;
149 import org.apache.shardingsphere.sql.parser.sql.common.value.identifier.IdentifierValue;
150 import org.apache.shardingsphere.sql.parser.sql.common.value.keyword.KeywordValue;
151 import org.apache.shardingsphere.sql.parser.sql.common.value.literal.impl.BooleanLiteralValue;
152 import org.apache.shardingsphere.sql.parser.sql.common.value.literal.impl.DateTimeLiteralValue;
153 import org.apache.shardingsphere.sql.parser.sql.common.value.literal.impl.NullLiteralValue;
154 import org.apache.shardingsphere.sql.parser.sql.common.value.literal.impl.NumberLiteralValue;
155 import org.apache.shardingsphere.sql.parser.sql.common.value.literal.impl.OtherLiteralValue;
156 import org.apache.shardingsphere.sql.parser.sql.common.value.literal.impl.StringLiteralValue;
157 import org.apache.shardingsphere.sql.parser.sql.common.value.parametermarker.ParameterMarkerValue;
158 import org.apache.shardingsphere.sql.parser.sql.dialect.segment.oracle.datetime.DatetimeExpression;
159 import org.apache.shardingsphere.sql.parser.sql.dialect.segment.oracle.interval.IntervalDayToSecondExpression;
160 import org.apache.shardingsphere.sql.parser.sql.dialect.segment.oracle.interval.IntervalYearToMonthExpression;
161 import org.apache.shardingsphere.sql.parser.sql.dialect.segment.oracle.join.OuterJoinExpression;
162 import org.apache.shardingsphere.sql.parser.sql.dialect.segment.oracle.multiset.MultisetExpression;
163 import org.apache.shardingsphere.sql.parser.sql.dialect.segment.oracle.xml.XmlElementFunctionSegment;
164 import org.apache.shardingsphere.sql.parser.sql.dialect.segment.oracle.xml.XmlNamespaceStringAsIdentifierSegment;
165 import org.apache.shardingsphere.sql.parser.sql.dialect.segment.oracle.xml.XmlNamespacesClauseSegment;
166 import org.apache.shardingsphere.sql.parser.sql.dialect.segment.oracle.xml.XmlPiFunctionSegment;
167 import org.apache.shardingsphere.sql.parser.sql.dialect.segment.oracle.xml.XmlQueryAndExistsFunctionSegment;
168 import org.apache.shardingsphere.sql.parser.sql.dialect.segment.oracle.xml.XmlSerializeFunctionSegment;
169 import org.apache.shardingsphere.sql.parser.sql.dialect.segment.oracle.xml.XmlTableColumnSegment;
170 import org.apache.shardingsphere.sql.parser.sql.dialect.segment.oracle.xml.XmlTableFunctionSegment;
171 import org.apache.shardingsphere.sql.parser.sql.dialect.segment.oracle.xml.XmlTableOptionsSegment;
172 import org.apache.shardingsphere.sql.parser.sql.dialect.statement.oracle.dml.OracleSelectStatement;
173 import org.apache.shardingsphere.sql.parser.sql.dialect.statement.oracle.plsql.CursorForLoopStatementSegment;
174 import org.apache.shardingsphere.sql.parser.sql.dialect.statement.oracle.plsql.ProcedureBodyEndNameSegment;
175 import org.apache.shardingsphere.sql.parser.sql.dialect.statement.oracle.plsql.ProcedureCallNameSegment;
176 import org.apache.shardingsphere.sql.parser.sql.dialect.statement.oracle.plsql.SQLStatementSegment;
177 
178 import java.util.ArrayList;
179 import java.util.Collection;
180 import java.util.Collections;
181 import java.util.HashMap;
182 import java.util.HashSet;
183 import java.util.LinkedList;
184 import java.util.List;
185 import java.util.Map;
186 import java.util.Set;
187 import java.util.stream.Collectors;
188 
189 /**
190  * Statement visitor for Oracle.
191  */
192 @Getter
193 public abstract class OracleStatementVisitor extends OracleStatementBaseVisitor<ASTNode> {
194     
195     private final Collection<ParameterMarkerSegment> globalParameterMarkerSegments = new LinkedList<>();
196     
197     private final Collection<ParameterMarkerSegment> statementParameterMarkerSegments = new LinkedList<>();
198     
199     private final List<SQLStatementSegment> sqlStatementsInPlsql = new ArrayList<>();
200     
201     private final List<ProcedureCallNameSegment> procedureCallNames = new ArrayList<>();
202     
203     private final List<ProcedureBodyEndNameSegment> procedureBodyEndNameSegments = new ArrayList<>();
204     
205     private final List<ExpressionSegment> dynamicSqlStatementExpressions = new ArrayList<>();
206     
207     private final Collection<String> variableNames = new HashSet<>();
208     
209     private final Map<String, SQLStatement> cursorStatements = new HashMap<>();
210     
211     private final List<CursorForLoopStatementSegment> cursorForLoopStatementSegments = new ArrayList<>();
212     
213     private final Map<Integer, Set<SQLStatement>> tempCursorForLoopStatements = new HashMap<>();
214     
215     private int cursorForLoopLevel;
216     
217     @Override
218     public final ASTNode visitParameterMarker(final ParameterMarkerContext ctx) {
219         return new ParameterMarkerValue(globalParameterMarkerSegments.size(), ParameterMarkerType.QUESTION);
220     }
221     
222     @Override
223     public final ASTNode visitLiterals(final LiteralsContext ctx) {
224         if (null != ctx.stringLiterals()) {
225             return visit(ctx.stringLiterals());
226         }
227         if (null != ctx.numberLiterals()) {
228             return visit(ctx.numberLiterals());
229         }
230         if (null != ctx.hexadecimalLiterals()) {
231             return visit(ctx.hexadecimalLiterals());
232         }
233         if (null != ctx.bitValueLiterals()) {
234             return visit(ctx.bitValueLiterals());
235         }
236         if (null != ctx.booleanLiterals()) {
237             return visit(ctx.booleanLiterals());
238         }
239         if (null != ctx.nullValueLiterals()) {
240             return visit(ctx.nullValueLiterals());
241         }
242         if (null != ctx.dateTimeLiterals()) {
243             return visit(ctx.dateTimeLiterals());
244         }
245         if (null != ctx.intervalLiterals()) {
246             return visit(ctx.intervalLiterals());
247         }
248         if (null != ctx.bindLiterals()) {
249             return visit(ctx.bindLiterals());
250         }
251         throw new IllegalStateException("Literals must have string, number, dateTime, hex, bit, interval, boolean or null.");
252     }
253     
254     @Override
255     public ASTNode visitDateTimeLiterals(final DateTimeLiteralsContext ctx) {
256         if (null != ctx.LBE_()) {
257             return new DateTimeLiteralValue(ctx.identifier().getText(), ((StringLiteralValue) visit(ctx.stringLiterals())).getValue(), true);
258         }
259         String dateTimeType;
260         if (null != ctx.DATE()) {
261             dateTimeType = ctx.DATE().getText();
262         } else if (null != ctx.TIME()) {
263             dateTimeType = ctx.TIME().getText();
264         } else {
265             dateTimeType = ctx.TIMESTAMP().getText();
266         }
267         return new DateTimeLiteralValue(dateTimeType, ((StringLiteralValue) visit(ctx.stringLiterals())).getValue(), false);
268     }
269     
270     @Override
271     public final ASTNode visitStringLiterals(final StringLiteralsContext ctx) {
272         if (null != ctx.STRING_()) {
273             return new StringLiteralValue(ctx.getText());
274         } else {
275             return new StringLiteralValue(ctx.getText().substring(1));
276         }
277     }
278     
279     @Override
280     public final ASTNode visitNumberLiterals(final NumberLiteralsContext ctx) {
281         return new NumberLiteralValue(ctx.getText());
282     }
283     
284     @Override
285     public final ASTNode visitHexadecimalLiterals(final HexadecimalLiteralsContext ctx) {
286         // TODO deal with hexadecimalLiterals
287         return new OtherLiteralValue(ctx.getText());
288     }
289     
290     @Override
291     public final ASTNode visitBitValueLiterals(final BitValueLiteralsContext ctx) {
292         // TODO deal with bitValueLiterals
293         return new OtherLiteralValue(ctx.getText());
294     }
295     
296     @Override
297     public final ASTNode visitBooleanLiterals(final BooleanLiteralsContext ctx) {
298         return new BooleanLiteralValue(ctx.getText());
299     }
300     
301     @Override
302     public final ASTNode visitNullValueLiterals(final NullValueLiteralsContext ctx) {
303         return new NullLiteralValue(ctx.getText());
304     }
305     
306     @Override
307     public final ASTNode visitIdentifier(final IdentifierContext ctx) {
308         UnreservedWordContext unreservedWord = ctx.unreservedWord();
309         return null == unreservedWord ? new IdentifierValue(ctx.getText()) : visit(unreservedWord);
310     }
311     
312     @Override
313     public final ASTNode visitUnreservedWord(final UnreservedWordContext ctx) {
314         return new IdentifierValue(ctx.getText());
315     }
316     
317     @Override
318     public final ASTNode visitSchemaName(final SchemaNameContext ctx) {
319         return visit(ctx.identifier());
320     }
321     
322     @Override
323     public final ASTNode visitSynonymName(final SynonymNameContext ctx) {
324         return visit(ctx.identifier());
325     }
326     
327     @Override
328     public final ASTNode visitTableName(final TableNameContext ctx) {
329         SimpleTableSegment result = new SimpleTableSegment(new TableNameSegment(ctx.name().getStart().getStartIndex(),
330                 ctx.name().getStop().getStopIndex(), new IdentifierValue(ctx.name().identifier().getText())));
331         OwnerContext owner = ctx.owner();
332         if (null != owner) {
333             result.setOwner(new OwnerSegment(owner.getStart().getStartIndex(), owner.getStop().getStopIndex(), (IdentifierValue) visit(owner.identifier())));
334         }
335         return result;
336     }
337     
338     @Override
339     public final ASTNode visitColumnName(final ColumnNameContext ctx) {
340         if (SequenceFunction.valueFrom(ctx.name().getText()).isPresent()) {
341             return createSequenceFunction(ctx);
342         }
343         ColumnSegment result = new ColumnSegment(ctx.getStart().getStartIndex(), ctx.getStop().getStopIndex(), (IdentifierValue) visit(ctx.name()));
344         OwnerContext owner = ctx.owner();
345         if (null != owner) {
346             result.setOwner(new OwnerSegment(owner.getStart().getStartIndex(), owner.getStop().getStopIndex(), (IdentifierValue) visit(owner.identifier())));
347         }
348         if (null != ctx.nestedItem() && !ctx.nestedItem().isEmpty()) {
349             result.setNestedObjectAttributes(ctx.nestedItem().stream().map(item -> (IdentifierValue) visit(item.identifier())).collect(Collectors.toList()));
350         }
351         return result;
352     }
353     
354     private FunctionSegment createSequenceFunction(final ColumnNameContext ctx) {
355         FunctionSegment result = new FunctionSegment(ctx.getStart().getStartIndex(), ctx.getStop().getStopIndex(), ctx.name().getText(), getOriginalText(ctx));
356         OwnerContext owner = ctx.owner();
357         if (null != owner) {
358             result.setOwner(new OwnerSegment(owner.getStart().getStartIndex(), owner.getStop().getStopIndex(), (IdentifierValue) visit(owner.identifier())));
359         }
360         return result;
361     }
362     
363     @Override
364     public final ASTNode visitViewName(final ViewNameContext ctx) {
365         SimpleTableSegment result = new SimpleTableSegment(new TableNameSegment(ctx.name().getStart().getStartIndex(),
366                 ctx.name().getStop().getStopIndex(), new IdentifierValue(ctx.name().identifier().getText())));
367         OwnerContext owner = ctx.owner();
368         if (null != owner) {
369             result.setOwner(new OwnerSegment(owner.getStart().getStartIndex(), owner.getStop().getStopIndex(), (IdentifierValue) visit(owner.identifier())));
370         }
371         return result;
372     }
373     
374     @Override
375     public final ASTNode visitIndexName(final IndexNameContext ctx) {
376         IndexNameSegment indexName = new IndexNameSegment(ctx.start.getStartIndex(), ctx.stop.getStopIndex(), (IdentifierValue) visit(ctx.name()));
377         return new IndexSegment(ctx.getStart().getStartIndex(), ctx.getStop().getStopIndex(), indexName);
378     }
379     
380     @Override
381     public final ASTNode visitFunction(final FunctionContext ctx) {
382         return new FunctionSegment(ctx.getStart().getStartIndex(), ctx.getStop().getStopIndex(), ((IdentifierValue) visit(ctx.name())).getValue(), ctx.getText());
383     }
384     
385     @Override
386     public final ASTNode visitPackageName(final PackageNameContext ctx) {
387         return new PackageSegment(ctx.getStart().getStartIndex(), ctx.getStop().getStopIndex(), (IdentifierValue) visit(ctx.name()));
388     }
389     
390     @Override
391     public final ASTNode visitTypeName(final TypeNameContext ctx) {
392         return new TypeSegment(ctx.getStart().getStartIndex(), ctx.getStop().getStopIndex(), (IdentifierValue) visit(ctx.name()));
393     }
394     
395     @Override
396     public final ASTNode visitIndexTypeName(final IndexTypeNameContext ctx) {
397         return new IndexTypeSegment(ctx.getStart().getStartIndex(), ctx.getStop().getStopIndex(), (IdentifierValue) visit(ctx.name()));
398     }
399     
400     @Override
401     public final ASTNode visitConstraintName(final ConstraintNameContext ctx) {
402         return new ConstraintSegment(ctx.getStart().getStartIndex(), ctx.getStop().getStopIndex(), (IdentifierValue) visit(ctx.identifier()));
403     }
404     
405     @Override
406     public final ASTNode visitTableNames(final TableNamesContext ctx) {
407         CollectionValue<SimpleTableSegment> result = new CollectionValue<>();
408         for (TableNameContext each : ctx.tableName()) {
409             result.getValue().add((SimpleTableSegment) visit(each));
410         }
411         return result;
412     }
413     
414     @Override
415     public final ASTNode visitColumnNames(final ColumnNamesContext ctx) {
416         CollectionValue<ColumnSegment> result = new CollectionValue<>();
417         for (ColumnNameContext each : ctx.columnName()) {
418             result.getValue().add((ColumnSegment) visit(each));
419         }
420         return result;
421     }
422     
423     @Override
424     public final ASTNode visitExpr(final ExprContext ctx) {
425         if (null != ctx.booleanPrimary()) {
426             return visit(ctx.booleanPrimary());
427         }
428         if (null != ctx.LP_()) {
429             return visit(ctx.expr(0));
430         }
431         if (null != ctx.andOperator()) {
432             return createBinaryOperationExpression(ctx, ctx.andOperator().getText());
433         }
434         if (null != ctx.orOperator()) {
435             return createBinaryOperationExpression(ctx, ctx.orOperator().getText());
436         }
437         if (null != ctx.datetimeExpr()) {
438             return createDatetimeExpression(ctx, ctx.datetimeExpr());
439         }
440         if (null != ctx.multisetExpr()) {
441             return createMultisetExpression(ctx);
442         }
443         return new NotExpression(ctx.start.getStartIndex(), ctx.stop.getStopIndex(), (ExpressionSegment) visit(ctx.expr(0)), false);
444     }
445     
446     private ASTNode createMultisetExpression(final ExprContext ctx) {
447         ExpressionSegment left = (ColumnSegment) visitColumnName(ctx.multisetExpr().columnName(0));
448         ExpressionSegment right = (ColumnSegment) visitColumnName(ctx.multisetExpr().columnName(1));
449         String text = ctx.start.getInputStream().getText(new Interval(ctx.start.getStartIndex(), ctx.stop.getStopIndex()));
450         String keyWord = null == ctx.multisetExpr().DISTINCT() ? "ALL" : "DISTINCT";
451         return new MultisetExpression(ctx.start.getStartIndex(), ctx.stop.getStopIndex(), left, right, ctx.multisetExpr().multisetOperator().getText(), keyWord, text);
452     }
453     
454     private ASTNode createDatetimeExpression(final ExprContext ctx, final DatetimeExprContext datetimeExpr) {
455         ExpressionSegment left = (ExpressionSegment) visit(ctx.expr(0));
456         String text = ctx.start.getInputStream().getText(new Interval(ctx.start.getStartIndex(), ctx.stop.getStopIndex()));
457         if (null == datetimeExpr.expr()) {
458             return new DatetimeExpression(ctx.start.getStartIndex(), ctx.stop.getStopIndex(), left, text);
459         }
460         ExpressionSegment right = new ExpressionProjectionSegment(datetimeExpr.getStart().getStartIndex(),
461                 datetimeExpr.getStop().getStopIndex(), datetimeExpr.getText(), (ExpressionSegment) visit(datetimeExpr.expr()));
462         return new DatetimeExpression(ctx.start.getStartIndex(), ctx.stop.getStopIndex(), left, right, text);
463     }
464     
465     private ASTNode createBinaryOperationExpression(final ExprContext ctx, final String operator) {
466         ExpressionSegment left = (ExpressionSegment) visit(ctx.expr(0));
467         ExpressionSegment right = (ExpressionSegment) visit(ctx.expr(1));
468         String text = ctx.start.getInputStream().getText(new Interval(ctx.start.getStartIndex(), ctx.stop.getStopIndex()));
469         return new BinaryOperationExpression(ctx.start.getStartIndex(), ctx.stop.getStopIndex(), left, right, operator, text);
470     }
471     
472     @Override
473     public final ASTNode visitBooleanPrimary(final BooleanPrimaryContext ctx) {
474         if (null != ctx.IS()) {
475             String rightText = "";
476             if (null != ctx.NOT()) {
477                 rightText = rightText.concat(ctx.start.getInputStream().getText(new Interval(ctx.NOT().getSymbol().getStartIndex(), ctx.NOT().getSymbol().getStopIndex()))).concat(" ");
478             }
479             Token operatorToken = null;
480             if (null != ctx.NULL()) {
481                 operatorToken = ctx.NULL().getSymbol();
482             }
483             if (null != ctx.TRUE()) {
484                 operatorToken = ctx.TRUE().getSymbol();
485             }
486             if (null != ctx.FALSE()) {
487                 operatorToken = ctx.FALSE().getSymbol();
488             }
489             int startIndex = null == operatorToken ? ctx.IS().getSymbol().getStopIndex() + 2 : operatorToken.getStartIndex();
490             rightText = rightText.concat(ctx.start.getInputStream().getText(new Interval(startIndex, ctx.stop.getStopIndex())));
491             ExpressionSegment right = new LiteralExpressionSegment(ctx.IS().getSymbol().getStopIndex() + 2, ctx.stop.getStopIndex(), rightText);
492             String text = ctx.start.getInputStream().getText(new Interval(ctx.start.getStartIndex(), ctx.stop.getStopIndex()));
493             ExpressionSegment left = (ExpressionSegment) visit(ctx.booleanPrimary());
494             String operator = "IS";
495             return new BinaryOperationExpression(ctx.start.getStartIndex(), ctx.stop.getStopIndex(), left, right, operator, text);
496         }
497         if (null != ctx.comparisonOperator() || null != ctx.SAFE_EQ_()) {
498             return createCompareSegment(ctx);
499         }
500         return visit(ctx.predicate());
501     }
502     
503     private ASTNode createCompareSegment(final BooleanPrimaryContext ctx) {
504         ExpressionSegment left = (ExpressionSegment) visit(ctx.booleanPrimary());
505         ExpressionSegment right;
506         if (null != ctx.predicate()) {
507             right = (ExpressionSegment) visit(ctx.predicate());
508         } else {
509             right = new SubqueryExpressionSegment(
510                     new SubquerySegment(ctx.subquery().start.getStartIndex(), ctx.subquery().stop.getStopIndex(), (OracleSelectStatement) visit(ctx.subquery()), getOriginalText(ctx.subquery())));
511         }
512         String operator = null == ctx.SAFE_EQ_() ? ctx.comparisonOperator().getText() : ctx.SAFE_EQ_().getText();
513         String text = ctx.start.getInputStream().getText(new Interval(ctx.start.getStartIndex(), ctx.stop.getStopIndex()));
514         return new BinaryOperationExpression(ctx.start.getStartIndex(), ctx.stop.getStopIndex(), left, right, operator, text);
515     }
516     
517     @Override
518     public final ASTNode visitPredicate(final PredicateContext ctx) {
519         if (null != ctx.IN()) {
520             return createInSegment(ctx);
521         }
522         if (null != ctx.BETWEEN()) {
523             return createBetweenSegment(ctx);
524         }
525         if (null != ctx.LIKE()) {
526             return createBinaryOperationExpressionFromLike(ctx);
527         }
528         return visit(ctx.bitExpr(0));
529     }
530     
531     private InExpression createInSegment(final PredicateContext ctx) {
532         ExpressionSegment left = (ExpressionSegment) visit(ctx.bitExpr(0));
533         ExpressionSegment right;
534         if (null == ctx.subquery()) {
535             ListExpression listExpression = new ListExpression(ctx.LP_().getSymbol().getStartIndex(), ctx.RP_().getSymbol().getStopIndex());
536             for (ExprContext each : ctx.expr()) {
537                 listExpression.getItems().add((ExpressionSegment) visit(each));
538             }
539             right = listExpression;
540         } else {
541             right = new SubqueryExpressionSegment(
542                     new SubquerySegment(ctx.subquery().start.getStartIndex(), ctx.subquery().stop.getStopIndex(), (OracleSelectStatement) visit(ctx.subquery()), getOriginalText(ctx.subquery())));
543         }
544         boolean not = null != ctx.NOT();
545         return new InExpression(ctx.start.getStartIndex(), ctx.stop.getStopIndex(), left, right, not);
546     }
547     
548     private BinaryOperationExpression createBinaryOperationExpressionFromLike(final PredicateContext ctx) {
549         ExpressionSegment left = (ExpressionSegment) visit(ctx.bitExpr(0));
550         ListExpression right = new ListExpression(ctx.simpleExpr(0).start.getStartIndex(), ctx.simpleExpr().get(ctx.simpleExpr().size() - 1).stop.getStopIndex());
551         for (SimpleExprContext each : ctx.simpleExpr()) {
552             right.getItems().add((ExpressionSegment) visit(each));
553         }
554         String operator = null == ctx.NOT() ? "LIKE" : "NOT LIKE";
555         String text = ctx.start.getInputStream().getText(new Interval(ctx.start.getStartIndex(), ctx.stop.getStopIndex()));
556         return new BinaryOperationExpression(ctx.start.getStartIndex(), ctx.stop.getStopIndex(), left, right, operator, text);
557     }
558     
559     private BetweenExpression createBetweenSegment(final PredicateContext ctx) {
560         ExpressionSegment left = (ExpressionSegment) visit(ctx.bitExpr(0));
561         ExpressionSegment between = (ExpressionSegment) visit(ctx.bitExpr(1));
562         ExpressionSegment and = (ExpressionSegment) visit(ctx.predicate());
563         boolean not = null != ctx.NOT();
564         return new BetweenExpression(ctx.start.getStartIndex(), ctx.stop.getStopIndex(), left, between, and, not);
565     }
566     
567     @Override
568     public final ASTNode visitBitExpr(final BitExprContext ctx) {
569         if (null != ctx.simpleExpr()) {
570             return createExpressionSegment(visit(ctx.simpleExpr()), ctx);
571         }
572         ExpressionSegment left = (ExpressionSegment) visit(ctx.getChild(0));
573         ExpressionSegment right = (ExpressionSegment) visit(ctx.getChild(2));
574         String operator = ctx.getChild(1).getText();
575         String text = ctx.start.getInputStream().getText(new Interval(ctx.start.getStartIndex(), ctx.stop.getStopIndex()));
576         return new BinaryOperationExpression(ctx.start.getStartIndex(), ctx.stop.getStopIndex(), left, right, operator, text);
577     }
578     
579     private ASTNode createExpressionSegment(final ASTNode astNode, final ParserRuleContext context) {
580         if (astNode instanceof StringLiteralValue) {
581             return new LiteralExpressionSegment(context.start.getStartIndex(), context.stop.getStopIndex(), ((StringLiteralValue) astNode).getValue());
582         }
583         if (astNode instanceof NumberLiteralValue) {
584             return new LiteralExpressionSegment(context.start.getStartIndex(), context.stop.getStopIndex(), ((NumberLiteralValue) astNode).getValue());
585         }
586         if (astNode instanceof BooleanLiteralValue) {
587             return new LiteralExpressionSegment(context.start.getStartIndex(), context.stop.getStopIndex(), ((BooleanLiteralValue) astNode).getValue());
588         }
589         if (astNode instanceof ParameterMarkerValue) {
590             ParameterMarkerValue parameterMarker = (ParameterMarkerValue) astNode;
591             ParameterMarkerExpressionSegment segment = new ParameterMarkerExpressionSegment(context.start.getStartIndex(), context.stop.getStopIndex(),
592                     parameterMarker.getValue(), parameterMarker.getType());
593             globalParameterMarkerSegments.add(segment);
594             statementParameterMarkerSegments.add(segment);
595             return segment;
596         }
597         if (astNode instanceof SubquerySegment) {
598             return new SubqueryExpressionSegment((SubquerySegment) astNode);
599         }
600         if (astNode instanceof OtherLiteralValue) {
601             return new CommonExpressionSegment(context.getStart().getStartIndex(), context.getStop().getStopIndex(), context.getText());
602         }
603         return astNode;
604     }
605     
606     @Override
607     public final ASTNode visitSimpleExpr(final SimpleExprContext ctx) {
608         int startIndex = ctx.getStart().getStartIndex();
609         int stopIndex = ctx.getStop().getStopIndex();
610         if (null != ctx.subquery()) {
611             return new SubquerySegment(startIndex, stopIndex, (OracleSelectStatement) visit(ctx.subquery()), getOriginalText(ctx.subquery()));
612         }
613         if (null != ctx.parameterMarker()) {
614             ParameterMarkerValue parameterMarker = (ParameterMarkerValue) visit(ctx.parameterMarker());
615             ParameterMarkerExpressionSegment segment = new ParameterMarkerExpressionSegment(startIndex, stopIndex, parameterMarker.getValue(), parameterMarker.getType());
616             globalParameterMarkerSegments.add(segment);
617             statementParameterMarkerSegments.add(segment);
618             return segment;
619         }
620         if (null != ctx.literals()) {
621             return SQLUtils.createLiteralExpression(visit(ctx.literals()), startIndex, stopIndex, ctx.literals().start.getInputStream().getText(new Interval(startIndex, stopIndex)));
622         }
623         if (null != ctx.functionCall()) {
624             return visit(ctx.functionCall());
625         }
626         if (null != ctx.columnName()) {
627             return null == ctx.joinOperator() ? visit(ctx.columnName())
628                     : new OuterJoinExpression(startIndex, stopIndex, (ColumnSegment) visitColumnName(ctx.columnName()), ctx.joinOperator().getText());
629         }
630         if (null != ctx.privateExprOfDb()) {
631             return visit(ctx.privateExprOfDb());
632         }
633         if (null != ctx.LP_()) {
634             if (1 == ctx.expr().size()) {
635                 return visit(ctx.expr(0));
636             } else {
637                 ListExpression result = new ListExpression(ctx.LP_().getSymbol().getStartIndex(), ctx.RP_().getSymbol().getStopIndex());
638                 for (ExprContext each : ctx.expr()) {
639                     result.getItems().add((ExpressionSegment) visit(each));
640                 }
641                 return result;
642             }
643         }
644         return visitRemainSimpleExpr(ctx, startIndex, stopIndex);
645     }
646     
647     private ASTNode visitRemainSimpleExpr(final SimpleExprContext ctx, final int startIndex, final int stopIndex) {
648         if (null != ctx.OR_()) {
649             ExpressionSegment left = (ExpressionSegment) visit(ctx.simpleExpr(0));
650             ExpressionSegment right = (ExpressionSegment) visit(ctx.simpleExpr(1));
651             String text = ctx.start.getInputStream().getText(new Interval(ctx.start.getStartIndex(), ctx.stop.getStopIndex()));
652             return new BinaryOperationExpression(ctx.start.getStartIndex(), ctx.stop.getStopIndex(), left, right, ctx.OR_().getText(), text);
653         }
654         if (null != ctx.caseExpression()) {
655             return visit(ctx.caseExpression());
656         }
657         if (null != ctx.BINARY()) {
658             return visit(ctx.simpleExpr(0));
659         }
660         for (SimpleExprContext each : ctx.simpleExpr()) {
661             visit(each);
662         }
663         return new CommonExpressionSegment(startIndex, stopIndex, ctx.getText());
664     }
665     
666     @Override
667     public ASTNode visitCaseExpression(final CaseExpressionContext ctx) {
668         ExpressionSegment caseExpr = null == ctx.simpleExpr() ? null : (ExpressionSegment) visit(ctx.simpleExpr());
669         Collection<ExpressionSegment> whenExprs = new ArrayList<>(ctx.caseWhen().size());
670         Collection<ExpressionSegment> thenExprs = new ArrayList<>(ctx.caseWhen().size());
671         for (CaseWhenContext each : ctx.caseWhen()) {
672             whenExprs.add((ExpressionSegment) visit(each.expr(0)));
673             thenExprs.add((ExpressionSegment) visit(each.expr(1)));
674         }
675         ExpressionSegment elseExpr = null == ctx.caseElse() ? null : (ExpressionSegment) visit(ctx.caseElse().expr());
676         return new CaseWhenExpression(ctx.getStart().getStartIndex(), ctx.getStop().getStopIndex(), caseExpr, whenExprs, thenExprs, elseExpr);
677     }
678     
679     @Override
680     public ASTNode visitPrivateExprOfDb(final PrivateExprOfDbContext ctx) {
681         if (null != ctx.intervalExpression()) {
682             return visit(ctx.intervalExpression());
683         }
684         return super.visitPrivateExprOfDb(ctx);
685     }
686     
687     @Override
688     public ASTNode visitIntervalExpression(final IntervalExpressionContext ctx) {
689         IntervalExpressionProjection result = new IntervalExpressionProjection(ctx.getStart().getStartIndex(), ctx.getStop().getStopIndex(), (ExpressionSegment) visit(ctx.expr(0)),
690                 (ExpressionSegment) visit(ctx.MINUS_()), (ExpressionSegment) visit(ctx.expr(1)), getOriginalText(ctx));
691         if (null != ctx.intervalDayToSecondExpression()) {
692             result.setDayToSecondExpression((IntervalDayToSecondExpression) visit(ctx.intervalDayToSecondExpression()));
693         } else {
694             result.setYearToMonthExpression((IntervalYearToMonthExpression) visit(ctx.intervalYearToMonthExpression()));
695         }
696         return result;
697     }
698     
699     @Override
700     public ASTNode visitIntervalDayToSecondExpression(final IntervalDayToSecondExpressionContext ctx) {
701         IntervalDayToSecondExpression result = new IntervalDayToSecondExpression(ctx.getStart().getStartIndex(), ctx.getStop().getStopIndex(),
702                 ctx.DAY().getText(), ctx.TO().getText(), ctx.SECOND().getText());
703         if (null != ctx.leadingFieldPrecision()) {
704             result.setLeadingFieldPrecision(Integer.parseInt(ctx.leadingFieldPrecision().INTEGER_().getText()));
705         }
706         if (null != ctx.fractionalSecondPrecision()) {
707             result.setFractionalSecondPrecision(Integer.parseInt(ctx.fractionalSecondPrecision().getText()));
708         }
709         return result;
710     }
711     
712     @Override
713     public ASTNode visitIntervalYearToMonthExpression(final IntervalYearToMonthExpressionContext ctx) {
714         IntervalYearToMonthExpression result = new IntervalYearToMonthExpression(ctx.getStart().getStartIndex(), ctx.getStop().getStopIndex(),
715                 ctx.YEAR().getText(), ctx.TO().getText(), ctx.MONTH().getText());
716         if (null != ctx.leadingFieldPrecision()) {
717             result.setLeadingFieldPrecision(Integer.parseInt(ctx.leadingFieldPrecision().INTEGER_().getText()));
718         }
719         return result;
720     }
721     
722     @Override
723     public final ASTNode visitFunctionCall(final FunctionCallContext ctx) {
724         if (null != ctx.aggregationFunction()) {
725             return visit(ctx.aggregationFunction());
726         }
727         if (null != ctx.specialFunction()) {
728             return visit(ctx.specialFunction());
729         }
730         if (null != ctx.analyticFunction()) {
731             return visit(ctx.analyticFunction());
732         }
733         if (null != ctx.regularFunction()) {
734             return visit(ctx.regularFunction());
735         }
736         if (null != ctx.xmlFunction()) {
737             return visit(ctx.xmlFunction());
738         }
739         throw new IllegalStateException("FunctionCallContext must have aggregationFunction, regularFunction, analyticFunction or specialFunction.");
740     }
741     
742     @Override
743     public ASTNode visitAnalyticFunction(final AnalyticFunctionContext ctx) {
744         String functionName = null == ctx.analyticFunctionName() ? ctx.specifiedAnalyticFunctionName.getText() : ctx.analyticFunctionName().getText();
745         FunctionSegment result = new FunctionSegment(ctx.getStart().getStartIndex(), ctx.getStop().getStopIndex(), functionName, getOriginalText(ctx));
746         result.getParameters().addAll(getExpressions(ctx.expr()));
747         for (DataTypeContext each : ctx.dataType()) {
748             result.getParameters().add((DataTypeSegment) visit(each));
749         }
750         return result;
751     }
752     
753     @Override
754     public final ASTNode visitAggregationFunction(final AggregationFunctionContext ctx) {
755         String aggregationType = ctx.aggregationFunctionName().getText();
756         return AggregationType.isAggregationType(aggregationType)
757                 ? createAggregationSegment(ctx, aggregationType)
758                 : createAggregationFunctionSegment(ctx, aggregationType);
759     }
760     
761     @Override
762     public ASTNode visitWmConcatFunction(final WmConcatFunctionContext ctx) {
763         FunctionSegment result = new FunctionSegment(ctx.getStart().getStartIndex(), ctx.getStop().getStopIndex(), ctx.WM_CONCAT().getText(), getOriginalText(ctx));
764         result.getParameters().add((ExpressionSegment) visit(ctx.expr()));
765         if (null != ctx.owner()) {
766             OwnerContext owner = ctx.owner();
767             result.setOwner(new OwnerSegment(owner.getStart().getStartIndex(), owner.getStop().getStopIndex(), (IdentifierValue) visit(owner.identifier())));
768         }
769         return result;
770     }
771     
772     private FunctionSegment createAggregationFunctionSegment(final AggregationFunctionContext ctx, final String aggregationType) {
773         FunctionSegment result = new FunctionSegment(ctx.getStart().getStartIndex(), ctx.getStop().getStopIndex(), aggregationType, getOriginalText(ctx));
774         result.getParameters().addAll(getExpressions(ctx.expr()));
775         return result;
776     }
777     
778     private ASTNode createAggregationSegment(final AggregationFunctionContext ctx, final String aggregationType) {
779         AggregationType type = AggregationType.valueOf(aggregationType.toUpperCase());
780         if (null != ctx.DISTINCT()) {
781             AggregationDistinctProjectionSegment result =
782                     new AggregationDistinctProjectionSegment(ctx.getStart().getStartIndex(), ctx.getStop().getStopIndex(), type, getOriginalText(ctx), getDistinctExpression(ctx));
783             result.getParameters().addAll(getExpressions(ctx.expr()));
784             return result;
785         }
786         AggregationProjectionSegment result = new AggregationProjectionSegment(ctx.getStart().getStartIndex(), ctx.getStop().getStopIndex(), type, getOriginalText(ctx));
787         result.getParameters().addAll(getExpressions(ctx.expr()));
788         return result;
789     }
790     
791     @Override
792     public ASTNode visitXmlFunction(final XmlFunctionContext ctx) {
793         if (null != ctx.xmlAggFunction()) {
794             return visit(ctx.xmlAggFunction());
795         }
796         if (null != ctx.xmlColattvalFunction()) {
797             return visit(ctx.xmlColattvalFunction());
798         }
799         if (null != ctx.xmlExistsFunction()) {
800             return visit(ctx.xmlExistsFunction());
801         }
802         if (null != ctx.xmlForestFunction()) {
803             return visit(ctx.xmlForestFunction());
804         }
805         if (null != ctx.xmlParseFunction()) {
806             return visit(ctx.xmlParseFunction());
807         }
808         if (null != ctx.xmlPiFunction()) {
809             return visit(ctx.xmlPiFunction());
810         }
811         if (null != ctx.xmlQueryFunction()) {
812             return visit(ctx.xmlQueryFunction());
813         }
814         if (null != ctx.xmlRootFunction()) {
815             return visit(ctx.xmlRootFunction());
816         }
817         if (null != ctx.xmlSerializeFunction()) {
818             return visit(ctx.xmlSerializeFunction());
819         }
820         if (null != ctx.xmlIsSchemaValidFunction()) {
821             return visit(ctx.xmlIsSchemaValidFunction());
822         }
823         if (null != ctx.xmlTableFunction()) {
824             return visit(ctx.xmlTableFunction());
825         }
826         if (null != ctx.xmlElementFunction()) {
827             return visit(ctx.xmlElementFunction());
828         }
829         FunctionSegment result = new FunctionSegment(ctx.getStart().getStartIndex(), ctx.getStop().getStopIndex(), ctx.specifiedFunctionName.getText(), getOriginalText(ctx));
830         result.getParameters().addAll(getExpressions(ctx.exprList()));
831         return result;
832     }
833     
834     @Override
835     public ASTNode visitXmlElementFunction(final XmlElementFunctionContext ctx) {
836         XmlElementFunctionSegment result =
837                 new XmlElementFunctionSegment(ctx.start.getStartIndex(), ctx.stop.getStopIndex(), ctx.XMLELEMENT().getText(), (IdentifierValue) visit(ctx.identifier()), getOriginalText(ctx));
838         Collection<ExpressionSegment> expressionSegments = ctx.exprWithAlias().stream().map(each -> (ExpressionSegment) visit(each.expr())).collect(Collectors.toList());
839         result.getParameters().addAll(expressionSegments);
840         if (null != ctx.xmlAttributes()) {
841             Collection<ExpressionSegment> xmlAttributes = ctx.xmlAttributes().exprWithAlias().stream().map(each -> (ExpressionSegment) visit(each.expr())).collect(Collectors.toList());
842             result.getXmlAttributes().addAll(xmlAttributes);
843         }
844         return result;
845     }
846     
847     @Override
848     public ASTNode visitXmlCdataFunction(final XmlCdataFunctionContext ctx) {
849         FunctionSegment result = new FunctionSegment(ctx.start.getStartIndex(), ctx.stop.getStopIndex(), ctx.XMLCDATA().getText(), getOriginalText(ctx));
850         result.getParameters().add((ExpressionSegment) visit(ctx.stringLiterals()));
851         return result;
852     }
853     
854     @Override
855     public ASTNode visitXmlAggFunction(final XmlAggFunctionContext ctx) {
856         return new FunctionSegment(ctx.getStart().getStartIndex(), ctx.getStop().getStopIndex(), ctx.XMLAGG().getText(), getOriginalText(ctx));
857     }
858     
859     @Override
860     public ASTNode visitXmlColattvalFunction(final XmlColattvalFunctionContext ctx) {
861         FunctionSegment result = new FunctionSegment(ctx.start.getStartIndex(), ctx.stop.getStopIndex(), ctx.XMLCOLATTVAL().getText(), getOriginalText(ctx));
862         Collection<ExpressionSegment> expressionSegments = ctx.expr().stream().map(each -> (ExpressionSegment) visit(each)).collect(Collectors.toList());
863         result.getParameters().addAll(expressionSegments);
864         return result;
865     }
866     
867     @Override
868     public ASTNode visitXmlExistsFunction(final XmlExistsFunctionContext ctx) {
869         XmlQueryAndExistsFunctionSegment result =
870                 new XmlQueryAndExistsFunctionSegment(ctx.start.getStartIndex(), ctx.stop.getStopIndex(), ctx.XMLEXISTS().getText(), ctx.STRING_().getText(), getOriginalText(ctx));
871         Collection<ExpressionSegment> expressionSegments = ctx.xmlPassingClause().expr().stream().map(each -> (ExpressionSegment) visit(each)).collect(Collectors.toList());
872         result.getParameters().addAll(expressionSegments);
873         return result;
874     }
875     
876     @Override
877     public ASTNode visitXmlForestFunction(final XmlForestFunctionContext ctx) {
878         FunctionSegment result = new FunctionSegment(ctx.start.getStartIndex(), ctx.stop.getStopIndex(), ctx.XMLFOREST().getText(), getOriginalText(ctx));
879         Collection<ExpressionSegment> expressionSegments = ctx.expr().stream().map(each -> (ExpressionSegment) visit(each)).collect(Collectors.toList());
880         result.getParameters().addAll(expressionSegments);
881         return result;
882     }
883     
884     @Override
885     public ASTNode visitXmlParseFunction(final XmlParseFunctionContext ctx) {
886         return new ExpressionProjectionSegment(ctx.start.getStartIndex(), ctx.stop.getStopIndex(), getOriginalText(ctx), (ExpressionSegment) visit(ctx.expr()));
887     }
888     
889     @Override
890     public ASTNode visitXmlPiFunction(final XmlPiFunctionContext ctx) {
891         if (null != ctx.identifier()) {
892             return new XmlPiFunctionSegment(ctx.start.getStopIndex(), ctx.stop.getStopIndex(), ctx.XMLPI().getText(),
893                     ctx.identifier().getText(), (ExpressionSegment) visit(ctx.expr(0)), getOriginalText(ctx));
894         }
895         return new XmlPiFunctionSegment(ctx.start.getStopIndex(), ctx.stop.getStopIndex(), ctx.XMLPI().getText(),
896                 (ExpressionSegment) visit(ctx.expr(0)), (ExpressionSegment) visit(ctx.expr(1)), getOriginalText(ctx));
897     }
898     
899     @Override
900     public ASTNode visitXmlQueryFunction(final XmlQueryFunctionContext ctx) {
901         XmlQueryAndExistsFunctionSegment result =
902                 new XmlQueryAndExistsFunctionSegment(ctx.start.getStartIndex(), ctx.stop.getStopIndex(), ctx.XMLQUERY().getText(), ctx.STRING_().getText(), getOriginalText(ctx));
903         Collection<ExpressionSegment> expressionSegments = ctx.xmlPassingClause().expr().stream().map(each -> (ExpressionSegment) visit(each)).collect(Collectors.toList());
904         result.getParameters().addAll(expressionSegments);
905         return result;
906     }
907     
908     @Override
909     public ASTNode visitXmlRootFunction(final XmlRootFunctionContext ctx) {
910         FunctionSegment result = new FunctionSegment(ctx.start.getStartIndex(), ctx.stop.getStopIndex(), ctx.XMLROOT().getText(), getOriginalText(ctx));
911         Collection<ExpressionSegment> expressionSegments = ctx.expr().stream().map(each -> (ExpressionSegment) visit(each)).collect(Collectors.toList());
912         result.getParameters().addAll(expressionSegments);
913         return result;
914     }
915     
916     @Override
917     public ASTNode visitXmlSerializeFunction(final XmlSerializeFunctionContext ctx) {
918         String dataType = null == ctx.dataType() ? null : ctx.dataType().getText();
919         String encoding = null == ctx.STRING_() ? null : ctx.STRING_().getText();
920         String version = null == ctx.stringLiterals() ? null : ctx.stringLiterals().getText();
921         String identSize = null == ctx.INTEGER_() ? null : ctx.INTEGER_().getText();
922         return new XmlSerializeFunctionSegment(ctx.start.getStartIndex(), ctx.stop.getStopIndex(), ctx.XMLSERIALIZE().getText(), (ExpressionSegment) visit(ctx.expr()),
923                 dataType, encoding, version, identSize, getOriginalText(ctx));
924     }
925     
926     @Override
927     public ASTNode visitXmlTableFunction(final XmlTableFunctionContext ctx) {
928         XmlNamespacesClauseSegment xmlNamespacesClause = null == ctx.xmlNamespacesClause() ? null : (XmlNamespacesClauseSegment) visit(ctx.xmlNamespacesClause());
929         return new XmlTableFunctionSegment(ctx.start.getStartIndex(), ctx.stop.getStopIndex(), ctx.XMLTABLE().getText(),
930                 xmlNamespacesClause, ctx.STRING_().getText(), (XmlTableOptionsSegment) visit(ctx.xmlTableOptions()), getOriginalText(ctx));
931     }
932     
933     @Override
934     public ASTNode visitXmlNamespacesClause(final XmlNamespacesClauseContext ctx) {
935         // TODO : throw exception if more than one defaultString exists in a xml name space clause
936         String defaultString = null == ctx.defaultString() ? null : ctx.defaultString(0).STRING_().getText();
937         Collection<XmlNamespaceStringAsIdentifierSegment> xmlNamespaceStringAsIdentifierSegments = null == ctx.xmlNamespaceStringAsIdentifier() ? Collections.emptyList()
938                 : ctx.xmlNamespaceStringAsIdentifier().stream().map(each -> (XmlNamespaceStringAsIdentifierSegment) visit(each)).collect(Collectors.toList());
939         XmlNamespacesClauseSegment result = new XmlNamespacesClauseSegment(ctx.start.getStartIndex(), ctx.stop.getStopIndex(), defaultString, getOriginalText(ctx));
940         result.getStringAsIdentifier().addAll(xmlNamespaceStringAsIdentifierSegments);
941         return result;
942     }
943     
944     @Override
945     public ASTNode visitXmlNamespaceStringAsIdentifier(final XmlNamespaceStringAsIdentifierContext ctx) {
946         return new XmlNamespaceStringAsIdentifierSegment(ctx.start.getStartIndex(), ctx.stop.getStopIndex(), ctx.STRING_().getText(), ctx.identifier().getText(), getOriginalText(ctx));
947     }
948     
949     @Override
950     public ASTNode visitXmlTableOptions(final XmlTableOptionsContext ctx) {
951         XmlTableOptionsSegment result = new XmlTableOptionsSegment(ctx.start.getStartIndex(), ctx.stop.getStopIndex(), getOriginalText(ctx));
952         Collection<ExpressionSegment> expressionSegments = null == ctx.xmlPassingClause().expr() ? Collections.emptyList()
953                 : ctx.xmlPassingClause().expr().stream().map(each -> (ExpressionSegment) visit(each)).collect(Collectors.toList());
954         Collection<XmlTableColumnSegment> xmlTableColumnSegments = null == ctx.xmlTableColumn() ? Collections.emptyList()
955                 : ctx.xmlTableColumn().stream().map(each -> (XmlTableColumnSegment) visit(each)).collect(Collectors.toList());
956         result.getParameters().addAll(expressionSegments);
957         result.getXmlTableColumnSegments().addAll(xmlTableColumnSegments);
958         return result;
959     }
960     
961     @Override
962     public ASTNode visitXmlTableColumn(final XmlTableColumnContext ctx) {
963         String dataType = null == ctx.dataType() ? null : ctx.dataType().getText();
964         String path = null == ctx.STRING_() ? null : ctx.STRING_().getText();
965         ExpressionSegment defaultExpr = null == ctx.expr() ? null : (ExpressionSegment) visit(ctx.expr());
966         return new XmlTableColumnSegment(ctx.start.getStartIndex(), ctx.stop.getStopIndex(), ctx.columnName().getText(), dataType, path, defaultExpr, getOriginalText(ctx));
967     }
968     
969     @Override
970     public ASTNode visitXmlIsSchemaValidFunction(final XmlIsSchemaValidFunctionContext ctx) {
971         FunctionSegment result = new FunctionSegment(ctx.start.getStartIndex(), ctx.stop.getStopIndex(), ctx.ISSCHEMAVALID().getText(), getOriginalText(ctx));
972         if (null != ctx.expr()) {
973             for (ExprContext each : ctx.expr()) {
974                 result.getParameters().add((ExpressionSegment) visit(each));
975             }
976         }
977         return result;
978     }
979     
980     private Collection<ExpressionSegment> getExpressions(final ExprListContext exprList) {
981         if (null == exprList) {
982             return Collections.emptyList();
983         }
984         return getExpressions(exprList.exprs().expr());
985     }
986     
987     private Collection<ExpressionSegment> getExpressions(final List<ExprContext> exprList) {
988         if (null == exprList) {
989             return Collections.emptyList();
990         }
991         Collection<ExpressionSegment> result = new ArrayList<>(exprList.size());
992         for (ExprContext each : exprList) {
993             result.add((ExpressionSegment) visit(each));
994         }
995         return result;
996     }
997     
998     private String getDistinctExpression(final AggregationFunctionContext ctx) {
999         StringBuilder result = new StringBuilder();
1000         for (int i = 3; i < ctx.getChildCount() - 1; i++) {
1001             result.append(ctx.getChild(i).getText());
1002         }
1003         return result.toString();
1004     }
1005     
1006     @Override
1007     public final ASTNode visitSpecialFunction(final SpecialFunctionContext ctx) {
1008         if (null != ctx.castFunction()) {
1009             return visit(ctx.castFunction());
1010         }
1011         if (null != ctx.charFunction()) {
1012             return visit(ctx.charFunction());
1013         }
1014         if (null != ctx.extractFunction()) {
1015             return visit(ctx.extractFunction());
1016         }
1017         if (null != ctx.formatFunction()) {
1018             return visit(ctx.formatFunction());
1019         }
1020         if (null != ctx.firstOrLastValueFunction()) {
1021             return visit(ctx.firstOrLastValueFunction());
1022         }
1023         if (null != ctx.trimFunction()) {
1024             return visit(ctx.trimFunction());
1025         }
1026         if (null != ctx.featureFunction()) {
1027             return visit(ctx.featureFunction());
1028         }
1029         if (null != ctx.setFunction()) {
1030             return visit(ctx.setFunction());
1031         }
1032         if (null != ctx.translateFunction()) {
1033             return visit(ctx.translateFunction());
1034         }
1035         if (null != ctx.cursorFunction()) {
1036             return visit(ctx.cursorFunction());
1037         }
1038         if (null != ctx.toDateFunction()) {
1039             return visit(ctx.toDateFunction());
1040         }
1041         if (null != ctx.approxRank()) {
1042             return visit(ctx.approxRank());
1043         }
1044         if (null != ctx.wmConcatFunction()) {
1045             return visit(ctx.wmConcatFunction());
1046         }
1047         throw new IllegalStateException(
1048                 "SpecialFunctionContext must have castFunction, charFunction, extractFunction, formatFunction, firstOrLastValueFunction, trimFunction, toDateFunction, approxCount"
1049                         + " or featureFunction.");
1050     }
1051     
1052     @Override
1053     public ASTNode visitApproxRank(final ApproxRankContext ctx) {
1054         return new FunctionSegment(ctx.getStart().getStartIndex(), ctx.getStop().getStopIndex(), ctx.APPROX_RANK().getText(), getOriginalText(ctx));
1055     }
1056     
1057     @Override
1058     public ASTNode visitCursorFunction(final CursorFunctionContext ctx) {
1059         FunctionSegment result = new FunctionSegment(ctx.getStart().getStartIndex(), ctx.getStop().getStopIndex(), ctx.CURSOR().toString(), ctx.getText());
1060         result.getParameters()
1061                 .add(new SubqueryExpressionSegment(
1062                         new SubquerySegment(ctx.subquery().start.getStartIndex(), ctx.subquery().stop.getStopIndex(), (OracleSelectStatement) visit(ctx.subquery()), getOriginalText(ctx.subquery()))));
1063         return result;
1064     }
1065     
1066     @Override
1067     public ASTNode visitToDateFunction(final ToDateFunctionContext ctx) {
1068         FunctionSegment result = new FunctionSegment(ctx.getStart().getStartIndex(), ctx.getStop().getStopIndex(), ctx.TO_DATE().getText(), getOriginalText(ctx));
1069         if (null != ctx.STRING_()) {
1070             ctx.STRING_().forEach(each -> result.getParameters().add(new LiteralExpressionSegment(each.getSymbol().getStartIndex(), each.getSymbol().getStopIndex(), each.getSymbol().getText())));
1071         }
1072         return result;
1073     }
1074     
1075     @Override
1076     public final ASTNode visitTranslateFunction(final TranslateFunctionContext ctx) {
1077         FunctionSegment result = new FunctionSegment(ctx.getStart().getStartIndex(), ctx.getStop().getStopIndex(), ctx.TRANSLATE().getText(), getOriginalText(ctx));
1078         result.getParameters().add((ExpressionSegment) visit(ctx.expr()));
1079         TerminalNode charSet = null == ctx.NCHAR_CS() ? ctx.CHAR_CS() : ctx.NCHAR_CS();
1080         result.getParameters().add(new LiteralExpressionSegment(charSet.getSymbol().getStartIndex(), charSet.getSymbol().getStopIndex(), charSet.getText()));
1081         return result;
1082     }
1083     
1084     @Override
1085     public final ASTNode visitSetFunction(final SetFunctionContext ctx) {
1086         FunctionSegment result = new FunctionSegment(ctx.getStart().getStartIndex(), ctx.getStop().getStopIndex(), ctx.SET().getText(), getOriginalText(ctx));
1087         result.getParameters().add((ExpressionSegment) visit(ctx.expr()));
1088         return result;
1089     }
1090     
1091     @Override
1092     public final ASTNode visitCastFunction(final CastFunctionContext ctx) {
1093         FunctionSegment result;
1094         if (null != ctx.CAST()) {
1095             result = new FunctionSegment(ctx.getStart().getStartIndex(), ctx.getStop().getStopIndex(), ctx.CAST().getText(), getOriginalText(ctx));
1096         } else {
1097             result = new FunctionSegment(ctx.getStart().getStartIndex(), ctx.getStop().getStopIndex(), ctx.XMLCAST().getText(), getOriginalText(ctx));
1098         }
1099         if (null != ctx.MULTISET()) {
1100             result.getParameters().add(new SubqueryExpressionSegment(new SubquerySegment(ctx.subquery().start.getStartIndex(), ctx.subquery().stop.getStopIndex(),
1101                     (OracleSelectStatement) visit(ctx.subquery()), getOriginalText(ctx.subquery()))));
1102         } else {
1103             result.getParameters().add((ExpressionSegment) visit(ctx.expr()));
1104         }
1105         result.getParameters().add((DataTypeSegment) visit(ctx.dataType()));
1106         return result;
1107     }
1108     
1109     @Override
1110     public final ASTNode visitCharFunction(final CharFunctionContext ctx) {
1111         calculateParameterCount(ctx.expr());
1112         FunctionSegment result;
1113         if (null != ctx.CHR()) {
1114             result = new FunctionSegment(ctx.getStart().getStartIndex(), ctx.getStop().getStopIndex(), ctx.CHR().getText(), getOriginalText(ctx));
1115         } else {
1116             result = new FunctionSegment(ctx.getStart().getStartIndex(), ctx.getStop().getStopIndex(), ctx.CHAR().getText(), getOriginalText(ctx));
1117         }
1118         result.getParameters().addAll(getExpressions(ctx.expr()));
1119         return result;
1120     }
1121     
1122     @Override
1123     public ASTNode visitExtractFunction(final ExtractFunctionContext ctx) {
1124         FunctionSegment result = new FunctionSegment(ctx.getStart().getStartIndex(), ctx.getStop().getStopIndex(), ctx.EXTRACT().getText(), getOriginalText(ctx));
1125         result.getParameters().add((ExpressionSegment) visit(ctx.expr()));
1126         return result;
1127     }
1128     
1129     @Override
1130     public ASTNode visitFormatFunction(final FormatFunctionContext ctx) {
1131         FunctionSegment result = new FunctionSegment(ctx.getStart().getStartIndex(), ctx.getStop().getStopIndex(), ctx.FORMAT().getText(), getOriginalText(ctx));
1132         result.getParameters().addAll(getExpressions(ctx.expr()));
1133         return result;
1134     }
1135     
1136     @Override
1137     public ASTNode visitFirstOrLastValueFunction(final FirstOrLastValueFunctionContext ctx) {
1138         FunctionSegment result = new FunctionSegment(ctx.getStart().getStartIndex(), ctx.getStop().getStopIndex(),
1139                 null == ctx.FIRST_VALUE() ? ctx.LAST_VALUE().getText() : ctx.FIRST_VALUE().getText(), getOriginalText(ctx));
1140         result.getParameters().add((ExpressionSegment) visit(ctx.expr()));
1141         return result;
1142     }
1143     
1144     @Override
1145     public ASTNode visitTrimFunction(final TrimFunctionContext ctx) {
1146         FunctionSegment result = new FunctionSegment(ctx.getStart().getStartIndex(), ctx.getStop().getStopIndex(), ctx.TRIM().getText(), getOriginalText(ctx));
1147         result.getParameters().add((ExpressionSegment) visit(ctx.expr()));
1148         return result;
1149     }
1150     
1151     @Override
1152     public ASTNode visitFeatureFunction(final FeatureFunctionContext ctx) {
1153         return new FunctionSegment(ctx.getStart().getStartIndex(), ctx.getStop().getStopIndex(), ctx.featureFunctionName().getText(), getOriginalText(ctx));
1154     }
1155     
1156     @Override
1157     public final ASTNode visitRegularFunction(final RegularFunctionContext ctx) {
1158         FunctionSegment result = new FunctionSegment(ctx.getStart().getStartIndex(), ctx.getStop().getStopIndex(), ctx.regularFunctionName().getText(), getOriginalText(ctx));
1159         if (null != ctx.owner()) {
1160             OwnerContext owner = ctx.owner();
1161             result.setOwner(new OwnerSegment(owner.getStart().getStartIndex(), owner.getStop().getStopIndex(), (IdentifierValue) visit(owner.identifier())));
1162         }
1163         result.getParameters().addAll(getExpressions(ctx.expr()));
1164         return result;
1165     }
1166     
1167     @Override
1168     public final ASTNode visitDataTypeName(final DataTypeNameContext ctx) {
1169         Collection<String> dataTypeNames = new LinkedList<>();
1170         for (int i = 0; i < ctx.getChildCount(); i++) {
1171             dataTypeNames.add(ctx.getChild(i).getText());
1172         }
1173         return new KeywordValue(String.join(" ", dataTypeNames));
1174     }
1175     
1176     // TODO :FIXME, sql case id: insert_with_str_to_date
1177     private void calculateParameterCount(final Collection<ExprContext> exprContexts) {
1178         for (ExprContext each : exprContexts) {
1179             visit(each);
1180         }
1181     }
1182     
1183     @Override
1184     public final ASTNode visitOrderByClause(final OrderByClauseContext ctx) {
1185         Collection<OrderByItemSegment> items = new LinkedList<>();
1186         for (OrderByItemContext each : ctx.orderByItem()) {
1187             items.add((OrderByItemSegment) visit(each));
1188         }
1189         return new OrderBySegment(ctx.getStart().getStartIndex(), ctx.getStop().getStopIndex(), items);
1190     }
1191     
1192     @Override
1193     public final ASTNode visitOrderByItem(final OrderByItemContext ctx) {
1194         OrderDirection orderDirection = null == ctx.DESC() ? OrderDirection.ASC : OrderDirection.DESC;
1195         NullsOrderType nullsOrderType = generateNullsOrderType(ctx);
1196         if (null != ctx.columnName()) {
1197             ColumnSegment column = (ColumnSegment) visit(ctx.columnName());
1198             return new ColumnOrderByItemSegment(column, orderDirection, nullsOrderType);
1199         }
1200         if (null != ctx.numberLiterals()) {
1201             return new IndexOrderByItemSegment(ctx.numberLiterals().getStart().getStartIndex(), ctx.numberLiterals().getStop().getStopIndex(),
1202                     SQLUtils.getExactlyNumber(ctx.numberLiterals().getText(), 10).intValue(), orderDirection, nullsOrderType);
1203         }
1204         return new ExpressionOrderByItemSegment(ctx.expr().getStart().getStartIndex(), ctx.expr().getStop().getStopIndex(),
1205                 getOriginalText(ctx.expr()), orderDirection, nullsOrderType, (ExpressionSegment) visit(ctx.expr()));
1206     }
1207     
1208     private NullsOrderType generateNullsOrderType(final OrderByItemContext ctx) {
1209         if (null == ctx.FIRST() && null == ctx.LAST()) {
1210             return null;
1211         }
1212         return null == ctx.FIRST() ? NullsOrderType.LAST : NullsOrderType.FIRST;
1213     }
1214     
1215     @Override
1216     public final ASTNode visitDataType(final DataTypeContext ctx) {
1217         DataTypeSegment result = new DataTypeSegment();
1218         if (null != ctx.dataTypeName()) {
1219             result.setDataTypeName(((KeywordValue) visit(ctx.dataTypeName())).getValue());
1220         }
1221         if (null != ctx.specialDatatype()) {
1222             result.setDataTypeName(((KeywordValue) visit(ctx.specialDatatype().dataTypeName())).getValue());
1223         }
1224         result.setStartIndex(ctx.start.getStartIndex());
1225         result.setStopIndex(ctx.stop.getStopIndex());
1226         if (null != ctx.dataTypeLength()) {
1227             DataTypeLengthSegment dataTypeLengthSegment = (DataTypeLengthSegment) visit(ctx.dataTypeLength());
1228             result.setDataLength(dataTypeLengthSegment);
1229         }
1230         return result;
1231     }
1232     
1233     @Override
1234     public final ASTNode visitDataTypeLength(final DataTypeLengthContext ctx) {
1235         DataTypeLengthSegment result = new DataTypeLengthSegment();
1236         result.setStartIndex(ctx.start.getStartIndex());
1237         result.setStopIndex(ctx.stop.getStartIndex());
1238         List<TerminalNode> numbers = ctx.INTEGER_();
1239         if (numbers.size() == 1) {
1240             result.setPrecision(Integer.parseInt(numbers.get(0).getText()));
1241         }
1242         if (numbers.size() == 2) {
1243             result.setPrecision(Integer.parseInt(numbers.get(0).getText()));
1244             result.setScale(Integer.parseInt(numbers.get(1).getText()));
1245         }
1246         return result;
1247     }
1248     
1249     /**
1250      * Get original text.
1251      *
1252      * @param ctx context
1253      * @return original text
1254      */
1255     protected String getOriginalText(final ParserRuleContext ctx) {
1256         return ctx.start.getInputStream().getText(new Interval(ctx.start.getStartIndex(), ctx.stop.getStopIndex()));
1257     }
1258     
1259     /**
1260      * Pop all statement parameter marker segments.
1261      *
1262      * @return all statement parameter marker segments
1263      */
1264     protected Collection<ParameterMarkerSegment> popAllStatementParameterMarkerSegments() {
1265         Collection<ParameterMarkerSegment> result = new LinkedList<>(statementParameterMarkerSegments);
1266         statementParameterMarkerSegments.clear();
1267         return result;
1268     }
1269     
1270     /**
1271      * Increase cursor for loop level.
1272      */
1273     protected void increaseCursorForLoopLevel() {
1274         ++cursorForLoopLevel;
1275     }
1276     
1277     /**
1278      * Decrease cursor for loop level.
1279      */
1280     protected void decreaseCursorForLoopLevel() {
1281         --cursorForLoopLevel;
1282     }
1283 }