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