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