View Javadoc
1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one or more
3    * contributor license agreements.  See the NOTICE file distributed with
4    * this work for additional information regarding copyright ownership.
5    * The ASF licenses this file to You under the Apache License, Version 2.0
6    * (the "License"); you may not use this file except in compliance with
7    * the License.  You may obtain a copy of the License at
8    *
9    *     http://www.apache.org/licenses/LICENSE-2.0
10   *
11   * Unless required by applicable law or agreed to in writing, software
12   * distributed under the License is distributed on an "AS IS" BASIS,
13   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14   * See the License for the specific language governing permissions and
15   * limitations under the License.
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  * Statement visitor for SQLServer.
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         // TODO deal with hexadecimalLiterals
298         return new OtherLiteralValue(ctx.getText());
299     }
300     
301     @Override
302     public final ASTNode visitBitValueLiterals(final BitValueLiteralsContext ctx) {
303         // TODO deal with bitValueLiterals
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     // TODO :FIXME, sql case id: insert_with_str_to_date
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         // TODO :Unsupported for union | except | intersect SQL.
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      * Get original text.
1122      *
1123      * @param ctx context
1124      * @return original text
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         // FIXME :For DISTINCT()
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 }