1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
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
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
290 return new OtherLiteralValue(ctx.getText());
291 }
292
293 @Override
294 public final ASTNode visitBitValueLiterals(final BitValueLiteralsContext ctx) {
295
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
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
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
1286
1287
1288
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
1296
1297
1298
1299 protected Collection<ParameterMarkerSegment> popAllStatementParameterMarkerSegments() {
1300 Collection<ParameterMarkerSegment> result = new LinkedList<>(statementParameterMarkerSegments);
1301 statementParameterMarkerSegments.clear();
1302 return result;
1303 }
1304
1305
1306
1307
1308 protected void increaseCursorForLoopLevel() {
1309 ++cursorForLoopLevel;
1310 }
1311
1312
1313
1314
1315 protected void decreaseCursorForLoopLevel() {
1316 --cursorForLoopLevel;
1317 }
1318 }