1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 package org.apache.shardingsphere.sql.parser.sqlserver.visitor.statement;
19
20 import lombok.AccessLevel;
21 import lombok.Getter;
22 import org.antlr.v4.runtime.ParserRuleContext;
23 import org.antlr.v4.runtime.Token;
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.sql.parser.api.ASTNode;
28 import org.apache.shardingsphere.sql.parser.autogen.SQLServerStatementBaseVisitor;
29 import org.apache.shardingsphere.sql.parser.autogen.SQLServerStatementParser.AggregationClauseContext;
30 import org.apache.shardingsphere.sql.parser.autogen.SQLServerStatementParser.AggregationFunctionContext;
31 import org.apache.shardingsphere.sql.parser.autogen.SQLServerStatementParser.AliasContext;
32 import org.apache.shardingsphere.sql.parser.autogen.SQLServerStatementParser.ApproxFunctionContext;
33 import org.apache.shardingsphere.sql.parser.autogen.SQLServerStatementParser.AssignmentContext;
34 import org.apache.shardingsphere.sql.parser.autogen.SQLServerStatementParser.AssignmentValueContext;
35 import org.apache.shardingsphere.sql.parser.autogen.SQLServerStatementParser.AssignmentValuesContext;
36 import org.apache.shardingsphere.sql.parser.autogen.SQLServerStatementParser.BitExprContext;
37 import org.apache.shardingsphere.sql.parser.autogen.SQLServerStatementParser.BitValueLiteralsContext;
38 import org.apache.shardingsphere.sql.parser.autogen.SQLServerStatementParser.BooleanLiteralsContext;
39 import org.apache.shardingsphere.sql.parser.autogen.SQLServerStatementParser.BooleanPrimaryContext;
40 import org.apache.shardingsphere.sql.parser.autogen.SQLServerStatementParser.CastFunctionContext;
41 import org.apache.shardingsphere.sql.parser.autogen.SQLServerStatementParser.CharFunctionContext;
42 import org.apache.shardingsphere.sql.parser.autogen.SQLServerStatementParser.ColumnNameContext;
43 import org.apache.shardingsphere.sql.parser.autogen.SQLServerStatementParser.ColumnNameWithSortContext;
44 import org.apache.shardingsphere.sql.parser.autogen.SQLServerStatementParser.ColumnNamesContext;
45 import org.apache.shardingsphere.sql.parser.autogen.SQLServerStatementParser.ColumnNamesWithSortContext;
46 import org.apache.shardingsphere.sql.parser.autogen.SQLServerStatementParser.ConstraintNameContext;
47 import org.apache.shardingsphere.sql.parser.autogen.SQLServerStatementParser.ConversionFunctionContext;
48 import org.apache.shardingsphere.sql.parser.autogen.SQLServerStatementParser.ConvertFunctionContext;
49 import org.apache.shardingsphere.sql.parser.autogen.SQLServerStatementParser.CreateTableAsSelectClauseContext;
50 import org.apache.shardingsphere.sql.parser.autogen.SQLServerStatementParser.CteClauseContext;
51 import org.apache.shardingsphere.sql.parser.autogen.SQLServerStatementParser.CteClauseSetContext;
52 import org.apache.shardingsphere.sql.parser.autogen.SQLServerStatementParser.DataTypeContext;
53 import org.apache.shardingsphere.sql.parser.autogen.SQLServerStatementParser.DataTypeLengthContext;
54 import org.apache.shardingsphere.sql.parser.autogen.SQLServerStatementParser.DataTypeNameContext;
55 import org.apache.shardingsphere.sql.parser.autogen.SQLServerStatementParser.DatabaseNameContext;
56 import org.apache.shardingsphere.sql.parser.autogen.SQLServerStatementParser.DeleteContext;
57 import org.apache.shardingsphere.sql.parser.autogen.SQLServerStatementParser.DelimitedIdentifierContext;
58 import org.apache.shardingsphere.sql.parser.autogen.SQLServerStatementParser.DuplicateSpecificationContext;
59 import org.apache.shardingsphere.sql.parser.autogen.SQLServerStatementParser.ExecContext;
60 import org.apache.shardingsphere.sql.parser.autogen.SQLServerStatementParser.ExprContext;
61 import org.apache.shardingsphere.sql.parser.autogen.SQLServerStatementParser.FromClauseContext;
62 import org.apache.shardingsphere.sql.parser.autogen.SQLServerStatementParser.FunctionCallContext;
63 import org.apache.shardingsphere.sql.parser.autogen.SQLServerStatementParser.GraphAggFunctionContext;
64 import org.apache.shardingsphere.sql.parser.autogen.SQLServerStatementParser.GraphFunctionContext;
65 import org.apache.shardingsphere.sql.parser.autogen.SQLServerStatementParser.GroupByClauseContext;
66 import org.apache.shardingsphere.sql.parser.autogen.SQLServerStatementParser.HavingClauseContext;
67 import org.apache.shardingsphere.sql.parser.autogen.SQLServerStatementParser.HexadecimalLiteralsContext;
68 import org.apache.shardingsphere.sql.parser.autogen.SQLServerStatementParser.IdentifierContext;
69 import org.apache.shardingsphere.sql.parser.autogen.SQLServerStatementParser.IndexNameContext;
70 import org.apache.shardingsphere.sql.parser.autogen.SQLServerStatementParser.InsertContext;
71 import org.apache.shardingsphere.sql.parser.autogen.SQLServerStatementParser.InsertDefaultValueContext;
72 import org.apache.shardingsphere.sql.parser.autogen.SQLServerStatementParser.InsertExecClauseContext;
73 import org.apache.shardingsphere.sql.parser.autogen.SQLServerStatementParser.InsertSelectClauseContext;
74 import org.apache.shardingsphere.sql.parser.autogen.SQLServerStatementParser.InsertValuesClauseContext;
75 import org.apache.shardingsphere.sql.parser.autogen.SQLServerStatementParser.IntoClauseContext;
76 import org.apache.shardingsphere.sql.parser.autogen.SQLServerStatementParser.JoinSpecificationContext;
77 import org.apache.shardingsphere.sql.parser.autogen.SQLServerStatementParser.JoinedTableContext;
78 import org.apache.shardingsphere.sql.parser.autogen.SQLServerStatementParser.JsonArrayFunctionContext;
79 import org.apache.shardingsphere.sql.parser.autogen.SQLServerStatementParser.JsonFunctionContext;
80 import org.apache.shardingsphere.sql.parser.autogen.SQLServerStatementParser.JsonKeyValueContext;
81 import org.apache.shardingsphere.sql.parser.autogen.SQLServerStatementParser.JsonNullClauseContext;
82 import org.apache.shardingsphere.sql.parser.autogen.SQLServerStatementParser.JsonObjectFunctionContext;
83 import org.apache.shardingsphere.sql.parser.autogen.SQLServerStatementParser.LiteralsContext;
84 import org.apache.shardingsphere.sql.parser.autogen.SQLServerStatementParser.MergeContext;
85 import org.apache.shardingsphere.sql.parser.autogen.SQLServerStatementParser.MergeInsertClauseContext;
86 import org.apache.shardingsphere.sql.parser.autogen.SQLServerStatementParser.MergeUpdateClauseContext;
87 import org.apache.shardingsphere.sql.parser.autogen.SQLServerStatementParser.MergeWhenClauseContext;
88 import org.apache.shardingsphere.sql.parser.autogen.SQLServerStatementParser.MultipleTableNamesContext;
89 import org.apache.shardingsphere.sql.parser.autogen.SQLServerStatementParser.MultipleTablesClauseContext;
90 import org.apache.shardingsphere.sql.parser.autogen.SQLServerStatementParser.NullValueLiteralsContext;
91 import org.apache.shardingsphere.sql.parser.autogen.SQLServerStatementParser.NumberLiteralsContext;
92 import org.apache.shardingsphere.sql.parser.autogen.SQLServerStatementParser.OpenJsonFunctionContext;
93 import org.apache.shardingsphere.sql.parser.autogen.SQLServerStatementParser.OpenQueryFunctionContext;
94 import org.apache.shardingsphere.sql.parser.autogen.SQLServerStatementParser.OpenRowSetFunctionContext;
95 import org.apache.shardingsphere.sql.parser.autogen.SQLServerStatementParser.OptionHintContext;
96 import org.apache.shardingsphere.sql.parser.autogen.SQLServerStatementParser.OrderByClauseContext;
97 import org.apache.shardingsphere.sql.parser.autogen.SQLServerStatementParser.OrderByItemContext;
98 import org.apache.shardingsphere.sql.parser.autogen.SQLServerStatementParser.OutputClauseContext;
99 import org.apache.shardingsphere.sql.parser.autogen.SQLServerStatementParser.OutputWithColumnContext;
100 import org.apache.shardingsphere.sql.parser.autogen.SQLServerStatementParser.OutputWithColumnsContext;
101 import org.apache.shardingsphere.sql.parser.autogen.SQLServerStatementParser.OwnerContext;
102 import org.apache.shardingsphere.sql.parser.autogen.SQLServerStatementParser.ParameterMarkerContext;
103 import org.apache.shardingsphere.sql.parser.autogen.SQLServerStatementParser.PredicateContext;
104 import org.apache.shardingsphere.sql.parser.autogen.SQLServerStatementParser.ProcedureNameContext;
105 import org.apache.shardingsphere.sql.parser.autogen.SQLServerStatementParser.ProjectionContext;
106 import org.apache.shardingsphere.sql.parser.autogen.SQLServerStatementParser.ProjectionsContext;
107 import org.apache.shardingsphere.sql.parser.autogen.SQLServerStatementParser.QualifiedShorthandContext;
108 import org.apache.shardingsphere.sql.parser.autogen.SQLServerStatementParser.RegularFunctionContext;
109 import org.apache.shardingsphere.sql.parser.autogen.SQLServerStatementParser.RegularIdentifierContext;
110 import org.apache.shardingsphere.sql.parser.autogen.SQLServerStatementParser.RowSetFunctionContext;
111 import org.apache.shardingsphere.sql.parser.autogen.SQLServerStatementParser.SampleOptionContext;
112 import org.apache.shardingsphere.sql.parser.autogen.SQLServerStatementParser.ScalarExpressionContext;
113 import org.apache.shardingsphere.sql.parser.autogen.SQLServerStatementParser.SchemaNameContext;
114 import org.apache.shardingsphere.sql.parser.autogen.SQLServerStatementParser.ScriptVariableNameContext;
115 import org.apache.shardingsphere.sql.parser.autogen.SQLServerStatementParser.SelectClauseContext;
116 import org.apache.shardingsphere.sql.parser.autogen.SQLServerStatementParser.SelectContext;
117 import org.apache.shardingsphere.sql.parser.autogen.SQLServerStatementParser.SetAssignmentsClauseContext;
118 import org.apache.shardingsphere.sql.parser.autogen.SQLServerStatementParser.SimpleExprContext;
119 import org.apache.shardingsphere.sql.parser.autogen.SQLServerStatementParser.SingleTableClauseContext;
120 import org.apache.shardingsphere.sql.parser.autogen.SQLServerStatementParser.SpecialFunctionContext;
121 import org.apache.shardingsphere.sql.parser.autogen.SQLServerStatementParser.StatisticsOptionContext;
122 import org.apache.shardingsphere.sql.parser.autogen.SQLServerStatementParser.StatisticsOptionsContext;
123 import org.apache.shardingsphere.sql.parser.autogen.SQLServerStatementParser.StatisticsWithClauseContext;
124 import org.apache.shardingsphere.sql.parser.autogen.SQLServerStatementParser.StringLiteralsContext;
125 import org.apache.shardingsphere.sql.parser.autogen.SQLServerStatementParser.SubqueryContext;
126 import org.apache.shardingsphere.sql.parser.autogen.SQLServerStatementParser.TableFactorContext;
127 import org.apache.shardingsphere.sql.parser.autogen.SQLServerStatementParser.TableHintLimitedContext;
128 import org.apache.shardingsphere.sql.parser.autogen.SQLServerStatementParser.TableNameContext;
129 import org.apache.shardingsphere.sql.parser.autogen.SQLServerStatementParser.TableNamesContext;
130 import org.apache.shardingsphere.sql.parser.autogen.SQLServerStatementParser.TableReferenceContext;
131 import org.apache.shardingsphere.sql.parser.autogen.SQLServerStatementParser.TableReferencesContext;
132 import org.apache.shardingsphere.sql.parser.autogen.SQLServerStatementParser.TopContext;
133 import org.apache.shardingsphere.sql.parser.autogen.SQLServerStatementParser.TrimFunctionContext;
134 import org.apache.shardingsphere.sql.parser.autogen.SQLServerStatementParser.UnreservedWordContext;
135 import org.apache.shardingsphere.sql.parser.autogen.SQLServerStatementParser.UpdateContext;
136 import org.apache.shardingsphere.sql.parser.autogen.SQLServerStatementParser.UpdateStatisticsContext;
137 import org.apache.shardingsphere.sql.parser.autogen.SQLServerStatementParser.ViewNameContext;
138 import org.apache.shardingsphere.sql.parser.autogen.SQLServerStatementParser.WhereClauseContext;
139 import org.apache.shardingsphere.sql.parser.autogen.SQLServerStatementParser.WindowFunctionContext;
140 import org.apache.shardingsphere.sql.parser.autogen.SQLServerStatementParser.WithClauseContext;
141 import org.apache.shardingsphere.sql.parser.autogen.SQLServerStatementParser.WithTableHintContext;
142 import org.apache.shardingsphere.sql.parser.statement.core.enums.AggregationType;
143 import org.apache.shardingsphere.sql.parser.statement.core.enums.JoinType;
144 import org.apache.shardingsphere.sql.parser.statement.core.enums.OrderDirection;
145 import org.apache.shardingsphere.sql.parser.statement.core.enums.ParameterMarkerType;
146 import org.apache.shardingsphere.sql.parser.statement.core.enums.ScanUnit;
147 import org.apache.shardingsphere.sql.parser.statement.core.enums.StatisticsDimension;
148 import org.apache.shardingsphere.sql.parser.statement.core.segment.SQLSegment;
149 import org.apache.shardingsphere.sql.parser.statement.core.segment.ddl.constraint.ConstraintSegment;
150 import org.apache.shardingsphere.sql.parser.statement.core.segment.ddl.index.IndexNameSegment;
151 import org.apache.shardingsphere.sql.parser.statement.core.segment.ddl.index.IndexSegment;
152 import org.apache.shardingsphere.sql.parser.statement.core.segment.ddl.routine.FunctionNameSegment;
153 import org.apache.shardingsphere.sql.parser.statement.core.segment.dml.assignment.ColumnAssignmentSegment;
154 import org.apache.shardingsphere.sql.parser.statement.core.segment.dml.assignment.InsertValuesSegment;
155 import org.apache.shardingsphere.sql.parser.statement.core.segment.dml.assignment.SetAssignmentSegment;
156 import org.apache.shardingsphere.sql.parser.statement.core.segment.dml.column.ColumnSegment;
157 import org.apache.shardingsphere.sql.parser.statement.core.segment.dml.column.InsertColumnsSegment;
158 import org.apache.shardingsphere.sql.parser.statement.core.segment.dml.exec.ExecSegment;
159 import org.apache.shardingsphere.sql.parser.statement.core.segment.dml.expr.BetweenExpression;
160 import org.apache.shardingsphere.sql.parser.statement.core.segment.dml.expr.BinaryOperationExpression;
161 import org.apache.shardingsphere.sql.parser.statement.core.segment.dml.expr.ExpressionSegment;
162 import org.apache.shardingsphere.sql.parser.statement.core.segment.dml.expr.ExpressionWithParamsSegment;
163 import org.apache.shardingsphere.sql.parser.statement.core.segment.dml.expr.FunctionSegment;
164 import org.apache.shardingsphere.sql.parser.statement.core.segment.dml.expr.InExpression;
165 import org.apache.shardingsphere.sql.parser.statement.core.segment.dml.expr.KeyValueSegment;
166 import org.apache.shardingsphere.sql.parser.statement.core.segment.dml.expr.ListExpression;
167 import org.apache.shardingsphere.sql.parser.statement.core.segment.dml.expr.NotExpression;
168 import org.apache.shardingsphere.sql.parser.statement.core.segment.dml.expr.complex.CommonExpressionSegment;
169 import org.apache.shardingsphere.sql.parser.statement.core.segment.dml.expr.complex.CommonTableExpressionSegment;
170 import org.apache.shardingsphere.sql.parser.statement.core.segment.dml.expr.simple.LiteralExpressionSegment;
171 import org.apache.shardingsphere.sql.parser.statement.core.segment.dml.expr.simple.ParameterMarkerExpressionSegment;
172 import org.apache.shardingsphere.sql.parser.statement.core.segment.dml.expr.subquery.SubqueryExpressionSegment;
173 import org.apache.shardingsphere.sql.parser.statement.core.segment.dml.expr.subquery.SubquerySegment;
174 import org.apache.shardingsphere.sql.parser.statement.core.segment.dml.hint.OptionHintSegment;
175 import org.apache.shardingsphere.sql.parser.statement.core.segment.dml.hint.TableHintLimitedSegment;
176 import org.apache.shardingsphere.sql.parser.statement.core.segment.dml.hint.WithTableHintSegment;
177 import org.apache.shardingsphere.sql.parser.statement.core.segment.dml.item.AggregationDistinctProjectionSegment;
178 import org.apache.shardingsphere.sql.parser.statement.core.segment.dml.item.AggregationProjectionSegment;
179 import org.apache.shardingsphere.sql.parser.statement.core.segment.dml.item.ColumnProjectionSegment;
180 import org.apache.shardingsphere.sql.parser.statement.core.segment.dml.item.ExpressionProjectionSegment;
181 import org.apache.shardingsphere.sql.parser.statement.core.segment.dml.item.ProjectionSegment;
182 import org.apache.shardingsphere.sql.parser.statement.core.segment.dml.item.ProjectionsSegment;
183 import org.apache.shardingsphere.sql.parser.statement.core.segment.dml.item.ShorthandProjectionSegment;
184 import org.apache.shardingsphere.sql.parser.statement.core.segment.dml.item.SubqueryProjectionSegment;
185 import org.apache.shardingsphere.sql.parser.statement.core.segment.dml.json.JsonNullClauseSegment;
186 import org.apache.shardingsphere.sql.parser.statement.core.segment.dml.merge.MergeWhenAndThenSegment;
187 import org.apache.shardingsphere.sql.parser.statement.core.segment.dml.order.GroupBySegment;
188 import org.apache.shardingsphere.sql.parser.statement.core.segment.dml.order.OrderBySegment;
189 import org.apache.shardingsphere.sql.parser.statement.core.segment.dml.order.item.ColumnOrderByItemSegment;
190 import org.apache.shardingsphere.sql.parser.statement.core.segment.dml.order.item.ExpressionOrderByItemSegment;
191 import org.apache.shardingsphere.sql.parser.statement.core.segment.dml.order.item.IndexOrderByItemSegment;
192 import org.apache.shardingsphere.sql.parser.statement.core.segment.dml.order.item.OrderByItemSegment;
193 import org.apache.shardingsphere.sql.parser.statement.core.segment.dml.pagination.PaginationValueSegment;
194 import org.apache.shardingsphere.sql.parser.statement.core.segment.dml.pagination.limit.LimitSegment;
195 import org.apache.shardingsphere.sql.parser.statement.core.segment.dml.pagination.limit.NumberLiteralLimitValueSegment;
196 import org.apache.shardingsphere.sql.parser.statement.core.segment.dml.pagination.limit.ParameterMarkerLimitValueSegment;
197 import org.apache.shardingsphere.sql.parser.statement.core.segment.dml.pagination.rownum.NumberLiteralRowNumberValueSegment;
198 import org.apache.shardingsphere.sql.parser.statement.core.segment.dml.pagination.rownum.ParameterMarkerRowNumberValueSegment;
199 import org.apache.shardingsphere.sql.parser.statement.core.segment.dml.pagination.rownum.RowNumberValueSegment;
200 import org.apache.shardingsphere.sql.parser.statement.core.segment.dml.pagination.top.TopProjectionSegment;
201 import org.apache.shardingsphere.sql.parser.statement.core.segment.dml.predicate.HavingSegment;
202 import org.apache.shardingsphere.sql.parser.statement.core.segment.dml.predicate.WhereSegment;
203 import org.apache.shardingsphere.sql.parser.statement.core.segment.dml.sample.SampleOptionSegment;
204 import org.apache.shardingsphere.sql.parser.statement.core.segment.dml.sample.SampleStrategy;
205 import org.apache.shardingsphere.sql.parser.statement.core.segment.dml.statistics.StatisticsOptionSegment;
206 import org.apache.shardingsphere.sql.parser.statement.core.segment.dml.statistics.StatisticsStrategySegment;
207 import org.apache.shardingsphere.sql.parser.statement.core.segment.generic.AliasSegment;
208 import org.apache.shardingsphere.sql.parser.statement.core.segment.generic.DataTypeLengthSegment;
209 import org.apache.shardingsphere.sql.parser.statement.core.segment.generic.DataTypeSegment;
210 import org.apache.shardingsphere.sql.parser.statement.core.segment.generic.OutputSegment;
211 import org.apache.shardingsphere.sql.parser.statement.core.segment.generic.OwnerSegment;
212 import org.apache.shardingsphere.sql.parser.statement.core.segment.generic.ParameterMarkerSegment;
213 import org.apache.shardingsphere.sql.parser.statement.core.segment.generic.WithSegment;
214 import org.apache.shardingsphere.sql.parser.statement.core.segment.generic.table.DeleteMultiTableSegment;
215 import org.apache.shardingsphere.sql.parser.statement.core.segment.generic.table.FunctionTableSegment;
216 import org.apache.shardingsphere.sql.parser.statement.core.segment.generic.table.JoinTableSegment;
217 import org.apache.shardingsphere.sql.parser.statement.core.segment.generic.table.SimpleTableSegment;
218 import org.apache.shardingsphere.sql.parser.statement.core.segment.generic.table.SubqueryTableSegment;
219 import org.apache.shardingsphere.sql.parser.statement.core.segment.generic.table.TableNameSegment;
220 import org.apache.shardingsphere.sql.parser.statement.core.segment.generic.table.TableSegment;
221 import org.apache.shardingsphere.sql.parser.statement.core.statement.type.ddl.table.CreateTableStatement;
222 import org.apache.shardingsphere.sql.parser.statement.core.statement.type.dml.DeleteStatement;
223 import org.apache.shardingsphere.sql.parser.statement.core.statement.type.dml.InsertStatement;
224 import org.apache.shardingsphere.sql.parser.statement.core.statement.type.dml.MergeStatement;
225 import org.apache.shardingsphere.sql.parser.statement.core.statement.type.dml.SelectStatement;
226 import org.apache.shardingsphere.sql.parser.statement.core.statement.type.dml.UpdateStatement;
227 import org.apache.shardingsphere.sql.parser.statement.core.util.SQLUtils;
228 import org.apache.shardingsphere.sql.parser.statement.core.value.collection.CollectionValue;
229 import org.apache.shardingsphere.sql.parser.statement.core.value.identifier.IdentifierValue;
230 import org.apache.shardingsphere.sql.parser.statement.core.value.keyword.KeywordValue;
231 import org.apache.shardingsphere.sql.parser.statement.core.value.literal.impl.BooleanLiteralValue;
232 import org.apache.shardingsphere.sql.parser.statement.core.value.literal.impl.NullLiteralValue;
233 import org.apache.shardingsphere.sql.parser.statement.core.value.literal.impl.NumberLiteralValue;
234 import org.apache.shardingsphere.sql.parser.statement.core.value.literal.impl.OtherLiteralValue;
235 import org.apache.shardingsphere.sql.parser.statement.core.value.literal.impl.StringLiteralValue;
236 import org.apache.shardingsphere.sql.parser.statement.core.value.parametermarker.ParameterMarkerValue;
237 import org.apache.shardingsphere.sql.parser.statement.sqlserver.ddl.statistics.SQLServerUpdateStatisticsStatement;
238
239 import java.util.Collection;
240 import java.util.Collections;
241 import java.util.LinkedList;
242 import java.util.List;
243 import java.util.stream.Collectors;
244
245
246
247
248 @Getter(AccessLevel.PROTECTED)
249 public abstract class SQLServerStatementVisitor extends SQLServerStatementBaseVisitor<ASTNode> {
250
251 private final Collection<ParameterMarkerSegment> parameterMarkerSegments = new LinkedList<>();
252
253 @Override
254 public final ASTNode visitParameterMarker(final ParameterMarkerContext ctx) {
255 return new ParameterMarkerValue(parameterMarkerSegments.size(), ParameterMarkerType.QUESTION);
256 }
257
258 @Override
259 public final ASTNode visitLiterals(final LiteralsContext ctx) {
260 if (null != ctx.stringLiterals()) {
261 return visit(ctx.stringLiterals());
262 }
263 if (null != ctx.numberLiterals()) {
264 return visit(ctx.numberLiterals());
265 }
266 if (null != ctx.hexadecimalLiterals()) {
267 return visit(ctx.hexadecimalLiterals());
268 }
269 if (null != ctx.bitValueLiterals()) {
270 return visit(ctx.bitValueLiterals());
271 }
272 if (null != ctx.booleanLiterals()) {
273 return visit(ctx.booleanLiterals());
274 }
275 if (null != ctx.nullValueLiterals()) {
276 return visit(ctx.nullValueLiterals());
277 }
278 throw new IllegalStateException("Literals must have string, number, dateTime, hex, bit, boolean or null.");
279 }
280
281 @Override
282 public final ASTNode visitStringLiterals(final StringLiteralsContext ctx) {
283 if (null != ctx.STRING_()) {
284 return new StringLiteralValue(ctx.getText());
285 } else {
286 return new StringLiteralValue(ctx.getText().substring(1));
287 }
288 }
289
290 @Override
291 public final ASTNode visitNumberLiterals(final NumberLiteralsContext ctx) {
292 return new NumberLiteralValue(ctx.getText());
293 }
294
295 @Override
296 public final ASTNode visitHexadecimalLiterals(final HexadecimalLiteralsContext ctx) {
297
298 return new OtherLiteralValue(ctx.getText());
299 }
300
301 @Override
302 public final ASTNode visitBitValueLiterals(final BitValueLiteralsContext ctx) {
303
304 return new OtherLiteralValue(ctx.getText());
305 }
306
307 @Override
308 public final ASTNode visitBooleanLiterals(final BooleanLiteralsContext ctx) {
309 return new BooleanLiteralValue(ctx.getText());
310 }
311
312 @Override
313 public final ASTNode visitNullValueLiterals(final NullValueLiteralsContext ctx) {
314 return new NullLiteralValue(ctx.getText());
315 }
316
317 @Override
318 public final ASTNode visitIdentifier(final IdentifierContext ctx) {
319 return null == ctx.regularIdentifier() ? visit(ctx.delimitedIdentifier()) : visit(ctx.regularIdentifier());
320 }
321
322 @Override
323 public final ASTNode visitRegularIdentifier(final RegularIdentifierContext ctx) {
324 UnreservedWordContext unreservedWord = ctx.unreservedWord();
325 return null == unreservedWord ? new IdentifierValue(ctx.getText()) : (IdentifierValue) visit(unreservedWord);
326 }
327
328 @Override
329 public final ASTNode visitDelimitedIdentifier(final DelimitedIdentifierContext ctx) {
330 return new IdentifierValue(ctx.getText());
331 }
332
333 @Override
334 public final ASTNode visitUnreservedWord(final UnreservedWordContext ctx) {
335 return new IdentifierValue(ctx.getText());
336 }
337
338 @Override
339 public final ASTNode visitSchemaName(final SchemaNameContext ctx) {
340 return visit(ctx.identifier());
341 }
342
343 @Override
344 public final ASTNode visitTableName(final TableNameContext ctx) {
345 SimpleTableSegment result = new SimpleTableSegment(new TableNameSegment(ctx.name().getStart().getStartIndex(), ctx.name().getStop().getStopIndex(), (IdentifierValue) visit(ctx.name())));
346 OwnerContext owner = ctx.owner();
347 if (null != owner) {
348 OwnerSegment ownerSegment = new OwnerSegment(owner.getStart().getStartIndex(), owner.getStop().getStopIndex(), (IdentifierValue) visit(owner.identifier()));
349 if (null != ctx.databaseName()) {
350 DatabaseNameContext databaseName = ctx.databaseName();
351 ownerSegment.setOwner(new OwnerSegment(databaseName.getStart().getStartIndex(), databaseName.getStop().getStopIndex(), (IdentifierValue) visit(databaseName.identifier())));
352 }
353 result.setOwner(ownerSegment);
354 } else if (null != ctx.databaseName()) {
355 DatabaseNameContext databaseName = ctx.databaseName();
356 result.setOwner(new OwnerSegment(databaseName.getStart().getStartIndex(), databaseName.getStop().getStopIndex(), (IdentifierValue) visit(databaseName.identifier())));
357 }
358 return result;
359 }
360
361 @Override
362 public final ASTNode visitColumnName(final ColumnNameContext ctx) {
363 ColumnSegment result;
364 if (null != ctx.name()) {
365 result = new ColumnSegment(ctx.getStart().getStartIndex(), ctx.getStop().getStopIndex(), (IdentifierValue) visit(ctx.name()));
366 } else {
367 result = new ColumnSegment(ctx.getStart().getStartIndex(), ctx.getStop().getStopIndex(), (IdentifierValue) visit(ctx.scriptVariableName()));
368 }
369 OwnerContext owner = ctx.owner();
370 if (null != owner) {
371 OwnerSegment ownerSegment = new OwnerSegment(owner.getStart().getStartIndex(), owner.getStop().getStopIndex(), (IdentifierValue) visit(owner.identifier()));
372 if (null != ctx.databaseName()) {
373 ownerSegment.setOwner(new OwnerSegment(ctx.databaseName().getStart().getStartIndex(), ctx.databaseName().getStop().getStopIndex(),
374 (IdentifierValue) visit(ctx.databaseName().identifier())));
375 }
376 result.setOwner(ownerSegment);
377 }
378 return result;
379 }
380
381 @Override
382 public ASTNode visitScriptVariableName(final ScriptVariableNameContext ctx) {
383 return new IdentifierValue(ctx.getText());
384 }
385
386 @Override
387 public final ASTNode visitIndexName(final IndexNameContext ctx) {
388 IndexNameSegment indexName = new IndexNameSegment(ctx.start.getStartIndex(), ctx.stop.getStopIndex(), (IdentifierValue) visit(ctx.identifier()));
389 return new IndexSegment(ctx.getStart().getStartIndex(), ctx.getStop().getStopIndex(), indexName);
390 }
391
392 @Override
393 public final ASTNode visitConstraintName(final ConstraintNameContext ctx) {
394 return new ConstraintSegment(ctx.getStart().getStartIndex(), ctx.getStop().getStopIndex(), (IdentifierValue) visit(ctx.identifier()));
395 }
396
397 @Override
398 public final ASTNode visitTableNames(final TableNamesContext ctx) {
399 CollectionValue<SimpleTableSegment> result = new CollectionValue<>();
400 for (TableNameContext each : ctx.tableName()) {
401 result.getValue().add((SimpleTableSegment) visit(each));
402 }
403 return result;
404 }
405
406 @Override
407 public final ASTNode visitColumnNames(final ColumnNamesContext ctx) {
408 CollectionValue<ColumnSegment> result = new CollectionValue<>();
409 for (ColumnNameContext each : ctx.columnName()) {
410 result.getValue().add((ColumnSegment) visit(each));
411 }
412 return result;
413 }
414
415 @Override
416 public ASTNode visitColumnNamesWithSort(final ColumnNamesWithSortContext ctx) {
417 CollectionValue<ColumnSegment> result = new CollectionValue<>();
418 for (ColumnNameWithSortContext each : ctx.columnNameWithSort()) {
419 result.getValue().add((ColumnSegment) visit(each));
420 }
421 return result;
422 }
423
424 @Override
425 public final ASTNode visitExpr(final ExprContext ctx) {
426 if (null != ctx.booleanPrimary()) {
427 return visit(ctx.booleanPrimary());
428 }
429 if (null != ctx.LP_()) {
430 return visit(ctx.expr(0));
431 }
432 if (null != ctx.andOperator()) {
433 return createBinaryOperationExpression(ctx, ctx.andOperator().getText());
434 }
435 if (null != ctx.orOperator()) {
436 return createBinaryOperationExpression(ctx, ctx.orOperator().getText());
437 }
438 if (null != ctx.distinctFrom()) {
439 return createBinaryOperationExpression(ctx, ctx.distinctFrom().getText());
440 }
441 return new NotExpression(ctx.start.getStartIndex(), ctx.stop.getStopIndex(), (ExpressionSegment) visit(ctx.expr(0)), false);
442 }
443
444 private ASTNode createBinaryOperationExpression(final ExprContext ctx, final String operator) {
445 ExpressionSegment left = (ExpressionSegment) visit(ctx.expr(0));
446 ExpressionSegment right = (ExpressionSegment) visit(ctx.expr(1));
447 String text = ctx.start.getInputStream().getText(new Interval(ctx.start.getStartIndex(), ctx.stop.getStopIndex()));
448 return new BinaryOperationExpression(ctx.start.getStartIndex(), ctx.stop.getStopIndex(), left, right, operator, text);
449 }
450
451 @Override
452 public final ASTNode visitBooleanPrimary(final BooleanPrimaryContext ctx) {
453 if (null != ctx.IS()) {
454 String rightText = "";
455 if (null != ctx.NOT()) {
456 rightText = rightText + ctx.start.getInputStream().getText(new Interval(ctx.NOT().getSymbol().getStartIndex(), ctx.NOT().getSymbol().getStopIndex())) + " ";
457 }
458 Token operatorToken = null;
459 if (null != ctx.NULL()) {
460 operatorToken = ctx.NULL().getSymbol();
461 }
462 if (null != ctx.TRUE()) {
463 operatorToken = ctx.TRUE().getSymbol();
464 }
465 if (null != ctx.FALSE()) {
466 operatorToken = ctx.FALSE().getSymbol();
467 }
468 int startIndex = null == operatorToken ? ctx.IS().getSymbol().getStopIndex() + 2 : operatorToken.getStartIndex();
469 rightText = rightText + ctx.start.getInputStream().getText(new Interval(startIndex, ctx.stop.getStopIndex()));
470 ExpressionSegment right = new LiteralExpressionSegment(ctx.IS().getSymbol().getStopIndex() + 2, ctx.stop.getStopIndex(), rightText);
471 String text = ctx.start.getInputStream().getText(new Interval(ctx.start.getStartIndex(), ctx.stop.getStopIndex()));
472 ExpressionSegment left = (ExpressionSegment) visit(ctx.booleanPrimary());
473 String operator = "IS";
474 return new BinaryOperationExpression(ctx.start.getStartIndex(), ctx.stop.getStopIndex(), left, right, operator, text);
475 }
476 if (null != ctx.comparisonOperator() || null != ctx.SAFE_EQ_()) {
477 return createCompareSegment(ctx);
478 }
479 return visit(ctx.predicate());
480 }
481
482 private ASTNode createCompareSegment(final BooleanPrimaryContext ctx) {
483 ExpressionSegment left = (ExpressionSegment) visit(ctx.booleanPrimary());
484 ExpressionSegment right;
485 if (null != ctx.predicate()) {
486 right = (ExpressionSegment) visit(ctx.predicate());
487 } else {
488 right = (ExpressionSegment) visit(ctx.subquery());
489 }
490 String operator = null == ctx.SAFE_EQ_() ? ctx.comparisonOperator().getText() : ctx.SAFE_EQ_().getText();
491 String text = ctx.start.getInputStream().getText(new Interval(ctx.start.getStartIndex(), ctx.stop.getStopIndex()));
492 return new BinaryOperationExpression(ctx.start.getStartIndex(), ctx.stop.getStopIndex(), left, right, operator, text);
493 }
494
495 @Override
496 public final ASTNode visitPredicate(final PredicateContext ctx) {
497 if (null != ctx.IN()) {
498 return createInSegment(ctx);
499 }
500 if (null != ctx.BETWEEN()) {
501 return createBetweenSegment(ctx);
502 }
503 if (null != ctx.LIKE()) {
504 return createBinaryOperationExpressionFromLike(ctx);
505 }
506 return visit(ctx.bitExpr(0));
507 }
508
509 private BinaryOperationExpression createBinaryOperationExpressionFromLike(final PredicateContext ctx) {
510 ExpressionSegment left = (ExpressionSegment) visit(ctx.bitExpr(0));
511 ListExpression right = new ListExpression(ctx.simpleExpr(0).start.getStartIndex(), ctx.simpleExpr().get(ctx.simpleExpr().size() - 1).stop.getStopIndex());
512 for (SimpleExprContext each : ctx.simpleExpr()) {
513 right.getItems().add((ExpressionSegment) visit(each));
514 }
515 String operator = null == ctx.NOT() ? "LIKE" : "NOT LIKE";
516 String text = ctx.start.getInputStream().getText(new Interval(ctx.start.getStartIndex(), ctx.stop.getStopIndex()));
517 return new BinaryOperationExpression(ctx.start.getStartIndex(), ctx.stop.getStopIndex(), left, right, operator, text);
518 }
519
520 private InExpression createInSegment(final PredicateContext ctx) {
521 ExpressionSegment left = (ExpressionSegment) visit(ctx.bitExpr(0));
522 ExpressionSegment right;
523 if (null == ctx.subquery()) {
524 ListExpression listExpression = new ListExpression(ctx.LP_().getSymbol().getStartIndex(), ctx.RP_().getSymbol().getStopIndex());
525 for (ExprContext each : ctx.expr()) {
526 listExpression.getItems().add((ExpressionSegment) visit(each));
527 }
528 right = listExpression;
529 } else {
530 right = new SubqueryExpressionSegment(new SubquerySegment(ctx.subquery().start.getStartIndex(), ctx.subquery().stop.getStopIndex(), (SelectStatement) visit(ctx.subquery()),
531 getOriginalText(ctx.subquery())));
532 }
533 boolean not = null != ctx.NOT();
534 return new InExpression(ctx.start.getStartIndex(), ctx.stop.getStopIndex(), left, right, not);
535 }
536
537 private BetweenExpression createBetweenSegment(final PredicateContext ctx) {
538 ExpressionSegment left = (ExpressionSegment) visit(ctx.bitExpr(0));
539 ExpressionSegment between = (ExpressionSegment) visit(ctx.bitExpr(1));
540 ExpressionSegment and = (ExpressionSegment) visit(ctx.predicate());
541 boolean not = null != ctx.NOT();
542 return new BetweenExpression(ctx.start.getStartIndex(), ctx.stop.getStopIndex(), left, between, and, not);
543 }
544
545 @Override
546 public final ASTNode visitBitExpr(final BitExprContext ctx) {
547 if (null != ctx.simpleExpr()) {
548 return createExpressionSegment(visit(ctx.simpleExpr()), ctx);
549 }
550 ExpressionSegment left = (ExpressionSegment) visit(ctx.getChild(0));
551 ExpressionSegment right = (ExpressionSegment) visit(ctx.getChild(2));
552 String operator = ctx.getChild(1).getText();
553 String text = ctx.start.getInputStream().getText(new Interval(ctx.start.getStartIndex(), ctx.stop.getStopIndex()));
554 return new BinaryOperationExpression(ctx.start.getStartIndex(), ctx.stop.getStopIndex(), left, right, operator, text);
555 }
556
557 private ASTNode createExpressionSegment(final ASTNode astNode, final ParserRuleContext context) {
558 if (astNode instanceof StringLiteralValue) {
559 return new LiteralExpressionSegment(context.start.getStartIndex(), context.stop.getStopIndex(), ((StringLiteralValue) astNode).getValue());
560 }
561 if (astNode instanceof NumberLiteralValue) {
562 return new LiteralExpressionSegment(context.start.getStartIndex(), context.stop.getStopIndex(), ((NumberLiteralValue) astNode).getValue());
563 }
564 if (astNode instanceof BooleanLiteralValue) {
565 return new LiteralExpressionSegment(context.start.getStartIndex(), context.stop.getStopIndex(), ((BooleanLiteralValue) astNode).getValue());
566 }
567 if (astNode instanceof ParameterMarkerValue) {
568 ParameterMarkerValue parameterMarker = (ParameterMarkerValue) astNode;
569 ParameterMarkerExpressionSegment segment = new ParameterMarkerExpressionSegment(context.start.getStartIndex(), context.stop.getStopIndex(),
570 parameterMarker.getValue(), parameterMarker.getType());
571 parameterMarkerSegments.add(segment);
572 return segment;
573 }
574 if (astNode instanceof SubquerySegment) {
575 return new SubqueryExpressionSegment((SubquerySegment) astNode);
576 }
577 if (astNode instanceof OtherLiteralValue) {
578 return new CommonExpressionSegment(context.getStart().getStartIndex(), context.getStop().getStopIndex(), context.getText());
579 }
580 return astNode;
581 }
582
583 @Override
584 public final ASTNode visitSimpleExpr(final SimpleExprContext ctx) {
585 int startIndex = ctx.getStart().getStartIndex();
586 int stopIndex = ctx.getStop().getStopIndex();
587 if (null != ctx.subquery()) {
588 return new SubquerySegment(startIndex, stopIndex, (SelectStatement) visit(ctx.subquery()), getOriginalText(ctx.subquery()));
589 }
590 if (null != ctx.parameterMarker()) {
591 ParameterMarkerValue parameterMarker = (ParameterMarkerValue) visit(ctx.parameterMarker());
592 ParameterMarkerExpressionSegment result = new ParameterMarkerExpressionSegment(startIndex, stopIndex, parameterMarker.getValue(), parameterMarker.getType());
593 parameterMarkerSegments.add(result);
594 return result;
595 }
596 if (null != ctx.literals()) {
597 return SQLUtils.createLiteralExpression(visit(ctx.literals()), startIndex, stopIndex, ctx.literals().start.getInputStream().getText(new Interval(startIndex, stopIndex)));
598 }
599 if (null != ctx.functionCall()) {
600 return visit(ctx.functionCall());
601 }
602 if (null != ctx.columnName()) {
603 return visit(ctx.columnName());
604 }
605 if (null != ctx.LP_() && 1 == ctx.expr().size()) {
606 return visit(ctx.expr(0));
607 }
608 return visitRemainSimpleExpr(ctx);
609 }
610
611 private ASTNode visitRemainSimpleExpr(final SimpleExprContext ctx) {
612 if (null != ctx.caseExpression()) {
613 visit(ctx.caseExpression());
614 String text = ctx.start.getInputStream().getText(new Interval(ctx.start.getStartIndex(), ctx.stop.getStopIndex()));
615 return new OtherLiteralValue(text);
616 }
617 for (ExprContext each : ctx.expr()) {
618 visit(each);
619 }
620 for (SimpleExprContext each : ctx.simpleExpr()) {
621 visit(each);
622 }
623 String text = ctx.start.getInputStream().getText(new Interval(ctx.start.getStartIndex(), ctx.stop.getStopIndex()));
624 return new CommonExpressionSegment(ctx.getStart().getStartIndex(), ctx.getStop().getStopIndex(), text);
625 }
626
627 @Override
628 public final ASTNode visitFunctionCall(final FunctionCallContext ctx) {
629 if (null != ctx.aggregationFunction()) {
630 return visit(ctx.aggregationFunction());
631 }
632 if (null != ctx.specialFunction()) {
633 return visit(ctx.specialFunction());
634 }
635 if (null != ctx.regularFunction()) {
636 return visit(ctx.regularFunction());
637 }
638 throw new IllegalStateException("FunctionCallContext must have aggregationFunction, regularFunction or specialFunction.");
639 }
640
641 @Override
642 public final ASTNode visitAggregationFunction(final AggregationFunctionContext ctx) {
643 String aggregationType = ctx.aggregationFunctionName().getText();
644 return AggregationType.isAggregationType(aggregationType)
645 ? createAggregationSegment(ctx, aggregationType)
646 : new ExpressionProjectionSegment(ctx.getStart().getStartIndex(), ctx.getStop().getStopIndex(), getOriginalText(ctx));
647 }
648
649 private ASTNode createAggregationSegment(final AggregationFunctionContext ctx, final String aggregationType) {
650 AggregationType type = AggregationType.valueOf(aggregationType.toUpperCase());
651 if (null != ctx.distinct()) {
652 AggregationDistinctProjectionSegment result =
653 new AggregationDistinctProjectionSegment(ctx.getStart().getStartIndex(), ctx.getStop().getStopIndex(), type, getOriginalText(ctx), getDistinctExpression(ctx));
654 result.getParameters().addAll(getExpressions(ctx));
655 return result;
656 }
657 AggregationProjectionSegment result = new AggregationProjectionSegment(ctx.getStart().getStartIndex(), ctx.getStop().getStopIndex(), type, getOriginalText(ctx));
658 result.getParameters().addAll(getExpressions(ctx));
659 return result;
660 }
661
662 private Collection<ExpressionSegment> getExpressions(final AggregationFunctionContext ctx) {
663 if (null == ctx.expr()) {
664 return Collections.emptyList();
665 }
666 Collection<ExpressionSegment> result = new LinkedList<>();
667 for (ExprContext each : ctx.expr()) {
668 result.add((ExpressionSegment) visit(each));
669 }
670 return result;
671 }
672
673 private String getDistinctExpression(final AggregationFunctionContext ctx) {
674 StringBuilder result = new StringBuilder();
675 for (int i = 3; i < ctx.getChildCount() - 1; i++) {
676 result.append(ctx.getChild(i).getText());
677 }
678 return result.toString();
679 }
680
681 @Override
682 public final ASTNode visitSpecialFunction(final SpecialFunctionContext ctx) {
683 if (null != ctx.conversionFunction()) {
684 return visit(ctx.conversionFunction());
685 }
686 if (null != ctx.charFunction()) {
687 return visit(ctx.charFunction());
688 }
689 if (null != ctx.openJsonFunction()) {
690 return visit(ctx.openJsonFunction());
691 }
692 if (null != ctx.openRowSetFunction()) {
693 return visit(ctx.openRowSetFunction());
694 }
695 if (null != ctx.jsonFunction()) {
696 return visit(ctx.jsonFunction());
697 }
698 if (null != ctx.windowFunction()) {
699 return visit(ctx.windowFunction());
700 }
701 if (null != ctx.approxFunction()) {
702 return visit(ctx.approxFunction());
703 }
704 if (null != ctx.graphFunction()) {
705 return visit(ctx.graphFunction());
706 }
707 if (null != ctx.trimFunction()) {
708 return visit(ctx.trimFunction());
709 }
710 return new FunctionSegment(ctx.getStart().getStartIndex(), ctx.getStop().getStopIndex(), ctx.getChild(0).getChild(0).getText(), getOriginalText(ctx));
711 }
712
713 private ASTNode getFunctionSegment(final int startIndex, final int stopIndex, final String functionName, final String text, final List<ExprContext> exprList) {
714 FunctionSegment result = new FunctionSegment(startIndex, stopIndex, functionName, text);
715 if (null != exprList) {
716 for (ExprContext each : exprList) {
717 result.getParameters().add((ExpressionSegment) visit(each));
718 }
719 }
720 return result;
721 }
722
723 @Override
724 public ASTNode visitTrimFunction(final TrimFunctionContext ctx) {
725 FunctionSegment result = new FunctionSegment(ctx.getStart().getStartIndex(), ctx.getStop().getStopIndex(), ctx.TRIM().getText(), getOriginalText(ctx));
726 if (null != ctx.BOTH()) {
727 result.getParameters().add(new LiteralExpressionSegment(ctx.BOTH().getSymbol().getStartIndex(), ctx.BOTH().getSymbol().getStopIndex(),
728 new OtherLiteralValue(ctx.BOTH().getSymbol().getText()).getValue()));
729 }
730 if (null != ctx.TRAILING()) {
731 result.getParameters().add(new LiteralExpressionSegment(ctx.TRAILING().getSymbol().getStartIndex(), ctx.TRAILING().getSymbol().getStopIndex(),
732 new OtherLiteralValue(ctx.TRAILING().getSymbol().getText()).getValue()));
733 }
734 if (null != ctx.LEADING()) {
735 result.getParameters().add(new LiteralExpressionSegment(ctx.LEADING().getSymbol().getStartIndex(), ctx.LEADING().getSymbol().getStopIndex(),
736 new OtherLiteralValue(ctx.LEADING().getSymbol().getText()).getValue()));
737 }
738 for (ExprContext each : ctx.expr()) {
739 result.getParameters().add((ExpressionSegment) visit(each));
740 }
741 return result;
742 }
743
744 @Override
745 public ASTNode visitGraphFunction(final GraphFunctionContext ctx) {
746 if (null != ctx.graphAggFunction()) {
747 return visit(ctx.graphAggFunction());
748 }
749 return new FunctionSegment(ctx.getStart().getStartIndex(), ctx.getStop().getStopIndex(), ctx.getChild(0).getChild(0).getText(), getOriginalText(ctx));
750 }
751
752 @Override
753 public ASTNode visitGraphAggFunction(final GraphAggFunctionContext ctx) {
754 return getFunctionSegment(ctx.getStart().getStartIndex(), ctx.getStop().getStopIndex(), ctx.graphAggFunctionName().getText(), getOriginalText(ctx), ctx.expr());
755 }
756
757 @Override
758 public final ASTNode visitApproxFunction(final ApproxFunctionContext ctx) {
759 return getFunctionSegment(ctx.getStart().getStartIndex(), ctx.getStop().getStopIndex(), ctx.funcName.getText(), getOriginalText(ctx), ctx.expr());
760 }
761
762 @Override
763 public final ASTNode visitConversionFunction(final ConversionFunctionContext ctx) {
764 if (null != ctx.castFunction()) {
765 return visit(ctx.castFunction());
766 }
767 if (null != ctx.convertFunction()) {
768 return visit(ctx.convertFunction());
769 }
770 return new FunctionSegment(ctx.getStart().getStartIndex(), ctx.getStop().getStopIndex(), ctx.getChild(0).getChild(0).getText(), getOriginalText(ctx));
771 }
772
773 @Override
774 public final ASTNode visitWindowFunction(final WindowFunctionContext ctx) {
775 FunctionSegment result = new FunctionSegment(ctx.getStart().getStartIndex(), ctx.getStop().getStopIndex(), ctx.funcName.getText(), getOriginalText(ctx));
776 result.getParameters().add((ExpressionSegment) visit(ctx.expr()));
777 return result;
778 }
779
780 @Override
781 public final ASTNode visitJsonFunction(final JsonFunctionContext ctx) {
782 if (null != ctx.jsonArrayFunction()) {
783 return visit(ctx.jsonArrayFunction());
784 }
785 if (null != ctx.jsonObjectFunction()) {
786 return visit(ctx.jsonObjectFunction());
787 }
788 return new FunctionSegment(ctx.getStart().getStartIndex(), ctx.getStop().getStopIndex(), ctx.getText(), getOriginalText(ctx));
789 }
790
791 @Override
792 public final ASTNode visitJsonArrayFunction(final JsonArrayFunctionContext ctx) {
793 FunctionSegment result = (FunctionSegment) getFunctionSegment(ctx.getStart().getStartIndex(), ctx.getStop().getStopIndex(), ctx.JSON_ARRAY().getText(), getOriginalText(ctx), ctx.expr());
794 if (null != ctx.jsonNullClause()) {
795 result.getParameters().add(new LiteralExpressionSegment(ctx.jsonNullClause().start.getStartIndex(), ctx.jsonNullClause().stop.getStopIndex(), ctx.jsonNullClause().getText()));
796 }
797 return result;
798 }
799
800 @Override
801 public final ASTNode visitJsonObjectFunction(final JsonObjectFunctionContext ctx) {
802 FunctionSegment result = new FunctionSegment(ctx.getStart().getStartIndex(), ctx.getStop().getStopIndex(), ctx.JSON_OBJECT().getText(), getOriginalText(ctx));
803 if (null != ctx.jsonKeyValue()) {
804 for (JsonKeyValueContext each : ctx.jsonKeyValue()) {
805 result.getParameters().add((ExpressionSegment) visit(each));
806 }
807 }
808 if (null != ctx.jsonNullClause()) {
809 result.getParameters().add((ExpressionSegment) visit(ctx.jsonNullClause()));
810 }
811 return result;
812 }
813
814 @Override
815 public final ASTNode visitJsonNullClause(final JsonNullClauseContext ctx) {
816 return new JsonNullClauseSegment(ctx.start.getStartIndex(), ctx.stop.getStopIndex(), getOriginalText(ctx));
817 }
818
819 @Override
820 public final ASTNode visitJsonKeyValue(final JsonKeyValueContext ctx) {
821 KeyValueSegment result = new KeyValueSegment(ctx.start.getStartIndex(), ctx.stop.getStopIndex(), ctx.getText());
822 if (null != ctx.expr()) {
823 result.setKey((ExpressionSegment) visit(ctx.expr(0)));
824 result.setValue((ExpressionSegment) visit(ctx.expr(1)));
825 }
826 return result;
827 }
828
829 @Override
830 public final ASTNode visitCastFunction(final CastFunctionContext ctx) {
831 calculateParameterCount(Collections.singleton(ctx.expr()));
832 String functionName = null != ctx.CAST() ? ctx.CAST().getText() : ctx.TRY_CAST().getText();
833 FunctionSegment result = new FunctionSegment(ctx.getStart().getStartIndex(), ctx.getStop().getStopIndex(), functionName, getOriginalText(ctx));
834 ASTNode exprSegment = visit(ctx.expr());
835 if (exprSegment instanceof ColumnSegment) {
836 result.getParameters().add((ColumnSegment) exprSegment);
837 } else if (exprSegment instanceof LiteralExpressionSegment) {
838 result.getParameters().add((LiteralExpressionSegment) exprSegment);
839 } else if (exprSegment instanceof FunctionSegment) {
840 result.getParameters().add((FunctionSegment) exprSegment);
841 }
842 result.getParameters().add((DataTypeSegment) visit(ctx.dataType()));
843 return result;
844 }
845
846 @Override
847 public ASTNode visitConvertFunction(final ConvertFunctionContext ctx) {
848 String functionName = null != ctx.CONVERT() ? ctx.CONVERT().getText() : ctx.TRY_CONVERT().getText();
849 FunctionSegment result = new FunctionSegment(ctx.getStart().getStartIndex(), ctx.getStop().getStopIndex(), functionName, getOriginalText(ctx));
850 result.getParameters().add((DataTypeSegment) visit(ctx.dataType()));
851 result.getParameters().add((ExpressionSegment) visit(ctx.expr()));
852 if (null != ctx.NUMBER_()) {
853 result.getParameters().add(new LiteralExpressionSegment(ctx.NUMBER_().getSymbol().getStartIndex(), ctx.NUMBER_().getSymbol().getStopIndex(), ctx.NUMBER_().getText()));
854 }
855 return result;
856 }
857
858 @Override
859 public final ASTNode visitCharFunction(final CharFunctionContext ctx) {
860 calculateParameterCount(ctx.expr());
861 return new FunctionSegment(ctx.getStart().getStartIndex(), ctx.getStop().getStopIndex(), ctx.CHAR().getText(), getOriginalText(ctx));
862 }
863
864 @Override
865 public final ASTNode visitOpenJsonFunction(final OpenJsonFunctionContext ctx) {
866 return getFunctionSegment(ctx.getStart().getStartIndex(), ctx.getStop().getStopIndex(), ctx.OPENJSON().getText(), getOriginalText(ctx), ctx.expr());
867 }
868
869 @Override
870 public final ASTNode visitOpenRowSetFunction(final OpenRowSetFunctionContext ctx) {
871 FunctionSegment result = (FunctionSegment) getFunctionSegment(ctx.getStart().getStartIndex(), ctx.getStop().getStopIndex(), ctx.OPENROWSET().getText(), getOriginalText(ctx), ctx.expr());
872 if (null != ctx.tableName()) {
873 result.getParameters().add(new LiteralExpressionSegment(ctx.tableName().getStart().getStartIndex(), ctx.tableName().getStop().getStopIndex(), ctx.tableName().getText()));
874 }
875 return result;
876 }
877
878 @Override
879 public ASTNode visitOpenQueryFunction(final OpenQueryFunctionContext ctx) {
880 return getFunctionSegment(ctx.getStart().getStartIndex(), ctx.getStop().getStopIndex(), ctx.OPENQUERY().getText(), getOriginalText(ctx), ctx.expr());
881 }
882
883 @Override
884 public final ASTNode visitRegularFunction(final RegularFunctionContext ctx) {
885 return getFunctionSegment(ctx.getStart().getStartIndex(), ctx.getStop().getStopIndex(), ctx.regularFunctionName().getText(), getOriginalText(ctx), ctx.expr());
886 }
887
888 @Override
889 public final ASTNode visitDataTypeName(final DataTypeNameContext ctx) {
890 return new KeywordValue(ctx.getText());
891 }
892
893
894 private void calculateParameterCount(final Collection<ExprContext> exprContexts) {
895 for (ExprContext each : exprContexts) {
896 visit(each);
897 }
898 }
899
900 @Override
901 public final ASTNode visitOrderByItem(final OrderByItemContext ctx) {
902 OrderDirection orderDirection = null == ctx.DESC() ? OrderDirection.ASC : OrderDirection.DESC;
903 if (null != ctx.columnName()) {
904 ColumnSegment column = (ColumnSegment) visit(ctx.columnName());
905 return new ColumnOrderByItemSegment(column, orderDirection, null);
906 }
907 if (null != ctx.numberLiterals()) {
908 return new IndexOrderByItemSegment(ctx.numberLiterals().getStart().getStartIndex(), ctx.numberLiterals().getStop().getStopIndex(),
909 SQLUtils.getExactlyNumber(ctx.numberLiterals().getText(), 10).intValue(), orderDirection, null);
910 }
911 return new ExpressionOrderByItemSegment(ctx.expr().getStart().getStartIndex(), ctx.expr().getStop().getStopIndex(), getOriginalText(ctx.expr()), orderDirection, null,
912 (ExpressionSegment) visit(ctx.expr()));
913 }
914
915 @Override
916 public final ASTNode visitDataType(final DataTypeContext ctx) {
917 DataTypeSegment result = new DataTypeSegment();
918 result.setDataTypeName(((KeywordValue) visit(ctx.dataTypeName())).getValue());
919 result.setStartIndex(ctx.start.getStartIndex());
920 result.setStopIndex(ctx.stop.getStopIndex());
921 if (null != ctx.dataTypeLength()) {
922 DataTypeLengthSegment dataTypeLengthSegment = (DataTypeLengthSegment) visit(ctx.dataTypeLength());
923 result.setDataLength(dataTypeLengthSegment);
924 }
925 return result;
926 }
927
928 @Override
929 public final ASTNode visitDataTypeLength(final DataTypeLengthContext ctx) {
930 DataTypeLengthSegment result = new DataTypeLengthSegment();
931 result.setStartIndex(ctx.start.getStartIndex());
932 result.setStopIndex(ctx.stop.getStartIndex());
933 List<TerminalNode> numbers = ctx.NUMBER_();
934 if (numbers.size() == 1) {
935 result.setPrecision(Integer.parseInt(numbers.get(0).getText()));
936 }
937 if (numbers.size() == 2) {
938 result.setPrecision(Integer.parseInt(numbers.get(0).getText()));
939 result.setScale(Integer.parseInt(numbers.get(1).getText()));
940 }
941 return result;
942 }
943
944 @Override
945 public final ASTNode visitViewName(final ViewNameContext ctx) {
946 SimpleTableSegment result = new SimpleTableSegment(new TableNameSegment(ctx.name().getStart().getStartIndex(),
947 ctx.name().getStop().getStopIndex(), (IdentifierValue) visit(ctx.name())));
948 OwnerContext owner = ctx.owner();
949 if (null != owner) {
950 result.setOwner(new OwnerSegment(owner.getStart().getStartIndex(), owner.getStop().getStopIndex(), (IdentifierValue) visit(owner.identifier())));
951 }
952 return result;
953 }
954
955 @Override
956 public ASTNode visitSelect(final SelectContext ctx) {
957 SelectStatement result = (SelectStatement) visit(ctx.aggregationClause());
958 result.addParameterMarkers(getParameterMarkerSegments());
959 return result;
960 }
961
962 @Override
963 public ASTNode visitAggregationClause(final AggregationClauseContext ctx) {
964
965 return visit(ctx.selectClause(0));
966 }
967
968 @Override
969 public ASTNode visitSelectClause(final SelectClauseContext ctx) {
970 SelectStatement result = new SelectStatement();
971 result.setProjections((ProjectionsSegment) visit(ctx.projections()));
972 if (null != ctx.selectWithClause() && null != ctx.selectWithClause().cteClauseSet()) {
973 Collection<CommonTableExpressionSegment> commonTableExpressionSegments = getCommonTableExpressionSegmentsUsingCteClauseSet(ctx.selectWithClause().cteClauseSet());
974 WithSegment withSegment = new WithSegment(ctx.selectWithClause().start.getStartIndex(), ctx.selectWithClause().stop.getStopIndex(), commonTableExpressionSegments);
975 result.setWith(withSegment);
976 }
977 if (null != ctx.duplicateSpecification()) {
978 result.getProjections().setDistinctRow(isDistinct(ctx));
979 }
980 if (null != ctx.intoClause()) {
981 result.setInto((TableSegment) visit(ctx.intoClause()));
982 }
983 if (null != ctx.fromClause()) {
984 TableSegment tableSource = (TableSegment) visit(ctx.fromClause().tableReferences());
985 result.setFrom(tableSource);
986 }
987 if (null != ctx.withTableHint()) {
988 result.setWithTableHint((WithTableHintSegment) visit(ctx.withTableHint()));
989 }
990 if (null != ctx.whereClause()) {
991 result.setWhere((WhereSegment) visit(ctx.whereClause()));
992 }
993 if (null != ctx.groupByClause()) {
994 result.setGroupBy((GroupBySegment) visit(ctx.groupByClause()));
995 }
996 if (null != ctx.havingClause()) {
997 result.setHaving((HavingSegment) visit(ctx.havingClause()));
998 }
999 if (null != ctx.orderByClause()) {
1000 result.setOrderBy(getOrderBySegment(ctx.orderByClause()));
1001 result.setLimit(getLimitSegment(ctx.orderByClause()));
1002 }
1003 return result;
1004 }
1005
1006 private Collection<CommonTableExpressionSegment> getCommonTableExpressionSegmentsUsingCteClauseSet(final CteClauseSetContext ctx) {
1007 Collection<CommonTableExpressionSegment> result = new LinkedList<>();
1008 for (CteClauseContext each : ctx.cteClause()) {
1009 SubquerySegment subquery = new SubquerySegment(each.subquery().aggregationClause().start.getStartIndex(),
1010 each.subquery().aggregationClause().stop.getStopIndex(), (SelectStatement) visit(each.subquery()), getOriginalText(each.subquery()));
1011 CommonTableExpressionSegment commonTableExpression = new CommonTableExpressionSegment(each.start.getStartIndex(), each.stop.getStopIndex(), (AliasSegment) visit(each.alias()), subquery);
1012 if (null != each.columnNames()) {
1013 ColumnNamesContext columnNames = each.columnNames();
1014 CollectionValue<ColumnSegment> columns = (CollectionValue<ColumnSegment>) visit(columnNames);
1015 commonTableExpression.getColumns().addAll(columns.getValue());
1016 }
1017 result.add(commonTableExpression);
1018 }
1019 return result;
1020 }
1021
1022 @Override
1023 public ASTNode visitHavingClause(final HavingClauseContext ctx) {
1024 ExpressionSegment expr = (ExpressionSegment) visit(ctx.expr());
1025 return new HavingSegment(ctx.getStart().getStartIndex(), ctx.getStop().getStopIndex(), expr);
1026 }
1027
1028 private LimitSegment getLimitSegment(final OrderByClauseContext ctx) {
1029 LimitSegment result = null;
1030 PaginationValueSegment offset = null;
1031 PaginationValueSegment rowcount = null;
1032 if (null != ctx.OFFSET()) {
1033 ASTNode astNode = visit(ctx.expr(0));
1034 if (astNode instanceof LiteralExpressionSegment && ((LiteralExpressionSegment) astNode).getLiterals() instanceof Number) {
1035 offset = new NumberLiteralLimitValueSegment(ctx.expr(0).start.getStartIndex(), ctx.expr(0).stop.getStopIndex(),
1036 ((Number) ((LiteralExpressionSegment) astNode).getLiterals()).longValue());
1037 } else if (astNode instanceof ParameterMarkerExpressionSegment) {
1038 offset = new ParameterMarkerLimitValueSegment(ctx.expr(0).start.getStartIndex(), ctx.expr(0).stop.getStopIndex(), parameterMarkerSegments.size() - 1);
1039 }
1040 }
1041 if (null != ctx.FETCH()) {
1042 ASTNode astNode = visit(ctx.expr(1));
1043 if (astNode instanceof LiteralExpressionSegment && ((LiteralExpressionSegment) astNode).getLiterals() instanceof Number) {
1044 rowcount = new NumberLiteralLimitValueSegment(ctx.expr(1).start.getStartIndex(), ctx.expr(1).stop.getStopIndex(),
1045 ((Number) ((LiteralExpressionSegment) astNode).getLiterals()).longValue());
1046 } else if (astNode instanceof ParameterMarkerExpressionSegment) {
1047 rowcount = new ParameterMarkerLimitValueSegment(ctx.expr(1).start.getStartIndex(), ctx.expr(1).stop.getStopIndex(), parameterMarkerSegments.size() - 1);
1048 }
1049 }
1050 if (null != offset) {
1051 result = new LimitSegment(ctx.OFFSET().getSymbol().getStartIndex(), ctx.stop.getStopIndex(), offset, rowcount);
1052 }
1053 return result;
1054 }
1055
1056 private OrderBySegment getOrderBySegment(final OrderByClauseContext ctx) {
1057 Collection<OrderByItemSegment> items = new LinkedList<>();
1058 int orderByStartIndex = ctx.start.getStartIndex();
1059 int orderByStopIndex = ctx.start.getStartIndex();
1060 for (OrderByItemContext each : ctx.orderByItem()) {
1061 items.add((OrderByItemSegment) visit(each));
1062 orderByStopIndex = each.stop.getStopIndex();
1063 }
1064 return new OrderBySegment(orderByStartIndex, orderByStopIndex, items);
1065 }
1066
1067 private boolean isDistinct(final SelectClauseContext ctx) {
1068 return ((BooleanLiteralValue) visit(ctx.duplicateSpecification())).getValue();
1069 }
1070
1071 @Override
1072 public ASTNode visitProjections(final ProjectionsContext ctx) {
1073 List<ProjectionSegment> projections = new LinkedList<>();
1074 if (null != ctx.top()) {
1075 projections.add((ProjectionSegment) visit(ctx.top()));
1076 }
1077 for (ProjectionContext each : ctx.projection()) {
1078 projections.add((ProjectionSegment) visit(each));
1079 }
1080 ProjectionsSegment result = new ProjectionsSegment(ctx.getStart().getStartIndex(), ctx.getStop().getStopIndex());
1081 result.getProjections().addAll(projections);
1082 return result;
1083 }
1084
1085 @Override
1086 public ASTNode visitTableReferences(final TableReferencesContext ctx) {
1087 TableSegment result = (TableSegment) visit(ctx.tableReference(0));
1088 if (ctx.tableReference().size() > 1) {
1089 for (int i = 1; i < ctx.tableReference().size(); i++) {
1090 result = generateJoinTableSourceFromTableReference(ctx.tableReference(i), result);
1091 }
1092 }
1093 return result;
1094 }
1095
1096 private JoinTableSegment generateJoinTableSourceFromTableReference(final TableReferenceContext ctx, final TableSegment tableSegment) {
1097 JoinTableSegment result = new JoinTableSegment();
1098 result.setStartIndex(tableSegment.getStartIndex());
1099 result.setStopIndex(ctx.stop.getStopIndex());
1100 result.setLeft(tableSegment);
1101 result.setRight((TableSegment) visit(ctx));
1102 result.setJoinType(JoinType.COMMA.name());
1103 return result;
1104 }
1105
1106 @Override
1107 public ASTNode visitWhereClause(final WhereClauseContext ctx) {
1108 return new WhereSegment(ctx.getStart().getStartIndex(), ctx.getStop().getStopIndex(), (ExpressionSegment) visit(ctx.expr()));
1109 }
1110
1111 @Override
1112 public ASTNode visitGroupByClause(final GroupByClauseContext ctx) {
1113 Collection<OrderByItemSegment> items = new LinkedList<>();
1114 for (OrderByItemContext each : ctx.orderByItem()) {
1115 items.add((OrderByItemSegment) visit(each));
1116 }
1117 return new GroupBySegment(ctx.getStart().getStartIndex(), ctx.getStop().getStopIndex(), items);
1118 }
1119
1120
1121
1122
1123
1124
1125
1126 protected String getOriginalText(final ParserRuleContext ctx) {
1127 return ctx.start.getInputStream().getText(new Interval(ctx.start.getStartIndex(), ctx.stop.getStopIndex()));
1128 }
1129
1130 @Override
1131 public ASTNode visitInsert(final InsertContext ctx) {
1132 InsertStatement result;
1133 if (null != ctx.insertDefaultValue()) {
1134 result = (InsertStatement) visit(ctx.insertDefaultValue());
1135 } else if (null != ctx.insertValuesClause()) {
1136 result = (InsertStatement) visit(ctx.insertValuesClause());
1137 } else if (null != ctx.insertExecClause()) {
1138 result = (InsertStatement) visit(ctx.insertExecClause());
1139 } else {
1140 result = (InsertStatement) visit(ctx.insertSelectClause());
1141 }
1142 if (null != ctx.withClause()) {
1143 result.setWith((WithSegment) visit(ctx.withClause()));
1144 }
1145 if (null != ctx.withTableHint()) {
1146 result.setWithTableHint((WithTableHintSegment) visit(ctx.withTableHint()));
1147 }
1148 if (null != ctx.tableName()) {
1149 result.setTable((SimpleTableSegment) visit(ctx.tableName()));
1150 }
1151 if (null != ctx.rowSetFunction()) {
1152 result.setRowSetFunction((FunctionSegment) visit(ctx.rowSetFunction()));
1153 }
1154 result.addParameterMarkers(getParameterMarkerSegments());
1155 return result;
1156 }
1157
1158 @Override
1159 public ASTNode visitRowSetFunction(final RowSetFunctionContext ctx) {
1160 if (null != ctx.openRowSetFunction()) {
1161 return visit(ctx.openRowSetFunction());
1162 } else {
1163 return visit(ctx.openQueryFunction());
1164 }
1165 }
1166
1167 @Override
1168 public ASTNode visitWithTableHint(final WithTableHintContext ctx) {
1169 WithTableHintSegment result = new WithTableHintSegment(ctx.start.getStartIndex(), ctx.stop.getStopIndex());
1170 if (null != ctx.tableHintLimited()) {
1171 Collection<TableHintLimitedSegment> tableHintLimitedSegments = new LinkedList<>();
1172 for (TableHintLimitedContext each : ctx.tableHintLimited()) {
1173 tableHintLimitedSegments.add((TableHintLimitedSegment) visit(each));
1174 }
1175 result.getTableHintLimitedSegments().addAll(tableHintLimitedSegments);
1176 }
1177 return result;
1178 }
1179
1180 @Override
1181 public ASTNode visitTableHintLimited(final TableHintLimitedContext ctx) {
1182 TableHintLimitedSegment result = new TableHintLimitedSegment(ctx.start.getStartIndex(), ctx.stop.getStopIndex());
1183 result.setValue(ctx.getText());
1184 return result;
1185 }
1186
1187 @Override
1188 public ASTNode visitInsertDefaultValue(final InsertDefaultValueContext ctx) {
1189 InsertStatement result = new InsertStatement();
1190 result.setInsertColumns(createInsertColumns(ctx.columnNames(), ctx.start.getStartIndex()));
1191 if (null != ctx.outputClause()) {
1192 result.setOutput((OutputSegment) visit(ctx.outputClause()));
1193 }
1194 return result;
1195 }
1196
1197 @Override
1198 public ASTNode visitInsertExecClause(final InsertExecClauseContext ctx) {
1199 InsertStatement result = new InsertStatement();
1200 result.setInsertColumns(createInsertColumns(ctx.columnNames(), ctx.start.getStartIndex()));
1201 result.setExec((ExecSegment) visit(ctx.exec()));
1202 return result;
1203 }
1204
1205 @Override
1206 public ASTNode visitExec(final ExecContext ctx) {
1207 ExecSegment result = new ExecSegment(ctx.getStart().getStartIndex(), ctx.getStop().getStopIndex());
1208 if (null != ctx.procedureName()) {
1209 result.setProcedureName((FunctionNameSegment) visitProcedureName(ctx.procedureName()));
1210 }
1211 if (null != ctx.expr()) {
1212 Collection<ExpressionSegment> items = new LinkedList<>();
1213 for (ExprContext each : ctx.expr()) {
1214 items.add((ExpressionSegment) visit(each));
1215 }
1216 result.getExpressionSegments().addAll(items);
1217 }
1218 return result;
1219 }
1220
1221 @Override
1222 public ASTNode visitProcedureName(final ProcedureNameContext ctx) {
1223 FunctionNameSegment result = new FunctionNameSegment(ctx.name().start.getStartIndex(), ctx.name().stop.getStopIndex(), (IdentifierValue) visit(ctx.name()));
1224 if (null != ctx.owner()) {
1225 result.setOwner(new OwnerSegment(ctx.owner().start.getStartIndex(), ctx.owner().stop.getStopIndex(), (IdentifierValue) visit(ctx.owner())));
1226 }
1227 return result;
1228 }
1229
1230 @Override
1231 public ASTNode visitOutputClause(final OutputClauseContext ctx) {
1232 OutputSegment result = new OutputSegment(ctx.start.getStartIndex(), ctx.stop.getStopIndex());
1233 if (null != ctx.outputWithColumns()) {
1234 OutputWithColumnsContext outputWithColumnsContext = ctx.outputWithColumns();
1235 ProjectionsSegment outputColumns = new ProjectionsSegment(outputWithColumnsContext.start.getStartIndex(), outputWithColumnsContext.stop.getStopIndex());
1236 for (int i = 0; i < outputWithColumnsContext.getChildCount(); i += 2) {
1237 ParseTree each = outputWithColumnsContext.getChild(i);
1238 if (each instanceof OutputWithColumnContext) {
1239 outputColumns.getProjections().add(createColumnProjectionSegment((OutputWithColumnContext) each));
1240 }
1241 if (each instanceof ScalarExpressionContext) {
1242 outputColumns.getProjections().add(createScalarExpressionContext((ScalarExpressionContext) each));
1243 }
1244 }
1245 result.setOutputColumns(outputColumns);
1246 }
1247 if (null != ctx.outputTableName()) {
1248 if (null != ctx.outputTableName().tableName()) {
1249 result.setTable((SimpleTableSegment) visit(ctx.outputTableName().tableName()));
1250 }
1251 if (null != ctx.columnNames()) {
1252 ColumnNamesContext columnNames = ctx.columnNames();
1253 CollectionValue<ColumnSegment> columns = (CollectionValue<ColumnSegment>) visit(columnNames);
1254 result.getTableColumns().addAll(columns.getValue());
1255 }
1256 }
1257 return result;
1258 }
1259
1260 private ProjectionSegment createScalarExpressionContext(final ScalarExpressionContext context) {
1261 ExpressionProjectionSegment result = new ExpressionProjectionSegment(context.start.getStartIndex(), context.stop.getStopIndex(),
1262 getOriginalText(context), (ExpressionSegment) visit(context.expr()));
1263 if (null != context.alias()) {
1264 result.setAlias(new AliasSegment(context.alias().start.getStartIndex(), context.alias().stop.getStopIndex(), new IdentifierValue(context.alias().getText())));
1265 }
1266 return result;
1267 }
1268
1269 private ProjectionSegment createColumnProjectionSegment(final OutputWithColumnContext context) {
1270 ColumnSegment column = new ColumnSegment(context.start.getStartIndex(), context.stop.getStopIndex(), new IdentifierValue(context.name().getText()));
1271 ColumnProjectionSegment result = new ColumnProjectionSegment(column);
1272 if (null != context.alias()) {
1273 result.setAlias(new AliasSegment(context.alias().start.getStartIndex(), context.alias().stop.getStopIndex(), new IdentifierValue(context.alias().getText())));
1274 }
1275 return result;
1276 }
1277
1278 @Override
1279 public ASTNode visitInsertValuesClause(final InsertValuesClauseContext ctx) {
1280 InsertStatement result = new InsertStatement();
1281 result.setInsertColumns(createInsertColumns(ctx.columnNames(), ctx.start.getStartIndex()));
1282 result.getValues().addAll(createInsertValuesSegments(ctx.assignmentValues()));
1283 if (null != ctx.outputClause()) {
1284 result.setOutput((OutputSegment) visit(ctx.outputClause()));
1285 }
1286 return result;
1287 }
1288
1289 private Collection<InsertValuesSegment> createInsertValuesSegments(final Collection<AssignmentValuesContext> assignmentValuesContexts) {
1290 Collection<InsertValuesSegment> result = new LinkedList<>();
1291 for (AssignmentValuesContext each : assignmentValuesContexts) {
1292 result.add((InsertValuesSegment) visit(each));
1293 }
1294 return result;
1295 }
1296
1297 @Override
1298 public ASTNode visitInsertSelectClause(final InsertSelectClauseContext ctx) {
1299 InsertStatement result = new InsertStatement();
1300 result.setInsertColumns(createInsertColumns(ctx.columnNames(), ctx.start.getStartIndex()));
1301 result.setInsertSelect(createInsertSelectSegment(ctx));
1302 if (null != ctx.outputClause()) {
1303 result.setOutput((OutputSegment) visit(ctx.outputClause()));
1304 }
1305 return result;
1306 }
1307
1308 @SuppressWarnings("unchecked")
1309 private InsertColumnsSegment createInsertColumns(final ColumnNamesContext columnNames, final int startIndex) {
1310 if (null == columnNames) {
1311 return new InsertColumnsSegment(startIndex - 1, startIndex - 1, Collections.emptyList());
1312 } else {
1313 CollectionValue<ColumnSegment> columnSegments = (CollectionValue<ColumnSegment>) visit(columnNames);
1314 return new InsertColumnsSegment(columnNames.start.getStartIndex(), columnNames.stop.getStopIndex(), columnSegments.getValue());
1315 }
1316 }
1317
1318 private SubquerySegment createInsertSelectSegment(final InsertSelectClauseContext ctx) {
1319 SelectStatement selectStatement = (SelectStatement) visit(ctx.select());
1320 return new SubquerySegment(ctx.select().start.getStartIndex(), ctx.select().stop.getStopIndex(), selectStatement, getOriginalText(ctx.select()));
1321 }
1322
1323 @Override
1324 public ASTNode visitWithClause(final WithClauseContext ctx) {
1325 Collection<CommonTableExpressionSegment> commonTableExpressionSegments = getCommonTableExpressionSegmentsUsingCteClauseSet(ctx.cteClauseSet());
1326 return new WithSegment(ctx.start.getStartIndex(), ctx.stop.getStopIndex(), commonTableExpressionSegments);
1327 }
1328
1329 @Override
1330 public ASTNode visitUpdate(final UpdateContext ctx) {
1331 UpdateStatement result = new UpdateStatement();
1332 if (null != ctx.withClause()) {
1333 result.setWith((WithSegment) visit(ctx.withClause()));
1334 }
1335 result.setTable((TableSegment) visit(ctx.tableReferences()));
1336 result.setSetAssignment((SetAssignmentSegment) visit(ctx.setAssignmentsClause()));
1337 if (null != ctx.fromClause()) {
1338 result.setFrom((TableSegment) visit(ctx.fromClause()));
1339 }
1340 if (null != ctx.withTableHint()) {
1341 result.setWithTableHint((WithTableHintSegment) visit(ctx.withTableHint()));
1342 }
1343 if (null != ctx.whereClause()) {
1344 result.setWhere((WhereSegment) visit(ctx.whereClause()));
1345 }
1346 if (null != ctx.optionHint()) {
1347 result.setOptionHint((OptionHintSegment) visit(ctx.optionHint()));
1348 }
1349 if (null != ctx.outputClause()) {
1350 result.setOutput((OutputSegment) visit(ctx.outputClause()));
1351 }
1352 result.addParameterMarkers(getParameterMarkerSegments());
1353 return result;
1354 }
1355
1356 @Override
1357 public ASTNode visitOptionHint(final OptionHintContext ctx) {
1358 return new OptionHintSegment(ctx.getStart().getStartIndex(), ctx.getStop().getStopIndex(), getOriginalText(ctx));
1359 }
1360
1361 @Override
1362 public ASTNode visitSetAssignmentsClause(final SetAssignmentsClauseContext ctx) {
1363 Collection<ColumnAssignmentSegment> assignments = new LinkedList<>();
1364 for (AssignmentContext each : ctx.assignment()) {
1365 assignments.add((ColumnAssignmentSegment) visit(each));
1366 }
1367 return new SetAssignmentSegment(ctx.getStart().getStartIndex(), ctx.getStop().getStopIndex(), assignments);
1368 }
1369
1370 @Override
1371 public ASTNode visitAssignmentValues(final AssignmentValuesContext ctx) {
1372 List<ExpressionSegment> segments = new LinkedList<>();
1373 for (AssignmentValueContext each : ctx.assignmentValue()) {
1374 segments.add((ExpressionSegment) visit(each));
1375 }
1376 return new InsertValuesSegment(ctx.getStart().getStartIndex(), ctx.getStop().getStopIndex(), segments);
1377 }
1378
1379 @Override
1380 public ASTNode visitAssignment(final AssignmentContext ctx) {
1381 ColumnSegment column = (ColumnSegment) visitColumnName(ctx.columnName());
1382 List<ColumnSegment> columnSegments = new LinkedList<>();
1383 columnSegments.add(column);
1384 ExpressionSegment value = (ExpressionSegment) visit(ctx.assignmentValue());
1385 return new ColumnAssignmentSegment(ctx.getStart().getStartIndex(), ctx.getStop().getStopIndex(), columnSegments, value);
1386 }
1387
1388 @Override
1389 public ASTNode visitAssignmentValue(final AssignmentValueContext ctx) {
1390 ExprContext expr = ctx.expr();
1391 if (null != expr) {
1392 return visit(expr);
1393 }
1394 return new CommonExpressionSegment(ctx.getStart().getStartIndex(), ctx.getStop().getStopIndex(), ctx.getText());
1395 }
1396
1397 @Override
1398 public ASTNode visitDelete(final DeleteContext ctx) {
1399 DeleteStatement result = new DeleteStatement();
1400 if (null != ctx.withClause()) {
1401 result.setWith((WithSegment) visit(ctx.withClause()));
1402 }
1403 if (null != ctx.multipleTablesClause()) {
1404 result.setTable((TableSegment) visit(ctx.multipleTablesClause()));
1405 } else {
1406 result.setTable((TableSegment) visit(ctx.singleTableClause()));
1407 }
1408 if (null != ctx.outputClause()) {
1409 result.setOutput((OutputSegment) visit(ctx.outputClause()));
1410 }
1411 if (null != ctx.whereClause()) {
1412 result.setWhere((WhereSegment) visit(ctx.whereClause()));
1413 }
1414 if (null != ctx.outputClause()) {
1415 result.setOutput((OutputSegment) visit(ctx.outputClause()));
1416 }
1417 result.addParameterMarkers(getParameterMarkerSegments());
1418 return result;
1419 }
1420
1421 @Override
1422 public ASTNode visitSingleTableClause(final SingleTableClauseContext ctx) {
1423 SimpleTableSegment result = (SimpleTableSegment) visit(ctx.tableName());
1424 if (null != ctx.alias()) {
1425 result.setAlias((AliasSegment) visit(ctx.alias()));
1426 }
1427 return result;
1428 }
1429
1430 @Override
1431 public ASTNode visitMultipleTablesClause(final MultipleTablesClauseContext ctx) {
1432 DeleteMultiTableSegment result = new DeleteMultiTableSegment();
1433 TableSegment relateTableSource = (TableSegment) visit(ctx.tableReferences());
1434 result.setRelationTable(relateTableSource);
1435 result.setActualDeleteTables(generateTablesFromTableMultipleTableNames(ctx.multipleTableNames()));
1436 return result;
1437 }
1438
1439 private List<SimpleTableSegment> generateTablesFromTableMultipleTableNames(final MultipleTableNamesContext ctx) {
1440 List<SimpleTableSegment> result = new LinkedList<>();
1441 for (TableNameContext each : ctx.tableName()) {
1442 result.add((SimpleTableSegment) visit(each));
1443 }
1444 return result;
1445 }
1446
1447 @Override
1448 public ASTNode visitDuplicateSpecification(final DuplicateSpecificationContext ctx) {
1449 return new BooleanLiteralValue(null != ctx.DISTINCT());
1450 }
1451
1452 @Override
1453 public ASTNode visitProjection(final ProjectionContext ctx) {
1454 if (null != ctx.qualifiedShorthand()) {
1455 QualifiedShorthandContext shorthand = ctx.qualifiedShorthand();
1456 ShorthandProjectionSegment result = new ShorthandProjectionSegment(shorthand.getStart().getStartIndex(), shorthand.getStop().getStopIndex());
1457 IdentifierValue identifier = new IdentifierValue(shorthand.identifier().getText());
1458 result.setOwner(new OwnerSegment(shorthand.identifier().getStart().getStartIndex(), shorthand.identifier().getStop().getStopIndex(), identifier));
1459 return result;
1460 }
1461 if (null != ctx.unqualifiedShorthand()) {
1462 return new ShorthandProjectionSegment(ctx.unqualifiedShorthand().getStart().getStartIndex(), ctx.unqualifiedShorthand().getStop().getStopIndex());
1463 }
1464 AliasSegment alias = null == ctx.alias() ? null : (AliasSegment) visit(ctx.alias());
1465 if (null != ctx.columnName()) {
1466 ColumnSegment column = (ColumnSegment) visit(ctx.columnName());
1467 ColumnProjectionSegment result = new ColumnProjectionSegment(column);
1468 result.setAlias(alias);
1469 return result;
1470 }
1471 return createProjection(ctx, alias);
1472 }
1473
1474 @Override
1475 public ASTNode visitTop(final TopContext ctx) {
1476 int startIndex = ctx.topNum().getStart().getStartIndex();
1477 int stopIndex = ctx.topNum().getStop().getStopIndex();
1478 ASTNode topNum = visit(ctx.topNum());
1479 if (topNum instanceof NumberLiteralValue) {
1480 NumberLiteralRowNumberValueSegment rowNumberSegment = new NumberLiteralRowNumberValueSegment(startIndex, stopIndex, ((NumberLiteralValue) topNum).getValue().longValue(), false);
1481 return new TopProjectionSegment(ctx.getStart().getStartIndex(), ctx.getStop().getStopIndex(), rowNumberSegment, null != ctx.alias() ? ctx.alias().getText() : null);
1482 }
1483 ParameterMarkerSegment parameterSegment = new ParameterMarkerRowNumberValueSegment(startIndex, stopIndex, ((ParameterMarkerValue) topNum).getValue(), false);
1484 parameterMarkerSegments.add(parameterSegment);
1485 return new TopProjectionSegment(ctx.getStart().getStartIndex(), ctx.getStop().getStopIndex(), (RowNumberValueSegment) parameterSegment, null != ctx.alias() ? ctx.alias().getText() : null);
1486 }
1487
1488 @Override
1489 public ASTNode visitAlias(final AliasContext ctx) {
1490 if (null != ctx.identifier()) {
1491 return new AliasSegment(ctx.start.getStartIndex(), ctx.stop.getStopIndex(), (IdentifierValue) visit(ctx.identifier()));
1492 }
1493 if (null != ctx.NCHAR_TEXT()) {
1494 return new AliasSegment(ctx.start.getStartIndex(), ctx.stop.getStopIndex(), new IdentifierValue(ctx.NCHAR_TEXT().getText().substring(1)));
1495 }
1496 return new AliasSegment(ctx.start.getStartIndex(), ctx.stop.getStopIndex(), new IdentifierValue(ctx.STRING_().getText()));
1497 }
1498
1499 private ASTNode createProjection(final ProjectionContext ctx, final AliasSegment alias) {
1500 ASTNode projection = visit(ctx.expr());
1501 if (projection instanceof AggregationProjectionSegment) {
1502 ((AggregationProjectionSegment) projection).setAlias(alias);
1503 return projection;
1504 }
1505 if (projection instanceof ExpressionProjectionSegment) {
1506 ((ExpressionProjectionSegment) projection).setAlias(alias);
1507 return projection;
1508 }
1509 if (projection instanceof FunctionSegment) {
1510 FunctionSegment segment = (FunctionSegment) projection;
1511 ExpressionProjectionSegment result = new ExpressionProjectionSegment(segment.getStartIndex(), segment.getStopIndex(), segment.getText(), segment);
1512 result.setAlias(alias);
1513 return result;
1514 }
1515 if (projection instanceof CommonExpressionSegment) {
1516 CommonExpressionSegment segment = (CommonExpressionSegment) projection;
1517 ExpressionProjectionSegment result = new ExpressionProjectionSegment(segment.getStartIndex(), segment.getStopIndex(), segment.getText(), segment);
1518 result.setAlias(alias);
1519 return result;
1520 }
1521
1522 if (projection instanceof ColumnSegment) {
1523 ColumnProjectionSegment result = new ColumnProjectionSegment((ColumnSegment) projection);
1524 result.setAlias(alias);
1525 return result;
1526 }
1527 if (projection instanceof SubqueryExpressionSegment) {
1528 SubqueryExpressionSegment subqueryExpressionSegment = (SubqueryExpressionSegment) projection;
1529 String text = ctx.start.getInputStream().getText(new Interval(subqueryExpressionSegment.getStartIndex(), subqueryExpressionSegment.getStopIndex()));
1530 SubqueryProjectionSegment result = new SubqueryProjectionSegment(((SubqueryExpressionSegment) projection).getSubquery(), text);
1531 result.setAlias(alias);
1532 return result;
1533 }
1534 if (projection instanceof BinaryOperationExpression) {
1535 BinaryOperationExpression binaryExpression = (BinaryOperationExpression) projection;
1536 int startIndex = getStartIndexWithAlias(binaryExpression, alias);
1537 int stopIndex = getStopIndexWithAlias(binaryExpression, alias);
1538 ExpressionProjectionSegment result = new ExpressionProjectionSegment(startIndex, stopIndex, binaryExpression.getText(), binaryExpression);
1539 result.setAlias(alias);
1540 return result;
1541 }
1542 if (projection instanceof ParameterMarkerExpressionSegment) {
1543 ParameterMarkerExpressionSegment result = (ParameterMarkerExpressionSegment) projection;
1544 result.setAlias(alias);
1545 return projection;
1546 }
1547 ExpressionSegment column = (ExpressionSegment) projection;
1548 ExpressionProjectionSegment result = new ExpressionProjectionSegment(getStartIndexWithAlias(column, alias), getStopIndexWithAlias(column, alias), String.valueOf(column.getText()), column);
1549 result.setAlias(alias);
1550 return result;
1551 }
1552
1553 private int getStartIndexWithAlias(final SQLSegment sqlSegment, final AliasSegment alias) {
1554 return null != alias && alias.getStartIndex() < sqlSegment.getStartIndex() ? alias.getStartIndex() : sqlSegment.getStartIndex();
1555 }
1556
1557 private int getStopIndexWithAlias(final SQLSegment sqlSegment, final AliasSegment alias) {
1558 return null != alias && alias.getStopIndex() > sqlSegment.getStopIndex() ? alias.getStopIndex() : sqlSegment.getStopIndex();
1559 }
1560
1561 @Override
1562 public ASTNode visitIntoClause(final IntoClauseContext ctx) {
1563 return visit(ctx.tableName());
1564 }
1565
1566 @Override
1567 public ASTNode visitFromClause(final FromClauseContext ctx) {
1568 return visit(ctx.tableReferences());
1569 }
1570
1571 @Override
1572 public ASTNode visitTableReference(final TableReferenceContext ctx) {
1573 TableSegment result;
1574 TableSegment left;
1575 left = (TableSegment) visit(ctx.tableFactor());
1576 if (!ctx.joinedTable().isEmpty()) {
1577 for (JoinedTableContext each : ctx.joinedTable()) {
1578 left = visitJoinedTable(each, left);
1579 }
1580 }
1581 result = left;
1582 return result;
1583 }
1584
1585 @Override
1586 public ASTNode visitTableFactor(final TableFactorContext ctx) {
1587 if (null != ctx.subquery()) {
1588 SubquerySegment subquerySegment = new SubquerySegment(ctx.subquery().start.getStartIndex(), ctx.subquery().stop.getStopIndex(), getOriginalText(ctx.subquery()));
1589 if (null != ctx.subquery().merge()) {
1590 subquerySegment.setMerge((MergeStatement) visit(ctx.subquery()));
1591 } else {
1592 subquerySegment.setSelect((SelectStatement) visit(ctx.subquery()));
1593 }
1594 SubqueryTableSegment result = new SubqueryTableSegment(ctx.start.getStartIndex(), ctx.stop.getStopIndex(), subquerySegment);
1595 if (null != ctx.alias()) {
1596 result.setAlias((AliasSegment) visit(ctx.alias()));
1597 }
1598 return result;
1599 }
1600 if (null != ctx.tableName()) {
1601 SimpleTableSegment result = (SimpleTableSegment) visit(ctx.tableName());
1602 if (null != ctx.alias()) {
1603 result.setAlias((AliasSegment) visit(ctx.alias()));
1604 }
1605 return result;
1606 }
1607 if (null != ctx.expr()) {
1608 ExpressionSegment exprSegment = (ExpressionSegment) visit(ctx.expr());
1609 FunctionTableSegment result = new FunctionTableSegment(exprSegment.getStartIndex(), exprSegment.getStopIndex(), exprSegment);
1610 if (null != ctx.alias()) {
1611 result.setAlias((AliasSegment) visit(ctx.alias()));
1612 }
1613 return result;
1614 }
1615 return visit(ctx.tableReferences());
1616 }
1617
1618 private JoinTableSegment visitJoinedTable(final JoinedTableContext ctx, final TableSegment tableSegment) {
1619 JoinTableSegment result = new JoinTableSegment();
1620 result.setLeft(tableSegment);
1621 result.setStartIndex(tableSegment.getStartIndex());
1622 result.setStopIndex(ctx.stop.getStopIndex());
1623 TableSegment right = (TableSegment) visit(ctx.tableFactor());
1624 result.setRight(right);
1625 result.setJoinType(getJoinType(ctx));
1626 if (null != ctx.joinSpecification()) {
1627 visitJoinSpecification(ctx.joinSpecification(), result);
1628 }
1629 return result;
1630 }
1631
1632 private String getJoinType(final JoinedTableContext ctx) {
1633 if (null != ctx.LEFT()) {
1634 return JoinType.LEFT.name();
1635 } else if (null != ctx.RIGHT()) {
1636 return JoinType.RIGHT.name();
1637 } else if (null != ctx.FULL()) {
1638 return JoinType.FULL.name();
1639 } else if (null != ctx.INNER()) {
1640 return JoinType.INNER.name();
1641 } else if (null != ctx.CROSS()) {
1642 return JoinType.CROSS.name();
1643 }
1644 return JoinType.INNER.name();
1645 }
1646
1647 private void visitJoinSpecification(final JoinSpecificationContext ctx, final JoinTableSegment joinTableSource) {
1648 if (null != ctx.expr()) {
1649 ExpressionSegment condition = (ExpressionSegment) visit(ctx.expr());
1650 joinTableSource.setCondition(condition);
1651 }
1652 if (null != ctx.USING()) {
1653 joinTableSource.setUsing(ctx.columnNames().columnName().stream().map(each -> (ColumnSegment) visit(each)).collect(Collectors.toList()));
1654 }
1655 }
1656
1657 @Override
1658 public ASTNode visitSubquery(final SubqueryContext ctx) {
1659 if (null != ctx.merge()) {
1660 return visit(ctx.merge());
1661 }
1662 return visit(ctx.aggregationClause());
1663 }
1664
1665 @Override
1666 public ASTNode visitCreateTableAsSelectClause(final CreateTableAsSelectClauseContext ctx) {
1667 CreateTableStatement result = new CreateTableStatement();
1668 if (null != ctx.createTableAsSelect()) {
1669 result.setTable((SimpleTableSegment) visit(ctx.createTableAsSelect().tableName()));
1670 result.setSelectStatement((SelectStatement) visit(ctx.createTableAsSelect().select()));
1671 if (null != ctx.createTableAsSelect().columnNames()) {
1672 CollectionValue<ColumnSegment> columnSegments = (CollectionValue<ColumnSegment>) visit(ctx.createTableAsSelect().columnNames());
1673 for (ColumnSegment each : columnSegments.getValue()) {
1674 result.getColumns().add(each);
1675 }
1676 }
1677 } else {
1678 result.setTable((SimpleTableSegment) visit(ctx.createRemoteTableAsSelect().tableName()));
1679 result.setSelectStatement((SelectStatement) visit(ctx.createRemoteTableAsSelect().select()));
1680 }
1681 return result;
1682 }
1683
1684 @Override
1685 public ASTNode visitUpdateStatistics(final UpdateStatisticsContext ctx) {
1686 List<IndexSegment> indexSegments = null;
1687 if (null != ctx.indexName() && !ctx.indexName().isEmpty()) {
1688 indexSegments = new LinkedList<>();
1689 for (IndexNameContext indexNameContext : ctx.indexName()) {
1690 indexSegments.add((IndexSegment) visit(indexNameContext));
1691 }
1692 }
1693 return new SQLServerUpdateStatisticsStatement(null == ctx.tableName() ? null : (SimpleTableSegment) visit(ctx.tableName()),
1694 indexSegments, null == ctx.statisticsWithClause() ? null : (StatisticsStrategySegment) visit(ctx.statisticsWithClause()));
1695 }
1696
1697 @Override
1698 public ASTNode visitStatisticsWithClause(final StatisticsWithClauseContext ctx) {
1699 StatisticsStrategySegment result = new StatisticsStrategySegment(ctx.getStart().getStartIndex(), ctx.getStop().getStopIndex());
1700 if (null != ctx.sampleOption()) {
1701 result.setSampleOption((SampleOptionSegment) visit(ctx.sampleOption()));
1702 }
1703 if (null != ctx.statisticsOptions()) {
1704 result.setStatisticsOptions((StatisticsOptionSegment) visit(ctx.statisticsOptions()));
1705 }
1706 return result;
1707 }
1708
1709 @Override
1710 public ASTNode visitSampleOption(final SampleOptionContext ctx) {
1711 SampleOptionSegment result = new SampleOptionSegment(ctx.getStart().getStartIndex(), ctx.getStop().getStopIndex());
1712 if (null != ctx.FULLSCAN()) {
1713 result.setStrategy(SampleStrategy.FULLSCAN);
1714 } else if (null != ctx.SAMPLE()) {
1715 result.setStrategy(SampleStrategy.SAMPLE);
1716 if (null != ctx.NUMBER_()) {
1717 List<TerminalNode> number = ctx.NUMBER_();
1718 result.setSampleNumber(number.get(0).getText());
1719 }
1720 if (null != ctx.PERCENT()) {
1721 result.setScanUnit(ScanUnit.PERCENT);
1722 } else if (null != ctx.ROWS()) {
1723 result.setScanUnit(ScanUnit.ROWS);
1724 }
1725 } else if (null != ctx.RESAMPLE()) {
1726 result.setStrategy(SampleStrategy.RESAMPLE);
1727 if (null != ctx.NUMBER_()) {
1728 List<String> partitions = new LinkedList<>();
1729 for (TerminalNode terminalNode : ctx.NUMBER_()) {
1730 partitions.add(terminalNode.getText());
1731 }
1732 result.setPartitions(partitions);
1733 }
1734 }
1735 if (null != ctx.PERSIST_SAMPLE_PERCENT()) {
1736 result.setPersistSamplePercent(null != ctx.ON());
1737 }
1738 return result;
1739 }
1740
1741 @Override
1742 public ASTNode visitStatisticsOptions(final StatisticsOptionsContext ctx) {
1743 StatisticsOptionSegment result = new StatisticsOptionSegment(ctx.getStart().getStartIndex(), ctx.getStop().getStopIndex());
1744 for (StatisticsOptionContext option : ctx.statisticsOption()) {
1745 if (null != option.ALL()) {
1746 result.setStatisticsDimension(StatisticsDimension.ALL);
1747 } else if (null != option.COLUMNS()) {
1748 result.setStatisticsDimension(StatisticsDimension.COLUMNS);
1749 } else if (null != option.INDEX()) {
1750 result.setStatisticsDimension(StatisticsDimension.INDEX);
1751 }
1752 if (null != option.NORECOMPUTE()) {
1753 result.setNoRecompute(true);
1754 }
1755 if (null != option.INCREMENTAL()) {
1756 result.setIncremental(null != option.ON());
1757 }
1758 if (null != option.MAXDOP()) {
1759 result.setMaxDegreeOfParallelism(option.NUMBER_().getText());
1760 }
1761 if (null != option.AUTO_DROP()) {
1762 result.setAutoDrop(null != option.ON());
1763 }
1764 }
1765 return result;
1766 }
1767
1768 @Override
1769 public ASTNode visitMerge(final MergeContext ctx) {
1770 MergeStatement result = new MergeStatement();
1771 result.setTarget((TableSegment) visit(ctx.mergeIntoClause().tableReferences()));
1772 if (null != ctx.withClause()) {
1773 result.setWith((WithSegment) visit(ctx.withClause()));
1774 }
1775 if (null != ctx.withMergeHint()) {
1776 result.setWithTableHint((WithTableHintSegment) visit(ctx.withMergeHint().withTableHint()));
1777 if (null != ctx.withMergeHint().indexName()) {
1778 Collection<IndexSegment> indexSegments = new LinkedList<>();
1779 for (IndexNameContext each : ctx.withMergeHint().indexName()) {
1780 indexSegments.add((IndexSegment) visit(each));
1781 }
1782 result.setIndexes(indexSegments);
1783 }
1784 }
1785 if (null != ctx.mergeUsingClause()) {
1786 result.setSource((TableSegment) visit(ctx.mergeUsingClause().tableReferences()));
1787 ExpressionWithParamsSegment onExpression = new ExpressionWithParamsSegment(ctx.mergeUsingClause().expr().start.getStartIndex(), ctx.mergeUsingClause().expr().stop.getStopIndex(),
1788 (ExpressionSegment) visit(ctx.mergeUsingClause().expr()));
1789 result.setExpression(onExpression);
1790 }
1791 if (null != ctx.mergeWhenClause()) {
1792 for (MergeWhenClauseContext each : ctx.mergeWhenClause()) {
1793 result.getWhenAndThens().add((MergeWhenAndThenSegment) visit(each));
1794 }
1795 }
1796 if (null != ctx.outputClause()) {
1797 result.setOutput((OutputSegment) visit(ctx.outputClause()));
1798 }
1799 if (null != ctx.optionHint()) {
1800 result.setOptionHint((OptionHintSegment) visit(ctx.optionHint()));
1801 }
1802 return result;
1803 }
1804
1805 @Override
1806 public ASTNode visitMergeWhenClause(final MergeWhenClauseContext ctx) {
1807 MergeWhenAndThenSegment result = new MergeWhenAndThenSegment(ctx.start.getStartIndex(), ctx.stop.getStopIndex(), getOriginalText(ctx));
1808 if (null != ctx.mergeDeleteClause() && null != ctx.mergeDeleteClause().expr()) {
1809 result.setAndExpr((ExpressionSegment) visit(ctx.mergeDeleteClause().expr()));
1810 }
1811 if (null != ctx.mergeUpdateClause()) {
1812 result.setUpdate((UpdateStatement) visit(ctx.mergeUpdateClause()));
1813 if (null != ctx.mergeUpdateClause().expr()) {
1814 result.setAndExpr((ExpressionSegment) visit(ctx.mergeUpdateClause().expr()));
1815 }
1816 }
1817 if (null != ctx.mergeInsertClause()) {
1818 result.setInsert((InsertStatement) visit(ctx.mergeInsertClause()));
1819 if (null != ctx.mergeInsertClause().expr()) {
1820 result.setAndExpr((ExpressionSegment) visit(ctx.mergeInsertClause().expr()));
1821 }
1822 }
1823 return result;
1824 }
1825
1826 @Override
1827 public ASTNode visitMergeInsertClause(final MergeInsertClauseContext ctx) {
1828 InsertStatement result;
1829 if (null != ctx.insertDefaultValue()) {
1830 result = (InsertStatement) visit(ctx.insertDefaultValue());
1831 } else {
1832 result = (InsertStatement) visit(ctx.insertValuesClause());
1833 }
1834 return result;
1835 }
1836
1837 @Override
1838 public ASTNode visitMergeUpdateClause(final MergeUpdateClauseContext ctx) {
1839 UpdateStatement result = new UpdateStatement();
1840 result.setSetAssignment((SetAssignmentSegment) visit(ctx.setAssignmentsClause()));
1841 return result;
1842 }
1843 }