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