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