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