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