1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 package org.apache.shardingsphere.sql.parser.postgresql.visitor.statement;
19
20 import lombok.AccessLevel;
21 import lombok.Getter;
22 import lombok.RequiredArgsConstructor;
23 import org.antlr.v4.runtime.ParserRuleContext;
24 import org.antlr.v4.runtime.misc.Interval;
25 import org.antlr.v4.runtime.tree.ParseTree;
26 import org.antlr.v4.runtime.tree.TerminalNode;
27 import org.apache.shardingsphere.infra.database.core.metadata.database.enums.NullsOrderType;
28 import org.apache.shardingsphere.infra.database.core.type.DatabaseType;
29 import org.apache.shardingsphere.sql.parser.api.ASTNode;
30 import org.apache.shardingsphere.sql.parser.autogen.PostgreSQLStatementParser.AExprContext;
31 import org.apache.shardingsphere.sql.parser.autogen.PostgreSQLStatementParser.AexprConstContext;
32 import org.apache.shardingsphere.sql.parser.autogen.PostgreSQLStatementParser.AliasClauseContext;
33 import org.apache.shardingsphere.sql.parser.autogen.PostgreSQLStatementParser.AliasContext;
34 import org.apache.shardingsphere.sql.parser.autogen.PostgreSQLStatementParser.AnyNameContext;
35 import org.apache.shardingsphere.sql.parser.autogen.PostgreSQLStatementParser.AscDescContext;
36 import org.apache.shardingsphere.sql.parser.autogen.PostgreSQLStatementParser.AttrNameContext;
37 import org.apache.shardingsphere.sql.parser.autogen.PostgreSQLStatementParser.AttrsContext;
38 import org.apache.shardingsphere.sql.parser.autogen.PostgreSQLStatementParser.BExprContext;
39 import org.apache.shardingsphere.sql.parser.autogen.PostgreSQLStatementParser.CExprContext;
40 import org.apache.shardingsphere.sql.parser.autogen.PostgreSQLStatementParser.CaseExprContext;
41 import org.apache.shardingsphere.sql.parser.autogen.PostgreSQLStatementParser.ColIdContext;
42 import org.apache.shardingsphere.sql.parser.autogen.PostgreSQLStatementParser.ColumnNameContext;
43 import org.apache.shardingsphere.sql.parser.autogen.PostgreSQLStatementParser.ColumnNamesContext;
44 import org.apache.shardingsphere.sql.parser.autogen.PostgreSQLStatementParser.ColumnrefContext;
45 import org.apache.shardingsphere.sql.parser.autogen.PostgreSQLStatementParser.CommonTableExprContext;
46 import org.apache.shardingsphere.sql.parser.autogen.PostgreSQLStatementParser.ConstraintNameContext;
47 import org.apache.shardingsphere.sql.parser.autogen.PostgreSQLStatementParser.DataTypeContext;
48 import org.apache.shardingsphere.sql.parser.autogen.PostgreSQLStatementParser.DataTypeLengthContext;
49 import org.apache.shardingsphere.sql.parser.autogen.PostgreSQLStatementParser.DataTypeNameContext;
50 import org.apache.shardingsphere.sql.parser.autogen.PostgreSQLStatementParser.DeleteContext;
51 import org.apache.shardingsphere.sql.parser.autogen.PostgreSQLStatementParser.ExecuteStmtContext;
52 import org.apache.shardingsphere.sql.parser.autogen.PostgreSQLStatementParser.ExprListContext;
53 import org.apache.shardingsphere.sql.parser.autogen.PostgreSQLStatementParser.ExtractArgContext;
54 import org.apache.shardingsphere.sql.parser.autogen.PostgreSQLStatementParser.ForLockingClauseContext;
55 import org.apache.shardingsphere.sql.parser.autogen.PostgreSQLStatementParser.FromClauseContext;
56 import org.apache.shardingsphere.sql.parser.autogen.PostgreSQLStatementParser.FromListContext;
57 import org.apache.shardingsphere.sql.parser.autogen.PostgreSQLStatementParser.FuncApplicationContext;
58 import org.apache.shardingsphere.sql.parser.autogen.PostgreSQLStatementParser.FuncExprContext;
59 import org.apache.shardingsphere.sql.parser.autogen.PostgreSQLStatementParser.FuncNameContext;
60 import org.apache.shardingsphere.sql.parser.autogen.PostgreSQLStatementParser.FunctionExprCommonSubexprContext;
61 import org.apache.shardingsphere.sql.parser.autogen.PostgreSQLStatementParser.GroupByItemContext;
62 import org.apache.shardingsphere.sql.parser.autogen.PostgreSQLStatementParser.GroupClauseContext;
63 import org.apache.shardingsphere.sql.parser.autogen.PostgreSQLStatementParser.HavingClauseContext;
64 import org.apache.shardingsphere.sql.parser.autogen.PostgreSQLStatementParser.HostVariableContext;
65 import org.apache.shardingsphere.sql.parser.autogen.PostgreSQLStatementParser.IdentifierContext;
66 import org.apache.shardingsphere.sql.parser.autogen.PostgreSQLStatementParser.InExprContext;
67 import org.apache.shardingsphere.sql.parser.autogen.PostgreSQLStatementParser.IndexNameContext;
68 import org.apache.shardingsphere.sql.parser.autogen.PostgreSQLStatementParser.IndirectionContext;
69 import org.apache.shardingsphere.sql.parser.autogen.PostgreSQLStatementParser.InsertColumnItemContext;
70 import org.apache.shardingsphere.sql.parser.autogen.PostgreSQLStatementParser.InsertColumnListContext;
71 import org.apache.shardingsphere.sql.parser.autogen.PostgreSQLStatementParser.InsertContext;
72 import org.apache.shardingsphere.sql.parser.autogen.PostgreSQLStatementParser.InsertRestContext;
73 import org.apache.shardingsphere.sql.parser.autogen.PostgreSQLStatementParser.InsertTargetContext;
74 import org.apache.shardingsphere.sql.parser.autogen.PostgreSQLStatementParser.IntoClauseContext;
75 import org.apache.shardingsphere.sql.parser.autogen.PostgreSQLStatementParser.JoinQualContext;
76 import org.apache.shardingsphere.sql.parser.autogen.PostgreSQLStatementParser.JoinedTableContext;
77 import org.apache.shardingsphere.sql.parser.autogen.PostgreSQLStatementParser.LimitClauseContext;
78 import org.apache.shardingsphere.sql.parser.autogen.PostgreSQLStatementParser.NameContext;
79 import org.apache.shardingsphere.sql.parser.autogen.PostgreSQLStatementParser.NameListContext;
80 import org.apache.shardingsphere.sql.parser.autogen.PostgreSQLStatementParser.NaturalJoinTypeContext;
81 import org.apache.shardingsphere.sql.parser.autogen.PostgreSQLStatementParser.NullsOrderContext;
82 import org.apache.shardingsphere.sql.parser.autogen.PostgreSQLStatementParser.NumberLiteralsContext;
83 import org.apache.shardingsphere.sql.parser.autogen.PostgreSQLStatementParser.OptOnConflictContext;
84 import org.apache.shardingsphere.sql.parser.autogen.PostgreSQLStatementParser.OuterJoinTypeContext;
85 import org.apache.shardingsphere.sql.parser.autogen.PostgreSQLStatementParser.OwnerContext;
86 import org.apache.shardingsphere.sql.parser.autogen.PostgreSQLStatementParser.ParameterMarkerContext;
87 import org.apache.shardingsphere.sql.parser.autogen.PostgreSQLStatementParser.QualifiedNameContext;
88 import org.apache.shardingsphere.sql.parser.autogen.PostgreSQLStatementParser.QualifiedNameListContext;
89 import org.apache.shardingsphere.sql.parser.autogen.PostgreSQLStatementParser.RelationExprOptAliasContext;
90 import org.apache.shardingsphere.sql.parser.autogen.PostgreSQLStatementParser.SchemaNameContext;
91 import org.apache.shardingsphere.sql.parser.autogen.PostgreSQLStatementParser.SelectClauseNContext;
92 import org.apache.shardingsphere.sql.parser.autogen.PostgreSQLStatementParser.SelectContext;
93 import org.apache.shardingsphere.sql.parser.autogen.PostgreSQLStatementParser.SelectFetchValueContext;
94 import org.apache.shardingsphere.sql.parser.autogen.PostgreSQLStatementParser.SelectLimitContext;
95 import org.apache.shardingsphere.sql.parser.autogen.PostgreSQLStatementParser.SelectLimitValueContext;
96 import org.apache.shardingsphere.sql.parser.autogen.PostgreSQLStatementParser.SelectNoParensContext;
97 import org.apache.shardingsphere.sql.parser.autogen.PostgreSQLStatementParser.SelectOffsetValueContext;
98 import org.apache.shardingsphere.sql.parser.autogen.PostgreSQLStatementParser.SelectWithParensContext;
99 import org.apache.shardingsphere.sql.parser.autogen.PostgreSQLStatementParser.SetClauseContext;
100 import org.apache.shardingsphere.sql.parser.autogen.PostgreSQLStatementParser.SetClauseListContext;
101 import org.apache.shardingsphere.sql.parser.autogen.PostgreSQLStatementParser.SetTargetContext;
102 import org.apache.shardingsphere.sql.parser.autogen.PostgreSQLStatementParser.SignedIconstContext;
103 import org.apache.shardingsphere.sql.parser.autogen.PostgreSQLStatementParser.SimpleSelectContext;
104 import org.apache.shardingsphere.sql.parser.autogen.PostgreSQLStatementParser.SortClauseContext;
105 import org.apache.shardingsphere.sql.parser.autogen.PostgreSQLStatementParser.SortbyContext;
106 import org.apache.shardingsphere.sql.parser.autogen.PostgreSQLStatementParser.TableNameContext;
107 import org.apache.shardingsphere.sql.parser.autogen.PostgreSQLStatementParser.TableNamesContext;
108 import org.apache.shardingsphere.sql.parser.autogen.PostgreSQLStatementParser.TableReferenceContext;
109 import org.apache.shardingsphere.sql.parser.autogen.PostgreSQLStatementParser.TargetElContext;
110 import org.apache.shardingsphere.sql.parser.autogen.PostgreSQLStatementParser.TargetListContext;
111 import org.apache.shardingsphere.sql.parser.autogen.PostgreSQLStatementParser.UnreservedWordContext;
112 import org.apache.shardingsphere.sql.parser.autogen.PostgreSQLStatementParser.UpdateContext;
113 import org.apache.shardingsphere.sql.parser.autogen.PostgreSQLStatementParser.ValuesClauseContext;
114 import org.apache.shardingsphere.sql.parser.autogen.PostgreSQLStatementParser.WhenClauseContext;
115 import org.apache.shardingsphere.sql.parser.autogen.PostgreSQLStatementParser.WhereClauseContext;
116 import org.apache.shardingsphere.sql.parser.autogen.PostgreSQLStatementParser.WhereOrCurrentClauseContext;
117 import org.apache.shardingsphere.sql.parser.autogen.PostgreSQLStatementParser.WindowClauseContext;
118 import org.apache.shardingsphere.sql.parser.autogen.PostgreSQLStatementParser.WindowDefinitionContext;
119 import org.apache.shardingsphere.sql.parser.autogen.PostgreSQLStatementParser.WindowDefinitionListContext;
120 import org.apache.shardingsphere.sql.parser.autogen.PostgreSQLStatementParser.WithClauseContext;
121 import org.apache.shardingsphere.sql.parser.autogen.PostgreSQLStatementParserBaseVisitor;
122 import org.apache.shardingsphere.sql.parser.statement.core.enums.AggregationType;
123 import org.apache.shardingsphere.sql.parser.statement.core.enums.CombineType;
124 import org.apache.shardingsphere.sql.parser.statement.core.enums.JoinType;
125 import org.apache.shardingsphere.sql.parser.statement.core.enums.OrderDirection;
126 import org.apache.shardingsphere.sql.parser.statement.core.enums.ParameterMarkerType;
127 import org.apache.shardingsphere.sql.parser.statement.core.enums.SubqueryType;
128 import org.apache.shardingsphere.sql.parser.statement.core.segment.ddl.constraint.ConstraintSegment;
129 import org.apache.shardingsphere.sql.parser.statement.core.segment.ddl.index.IndexNameSegment;
130 import org.apache.shardingsphere.sql.parser.statement.core.segment.ddl.index.IndexSegment;
131 import org.apache.shardingsphere.sql.parser.statement.core.segment.dml.ReturningSegment;
132 import org.apache.shardingsphere.sql.parser.statement.core.segment.dml.assignment.ColumnAssignmentSegment;
133 import org.apache.shardingsphere.sql.parser.statement.core.segment.dml.assignment.InsertValuesSegment;
134 import org.apache.shardingsphere.sql.parser.statement.core.segment.dml.assignment.SetAssignmentSegment;
135 import org.apache.shardingsphere.sql.parser.statement.core.segment.dml.column.ColumnSegment;
136 import org.apache.shardingsphere.sql.parser.statement.core.segment.dml.column.InsertColumnsSegment;
137 import org.apache.shardingsphere.sql.parser.statement.core.segment.dml.column.OnDuplicateKeyColumnsSegment;
138 import org.apache.shardingsphere.sql.parser.statement.core.segment.dml.combine.CombineSegment;
139 import org.apache.shardingsphere.sql.parser.statement.core.segment.dml.expr.BetweenExpression;
140 import org.apache.shardingsphere.sql.parser.statement.core.segment.dml.expr.BinaryOperationExpression;
141 import org.apache.shardingsphere.sql.parser.statement.core.segment.dml.expr.CaseWhenExpression;
142 import org.apache.shardingsphere.sql.parser.statement.core.segment.dml.expr.ExistsSubqueryExpression;
143 import org.apache.shardingsphere.sql.parser.statement.core.segment.dml.expr.ExpressionSegment;
144 import org.apache.shardingsphere.sql.parser.statement.core.segment.dml.expr.ExtractArgExpression;
145 import org.apache.shardingsphere.sql.parser.statement.core.segment.dml.expr.FunctionSegment;
146 import org.apache.shardingsphere.sql.parser.statement.core.segment.dml.expr.InExpression;
147 import org.apache.shardingsphere.sql.parser.statement.core.segment.dml.expr.ListExpression;
148 import org.apache.shardingsphere.sql.parser.statement.core.segment.dml.expr.TypeCastExpression;
149 import org.apache.shardingsphere.sql.parser.statement.core.segment.dml.expr.complex.CommonExpressionSegment;
150 import org.apache.shardingsphere.sql.parser.statement.core.segment.dml.expr.complex.CommonTableExpressionSegment;
151 import org.apache.shardingsphere.sql.parser.statement.core.segment.dml.expr.simple.LiteralExpressionSegment;
152 import org.apache.shardingsphere.sql.parser.statement.core.segment.dml.expr.simple.ParameterMarkerExpressionSegment;
153 import org.apache.shardingsphere.sql.parser.statement.core.segment.dml.expr.subquery.SubqueryExpressionSegment;
154 import org.apache.shardingsphere.sql.parser.statement.core.segment.dml.expr.subquery.SubquerySegment;
155 import org.apache.shardingsphere.sql.parser.statement.core.segment.dml.item.AggregationDistinctProjectionSegment;
156 import org.apache.shardingsphere.sql.parser.statement.core.segment.dml.item.AggregationProjectionSegment;
157 import org.apache.shardingsphere.sql.parser.statement.core.segment.dml.item.ColumnProjectionSegment;
158 import org.apache.shardingsphere.sql.parser.statement.core.segment.dml.item.ExpressionProjectionSegment;
159 import org.apache.shardingsphere.sql.parser.statement.core.segment.dml.item.ProjectionSegment;
160 import org.apache.shardingsphere.sql.parser.statement.core.segment.dml.item.ProjectionsSegment;
161 import org.apache.shardingsphere.sql.parser.statement.core.segment.dml.item.ShorthandProjectionSegment;
162 import org.apache.shardingsphere.sql.parser.statement.core.segment.dml.item.SubqueryProjectionSegment;
163 import org.apache.shardingsphere.sql.parser.statement.core.segment.dml.order.GroupBySegment;
164 import org.apache.shardingsphere.sql.parser.statement.core.segment.dml.order.OrderBySegment;
165 import org.apache.shardingsphere.sql.parser.statement.core.segment.dml.order.item.ColumnOrderByItemSegment;
166 import org.apache.shardingsphere.sql.parser.statement.core.segment.dml.order.item.ExpressionOrderByItemSegment;
167 import org.apache.shardingsphere.sql.parser.statement.core.segment.dml.order.item.IndexOrderByItemSegment;
168 import org.apache.shardingsphere.sql.parser.statement.core.segment.dml.order.item.OrderByItemSegment;
169 import org.apache.shardingsphere.sql.parser.statement.core.segment.dml.pagination.limit.LimitSegment;
170 import org.apache.shardingsphere.sql.parser.statement.core.segment.dml.pagination.limit.LimitValueSegment;
171 import org.apache.shardingsphere.sql.parser.statement.core.segment.dml.pagination.limit.NumberLiteralLimitValueSegment;
172 import org.apache.shardingsphere.sql.parser.statement.core.segment.dml.pagination.limit.ParameterMarkerLimitValueSegment;
173 import org.apache.shardingsphere.sql.parser.statement.core.segment.dml.predicate.HavingSegment;
174 import org.apache.shardingsphere.sql.parser.statement.core.segment.dml.predicate.LockSegment;
175 import org.apache.shardingsphere.sql.parser.statement.core.segment.dml.predicate.WhereSegment;
176 import org.apache.shardingsphere.sql.parser.statement.core.segment.generic.AliasAvailable;
177 import org.apache.shardingsphere.sql.parser.statement.core.segment.generic.AliasSegment;
178 import org.apache.shardingsphere.sql.parser.statement.core.segment.generic.DataTypeLengthSegment;
179 import org.apache.shardingsphere.sql.parser.statement.core.segment.generic.DataTypeSegment;
180 import org.apache.shardingsphere.sql.parser.statement.core.segment.generic.NameSegment;
181 import org.apache.shardingsphere.sql.parser.statement.core.segment.generic.OwnerSegment;
182 import org.apache.shardingsphere.sql.parser.statement.core.segment.generic.ParameterMarkerSegment;
183 import org.apache.shardingsphere.sql.parser.statement.core.segment.generic.WindowItemSegment;
184 import org.apache.shardingsphere.sql.parser.statement.core.segment.generic.WindowSegment;
185 import org.apache.shardingsphere.sql.parser.statement.core.segment.generic.WithSegment;
186 import org.apache.shardingsphere.sql.parser.statement.core.segment.generic.table.FunctionTableSegment;
187 import org.apache.shardingsphere.sql.parser.statement.core.segment.generic.table.JoinTableSegment;
188 import org.apache.shardingsphere.sql.parser.statement.core.segment.generic.table.SimpleTableSegment;
189 import org.apache.shardingsphere.sql.parser.statement.core.segment.generic.table.SubqueryTableSegment;
190 import org.apache.shardingsphere.sql.parser.statement.core.segment.generic.table.TableNameSegment;
191 import org.apache.shardingsphere.sql.parser.statement.core.segment.generic.table.TableSegment;
192 import org.apache.shardingsphere.sql.parser.statement.core.statement.type.ddl.ExecuteStatement;
193 import org.apache.shardingsphere.sql.parser.statement.core.statement.type.dml.DeleteStatement;
194 import org.apache.shardingsphere.sql.parser.statement.core.statement.type.dml.InsertStatement;
195 import org.apache.shardingsphere.sql.parser.statement.core.statement.type.dml.SelectStatement;
196 import org.apache.shardingsphere.sql.parser.statement.core.statement.type.dml.UpdateStatement;
197 import org.apache.shardingsphere.sql.parser.statement.core.util.SQLUtils;
198 import org.apache.shardingsphere.sql.parser.statement.core.value.collection.CollectionValue;
199 import org.apache.shardingsphere.sql.parser.statement.core.value.identifier.IdentifierValue;
200 import org.apache.shardingsphere.sql.parser.statement.core.value.keyword.KeywordValue;
201 import org.apache.shardingsphere.sql.parser.statement.core.value.literal.LiteralValue;
202 import org.apache.shardingsphere.sql.parser.statement.core.value.literal.impl.BooleanLiteralValue;
203 import org.apache.shardingsphere.sql.parser.statement.core.value.literal.impl.NullLiteralValue;
204 import org.apache.shardingsphere.sql.parser.statement.core.value.literal.impl.NumberLiteralValue;
205 import org.apache.shardingsphere.sql.parser.statement.core.value.literal.impl.OtherLiteralValue;
206 import org.apache.shardingsphere.sql.parser.statement.core.value.literal.impl.StringLiteralValue;
207 import org.apache.shardingsphere.sql.parser.statement.core.value.parametermarker.ParameterMarkerValue;
208
209 import java.util.ArrayList;
210 import java.util.Collection;
211 import java.util.Collections;
212 import java.util.LinkedList;
213 import java.util.List;
214 import java.util.Optional;
215
216
217
218
219 @RequiredArgsConstructor
220 @Getter(AccessLevel.PROTECTED)
221 public abstract class PostgreSQLStatementVisitor extends PostgreSQLStatementParserBaseVisitor<ASTNode> {
222
223 private final DatabaseType databaseType;
224
225 private final Collection<ParameterMarkerSegment> parameterMarkerSegments = new LinkedList<>();
226
227 @Override
228 public final ASTNode visitParameterMarker(final ParameterMarkerContext ctx) {
229 if (null == ctx.DOLLAR_()) {
230 return new ParameterMarkerValue(parameterMarkerSegments.size(), ParameterMarkerType.QUESTION);
231 }
232 return new ParameterMarkerValue(new NumberLiteralValue(ctx.NUMBER_().getText()).getValue().intValue() - 1, ParameterMarkerType.DOLLAR);
233 }
234
235 @Override
236 public final ASTNode visitNumberLiterals(final NumberLiteralsContext ctx) {
237 return new NumberLiteralValue(ctx.NUMBER_().getText());
238 }
239
240 @Override
241 public final ASTNode visitIdentifier(final IdentifierContext ctx) {
242 UnreservedWordContext unreservedWord = ctx.unreservedWord();
243 return null == unreservedWord ? new IdentifierValue(ctx.getText()) : visit(unreservedWord);
244 }
245
246 @Override
247 public final ASTNode visitUnreservedWord(final UnreservedWordContext ctx) {
248 return new IdentifierValue(ctx.getText());
249 }
250
251 @Override
252 public final ASTNode visitSchemaName(final SchemaNameContext ctx) {
253 return visit(ctx.identifier());
254 }
255
256 @Override
257 public final ASTNode visitTableName(final TableNameContext ctx) {
258 SimpleTableSegment result = new SimpleTableSegment(new TableNameSegment(ctx.name().getStart().getStartIndex(), ctx.name().getStop().getStopIndex(), (IdentifierValue) visit(ctx.name())));
259 OwnerContext owner = ctx.owner();
260 if (null != owner) {
261 result.setOwner(new OwnerSegment(owner.getStart().getStartIndex(), owner.getStop().getStopIndex(), (IdentifierValue) visit(owner.identifier())));
262 }
263 return result;
264 }
265
266 @Override
267 public final ASTNode visitColumnName(final ColumnNameContext ctx) {
268 ColumnSegment result = new ColumnSegment(ctx.getStart().getStartIndex(), ctx.getStop().getStopIndex(), (IdentifierValue) visit(ctx.name()));
269 OwnerContext owner = ctx.owner();
270 if (null != owner) {
271 result.setOwner(new OwnerSegment(owner.getStart().getStartIndex(), owner.getStop().getStopIndex(), (IdentifierValue) visit(owner.identifier())));
272 }
273 return result;
274 }
275
276 @Override
277 public final ASTNode visitIndexName(final IndexNameContext ctx) {
278 IndexNameSegment indexName = new IndexNameSegment(ctx.start.getStartIndex(), ctx.stop.getStopIndex(), (IdentifierValue) visit(ctx.identifier()));
279 return new IndexSegment(ctx.getStart().getStartIndex(), ctx.getStop().getStopIndex(), indexName);
280 }
281
282 @Override
283 public final ASTNode visitConstraintName(final ConstraintNameContext ctx) {
284 return new ConstraintSegment(ctx.getStart().getStartIndex(), ctx.getStop().getStopIndex(), (IdentifierValue) visit(ctx.identifier()));
285 }
286
287 @Override
288 public final ASTNode visitTableNames(final TableNamesContext ctx) {
289 CollectionValue<SimpleTableSegment> result = new CollectionValue<>();
290 for (TableNameContext each : ctx.tableName()) {
291 result.getValue().add((SimpleTableSegment) visit(each));
292 }
293 return result;
294 }
295
296 @Override
297 public final ASTNode visitColumnNames(final ColumnNamesContext ctx) {
298 CollectionValue<ColumnSegment> result = new CollectionValue<>();
299 for (ColumnNameContext each : ctx.columnName()) {
300 result.getValue().add((ColumnSegment) visit(each));
301 }
302 return result;
303 }
304
305 @Override
306 public ASTNode visitAExpr(final AExprContext ctx) {
307 if (null != ctx.cExpr()) {
308 return visit(ctx.cExpr());
309 }
310 if (null != ctx.TYPE_CAST_()) {
311 return new TypeCastExpression(ctx.start.getStartIndex(), ctx.stop.getStopIndex(), ctx.getText(), (ExpressionSegment) visit(ctx.aExpr(0)), ctx.typeName().getText());
312 }
313 if (null != ctx.BETWEEN()) {
314 return createBetweenSegment(ctx);
315 }
316 if (null != ctx.IN()) {
317 return createInSegment(ctx);
318 }
319 if (null != ctx.patternMatchingOperator()) {
320 return createPatternMatchingOperationSegment(ctx);
321 }
322 Optional<String> binaryOperator = findBinaryOperator(ctx);
323 if (binaryOperator.isPresent()) {
324 return createBinaryOperationSegment(ctx, binaryOperator.get());
325 }
326 super.visitAExpr(ctx);
327 String text = ctx.start.getInputStream().getText(new Interval(ctx.start.getStartIndex(), ctx.stop.getStopIndex()));
328 return new CommonExpressionSegment(ctx.getStart().getStartIndex(), ctx.getStop().getStopIndex(), text);
329 }
330
331 private Optional<String> findBinaryOperator(final AExprContext ctx) {
332 if (null != ctx.IS()) {
333 return Optional.of(ctx.IS().getText());
334 }
335 if (null != ctx.ISNULL()) {
336 return Optional.of("IS");
337 }
338 if (1 == ctx.aExpr().size()) {
339 return Optional.empty();
340 }
341 if (null != ctx.comparisonOperator()) {
342 return Optional.of(ctx.comparisonOperator().getText());
343 }
344 if (null != ctx.andOperator()) {
345 return Optional.of(ctx.andOperator().getText());
346 }
347 if (null != ctx.orOperator()) {
348 return Optional.of(ctx.orOperator().getText());
349 }
350 if (null != ctx.PLUS_()) {
351 return Optional.of(ctx.PLUS_().getText());
352 }
353 if (null != ctx.MINUS_()) {
354 return Optional.of(ctx.MINUS_().getText());
355 }
356 if (null != ctx.ASTERISK_()) {
357 return Optional.of(ctx.ASTERISK_().getText());
358 }
359 if (null != ctx.SLASH_()) {
360 return Optional.of(ctx.SLASH_().getText());
361 }
362 return Optional.empty();
363 }
364
365 private BinaryOperationExpression createPatternMatchingOperationSegment(final AExprContext ctx) {
366 String operator = getOriginalText(ctx.patternMatchingOperator()).toUpperCase();
367 ExpressionSegment left = (ExpressionSegment) visit(ctx.aExpr(0));
368 ListExpression right = new ListExpression(ctx.aExpr(1).start.getStartIndex(), ctx.aExpr().get(ctx.aExpr().size() - 1).stop.getStopIndex());
369 for (int i = 1; i < ctx.aExpr().size(); i++) {
370 right.getItems().add((ExpressionSegment) visit(ctx.aExpr().get(i)));
371 }
372 String text = ctx.start.getInputStream().getText(new Interval(ctx.start.getStartIndex(), ctx.stop.getStopIndex()));
373 return new BinaryOperationExpression(ctx.start.getStartIndex(), ctx.stop.getStopIndex(), left, right, operator, text);
374 }
375
376 private BinaryOperationExpression createBinaryOperationSegment(final AExprContext ctx, final String operator) {
377 if ("IS".equalsIgnoreCase(operator)) {
378 ExpressionSegment left = (ExpressionSegment) visit(ctx.aExpr(0));
379 String rightText;
380 ExpressionSegment right;
381 if (null != ctx.IS()) {
382 rightText = ctx.start.getInputStream().getText(new Interval(ctx.IS().getSymbol().getStopIndex() + 2, ctx.stop.getStopIndex())).trim();
383 right = new LiteralExpressionSegment(ctx.IS().getSymbol().getStopIndex() + 2, ctx.stop.getStopIndex(), rightText);
384 } else {
385 rightText = ctx.start.getInputStream().getText(new Interval(ctx.ISNULL().getSymbol().getStartIndex() + 2, ctx.stop.getStopIndex())).trim();
386 right = new LiteralExpressionSegment(ctx.ISNULL().getSymbol().getStartIndex() + 2, ctx.stop.getStopIndex(), rightText);
387 }
388 return new BinaryOperationExpression(ctx.start.getStartIndex(), ctx.stop.getStopIndex(), left, right, "IS",
389 ctx.start.getInputStream().getText(new Interval(ctx.start.getStartIndex(), ctx.stop.getStopIndex())));
390 }
391 ExpressionSegment left = (ExpressionSegment) visit(ctx.aExpr(0));
392 ExpressionSegment right = (ExpressionSegment) visit(ctx.aExpr(1));
393 String text = ctx.start.getInputStream().getText(new Interval(ctx.start.getStartIndex(), ctx.stop.getStopIndex()));
394 return new BinaryOperationExpression(ctx.start.getStartIndex(), ctx.stop.getStopIndex(), left, right, operator, text);
395 }
396
397 @Override
398 public ASTNode visitCExpr(final CExprContext ctx) {
399 if (null != ctx.columnref()) {
400 return visit(ctx.columnref());
401 }
402 if (null != ctx.parameterMarker()) {
403 ParameterMarkerValue parameterMarker = (ParameterMarkerValue) visit(ctx.parameterMarker());
404 ParameterMarkerExpressionSegment result = new ParameterMarkerExpressionSegment(ctx.start.getStartIndex(), ctx.stop.getStopIndex(), parameterMarker.getValue(), parameterMarker.getType());
405 parameterMarkerSegments.add(result);
406 return result;
407 }
408 if (null != ctx.aexprConst()) {
409 return visit(ctx.aexprConst());
410 }
411 if (null != ctx.aExpr()) {
412 return visit(ctx.aExpr());
413 }
414 if (null != ctx.funcExpr()) {
415 return visit(ctx.funcExpr());
416 }
417 if (null != ctx.selectWithParens()) {
418 return createSubqueryExpressionSegment(ctx);
419 }
420 if (null != ctx.caseExpr()) {
421 return visit(ctx.caseExpr());
422 }
423 super.visitCExpr(ctx);
424 String text = ctx.start.getInputStream().getText(new Interval(ctx.start.getStartIndex(), ctx.stop.getStopIndex()));
425 return new CommonExpressionSegment(ctx.start.getStartIndex(), ctx.stop.getStopIndex(), text);
426 }
427
428 private ExpressionSegment createSubqueryExpressionSegment(final CExprContext ctx) {
429 SubquerySegment subquerySegment = new SubquerySegment(ctx.selectWithParens().getStart().getStartIndex(),
430 ctx.selectWithParens().getStop().getStopIndex(), (SelectStatement) visit(ctx.selectWithParens()), getOriginalText(ctx.selectWithParens()));
431 if (null != ctx.EXISTS()) {
432 subquerySegment.getSelect().setSubqueryType(SubqueryType.EXISTS);
433 return new ExistsSubqueryExpression(ctx.start.getStartIndex(), ctx.stop.getStopIndex(), subquerySegment);
434 }
435 return new SubqueryExpressionSegment(subquerySegment);
436 }
437
438 @Override
439 public ASTNode visitCaseExpr(final CaseExprContext ctx) {
440 Collection<ExpressionSegment> whenExprs = new LinkedList<>();
441 Collection<ExpressionSegment> thenExprs = new LinkedList<>();
442 for (WhenClauseContext each : ctx.whenClauseList().whenClause()) {
443 whenExprs.add((ExpressionSegment) visit(each.aExpr(0)));
444 thenExprs.add((ExpressionSegment) visit(each.aExpr(1)));
445 }
446 ExpressionSegment caseExpr = null == ctx.caseArg() ? null : (ExpressionSegment) visit(ctx.caseArg().aExpr());
447 ExpressionSegment elseExpr = null == ctx.caseDefault() ? null : (ExpressionSegment) visit(ctx.caseDefault().aExpr());
448 return new CaseWhenExpression(ctx.getStart().getStartIndex(), ctx.getStop().getStopIndex(), caseExpr, whenExprs, thenExprs, elseExpr);
449 }
450
451 @Override
452 public ASTNode visitFuncExpr(final FuncExprContext ctx) {
453 if (null != ctx.functionExprCommonSubexpr()) {
454 return visit(ctx.functionExprCommonSubexpr());
455 }
456 return visit(ctx.funcApplication());
457 }
458
459 @Override
460 public ASTNode visitFunctionExprCommonSubexpr(final FunctionExprCommonSubexprContext ctx) {
461 if (null != ctx.CAST()) {
462 return new TypeCastExpression(ctx.start.getStartIndex(), ctx.stop.getStopIndex(), ctx.getText(), (ExpressionSegment) visit(ctx.aExpr(0)), ctx.typeName().getText());
463 }
464 FunctionSegment result = new FunctionSegment(ctx.getStart().getStartIndex(), ctx.getStop().getStopIndex(), ctx.getChild(0).getText(), getOriginalText(ctx));
465 Collection<ExpressionSegment> expressionSegments = getExpressionSegments(getTargetRuleContextFromParseTree(ctx, AExprContext.class));
466 if ("EXTRACT".equalsIgnoreCase(ctx.getChild(0).getText())) {
467 result.getParameters().add((ExpressionSegment) visit(getTargetRuleContextFromParseTree(ctx, ExtractArgContext.class).iterator().next()));
468 }
469 result.getParameters().addAll(expressionSegments);
470 return result;
471 }
472
473 @Override
474 public ASTNode visitExtractArg(final ExtractArgContext ctx) {
475 return new ExtractArgExpression(ctx.getStart().getStartIndex(), ctx.getStop().getStopIndex(), ctx.getChild(0).getText());
476 }
477
478 private <T extends ParseTree> Collection<T> getTargetRuleContextFromParseTree(final ParseTree parseTree, final Class<? extends T> clazz) {
479 Collection<T> result = new LinkedList<>();
480 for (int index = 0; index < parseTree.getChildCount(); index++) {
481 ParseTree child = parseTree.getChild(index);
482 if (clazz.isInstance(child)) {
483 result.add(clazz.cast(child));
484 } else {
485 result.addAll(getTargetRuleContextFromParseTree(child, clazz));
486 }
487 }
488 return result;
489 }
490
491 private Collection<ExpressionSegment> getExpressionSegments(final Collection<AExprContext> aExprContexts) {
492 Collection<ExpressionSegment> result = new LinkedList<>();
493 for (AExprContext each : aExprContexts) {
494 result.add((ExpressionSegment) visit(each));
495 }
496 return result;
497 }
498
499 @Override
500 public ASTNode visitAexprConst(final AexprConstContext ctx) {
501 LiteralValue<?> value;
502 if (null != ctx.numberConst()) {
503 value = new NumberLiteralValue(ctx.numberConst().getText());
504 } else if (null != ctx.STRING_()) {
505 value = new StringLiteralValue(ctx.STRING_().getText());
506 } else if (null != ctx.FALSE()) {
507 value = new BooleanLiteralValue(ctx.FALSE().getText());
508 } else if (null != ctx.TRUE()) {
509 value = new BooleanLiteralValue(ctx.TRUE().getText());
510 } else if (null != ctx.NULL()) {
511 value = new NullLiteralValue(ctx.getText());
512 } else {
513 value = new OtherLiteralValue(ctx.getText());
514 }
515 if (null != ctx.constTypeName() || null != ctx.funcName() && null == ctx.LP_()) {
516 LiteralExpressionSegment expression = new LiteralExpressionSegment(ctx.STRING_().getSymbol().getStartIndex(), ctx.STRING_().getSymbol().getStopIndex(), value.getValue().toString());
517 String dataType = null == ctx.constTypeName() ? ctx.funcName().getText() : ctx.constTypeName().getText();
518 return new TypeCastExpression(ctx.start.getStartIndex(), ctx.stop.getStopIndex(), ctx.getText(), expression, dataType);
519 }
520 return SQLUtils.createLiteralExpression(value, ctx.start.getStartIndex(), ctx.stop.getStopIndex(), ctx.getText());
521 }
522
523 @Override
524 public ASTNode visitColumnref(final ColumnrefContext ctx) {
525 if (null != ctx.indirection() && null != ctx.indirection().indirectionEl().attrName()) {
526 AttrNameContext attrName = ctx.indirection().indirectionEl().attrName();
527 ColumnSegment result = new ColumnSegment(ctx.start.getStartIndex(), ctx.stop.getStopIndex(), new IdentifierValue(attrName.getText()));
528 OwnerSegment owner = new OwnerSegment(ctx.colId().start.getStartIndex(), ctx.colId().stop.getStopIndex(), new IdentifierValue(ctx.colId().getText()));
529 result.setOwner(owner);
530 return result;
531 }
532 return new ColumnSegment(ctx.colId().start.getStartIndex(), ctx.colId().stop.getStopIndex(), new IdentifierValue(ctx.colId().getText()));
533 }
534
535 private InExpression createInSegment(final AExprContext ctx) {
536 ExpressionSegment left = (ExpressionSegment) visit(ctx.aExpr(0));
537 ExpressionSegment right = createInExpressionSegment(ctx.inExpr());
538 boolean not = null != ctx.NOT();
539 return new InExpression(ctx.start.getStartIndex(), ctx.stop.getStopIndex(), left, right, not);
540 }
541
542 @SuppressWarnings("unchecked")
543 private ExpressionSegment createInExpressionSegment(final InExprContext ctx) {
544 if (null != ctx.selectWithParens()) {
545 SelectStatement select = (SelectStatement) visit(ctx.selectWithParens());
546 SubquerySegment subquerySegment = new SubquerySegment(ctx.start.getStartIndex(), ctx.stop.getStopIndex(), select, getOriginalText(ctx.selectWithParens()));
547 return new SubqueryExpressionSegment(subquerySegment);
548 }
549 ListExpression result = new ListExpression(ctx.LP_().getSymbol().getStartIndex(), ctx.RP_().getSymbol().getStopIndex());
550 result.getItems().addAll(((CollectionValue<ExpressionSegment>) visit(ctx.exprList())).getValue());
551 return result;
552 }
553
554 @SuppressWarnings("unchecked")
555 @Override
556 public ASTNode visitExprList(final ExprListContext ctx) {
557 CollectionValue<ExpressionSegment> result = new CollectionValue<>();
558 if (null != ctx.exprList()) {
559 result.combine((CollectionValue<ExpressionSegment>) visitExprList(ctx.exprList()));
560 }
561 result.getValue().add((ExpressionSegment) visit(ctx.aExpr()));
562 return result;
563 }
564
565 private BetweenExpression createBetweenSegment(final AExprContext ctx) {
566 ExpressionSegment left = (ExpressionSegment) visit(ctx.aExpr(0));
567 ExpressionSegment between = (ExpressionSegment) visit(ctx.bExpr());
568 ExpressionSegment and = (ExpressionSegment) visit(ctx.aExpr(1));
569 boolean not = null != ctx.NOT();
570 return new BetweenExpression(ctx.start.getStartIndex(), ctx.stop.getStopIndex(), left, between, and, not);
571 }
572
573 @Override
574 public ASTNode visitBExpr(final BExprContext ctx) {
575 if (null != ctx.cExpr()) {
576 return visit(ctx.cExpr());
577 }
578 if (null != ctx.TYPE_CAST_()) {
579 return new TypeCastExpression(ctx.start.getStartIndex(), ctx.stop.getStopIndex(), ctx.getText(), (ExpressionSegment) visit(ctx.bExpr(0)), ctx.typeName().getText());
580 }
581 if (null != ctx.qualOp()) {
582 ExpressionSegment left = (ExpressionSegment) visit(ctx.bExpr(0));
583 ExpressionSegment right = (ExpressionSegment) visit(ctx.bExpr(1));
584 String operator = ctx.qualOp().getText();
585 String text = ctx.start.getInputStream().getText(new Interval(ctx.start.getStartIndex(), ctx.stop.getStopIndex()));
586 return new BinaryOperationExpression(ctx.start.getStartIndex(), ctx.stop.getStopIndex(), left, right, operator, text);
587 }
588 for (BExprContext each : ctx.bExpr()) {
589 visit(each);
590 }
591 return new LiteralExpressionSegment(ctx.start.getStartIndex(), ctx.stop.getStopIndex(), ctx.getText());
592 }
593
594 private ProjectionSegment createAggregationSegment(final FuncApplicationContext ctx, final String aggregationType, final Collection<ExpressionSegment> expressionSegments) {
595 AggregationType type = AggregationType.valueOf(aggregationType.toUpperCase());
596 if (null == ctx.DISTINCT()) {
597 AggregationProjectionSegment result = new AggregationProjectionSegment(ctx.getStart().getStartIndex(), ctx.getStop().getStopIndex(), type, getOriginalText(ctx));
598 result.getParameters().addAll(expressionSegments);
599 return result;
600 }
601 AggregationDistinctProjectionSegment result =
602 new AggregationDistinctProjectionSegment(ctx.getStart().getStartIndex(), ctx.getStop().getStopIndex(), type, getOriginalText(ctx), getDistinctExpression(ctx));
603 result.getParameters().addAll(expressionSegments);
604 return result;
605 }
606
607 private String getDistinctExpression(final FuncApplicationContext ctx) {
608 StringBuilder result = new StringBuilder();
609 result.append(ctx.funcArgList().getText());
610 if (null != ctx.sortClause()) {
611 result.append(ctx.sortClause().getText());
612 }
613 return result.toString();
614 }
615
616 @Override
617 public final ASTNode visitDataTypeName(final DataTypeNameContext ctx) {
618 IdentifierContext identifierContext = ctx.identifier();
619 if (null != identifierContext) {
620 return new KeywordValue(identifierContext.getText());
621 }
622 Collection<String> dataTypeNames = new LinkedList<>();
623 for (int i = 0; i < ctx.getChildCount(); i++) {
624 dataTypeNames.add(ctx.getChild(i).getText());
625 }
626 return new KeywordValue(String.join(" ", dataTypeNames));
627 }
628
629 @Override
630 public final ASTNode visitSortClause(final SortClauseContext ctx) {
631 Collection<OrderByItemSegment> items = new LinkedList<>();
632 for (SortbyContext each : ctx.sortbyList().sortby()) {
633 items.add((OrderByItemSegment) visit(each));
634 }
635 return new OrderBySegment(ctx.getStart().getStartIndex(), ctx.getStop().getStopIndex(), items);
636 }
637
638 @Override
639 public final ASTNode visitSortby(final SortbyContext ctx) {
640 OrderDirection orderDirection = null == ctx.ascDesc() ? OrderDirection.ASC : generateOrderDirection(ctx.ascDesc());
641 NullsOrderType nullsOrderType = generateNullsOrderType(ctx.nullsOrder());
642 ASTNode expr = visit(ctx.aExpr());
643 if (expr instanceof ColumnSegment) {
644 ColumnSegment column = (ColumnSegment) expr;
645 return new ColumnOrderByItemSegment(column, orderDirection, nullsOrderType);
646 }
647 if (expr instanceof LiteralExpressionSegment) {
648 LiteralExpressionSegment index = (LiteralExpressionSegment) expr;
649 return new IndexOrderByItemSegment(index.getStartIndex(), index.getStopIndex(), Integer.parseInt(index.getLiterals().toString()), orderDirection, nullsOrderType);
650 }
651 if (expr instanceof ExpressionSegment) {
652 return new ExpressionOrderByItemSegment(ctx.aExpr().getStart().getStartIndex(),
653 ctx.aExpr().getStop().getStopIndex(), getOriginalText(ctx.aExpr()), orderDirection, nullsOrderType, (ExpressionSegment) expr);
654 }
655 return new ExpressionOrderByItemSegment(ctx.aExpr().getStart().getStartIndex(), ctx.aExpr().getStop().getStopIndex(), getOriginalText(ctx.aExpr()), orderDirection, nullsOrderType);
656 }
657
658 private NullsOrderType generateNullsOrderType(final NullsOrderContext ctx) {
659 if (null == ctx) {
660 return null;
661 }
662 return null == ctx.FIRST() ? NullsOrderType.LAST : NullsOrderType.FIRST;
663 }
664
665 private OrderDirection generateOrderDirection(final AscDescContext ctx) {
666 return null == ctx.DESC() ? OrderDirection.ASC : OrderDirection.DESC;
667 }
668
669 @Override
670 public final ASTNode visitDataType(final DataTypeContext ctx) {
671 DataTypeSegment result = new DataTypeSegment();
672 result.setDataTypeName(((KeywordValue) visit(ctx.dataTypeName())).getValue());
673 result.setStartIndex(ctx.start.getStartIndex());
674 result.setStopIndex(ctx.stop.getStopIndex());
675 if (null != ctx.dataTypeLength()) {
676 DataTypeLengthSegment dataTypeLengthSegment = (DataTypeLengthSegment) visit(ctx.dataTypeLength());
677 result.setDataLength(dataTypeLengthSegment);
678 }
679 return result;
680 }
681
682 @Override
683 public final ASTNode visitDataTypeLength(final DataTypeLengthContext ctx) {
684 DataTypeLengthSegment result = new DataTypeLengthSegment();
685 result.setStartIndex(ctx.start.getStartIndex());
686 result.setStopIndex(ctx.stop.getStartIndex());
687 List<TerminalNode> numbers = ctx.NUMBER_();
688 if (1 == numbers.size()) {
689 result.setPrecision(Integer.parseInt(numbers.get(0).getText()));
690 }
691 if (2 == numbers.size()) {
692 result.setPrecision(Integer.parseInt(numbers.get(0).getText()));
693 result.setScale(Integer.parseInt(numbers.get(1).getText()));
694 }
695 return result;
696 }
697
698 @Override
699 public ASTNode visitInsert(final InsertContext ctx) {
700
701
702 InsertStatement result = (InsertStatement) visit(ctx.insertRest());
703 result.setTable((SimpleTableSegment) visit(ctx.insertTarget()));
704 if (null != ctx.optOnConflict()) {
705 result.setOnDuplicateKeyColumns((OnDuplicateKeyColumnsSegment) visit(ctx.optOnConflict()));
706 }
707 if (null != ctx.returningClause()) {
708 result.setReturning((ReturningSegment) visit(ctx.returningClause()));
709 }
710 result.addParameterMarkers(getParameterMarkerSegments());
711 return result;
712 }
713
714 @Override
715 public ASTNode visitOptOnConflict(final OptOnConflictContext ctx) {
716 Collection<ColumnAssignmentSegment> assignments = new LinkedList<>();
717 if (null != ctx.setClauseList()) {
718 assignments = ((SetAssignmentSegment) visit(ctx.setClauseList())).getAssignments();
719 }
720 return new OnDuplicateKeyColumnsSegment(ctx.getStart().getStartIndex(), ctx.getStop().getStopIndex(), assignments);
721 }
722
723 @Override
724 public ASTNode visitInsertTarget(final InsertTargetContext ctx) {
725 SimpleTableSegment result = (SimpleTableSegment) visit(ctx.qualifiedName());
726 if (null != ctx.AS()) {
727 ColIdContext colId = ctx.colId();
728 result.setAlias(new AliasSegment(colId.start.getStartIndex(), colId.stop.getStopIndex(), new IdentifierValue(colId.getText())));
729 }
730 return result;
731 }
732
733 @Override
734 public ASTNode visitQualifiedNameList(final QualifiedNameListContext ctx) {
735 CollectionValue<SimpleTableSegment> result = new CollectionValue<>();
736 if (null != ctx.qualifiedName()) {
737 result.getValue().add((SimpleTableSegment) visit(ctx.qualifiedName()));
738 }
739 if (null != ctx.qualifiedNameList()) {
740 result.combine((CollectionValue) visit(ctx.qualifiedNameList()));
741 }
742 return result;
743 }
744
745 @Override
746 public ASTNode visitQualifiedName(final QualifiedNameContext ctx) {
747 if (null != ctx.indirection()) {
748 AttrNameContext attrName = ctx.indirection().indirectionEl().attrName();
749 TableNameSegment tableName = new TableNameSegment(attrName.start.getStartIndex(), attrName.stop.getStopIndex(), new IdentifierValue(attrName.getText()));
750 OwnerSegment owner = new OwnerSegment(ctx.colId().start.getStartIndex(), ctx.colId().stop.getStopIndex(), new IdentifierValue(ctx.colId().getText()));
751 SimpleTableSegment result = new SimpleTableSegment(tableName);
752 if (null != ctx.indirection().indirection()) {
753 OwnerSegment tableOwner = createTableOwner(ctx.indirection().indirection());
754 tableOwner.setOwner(owner);
755 result.setOwner(tableOwner);
756 } else {
757 result.setOwner(owner);
758 }
759 return result;
760 }
761 return new SimpleTableSegment(new TableNameSegment(ctx.colId().start.getStartIndex(), ctx.colId().stop.getStopIndex(), new IdentifierValue(ctx.colId().getText())));
762 }
763
764 @Override
765 public ASTNode visitInsertRest(final InsertRestContext ctx) {
766 InsertStatement result = new InsertStatement(databaseType);
767 ValuesClauseContext valuesClause = ctx.select().selectNoParens().selectClauseN().simpleSelect().valuesClause();
768 if (null == valuesClause) {
769 SelectStatement selectStatement = (SelectStatement) visit(ctx.select());
770 result.setInsertSelect(new SubquerySegment(ctx.select().start.getStartIndex(), ctx.select().stop.getStopIndex(), selectStatement, getOriginalText(ctx.select())));
771 } else {
772 result.getValues().addAll(createInsertValuesSegments(valuesClause));
773 }
774 if (null == ctx.insertColumnList()) {
775 result.setInsertColumns(new InsertColumnsSegment(ctx.start.getStartIndex() - 1, ctx.start.getStartIndex() - 1, Collections.emptyList()));
776 } else {
777 InsertColumnListContext insertColumns = ctx.insertColumnList();
778 CollectionValue<ColumnSegment> columns = (CollectionValue<ColumnSegment>) visit(insertColumns);
779 InsertColumnsSegment insertColumnsSegment = new InsertColumnsSegment(insertColumns.start.getStartIndex() - 1, insertColumns.stop.getStopIndex() + 1, columns.getValue());
780 result.setInsertColumns(insertColumnsSegment);
781 }
782 return result;
783 }
784
785 @Override
786 public ASTNode visitInsertColumnList(final InsertColumnListContext ctx) {
787 CollectionValue<ColumnSegment> result = new CollectionValue<>();
788 if (null != ctx.insertColumnList()) {
789 result.getValue().addAll(((CollectionValue<ColumnSegment>) visit(ctx.insertColumnList())).getValue());
790 }
791 result.getValue().add((ColumnSegment) visit(ctx.insertColumnItem()));
792 return result;
793 }
794
795 @Override
796 public ASTNode visitInsertColumnItem(final InsertColumnItemContext ctx) {
797 if (null == ctx.optIndirection().indirectionEl()) {
798 return new ColumnSegment(ctx.colId().start.getStartIndex(), ctx.colId().stop.getStopIndex(), new IdentifierValue(ctx.colId().getText()));
799 }
800 ColumnSegment result = new ColumnSegment(ctx.colId().start.getStartIndex(), ctx.optIndirection().stop.getStopIndex(),
801 new IdentifierValue(ctx.optIndirection().indirectionEl().attrName().getText()));
802 result.setOwner(new OwnerSegment(ctx.colId().start.getStartIndex(), ctx.colId().stop.getStopIndex(), new IdentifierValue(ctx.colId().getText())));
803 return result;
804 }
805
806 private Collection<InsertValuesSegment> createInsertValuesSegments(final ValuesClauseContext ctx) {
807 Collection<InsertValuesSegment> result = new LinkedList<>();
808 if (null != ctx.valuesClause()) {
809 Collection<InsertValuesSegment> expressions = createInsertValuesSegments(ctx.valuesClause());
810 result.addAll(expressions);
811 }
812 Collection<ExpressionSegment> expressions = createInsertValuesSegments(ctx.exprList());
813 InsertValuesSegment insertValuesSegment = new InsertValuesSegment(ctx.LP_().getSymbol().getStartIndex(), ctx.RP_().getSymbol().getStopIndex(), (List<ExpressionSegment>) expressions);
814 result.add(insertValuesSegment);
815 return result;
816 }
817
818 private Collection<ExpressionSegment> createInsertValuesSegments(final ExprListContext ctx) {
819 Collection<ExpressionSegment> result = new LinkedList<>();
820 if (null != ctx.exprList()) {
821 Collection<ExpressionSegment> tmpResult = createInsertValuesSegments(ctx.exprList());
822 result.addAll(tmpResult);
823 }
824 ExpressionSegment expr = (ExpressionSegment) visit(ctx.aExpr());
825 result.add(expr);
826 return result;
827 }
828
829 private Collection<ColumnAssignmentSegment> generateAssignmentSegments(final SetClauseListContext ctx) {
830 Collection<ColumnAssignmentSegment> result = new LinkedList<>();
831 if (null != ctx.setClauseList()) {
832 Collection<ColumnAssignmentSegment> tmpResult = generateAssignmentSegments(ctx.setClauseList());
833 result.addAll(tmpResult);
834 }
835 ColumnAssignmentSegment assignmentSegment = (ColumnAssignmentSegment) visit(ctx.setClause());
836 result.add(assignmentSegment);
837 return result;
838 }
839
840 @Override
841 public ASTNode visitSetClause(final SetClauseContext ctx) {
842 ColumnSegment columnSegment = (ColumnSegment) visit(ctx.setTarget());
843 List<ColumnSegment> columnSegments = new LinkedList<>();
844 columnSegments.add(columnSegment);
845 ExpressionSegment expressionSegment = (ExpressionSegment) visit(ctx.aExpr());
846 return new ColumnAssignmentSegment(ctx.start.getStartIndex(), ctx.stop.getStopIndex(), columnSegments, expressionSegment);
847 }
848
849 @Override
850 public ASTNode visitSetTarget(final SetTargetContext ctx) {
851 IdentifierValue identifierValue = new IdentifierValue(ctx.colId().getText());
852 return new ColumnSegment(ctx.start.getStartIndex(), ctx.stop.getStopIndex(), identifierValue);
853 }
854
855 @Override
856 public ASTNode visitRelationExprOptAlias(final RelationExprOptAliasContext ctx) {
857 SimpleTableSegment result = (SimpleTableSegment) visit(ctx.relationExpr().qualifiedName());
858 if (null != ctx.colId()) {
859 result.setAlias(new AliasSegment(ctx.colId().start.getStartIndex(), ctx.stop.getStopIndex(), new IdentifierValue(ctx.colId().getText())));
860 }
861 return result;
862 }
863
864 @Override
865 public ASTNode visitUpdate(final UpdateContext ctx) {
866 UpdateStatement result = new UpdateStatement(databaseType);
867 SimpleTableSegment tableSegment = (SimpleTableSegment) visit(ctx.relationExprOptAlias());
868 result.setTable(tableSegment);
869 result.setSetAssignment((SetAssignmentSegment) visit(ctx.setClauseList()));
870 if (null != ctx.whereOrCurrentClause()) {
871 result.setWhere((WhereSegment) visit(ctx.whereOrCurrentClause()));
872 }
873 if (null != ctx.fromClause()) {
874 result.setFrom((TableSegment) visit(ctx.fromClause()));
875 }
876 result.addParameterMarkers(getParameterMarkerSegments());
877 return result;
878 }
879
880 @Override
881 public ASTNode visitSetClauseList(final SetClauseListContext ctx) {
882 Collection<ColumnAssignmentSegment> assignments = generateAssignmentSegments(ctx);
883 return new SetAssignmentSegment(ctx.start.getStartIndex() - 4, ctx.stop.getStopIndex(), assignments);
884 }
885
886 @Override
887 public ASTNode visitDelete(final DeleteContext ctx) {
888 DeleteStatement result = new DeleteStatement(databaseType);
889 SimpleTableSegment tableSegment = (SimpleTableSegment) visit(ctx.relationExprOptAlias());
890 result.setTable(tableSegment);
891 if (null != ctx.whereOrCurrentClause()) {
892 result.setWhere((WhereSegment) visit(ctx.whereOrCurrentClause()));
893 }
894 result.addParameterMarkers(getParameterMarkerSegments());
895 return result;
896 }
897
898 @Override
899 public ASTNode visitWhereOrCurrentClause(final WhereOrCurrentClauseContext ctx) {
900 return visit(ctx.whereClause());
901 }
902
903 @Override
904 public ASTNode visitSelect(final SelectContext ctx) {
905
906 SelectStatement result = (SelectStatement) visit(ctx.selectNoParens());
907 result.addParameterMarkers(getParameterMarkerSegments());
908 return result;
909 }
910
911 @Override
912 public ASTNode visitSelectNoParens(final SelectNoParensContext ctx) {
913 SelectStatement result = (SelectStatement) visit(ctx.selectClauseN());
914 if (null != ctx.sortClause()) {
915 OrderBySegment orderBySegment = (OrderBySegment) visit(ctx.sortClause());
916 result.setOrderBy(orderBySegment);
917 }
918 if (null != ctx.selectLimit()) {
919 LimitSegment limitSegment = (LimitSegment) visit(ctx.selectLimit());
920 result.setLimit(limitSegment);
921 }
922 if (null != ctx.forLockingClause()) {
923 LockSegment lockSegment = (LockSegment) visit(ctx.forLockingClause());
924 result.setLock(lockSegment);
925 }
926 if (null != ctx.withClause()) {
927 WithSegment withSegment = (WithSegment) visit(ctx.withClause());
928 result.setWith(withSegment);
929 }
930 return result;
931 }
932
933 @Override
934 public ASTNode visitWithClause(final WithClauseContext ctx) {
935 Collection<CommonTableExpressionSegment> commonTableExpressions = new LinkedList<>();
936 for (CommonTableExprContext each : ctx.cteList().commonTableExpr()) {
937 commonTableExpressions.add((CommonTableExpressionSegment) visit(each));
938 }
939 return new WithSegment(ctx.start.getStartIndex(), ctx.stop.getStopIndex(), commonTableExpressions, null != ctx.RECURSIVE());
940 }
941
942 @Override
943 public ASTNode visitCommonTableExpr(final CommonTableExprContext ctx) {
944 return new CommonTableExpressionSegment(ctx.getStart().getStartIndex(), ctx.getStop().getStopIndex(), (AliasSegment) visit(ctx.alias()),
945 new SubquerySegment(ctx.getStart().getStartIndex(), ctx.getStop().getStopIndex(), (SelectStatement) visit(ctx.preparableStmt().select()),
946 getOriginalText(ctx.preparableStmt().select())));
947 }
948
949 @Override
950 public ASTNode visitAlias(final AliasContext ctx) {
951 return new AliasSegment(ctx.start.getStartIndex(), ctx.stop.getStopIndex(), new IdentifierValue(ctx.identifier().getText()));
952 }
953
954 @Override
955 public ASTNode visitForLockingClause(final ForLockingClauseContext ctx) {
956 return new LockSegment(ctx.start.getStartIndex(), ctx.stop.getStopIndex());
957 }
958
959 @Override
960 public ASTNode visitSelectWithParens(final SelectWithParensContext ctx) {
961 if (null != ctx.selectWithParens()) {
962 return visit(ctx.selectWithParens());
963 }
964 return visit(ctx.selectNoParens());
965 }
966
967 @Override
968 public ASTNode visitSelectClauseN(final SelectClauseNContext ctx) {
969 if (null != ctx.simpleSelect()) {
970 return visit(ctx.simpleSelect());
971 }
972 if (null != ctx.selectClauseN() && !ctx.selectClauseN().isEmpty()) {
973 SelectStatement result = new SelectStatement(databaseType);
974 SelectStatement left = (SelectStatement) visit(ctx.selectClauseN(0));
975 result.setProjections(left.getProjections());
976 left.getFrom().ifPresent(result::setFrom);
977 CombineSegment combineSegment = new CombineSegment(ctx.start.getStartIndex(), ctx.stop.getStopIndex(),
978 createSubquerySegment(ctx.selectClauseN(0), left), getCombineType(ctx), createSubquerySegment(ctx.selectClauseN(1), (SelectStatement) visit(ctx.selectClauseN(1))));
979 result.setCombine(combineSegment);
980 return result;
981 }
982 return visit(ctx.selectWithParens());
983 }
984
985 private SubquerySegment createSubquerySegment(final SelectClauseNContext ctx, final SelectStatement selectStatement) {
986 return new SubquerySegment(ctx.start.getStartIndex(), ctx.stop.getStopIndex(), selectStatement, getOriginalText(ctx));
987 }
988
989 private CombineType getCombineType(final SelectClauseNContext ctx) {
990 boolean isDistinct = null == ctx.allOrDistinct() || null != ctx.allOrDistinct().DISTINCT();
991 if (null != ctx.UNION()) {
992 return isDistinct ? CombineType.UNION : CombineType.UNION_ALL;
993 }
994 if (null != ctx.INTERSECT()) {
995 return isDistinct ? CombineType.INTERSECT : CombineType.INTERSECT_ALL;
996 }
997 return isDistinct ? CombineType.EXCEPT : CombineType.EXCEPT_ALL;
998 }
999
1000 @Override
1001 public ASTNode visitSimpleSelect(final SimpleSelectContext ctx) {
1002 SelectStatement result = new SelectStatement(databaseType);
1003 if (null == ctx.targetList()) {
1004 result.setProjections(new ProjectionsSegment(-1, -1));
1005 } else {
1006 ProjectionsSegment projects = (ProjectionsSegment) visit(ctx.targetList());
1007 if (null != ctx.distinctClause()) {
1008 projects.setDistinctRow(true);
1009 }
1010 result.setProjections(projects);
1011 }
1012 if (null != ctx.intoClause()) {
1013 result.setInto((TableSegment) visit(ctx.intoClause()));
1014 }
1015 if (null != ctx.fromClause()) {
1016 TableSegment tableSegment = (TableSegment) visit(ctx.fromClause());
1017 result.setFrom(tableSegment);
1018 }
1019 if (null != ctx.whereClause()) {
1020 result.setWhere((WhereSegment) visit(ctx.whereClause()));
1021 }
1022 if (null != ctx.groupClause()) {
1023 result.setGroupBy((GroupBySegment) visit(ctx.groupClause()));
1024 }
1025 if (null != ctx.havingClause()) {
1026 result.setHaving((HavingSegment) visit(ctx.havingClause()));
1027 }
1028 if (null != ctx.windowClause()) {
1029 result.setWindow((WindowSegment) visit(ctx.windowClause()));
1030 }
1031 return result;
1032 }
1033
1034 @Override
1035 public ASTNode visitIntoClause(final IntoClauseContext ctx) {
1036 return visit(ctx.optTempTableName().qualifiedName());
1037 }
1038
1039 @Override
1040 public ASTNode visitHavingClause(final HavingClauseContext ctx) {
1041 ExpressionSegment expr = (ExpressionSegment) visit(ctx.aExpr());
1042 return new HavingSegment(ctx.getStart().getStartIndex(), ctx.getStop().getStopIndex(), expr);
1043 }
1044
1045 @Override
1046 public ASTNode visitWindowClause(final WindowClauseContext ctx) {
1047 WindowSegment result = new WindowSegment(ctx.getStart().getStartIndex(), ctx.getStop().getStopIndex());
1048 appendWindowItems(ctx.windowDefinitionList(), result.getItemSegments());
1049 return result;
1050 }
1051
1052 private void appendWindowItems(final WindowDefinitionListContext ctx, final Collection<WindowItemSegment> windowItems) {
1053 if (null != ctx.windowDefinitionList()) {
1054 appendWindowItems(ctx.windowDefinitionList(), windowItems);
1055 windowItems.add((WindowItemSegment) visit(ctx.windowDefinition()));
1056 return;
1057 }
1058 windowItems.add((WindowItemSegment) visit(ctx.windowDefinition()));
1059 }
1060
1061 @SuppressWarnings("unchecked")
1062 @Override
1063 public ASTNode visitWindowDefinition(final WindowDefinitionContext ctx) {
1064 WindowItemSegment result = new WindowItemSegment(ctx.getStart().getStartIndex(), ctx.getStop().getStopIndex());
1065 result.setWindowName(new IdentifierValue(ctx.colId().getText()));
1066 if (null != ctx.windowSpecification().partitionClause()) {
1067 CollectionValue<ExpressionSegment> value = (CollectionValue<ExpressionSegment>) visit(ctx.windowSpecification().partitionClause().exprList());
1068 result.setPartitionListSegments(value.getValue());
1069 }
1070 if (null != ctx.windowSpecification().sortClause()) {
1071 OrderBySegment orderBySegment = (OrderBySegment) visit(ctx.windowSpecification().sortClause());
1072 result.setOrderBySegment(orderBySegment);
1073 }
1074 if (null != ctx.windowSpecification().frameClause()) {
1075 result.setFrameClause(new CommonExpressionSegment(ctx.windowSpecification().frameClause().start.getStartIndex(), ctx.windowSpecification().frameClause().stop.getStopIndex(),
1076 ctx.windowSpecification().frameClause().getText()));
1077 }
1078 return result;
1079 }
1080
1081 @Override
1082 public ASTNode visitGroupClause(final GroupClauseContext ctx) {
1083 Collection<OrderByItemSegment> items = new LinkedList<>();
1084 for (GroupByItemContext each : ctx.groupByList().groupByItem()) {
1085 items.add((OrderByItemSegment) visit(each));
1086 }
1087 return new GroupBySegment(ctx.start.getStartIndex(), ctx.stop.getStopIndex(), items);
1088 }
1089
1090 @Override
1091 public ASTNode visitGroupByItem(final GroupByItemContext ctx) {
1092 if (null != ctx.aExpr()) {
1093 ASTNode astNode = visit(ctx.aExpr());
1094 if (astNode instanceof ColumnSegment) {
1095 return new ColumnOrderByItemSegment((ColumnSegment) astNode, OrderDirection.ASC, null);
1096 }
1097 if (astNode instanceof LiteralExpressionSegment) {
1098 LiteralExpressionSegment index = (LiteralExpressionSegment) astNode;
1099 return new IndexOrderByItemSegment(index.getStartIndex(), index.getStopIndex(),
1100 Integer.parseInt(index.getLiterals().toString()), OrderDirection.ASC, null);
1101 }
1102 return new ExpressionOrderByItemSegment(ctx.start.getStartIndex(), ctx.stop.getStopIndex(), getOriginalText(ctx), OrderDirection.ASC, null, (ExpressionSegment) visit(ctx.aExpr()));
1103 }
1104 return new ExpressionOrderByItemSegment(ctx.start.getStartIndex(), ctx.stop.getStopIndex(), getOriginalText(ctx), OrderDirection.ASC, null);
1105 }
1106
1107 @Override
1108 public ASTNode visitTargetList(final TargetListContext ctx) {
1109 ProjectionsSegment result = new ProjectionsSegment(ctx.start.getStartIndex(), ctx.stop.getStopIndex());
1110 if (null != ctx.targetList()) {
1111 ProjectionsSegment projections = (ProjectionsSegment) visit(ctx.targetList());
1112 result.getProjections().addAll(projections.getProjections());
1113 }
1114 ProjectionSegment projection = (ProjectionSegment) visit(ctx.targetEl());
1115 result.getProjections().add(projection);
1116 return result;
1117 }
1118
1119 @Override
1120 public ASTNode visitTargetEl(final TargetElContext ctx) {
1121 ProjectionSegment result = createProjectionSegment(ctx, ctx.aExpr());
1122 if (null != ctx.identifier()) {
1123 ((AliasAvailable) result).setAlias(new AliasSegment(ctx.identifier().start.getStartIndex(), ctx.identifier().stop.getStopIndex(), new IdentifierValue(ctx.identifier().getText())));
1124 }
1125 return result;
1126 }
1127
1128 private ProjectionSegment createProjectionSegment(final TargetElContext ctx, final AExprContext expr) {
1129 if (null != ctx.ASTERISK_()) {
1130 return new ShorthandProjectionSegment(ctx.start.getStartIndex(), ctx.stop.getStopIndex());
1131 }
1132 if (null != ctx.DOT_ASTERISK_()) {
1133 ShorthandProjectionSegment result = new ShorthandProjectionSegment(ctx.start.getStartIndex(), ctx.stop.getStopIndex());
1134 result.setOwner(new OwnerSegment(ctx.colId().start.getStartIndex(), ctx.colId().stop.getStopIndex(), new IdentifierValue(ctx.colId().getText())));
1135 return result;
1136 }
1137 if (null != ctx.aExpr()) {
1138 ASTNode projection = visit(ctx.aExpr());
1139 return createProjectionSegment(ctx, expr, projection);
1140 }
1141 return new ExpressionProjectionSegment(ctx.start.getStartIndex(), ctx.stop.getStopIndex(), getOriginalText(expr), null);
1142 }
1143
1144 private ProjectionSegment createProjectionSegment(final TargetElContext ctx, final AExprContext expr, final ASTNode projection) {
1145 if (projection instanceof ColumnSegment) {
1146 return new ColumnProjectionSegment((ColumnSegment) projection);
1147 }
1148 if (projection instanceof AggregationProjectionSegment) {
1149 return (AggregationProjectionSegment) projection;
1150 }
1151 if (projection instanceof SubqueryExpressionSegment) {
1152 SubqueryExpressionSegment subqueryExpression = (SubqueryExpressionSegment) projection;
1153 String text = ctx.start.getInputStream().getText(new Interval(subqueryExpression.getStartIndex(), subqueryExpression.getStopIndex()));
1154 return new SubqueryProjectionSegment(subqueryExpression.getSubquery(), text);
1155 }
1156 if (projection instanceof ExpressionSegment) {
1157 return new ExpressionProjectionSegment(ctx.start.getStartIndex(), ctx.stop.getStopIndex(), getOriginalText(expr), (ExpressionSegment) projection);
1158 }
1159 return new ExpressionProjectionSegment(ctx.start.getStartIndex(), ctx.stop.getStopIndex(), getOriginalText(expr), null);
1160 }
1161
1162 @Override
1163 public ASTNode visitFromClause(final FromClauseContext ctx) {
1164 return visit(ctx.fromList());
1165 }
1166
1167 @Override
1168 public ASTNode visitFromList(final FromListContext ctx) {
1169 if (null != ctx.fromList()) {
1170 JoinTableSegment result = new JoinTableSegment();
1171 result.setStartIndex(ctx.start.getStartIndex());
1172 result.setStopIndex(ctx.stop.getStopIndex());
1173 result.setLeft((TableSegment) visit(ctx.fromList()));
1174 result.setRight((TableSegment) visit(ctx.tableReference()));
1175 result.setJoinType(JoinType.COMMA.name());
1176 return result;
1177 }
1178 return visit(ctx.tableReference());
1179 }
1180
1181 @Override
1182 public ASTNode visitTableReference(final TableReferenceContext ctx) {
1183 if (null != ctx.relationExpr()) {
1184 return getSimpleTableSegment(ctx);
1185 }
1186 if (null != ctx.selectWithParens()) {
1187 return getSubqueryTableSegment(ctx);
1188 }
1189 if (null != ctx.tableReference()) {
1190 return getJoinTableSegment(ctx);
1191 }
1192 if (null != ctx.functionTable() && null != ctx.functionTable().functionExprWindowless() && null != ctx.functionTable().functionExprWindowless().funcApplication()) {
1193 return getFunctionTableSegment(ctx);
1194 }
1195
1196 return new SimpleTableSegment(new TableNameSegment(ctx.start.getStartIndex(), ctx.stop.getStopIndex(), new IdentifierValue("not support")));
1197 }
1198
1199 private SimpleTableSegment getSimpleTableSegment(final TableReferenceContext ctx) {
1200 SimpleTableSegment result = (SimpleTableSegment) visit(ctx.relationExpr().qualifiedName());
1201 if (null != ctx.aliasClause()) {
1202 result.setAlias((AliasSegment) visit(ctx.aliasClause()));
1203 }
1204 return result;
1205 }
1206
1207 private SubqueryTableSegment getSubqueryTableSegment(final TableReferenceContext ctx) {
1208 SelectStatement select = (SelectStatement) visit(ctx.selectWithParens());
1209 SubquerySegment subquery = new SubquerySegment(ctx.selectWithParens().start.getStartIndex(), ctx.selectWithParens().stop.getStopIndex(), select, getOriginalText(ctx.selectWithParens()));
1210 AliasSegment alias = null == ctx.aliasClause() ? null : (AliasSegment) visit(ctx.aliasClause());
1211 SubqueryTableSegment result = new SubqueryTableSegment(ctx.start.getStartIndex(), ctx.stop.getStopIndex(), subquery);
1212 result.setAlias(alias);
1213 return result;
1214 }
1215
1216 private ASTNode getJoinTableSegment(final TableReferenceContext ctx) {
1217 JoinTableSegment result = new JoinTableSegment();
1218 result.setLeft((TableSegment) visit(ctx.tableReference()));
1219 int startIndex = null == ctx.LP_() ? ctx.tableReference().start.getStartIndex() : ctx.LP_().getSymbol().getStartIndex();
1220 int stopIndex = 0;
1221 AliasSegment alias = null;
1222 if (null == ctx.aliasClause()) {
1223 stopIndex = null == ctx.RP_() ? ctx.tableReference().start.getStopIndex() : ctx.RP_().getSymbol().getStopIndex();
1224 } else {
1225 alias = (AliasSegment) visit(ctx.aliasClause());
1226 startIndex = null == ctx.RP_() ? ctx.joinedTable().stop.getStopIndex() : ctx.RP_().getSymbol().getStopIndex();
1227 }
1228 result.setStartIndex(startIndex);
1229 result.setStopIndex(stopIndex);
1230 visitJoinedTable(ctx.joinedTable(), result);
1231 result.setAlias(alias);
1232 return result;
1233 }
1234
1235 private FunctionTableSegment getFunctionTableSegment(final TableReferenceContext ctx) {
1236 FunctionSegment functionSegment = (FunctionSegment) visit(ctx.functionTable().functionExprWindowless().funcApplication());
1237 return new FunctionTableSegment(ctx.start.getStartIndex(), ctx.stop.getStopIndex(), functionSegment);
1238 }
1239
1240 @Override
1241 public ASTNode visitFuncApplication(final FuncApplicationContext ctx) {
1242 Collection<ExpressionSegment> expressionSegments = getExpressionSegments(getTargetRuleContextFromParseTree(ctx, AExprContext.class));
1243 FuncNameContext funcNameContext = ctx.funcName();
1244 String functionName = null == funcNameContext.typeFunctionName() ? funcNameContext.indirection().indirectionEl().attrName().getText() : funcNameContext.typeFunctionName().getText();
1245 if (AggregationType.isAggregationType(functionName)) {
1246 return createAggregationSegment(ctx, functionName, expressionSegments);
1247 }
1248 FunctionSegment result = new FunctionSegment(ctx.start.getStartIndex(), ctx.stop.getStopIndex(), functionName, getOriginalText(ctx));
1249 if (null != funcNameContext.colId()) {
1250 result.setOwner(new OwnerSegment(funcNameContext.colId().start.getStartIndex(), funcNameContext.colId().stop.getStopIndex(), new IdentifierValue(funcNameContext.colId().getText())));
1251 }
1252 result.getParameters().addAll(expressionSegments);
1253 return result;
1254 }
1255
1256 private void visitJoinedTable(final JoinedTableContext ctx, final JoinTableSegment tableSegment) {
1257 TableSegment right = (TableSegment) visit(ctx.tableReference());
1258 tableSegment.setRight(right);
1259 tableSegment.setJoinType(getJoinType(ctx));
1260 tableSegment.setNatural(null != ctx.naturalJoinType());
1261 if (null != ctx.joinQual()) {
1262 visitJoinQual(ctx.joinQual(), tableSegment);
1263 }
1264 }
1265
1266 private String getJoinType(final JoinedTableContext ctx) {
1267 if (null != ctx.crossJoinType()) {
1268 return JoinType.CROSS.name();
1269 }
1270 if (null != ctx.innerJoinType()) {
1271 return JoinType.INNER.name();
1272 }
1273 if (null != ctx.outerJoinType()) {
1274 return getOutJoinType(ctx.outerJoinType());
1275 }
1276 if (null != ctx.naturalJoinType()) {
1277 return getNaturalJoinType(ctx.naturalJoinType());
1278 }
1279 return JoinType.COMMA.name();
1280 }
1281
1282 private static String getNaturalJoinType(final NaturalJoinTypeContext ctx) {
1283 if (null != ctx.INNER()) {
1284 return JoinType.INNER.name();
1285 }
1286 if (null != ctx.FULL()) {
1287 return JoinType.FULL.name();
1288 }
1289 if (null != ctx.LEFT()) {
1290 return JoinType.LEFT.name();
1291 }
1292 if (null != ctx.RIGHT()) {
1293 return JoinType.RIGHT.name();
1294 }
1295 return JoinType.INNER.name();
1296 }
1297
1298 private static String getOutJoinType(final OuterJoinTypeContext ctx) {
1299 if (null == ctx.FULL()) {
1300 return null == ctx.LEFT() ? JoinType.RIGHT.name() : JoinType.LEFT.name();
1301 }
1302 return JoinType.FULL.name();
1303 }
1304
1305 private void visitJoinQual(final JoinQualContext ctx, final JoinTableSegment joinTableSource) {
1306 if (null != ctx.aExpr()) {
1307 ExpressionSegment condition = (ExpressionSegment) visit(ctx.aExpr());
1308 joinTableSource.setCondition(condition);
1309 }
1310 if (null != ctx.USING()) {
1311 joinTableSource.setUsing(generateUsingColumn(ctx.nameList()));
1312 }
1313 }
1314
1315 private List<ColumnSegment> generateUsingColumn(final NameListContext ctx) {
1316 List<ColumnSegment> result = new ArrayList<>();
1317 if (null != ctx.nameList()) {
1318 result.addAll(generateUsingColumn(ctx.nameList()));
1319 }
1320 if (null != ctx.name()) {
1321 result.add(new ColumnSegment(ctx.name().start.getStartIndex(), ctx.name().stop.getStopIndex(), new IdentifierValue(ctx.name().getText())));
1322 }
1323 return result;
1324 }
1325
1326 @Override
1327 public ASTNode visitAliasClause(final AliasClauseContext ctx) {
1328 StringBuilder aliasName = new StringBuilder(ctx.colId().getText());
1329 if (null != ctx.nameList()) {
1330 aliasName.append(ctx.LP_().getText());
1331 aliasName.append(ctx.nameList().getText());
1332 aliasName.append(ctx.RP_().getText());
1333 }
1334 return new AliasSegment(ctx.colId().start.getStartIndex(), ctx.stop.getStopIndex(), new IdentifierValue(aliasName.toString()));
1335 }
1336
1337 private OwnerSegment createTableOwner(final IndirectionContext ctx) {
1338 AttrNameContext attrName = ctx.indirectionEl().attrName();
1339 return new OwnerSegment(attrName.start.getStartIndex(), attrName.stop.getStopIndex(), new IdentifierValue(attrName.getText()));
1340 }
1341
1342 @Override
1343 public ASTNode visitWhereClause(final WhereClauseContext ctx) {
1344 ExpressionSegment expr = (ExpressionSegment) visit(ctx.aExpr());
1345 return new WhereSegment(ctx.getStart().getStartIndex(), ctx.getStop().getStopIndex(), expr);
1346 }
1347
1348 @Override
1349 public ASTNode visitSelectLimit(final SelectLimitContext ctx) {
1350 if (null != ctx.limitClause() && null != ctx.offsetClause()) {
1351 return createLimitSegmentWhenLimitAndOffset(ctx);
1352 }
1353 return createLimitSegmentWhenRowCountOrOffsetAbsent(ctx);
1354 }
1355
1356 @Override
1357 public ASTNode visitSelectLimitValue(final SelectLimitValueContext ctx) {
1358 if (null != ctx.ALL()) {
1359 return null;
1360 }
1361 ASTNode astNode = visit(ctx.cExpr());
1362 if (astNode instanceof ParameterMarkerExpressionSegment) {
1363 return new ParameterMarkerLimitValueSegment(ctx.getStart().getStartIndex(), ctx.getStop().getStopIndex(), ((ParameterMarkerExpressionSegment) astNode).getParameterMarkerIndex());
1364 }
1365 return new NumberLiteralLimitValueSegment(ctx.start.getStartIndex(), ctx.stop.getStopIndex(),
1366 (null == ((ExpressionSegment) astNode).getText()) ? null : Long.parseLong(((ExpressionSegment) astNode).getText()));
1367 }
1368
1369 @Override
1370 public ASTNode visitSelectOffsetValue(final SelectOffsetValueContext ctx) {
1371 ASTNode astNode = visit(ctx.cExpr());
1372 if (astNode instanceof ParameterMarkerExpressionSegment) {
1373 return new ParameterMarkerLimitValueSegment(ctx.getStart().getStartIndex(), ctx.getStop().getStopIndex(), ((ParameterMarkerExpressionSegment) astNode).getParameterMarkerIndex());
1374 }
1375 return new NumberLiteralLimitValueSegment(ctx.start.getStartIndex(), ctx.stop.getStopIndex(),
1376 (null == ((ExpressionSegment) astNode).getText()) ? null : Long.parseLong(((ExpressionSegment) astNode).getText()));
1377 }
1378
1379 @Override
1380 public ASTNode visitSelectFetchValue(final SelectFetchValueContext ctx) {
1381 ASTNode astNode = visit(ctx.cExpr());
1382 if (astNode instanceof ParameterMarkerExpressionSegment) {
1383 return new ParameterMarkerLimitValueSegment(ctx.getStart().getStartIndex(), ctx.getStop().getStopIndex(), ((ParameterMarkerExpressionSegment) astNode).getParameterMarkerIndex());
1384 }
1385 return new NumberLiteralLimitValueSegment(ctx.start.getStartIndex(), ctx.stop.getStopIndex(),
1386 (null == ((ExpressionSegment) astNode).getText()) ? null : Long.parseLong(((ExpressionSegment) astNode).getText()));
1387 }
1388
1389 private LimitSegment createLimitSegmentWhenLimitAndOffset(final SelectLimitContext ctx) {
1390 ParseTree astNode0 = ctx.getChild(0);
1391 LimitValueSegment rowCount = null;
1392 LimitValueSegment offset = null;
1393 if (astNode0 instanceof LimitClauseContext) {
1394 rowCount = null == ctx.limitClause().selectLimitValue() ? null : (LimitValueSegment) visit(ctx.limitClause().selectLimitValue());
1395 } else {
1396 offset = (LimitValueSegment) visit(ctx.offsetClause().selectOffsetValue());
1397 }
1398 ParseTree astNode1 = ctx.getChild(1);
1399 if (astNode1 instanceof LimitClauseContext) {
1400 rowCount = null == ctx.limitClause().selectLimitValue() ? null : (LimitValueSegment) visit(ctx.limitClause().selectLimitValue());
1401 } else {
1402 offset = (LimitValueSegment) visit(ctx.offsetClause().selectOffsetValue());
1403 }
1404 return new LimitSegment(ctx.getStart().getStartIndex(), ctx.getStop().getStopIndex(), offset, rowCount);
1405 }
1406
1407 private LimitSegment createLimitSegmentWhenRowCountOrOffsetAbsent(final SelectLimitContext ctx) {
1408 if (null != ctx.limitClause()) {
1409 if (null != ctx.limitClause().selectFetchValue()) {
1410 LimitValueSegment limit = (LimitValueSegment) visit(ctx.limitClause().selectFetchValue());
1411 return new LimitSegment(ctx.getStart().getStartIndex(), ctx.getStop().getStopIndex(), null, limit);
1412 }
1413 LimitValueSegment limit = (LimitValueSegment) visit(ctx.limitClause().selectLimitValue());
1414 return new LimitSegment(ctx.getStart().getStartIndex(), ctx.getStop().getStopIndex(), null, limit);
1415 }
1416 LimitValueSegment offset = (LimitValueSegment) visit(ctx.offsetClause().selectOffsetValue());
1417 return new LimitSegment(ctx.getStart().getStartIndex(), ctx.getStop().getStopIndex(), offset, null);
1418 }
1419
1420 @Override
1421 public ASTNode visitExecuteStmt(final ExecuteStmtContext ctx) {
1422 return new ExecuteStatement(databaseType);
1423 }
1424
1425
1426
1427
1428
1429
1430
1431 protected String getOriginalText(final ParserRuleContext ctx) {
1432 return ctx.start.getInputStream().getText(new Interval(ctx.start.getStartIndex(), ctx.stop.getStopIndex()));
1433 }
1434
1435 @Override
1436 @SuppressWarnings("unchecked")
1437 public ASTNode visitAnyName(final AnyNameContext ctx) {
1438 CollectionValue<NameSegment> result = new CollectionValue<>();
1439 if (null != ctx.attrs()) {
1440 result.combine((CollectionValue<NameSegment>) visit(ctx.attrs()));
1441 }
1442 result.getValue().add(new NameSegment(ctx.colId().getStart().getStartIndex(), ctx.colId().getStop().getStopIndex(), new IdentifierValue(ctx.colId().getText())));
1443 return result;
1444 }
1445
1446 @Override
1447 @SuppressWarnings("unchecked")
1448 public ASTNode visitAttrs(final AttrsContext ctx) {
1449 CollectionValue<NameSegment> result = new CollectionValue<>();
1450 result.getValue().add(new NameSegment(ctx.attrName().getStart().getStartIndex(), ctx.attrName().getStop().getStopIndex(), new IdentifierValue(ctx.attrName().getText())));
1451 if (null != ctx.attrs()) {
1452 result.combine((CollectionValue<NameSegment>) visit(ctx.attrs()));
1453 }
1454 return result;
1455 }
1456
1457 @Override
1458 public ASTNode visitName(final NameContext ctx) {
1459 return visit(ctx.identifier());
1460 }
1461
1462 @Override
1463 public ASTNode visitHostVariable(final HostVariableContext ctx) {
1464 return visit(ctx.identifier());
1465 }
1466
1467 @Override
1468 public ASTNode visitSignedIconst(final SignedIconstContext ctx) {
1469 return new NumberLiteralValue(ctx.getText());
1470 }
1471 }