1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 package org.apache.shardingsphere.sql.parser.oracle.visitor.statement.type;
19
20 import org.antlr.v4.runtime.misc.Interval;
21 import org.apache.shardingsphere.sql.parser.api.ASTNode;
22 import org.apache.shardingsphere.sql.parser.api.visitor.statement.type.DMLStatementVisitor;
23 import org.apache.shardingsphere.sql.parser.autogen.OracleStatementParser.AliasContext;
24 import org.apache.shardingsphere.sql.parser.autogen.OracleStatementParser.AssignmentValueContext;
25 import org.apache.shardingsphere.sql.parser.autogen.OracleStatementParser.AssignmentValuesContext;
26 import org.apache.shardingsphere.sql.parser.autogen.OracleStatementParser.CellAssignmentContext;
27 import org.apache.shardingsphere.sql.parser.autogen.OracleStatementParser.CollectionExprContext;
28 import org.apache.shardingsphere.sql.parser.autogen.OracleStatementParser.ColumnNameContext;
29 import org.apache.shardingsphere.sql.parser.autogen.OracleStatementParser.ColumnNamesContext;
30 import org.apache.shardingsphere.sql.parser.autogen.OracleStatementParser.ConditionalInsertClauseContext;
31 import org.apache.shardingsphere.sql.parser.autogen.OracleStatementParser.ConditionalInsertElsePartContext;
32 import org.apache.shardingsphere.sql.parser.autogen.OracleStatementParser.ConditionalInsertWhenPartContext;
33 import org.apache.shardingsphere.sql.parser.autogen.OracleStatementParser.ContainersClauseContext;
34 import org.apache.shardingsphere.sql.parser.autogen.OracleStatementParser.CrossOuterApplyClauseContext;
35 import org.apache.shardingsphere.sql.parser.autogen.OracleStatementParser.DeleteContext;
36 import org.apache.shardingsphere.sql.parser.autogen.OracleStatementParser.DeleteSpecificationContext;
37 import org.apache.shardingsphere.sql.parser.autogen.OracleStatementParser.DeleteWhereClauseContext;
38 import org.apache.shardingsphere.sql.parser.autogen.OracleStatementParser.DimensionColumnContext;
39 import org.apache.shardingsphere.sql.parser.autogen.OracleStatementParser.DmlSubqueryClauseContext;
40 import org.apache.shardingsphere.sql.parser.autogen.OracleStatementParser.DmlTableClauseContext;
41 import org.apache.shardingsphere.sql.parser.autogen.OracleStatementParser.DuplicateSpecificationContext;
42 import org.apache.shardingsphere.sql.parser.autogen.OracleStatementParser.ExecuteContext;
43 import org.apache.shardingsphere.sql.parser.autogen.OracleStatementParser.ExprContext;
44 import org.apache.shardingsphere.sql.parser.autogen.OracleStatementParser.ExpressionListContext;
45 import org.apache.shardingsphere.sql.parser.autogen.OracleStatementParser.ForUpdateClauseContext;
46 import org.apache.shardingsphere.sql.parser.autogen.OracleStatementParser.ForUpdateClauseListContext;
47 import org.apache.shardingsphere.sql.parser.autogen.OracleStatementParser.ForUpdateClauseOptionContext;
48 import org.apache.shardingsphere.sql.parser.autogen.OracleStatementParser.FromClauseListContext;
49 import org.apache.shardingsphere.sql.parser.autogen.OracleStatementParser.FromClauseOptionContext;
50 import org.apache.shardingsphere.sql.parser.autogen.OracleStatementParser.GroupByClauseContext;
51 import org.apache.shardingsphere.sql.parser.autogen.OracleStatementParser.GroupByItemContext;
52 import org.apache.shardingsphere.sql.parser.autogen.OracleStatementParser.GroupingExprListContext;
53 import org.apache.shardingsphere.sql.parser.autogen.OracleStatementParser.GroupingSetsClauseContext;
54 import org.apache.shardingsphere.sql.parser.autogen.OracleStatementParser.HavingClauseContext;
55 import org.apache.shardingsphere.sql.parser.autogen.OracleStatementParser.InnerCrossJoinClauseContext;
56 import org.apache.shardingsphere.sql.parser.autogen.OracleStatementParser.InsertContext;
57 import org.apache.shardingsphere.sql.parser.autogen.OracleStatementParser.InsertIntoClauseContext;
58 import org.apache.shardingsphere.sql.parser.autogen.OracleStatementParser.InsertMultiTableContext;
59 import org.apache.shardingsphere.sql.parser.autogen.OracleStatementParser.InsertSingleTableContext;
60 import org.apache.shardingsphere.sql.parser.autogen.OracleStatementParser.InsertValuesClauseContext;
61 import org.apache.shardingsphere.sql.parser.autogen.OracleStatementParser.IntoClauseContext;
62 import org.apache.shardingsphere.sql.parser.autogen.OracleStatementParser.JoinClauseContext;
63 import org.apache.shardingsphere.sql.parser.autogen.OracleStatementParser.MergeAssignmentContext;
64 import org.apache.shardingsphere.sql.parser.autogen.OracleStatementParser.MergeAssignmentValueContext;
65 import org.apache.shardingsphere.sql.parser.autogen.OracleStatementParser.MergeColumnValueContext;
66 import org.apache.shardingsphere.sql.parser.autogen.OracleStatementParser.MergeContext;
67 import org.apache.shardingsphere.sql.parser.autogen.OracleStatementParser.MergeInsertClauseContext;
68 import org.apache.shardingsphere.sql.parser.autogen.OracleStatementParser.MergeInsertColumnContext;
69 import org.apache.shardingsphere.sql.parser.autogen.OracleStatementParser.MergeSetAssignmentsClauseContext;
70 import org.apache.shardingsphere.sql.parser.autogen.OracleStatementParser.MergeUpdateClauseContext;
71 import org.apache.shardingsphere.sql.parser.autogen.OracleStatementParser.ModelClauseContext;
72 import org.apache.shardingsphere.sql.parser.autogen.OracleStatementParser.MultiColumnForLoopContext;
73 import org.apache.shardingsphere.sql.parser.autogen.OracleStatementParser.MultiTableElementContext;
74 import org.apache.shardingsphere.sql.parser.autogen.OracleStatementParser.OrderByClauseContext;
75 import org.apache.shardingsphere.sql.parser.autogen.OracleStatementParser.OuterJoinClauseContext;
76 import org.apache.shardingsphere.sql.parser.autogen.OracleStatementParser.ParenthesisSelectSubqueryContext;
77 import org.apache.shardingsphere.sql.parser.autogen.OracleStatementParser.PivotClauseContext;
78 import org.apache.shardingsphere.sql.parser.autogen.OracleStatementParser.QueryBlockContext;
79 import org.apache.shardingsphere.sql.parser.autogen.OracleStatementParser.QueryNameContext;
80 import org.apache.shardingsphere.sql.parser.autogen.OracleStatementParser.QueryTableExprClauseContext;
81 import org.apache.shardingsphere.sql.parser.autogen.OracleStatementParser.QueryTableExprContext;
82 import org.apache.shardingsphere.sql.parser.autogen.OracleStatementParser.ReferenceModelContext;
83 import org.apache.shardingsphere.sql.parser.autogen.OracleStatementParser.RollupCubeClauseContext;
84 import org.apache.shardingsphere.sql.parser.autogen.OracleStatementParser.SelectContext;
85 import org.apache.shardingsphere.sql.parser.autogen.OracleStatementParser.SelectFromClauseContext;
86 import org.apache.shardingsphere.sql.parser.autogen.OracleStatementParser.SelectIntoStatementContext;
87 import org.apache.shardingsphere.sql.parser.autogen.OracleStatementParser.SelectJoinOptionContext;
88 import org.apache.shardingsphere.sql.parser.autogen.OracleStatementParser.SelectJoinSpecificationContext;
89 import org.apache.shardingsphere.sql.parser.autogen.OracleStatementParser.SelectListContext;
90 import org.apache.shardingsphere.sql.parser.autogen.OracleStatementParser.SelectProjectionContext;
91 import org.apache.shardingsphere.sql.parser.autogen.OracleStatementParser.SelectProjectionExprClauseContext;
92 import org.apache.shardingsphere.sql.parser.autogen.OracleStatementParser.SelectSubqueryContext;
93 import org.apache.shardingsphere.sql.parser.autogen.OracleStatementParser.SelectTableReferenceContext;
94 import org.apache.shardingsphere.sql.parser.autogen.OracleStatementParser.ShardsClauseContext;
95 import org.apache.shardingsphere.sql.parser.autogen.OracleStatementParser.SingleColumnForLoopContext;
96 import org.apache.shardingsphere.sql.parser.autogen.OracleStatementParser.SubqueryContext;
97 import org.apache.shardingsphere.sql.parser.autogen.OracleStatementParser.SubqueryFactoringClauseContext;
98 import org.apache.shardingsphere.sql.parser.autogen.OracleStatementParser.TableCollectionExprContext;
99 import org.apache.shardingsphere.sql.parser.autogen.OracleStatementParser.TableNameContext;
100 import org.apache.shardingsphere.sql.parser.autogen.OracleStatementParser.UnpivotClauseContext;
101 import org.apache.shardingsphere.sql.parser.autogen.OracleStatementParser.UpdateContext;
102 import org.apache.shardingsphere.sql.parser.autogen.OracleStatementParser.UpdateSetClauseContext;
103 import org.apache.shardingsphere.sql.parser.autogen.OracleStatementParser.UpdateSetColumnClauseContext;
104 import org.apache.shardingsphere.sql.parser.autogen.OracleStatementParser.UpdateSetValueClauseContext;
105 import org.apache.shardingsphere.sql.parser.autogen.OracleStatementParser.UpdateSpecificationContext;
106 import org.apache.shardingsphere.sql.parser.autogen.OracleStatementParser.UsingClauseContext;
107 import org.apache.shardingsphere.sql.parser.autogen.OracleStatementParser.WhereClauseContext;
108 import org.apache.shardingsphere.sql.parser.autogen.OracleStatementParser.WithClauseContext;
109 import org.apache.shardingsphere.sql.parser.oracle.visitor.statement.OracleStatementVisitor;
110 import org.apache.shardingsphere.sql.parser.statement.core.enums.CombineType;
111 import org.apache.shardingsphere.sql.parser.statement.core.enums.JoinType;
112 import org.apache.shardingsphere.sql.parser.statement.core.enums.OrderDirection;
113 import org.apache.shardingsphere.sql.parser.statement.core.segment.dal.VariableSegment;
114 import org.apache.shardingsphere.sql.parser.statement.core.segment.dml.assignment.ColumnAssignmentSegment;
115 import org.apache.shardingsphere.sql.parser.statement.core.segment.dml.assignment.InsertValuesSegment;
116 import org.apache.shardingsphere.sql.parser.statement.core.segment.dml.assignment.SetAssignmentSegment;
117 import org.apache.shardingsphere.sql.parser.statement.core.segment.dml.column.ColumnSegment;
118 import org.apache.shardingsphere.sql.parser.statement.core.segment.dml.column.InsertColumnsSegment;
119 import org.apache.shardingsphere.sql.parser.statement.core.segment.dml.combine.CombineSegment;
120 import org.apache.shardingsphere.sql.parser.statement.core.segment.dml.datetime.DatetimeExpression;
121 import org.apache.shardingsphere.sql.parser.statement.core.segment.dml.expr.BetweenExpression;
122 import org.apache.shardingsphere.sql.parser.statement.core.segment.dml.expr.BinaryOperationExpression;
123 import org.apache.shardingsphere.sql.parser.statement.core.segment.dml.expr.CaseWhenExpression;
124 import org.apache.shardingsphere.sql.parser.statement.core.segment.dml.expr.CollateExpression;
125 import org.apache.shardingsphere.sql.parser.statement.core.segment.dml.expr.ExpressionSegment;
126 import org.apache.shardingsphere.sql.parser.statement.core.segment.dml.expr.ExpressionWithParamsSegment;
127 import org.apache.shardingsphere.sql.parser.statement.core.segment.dml.expr.FunctionSegment;
128 import org.apache.shardingsphere.sql.parser.statement.core.segment.dml.expr.InExpression;
129 import org.apache.shardingsphere.sql.parser.statement.core.segment.dml.expr.complex.CommonExpressionSegment;
130 import org.apache.shardingsphere.sql.parser.statement.core.segment.dml.expr.complex.CommonTableExpressionSegment;
131 import org.apache.shardingsphere.sql.parser.statement.core.segment.dml.expr.complex.ComplexExpressionSegment;
132 import org.apache.shardingsphere.sql.parser.statement.core.segment.dml.expr.simple.LiteralExpressionSegment;
133 import org.apache.shardingsphere.sql.parser.statement.core.segment.dml.expr.simple.SimpleExpressionSegment;
134 import org.apache.shardingsphere.sql.parser.statement.core.segment.dml.expr.subquery.SubqueryExpressionSegment;
135 import org.apache.shardingsphere.sql.parser.statement.core.segment.dml.expr.subquery.SubquerySegment;
136 import org.apache.shardingsphere.sql.parser.statement.core.segment.dml.item.ColumnProjectionSegment;
137 import org.apache.shardingsphere.sql.parser.statement.core.segment.dml.item.DatetimeProjectionSegment;
138 import org.apache.shardingsphere.sql.parser.statement.core.segment.dml.item.ExpressionProjectionSegment;
139 import org.apache.shardingsphere.sql.parser.statement.core.segment.dml.item.IntervalExpressionProjection;
140 import org.apache.shardingsphere.sql.parser.statement.core.segment.dml.item.ProjectionSegment;
141 import org.apache.shardingsphere.sql.parser.statement.core.segment.dml.item.ProjectionsSegment;
142 import org.apache.shardingsphere.sql.parser.statement.core.segment.dml.item.ShorthandProjectionSegment;
143 import org.apache.shardingsphere.sql.parser.statement.core.segment.dml.item.SubqueryProjectionSegment;
144 import org.apache.shardingsphere.sql.parser.statement.core.segment.dml.multiset.MultisetExpression;
145 import org.apache.shardingsphere.sql.parser.statement.core.segment.dml.order.GroupBySegment;
146 import org.apache.shardingsphere.sql.parser.statement.core.segment.dml.order.OrderBySegment;
147 import org.apache.shardingsphere.sql.parser.statement.core.segment.dml.order.item.ColumnOrderByItemSegment;
148 import org.apache.shardingsphere.sql.parser.statement.core.segment.dml.order.item.ExpressionOrderByItemSegment;
149 import org.apache.shardingsphere.sql.parser.statement.core.segment.dml.order.item.IndexOrderByItemSegment;
150 import org.apache.shardingsphere.sql.parser.statement.core.segment.dml.order.item.OrderByItemSegment;
151 import org.apache.shardingsphere.sql.parser.statement.core.segment.dml.predicate.HavingSegment;
152 import org.apache.shardingsphere.sql.parser.statement.core.segment.dml.predicate.LockSegment;
153 import org.apache.shardingsphere.sql.parser.statement.core.segment.dml.predicate.WhereSegment;
154 import org.apache.shardingsphere.sql.parser.statement.core.segment.dml.table.MultiTableConditionalIntoElseSegment;
155 import org.apache.shardingsphere.sql.parser.statement.core.segment.dml.table.MultiTableConditionalIntoSegment;
156 import org.apache.shardingsphere.sql.parser.statement.core.segment.dml.table.MultiTableConditionalIntoThenSegment;
157 import org.apache.shardingsphere.sql.parser.statement.core.segment.dml.table.MultiTableConditionalIntoWhenThenSegment;
158 import org.apache.shardingsphere.sql.parser.statement.core.segment.dml.table.MultiTableInsertIntoSegment;
159 import org.apache.shardingsphere.sql.parser.statement.core.segment.dml.table.MultiTableInsertType;
160 import org.apache.shardingsphere.sql.parser.statement.core.segment.dml.xml.XmlElementFunctionSegment;
161 import org.apache.shardingsphere.sql.parser.statement.core.segment.dml.xml.XmlPiFunctionSegment;
162 import org.apache.shardingsphere.sql.parser.statement.core.segment.dml.xml.XmlQueryAndExistsFunctionSegment;
163 import org.apache.shardingsphere.sql.parser.statement.core.segment.dml.xml.XmlSerializeFunctionSegment;
164 import org.apache.shardingsphere.sql.parser.statement.core.segment.dml.xml.XmlTableFunctionSegment;
165 import org.apache.shardingsphere.sql.parser.statement.core.segment.generic.AliasAvailable;
166 import org.apache.shardingsphere.sql.parser.statement.core.segment.generic.AliasSegment;
167 import org.apache.shardingsphere.sql.parser.statement.core.segment.generic.ModelSegment;
168 import org.apache.shardingsphere.sql.parser.statement.core.segment.generic.OwnerSegment;
169 import org.apache.shardingsphere.sql.parser.statement.core.segment.generic.ParameterMarkerSegment;
170 import org.apache.shardingsphere.sql.parser.statement.core.segment.generic.PivotSegment;
171 import org.apache.shardingsphere.sql.parser.statement.core.segment.generic.WithSegment;
172 import org.apache.shardingsphere.sql.parser.statement.core.segment.generic.table.CollectionTableSegment;
173 import org.apache.shardingsphere.sql.parser.statement.core.segment.generic.table.FunctionTableSegment;
174 import org.apache.shardingsphere.sql.parser.statement.core.segment.generic.table.JoinTableSegment;
175 import org.apache.shardingsphere.sql.parser.statement.core.segment.generic.table.SimpleTableSegment;
176 import org.apache.shardingsphere.sql.parser.statement.core.segment.generic.table.SubqueryTableSegment;
177 import org.apache.shardingsphere.sql.parser.statement.core.segment.generic.table.TableNameSegment;
178 import org.apache.shardingsphere.sql.parser.statement.core.segment.generic.table.TableSegment;
179 import org.apache.shardingsphere.sql.parser.statement.core.statement.type.dml.DeleteStatement;
180 import org.apache.shardingsphere.sql.parser.statement.core.statement.type.dml.InsertStatement;
181 import org.apache.shardingsphere.sql.parser.statement.core.statement.type.dml.MergeStatement;
182 import org.apache.shardingsphere.sql.parser.statement.core.statement.type.dml.SelectStatement;
183 import org.apache.shardingsphere.sql.parser.statement.core.statement.type.dml.UpdateStatement;
184 import org.apache.shardingsphere.sql.parser.statement.core.util.SQLUtils;
185 import org.apache.shardingsphere.sql.parser.statement.core.value.collection.CollectionValue;
186 import org.apache.shardingsphere.sql.parser.statement.core.value.identifier.IdentifierValue;
187 import org.apache.shardingsphere.sql.parser.statement.core.value.literal.impl.BooleanLiteralValue;
188
189 import java.util.ArrayList;
190 import java.util.Collection;
191 import java.util.Collections;
192 import java.util.HashSet;
193 import java.util.LinkedList;
194 import java.util.List;
195 import java.util.stream.Collectors;
196
197
198
199
200 public final class OracleDMLStatementVisitor extends OracleStatementVisitor implements DMLStatementVisitor {
201
202 @Override
203 public ASTNode visitUpdate(final UpdateContext ctx) {
204 UpdateStatement result = new UpdateStatement();
205 result.setTable((TableSegment) visit(ctx.updateSpecification()));
206 if (null != ctx.alias()) {
207 result.getTable().setAlias((AliasSegment) visit(ctx.alias()));
208 }
209 result.setSetAssignment((SetAssignmentSegment) visit(ctx.updateSetClause()));
210 if (null != ctx.whereClause()) {
211 result.setWhere((WhereSegment) visit(ctx.whereClause()));
212 }
213 result.addParameterMarkers(ctx.getParent() instanceof ExecuteContext ? getGlobalParameterMarkerSegments() : popAllStatementParameterMarkerSegments());
214 result.getVariableNames().addAll(getVariableNames());
215 return result;
216 }
217
218 @Override
219 public ASTNode visitUpdateSpecification(final UpdateSpecificationContext ctx) {
220 if (null != ctx.dmlTableExprClause().dmlTableClause()) {
221 return visit(ctx.dmlTableExprClause().dmlTableClause());
222 }
223 if (null != ctx.dmlTableExprClause().dmlSubqueryClause()) {
224 SubquerySegment subquerySegment = (SubquerySegment) visit(ctx.dmlTableExprClause().dmlSubqueryClause());
225 return new SubqueryTableSegment(ctx.start.getStartIndex(), ctx.stop.getStopIndex(), subquerySegment);
226 }
227 SubquerySegment subquerySegment = (SubquerySegment) visit(ctx.dmlTableExprClause().tableCollectionExpr());
228 return new SubqueryTableSegment(ctx.start.getStartIndex(), ctx.stop.getStopIndex(), subquerySegment);
229 }
230
231 @Override
232 public ASTNode visitUpdateSetClause(final UpdateSetClauseContext ctx) {
233 Collection<ColumnAssignmentSegment> assignments = new LinkedList<>();
234 if (null != ctx.updateSetColumnList()) {
235 for (UpdateSetColumnClauseContext each : ctx.updateSetColumnList().updateSetColumnClause()) {
236 assignments.add((ColumnAssignmentSegment) visit(each));
237 }
238 } else {
239 assignments.add((ColumnAssignmentSegment) visit(ctx.updateSetValueClause()));
240 }
241 return new SetAssignmentSegment(ctx.getStart().getStartIndex(), ctx.getStop().getStopIndex(), assignments);
242 }
243
244 @Override
245 public ASTNode visitUpdateSetColumnClause(final UpdateSetColumnClauseContext ctx) {
246 return 1 == ctx.columnName().size() ? createAssignmentSegmentFromSingleColumnAssignment(ctx) : createAssignmentSegmentFromMultiColumnAssignment(ctx);
247 }
248
249 private ColumnAssignmentSegment createAssignmentSegmentFromSingleColumnAssignment(final UpdateSetColumnClauseContext ctx) {
250 ColumnSegment column = (ColumnSegment) visitColumnName(ctx.columnName(0));
251 List<ColumnSegment> columnSegments = new LinkedList<>();
252 columnSegments.add(column);
253 if (null != ctx.expr()) {
254 ExpressionSegment value = (ExpressionSegment) visit(ctx.expr());
255 return new ColumnAssignmentSegment(ctx.getStart().getStartIndex(), ctx.getStop().getStopIndex(), columnSegments, value);
256 }
257 if (null != ctx.selectSubquery()) {
258 SubquerySegment subquerySegment = new SubquerySegment(ctx.selectSubquery().start.getStartIndex(), ctx.selectSubquery().stop.getStopIndex(),
259 (SelectStatement) visit(ctx.selectSubquery()), getOriginalText(ctx.selectSubquery()));
260 SubqueryExpressionSegment value = new SubqueryExpressionSegment(subquerySegment);
261 ColumnAssignmentSegment result = new ColumnAssignmentSegment(ctx.getStart().getStartIndex(), ctx.getStop().getStopIndex(), columnSegments, value);
262 result.getColumns().add(column);
263 return result;
264 }
265 CommonExpressionSegment value = new CommonExpressionSegment(ctx.getStart().getStartIndex(), ctx.getStop().getStopIndex(), ctx.DEFAULT().getText());
266 ColumnAssignmentSegment result = new ColumnAssignmentSegment(ctx.getStart().getStartIndex(), ctx.getStop().getStopIndex(), columnSegments, value);
267 result.getColumns().add(column);
268 return result;
269 }
270
271 private ColumnAssignmentSegment createAssignmentSegmentFromMultiColumnAssignment(final UpdateSetColumnClauseContext ctx) {
272 List<ColumnSegment> columnSegments = new LinkedList<>();
273 for (ColumnNameContext each : ctx.columnName()) {
274 columnSegments.add((ColumnSegment) visit(each));
275 }
276 SubquerySegment subquerySegment = new SubquerySegment(ctx.selectSubquery().start.getStartIndex(), ctx.selectSubquery().stop.getStopIndex(),
277 (SelectStatement) visit(ctx.selectSubquery()), getOriginalText(ctx.selectSubquery()));
278 SubqueryExpressionSegment value = new SubqueryExpressionSegment(subquerySegment);
279 return new ColumnAssignmentSegment(ctx.getStart().getStartIndex(), ctx.getStop().getStopIndex(), columnSegments, value);
280 }
281
282 @Override
283 public ASTNode visitUpdateSetValueClause(final UpdateSetValueClauseContext ctx) {
284 ColumnSegment column = (ColumnSegment) visit(ctx.columnName());
285 List<ColumnSegment> columnSegments = new LinkedList<>();
286 columnSegments.add(column);
287 if (null != ctx.expr()) {
288 ExpressionSegment value = (ExpressionSegment) visit(ctx.expr());
289 ColumnAssignmentSegment result = new ColumnAssignmentSegment(ctx.getStart().getStartIndex(), ctx.getStop().getStopIndex(), columnSegments, value);
290 result.getColumns().add(column);
291 return result;
292 } else {
293 SubquerySegment subquerySegment = new SubquerySegment(ctx.selectSubquery().start.getStartIndex(), ctx.selectSubquery().stop.getStopIndex(),
294 (SelectStatement) visit(ctx.selectSubquery()), getOriginalText(ctx.selectSubquery()));
295 SubqueryExpressionSegment value = new SubqueryExpressionSegment(subquerySegment);
296 ColumnAssignmentSegment result = new ColumnAssignmentSegment(ctx.getStart().getStartIndex(), ctx.getStop().getStopIndex(), columnSegments, value);
297 result.getColumns().add(column);
298 return result;
299 }
300 }
301
302 @Override
303 public ASTNode visitInsert(final InsertContext ctx) {
304
305 InsertStatement result = (InsertStatement) (null == ctx.insertSingleTable() ? visit(ctx.insertMultiTable()) : visit(ctx.insertSingleTable()));
306 result.addParameterMarkers(ctx.getParent() instanceof ExecuteContext ? getGlobalParameterMarkerSegments() : popAllStatementParameterMarkerSegments());
307 return result;
308 }
309
310 @Override
311 public ASTNode visitInsertSingleTable(final InsertSingleTableContext ctx) {
312 InsertStatement result = (InsertStatement) visit(ctx.insertIntoClause());
313 if (null != ctx.insertValuesClause()) {
314 result.getValues().addAll(createInsertValuesSegments(ctx.insertValuesClause().assignmentValues()));
315 }
316 if (null != ctx.selectSubquery()) {
317 SelectStatement subquery = (SelectStatement) visit(ctx.selectSubquery());
318 SubquerySegment subquerySegment = new SubquerySegment(ctx.selectSubquery().start.getStartIndex(), ctx.selectSubquery().stop.getStopIndex(), subquery,
319 getOriginalText(ctx.selectSubquery()));
320 result.setInsertSelect(subquerySegment);
321 }
322 result.getVariableNames().addAll(getVariableNames());
323 return result;
324 }
325
326 private Collection<InsertValuesSegment> createInsertValuesSegments(final AssignmentValuesContext ctx) {
327 Collection<InsertValuesSegment> result = new LinkedList<>();
328 result.add((InsertValuesSegment) visit(ctx));
329 return result;
330 }
331
332 @Override
333 public ASTNode visitInsertMultiTable(final InsertMultiTableContext ctx) {
334 InsertStatement result = new InsertStatement();
335 result.setMultiTableInsertType(null != ctx.conditionalInsertClause() && null != ctx.conditionalInsertClause().FIRST() ? MultiTableInsertType.FIRST : MultiTableInsertType.ALL);
336 List<MultiTableElementContext> multiTableElementContexts = ctx.multiTableElement();
337 if (null != multiTableElementContexts && !multiTableElementContexts.isEmpty()) {
338 MultiTableInsertIntoSegment multiTableInsertIntoSegment = new MultiTableInsertIntoSegment(
339 multiTableElementContexts.get(0).getStart().getStartIndex(), multiTableElementContexts.get(multiTableElementContexts.size() - 1).getStop().getStopIndex());
340 multiTableInsertIntoSegment.getInsertStatements().addAll(createInsertIntoSegments(multiTableElementContexts));
341 result.setMultiTableInsertInto(multiTableInsertIntoSegment);
342 } else {
343 result.setMultiTableConditionalInto((MultiTableConditionalIntoSegment) visit(ctx.conditionalInsertClause()));
344 }
345 result.setInsertSelect(new SubquerySegment(ctx.selectSubquery().start.getStartIndex(), ctx.selectSubquery().stop.getStopIndex(), (SelectStatement) visit(ctx.selectSubquery()),
346 getOriginalText(ctx.selectSubquery())));
347 result.getVariableNames().addAll(getVariableNames());
348 return result;
349 }
350
351 private Collection<InsertStatement> createInsertIntoSegments(final List<MultiTableElementContext> ctx) {
352 Collection<InsertStatement> result = new LinkedList<>();
353 Collection<ParameterMarkerSegment> addedSegments = new HashSet<>();
354 for (MultiTableElementContext each : ctx) {
355 InsertStatement insertStatement = (InsertStatement) visit(each);
356 addParameterMarkerSegments(addedSegments, insertStatement);
357 result.add(insertStatement);
358 }
359 return result;
360 }
361
362 private void addParameterMarkerSegments(final Collection<ParameterMarkerSegment> addedSegments, final InsertStatement insertStatement) {
363 for (ParameterMarkerSegment parameterMarkerSegment : popAllStatementParameterMarkerSegments()) {
364 if (addedSegments.add(parameterMarkerSegment)) {
365 insertStatement.addParameterMarkers(Collections.singletonList(parameterMarkerSegment));
366 }
367 }
368 }
369
370 @Override
371 public ASTNode visitInsertValuesClause(final InsertValuesClauseContext ctx) {
372 InsertStatement result = new InsertStatement();
373 result.getValues().addAll(createInsertValuesSegments(ctx.assignmentValues()));
374 return result;
375 }
376
377 @SuppressWarnings("unchecked")
378 @Override
379 public ASTNode visitInsertIntoClause(final InsertIntoClauseContext ctx) {
380 InsertStatement result = new InsertStatement();
381 if (null != ctx.dmlTableExprClause().dmlTableClause()) {
382 result.setTable((SimpleTableSegment) visit(ctx.dmlTableExprClause().dmlTableClause()));
383 } else if (null != ctx.dmlTableExprClause().dmlSubqueryClause()) {
384 result.setInsertSelect((SubquerySegment) visit(ctx.dmlTableExprClause().dmlSubqueryClause()));
385 } else {
386 result.setInsertSelect((SubquerySegment) visit(ctx.dmlTableExprClause().tableCollectionExpr()));
387 }
388 if (null != ctx.columnNames()) {
389 ColumnNamesContext columnNames = ctx.columnNames();
390 CollectionValue<ColumnSegment> columnSegments = (CollectionValue<ColumnSegment>) visit(columnNames);
391 result.setInsertColumns(new InsertColumnsSegment(columnNames.start.getStartIndex(), columnNames.stop.getStopIndex(), columnSegments.getValue()));
392 } else {
393 result.setInsertColumns(new InsertColumnsSegment(ctx.stop.getStopIndex() + 1, ctx.stop.getStopIndex() + 1, Collections.emptyList()));
394 }
395 return result;
396 }
397
398 @Override
399 public ASTNode visitDelete(final DeleteContext ctx) {
400 DeleteStatement result = new DeleteStatement();
401 result.setTable((TableSegment) visit(ctx.deleteSpecification()));
402 if (null != ctx.alias()) {
403 result.getTable().setAlias((AliasSegment) visit(ctx.alias()));
404 }
405 if (null != ctx.whereClause()) {
406 result.setWhere((WhereSegment) visit(ctx.whereClause()));
407 }
408 result.addParameterMarkers(ctx.getParent() instanceof ExecuteContext ? getGlobalParameterMarkerSegments() : popAllStatementParameterMarkerSegments());
409 result.getVariableNames().addAll(getVariableNames());
410 return result;
411 }
412
413 @Override
414 public ASTNode visitDeleteSpecification(final DeleteSpecificationContext ctx) {
415 if (null != ctx.dmlTableExprClause().dmlTableClause()) {
416 return visit(ctx.dmlTableExprClause().dmlTableClause());
417 }
418 if (null != ctx.dmlTableExprClause().dmlSubqueryClause()) {
419 SubquerySegment subquerySegment = (SubquerySegment) visit(ctx.dmlTableExprClause().dmlSubqueryClause());
420 return new SubqueryTableSegment(ctx.dmlTableExprClause().dmlSubqueryClause().start.getStartIndex(), ctx.dmlTableExprClause().dmlSubqueryClause().stop.getStopIndex(), subquerySegment);
421 }
422 SubquerySegment subquerySegment = (SubquerySegment) visit(ctx.dmlTableExprClause().tableCollectionExpr());
423 return new SubqueryTableSegment(ctx.dmlTableExprClause().tableCollectionExpr().start.getStartIndex(), ctx.dmlTableExprClause().tableCollectionExpr().stop.getStopIndex(), subquerySegment);
424 }
425
426 @Override
427 public SelectStatement visitSelectIntoStatement(final SelectIntoStatementContext ctx) {
428 SelectStatement result = new SelectStatement();
429 result.setProjections((ProjectionsSegment) visit(ctx.selectList()));
430
431 result.setFrom((TableSegment) visit(ctx.fromClauseList()));
432 if (null != ctx.whereClause()) {
433 result.setWhere((WhereSegment) visit(ctx.whereClause()));
434 }
435 if (null != ctx.groupByClause()) {
436 result.setGroupBy((GroupBySegment) visit(ctx.groupByClause()));
437 }
438
439 if (null != ctx.modelClause()) {
440 result.setModel((ModelSegment) visit(ctx.modelClause()));
441 }
442
443 if (null != ctx.orderByClause()) {
444 result.setOrderBy((OrderBySegment) visit(ctx.orderByClause()));
445 }
446
447 result.addParameterMarkers(ctx.getParent() instanceof ExecuteContext ? getGlobalParameterMarkerSegments() : popAllStatementParameterMarkerSegments());
448 result.getVariableNames().addAll(getVariableNames());
449 return result;
450 }
451
452 @Override
453 public ASTNode visitMultiTableElement(final MultiTableElementContext ctx) {
454 InsertStatement result = (InsertStatement) visit(ctx.insertIntoClause());
455 if (null != ctx.insertValuesClause()) {
456 result.getValues().addAll(createInsertValuesSegments(ctx.insertValuesClause().assignmentValues()));
457 }
458 result.addParameterMarkers(ctx.getParent() instanceof ExecuteContext ? getGlobalParameterMarkerSegments() : popAllStatementParameterMarkerSegments());
459 return result;
460 }
461
462 @Override
463 public ASTNode visitSelect(final SelectContext ctx) {
464 SelectStatement result = (SelectStatement) visit(ctx.selectSubquery());
465 result.addParameterMarkers(ctx.getParent() instanceof ExecuteContext ? getGlobalParameterMarkerSegments() : popAllStatementParameterMarkerSegments());
466 result.getVariableNames().addAll(getVariableNames());
467 if (null != ctx.forUpdateClause()) {
468 result.setLock((LockSegment) visit(ctx.forUpdateClause()));
469 }
470 return result;
471 }
472
473 @Override
474 public ASTNode visitPivotClause(final PivotClauseContext ctx) {
475 Collection<ColumnSegment> pivotInColumns = new LinkedList<>();
476 if (null != ctx.pivotInClause()) {
477 ctx.pivotInClause().pivotInClauseExpr().forEach(each -> {
478 ExpressionSegment expr = (ExpressionSegment) visit(each.expr());
479 String columnName = null != each.alias() && null != each.alias().identifier() ? each.alias().identifier().IDENTIFIER_().getText() : expr.getText();
480 ColumnSegment columnSegment = new ColumnSegment(each.getStart().getStartIndex(), each.getStop().getStopIndex(), new IdentifierValue(columnName));
481 pivotInColumns.add(columnSegment);
482 });
483 }
484 return new PivotSegment(ctx.getStart().getStartIndex(), ctx.getStop().getStopIndex(), ((CollectionValue<ColumnSegment>) visit(ctx.pivotForClause().columnNames())).getValue(), pivotInColumns);
485 }
486
487 @Override
488 public ASTNode visitUnpivotClause(final UnpivotClauseContext ctx) {
489 Collection<ColumnSegment> unpivotInColumns = new LinkedList<>();
490 if (null != ctx.unpivotInClause()) {
491 ctx.unpivotInClause().unpivotInClauseExpr().forEach(each -> unpivotInColumns.addAll(((CollectionValue<ColumnSegment>) visit(ctx.columnNames())).getValue()));
492 }
493 PivotSegment result = new PivotSegment(ctx.getStart().getStartIndex(), ctx.getStop().getStopIndex(), ((CollectionValue<ColumnSegment>) visit(ctx.pivotForClause().columnNames())).getValue(),
494 unpivotInColumns, true);
495 result.setUnpivotColumns(((CollectionValue<ColumnSegment>) visit(ctx.columnNames())).getValue());
496 return result;
497 }
498
499 @Override
500 public ASTNode visitDmlTableClause(final DmlTableClauseContext ctx) {
501 if (null != ctx.AT_() && null != ctx.dbLink()) {
502 SimpleTableSegment result = new SimpleTableSegment(new TableNameSegment(ctx.start.getStartIndex(), ctx.stop.getStopIndex(), new IdentifierValue(ctx.tableName().name().getText())));
503 if (null != ctx.tableName().owner()) {
504 result.setOwner(
505 new OwnerSegment(ctx.tableName().owner().start.getStartIndex(), ctx.tableName().owner().stop.getStopIndex(), (IdentifierValue) visit(ctx.tableName().owner().identifier())));
506 }
507 result.setAt(new IdentifierValue(ctx.AT_().getText()));
508 result.setDbLink(new IdentifierValue(ctx.dbLink().identifier(0).getText()));
509 return result;
510 }
511 return visit(ctx.tableName());
512 }
513
514 @Override
515 public ASTNode visitDmlSubqueryClause(final DmlSubqueryClauseContext ctx) {
516 SelectStatement subquery = (SelectStatement) visit(ctx.selectSubquery());
517 return new SubquerySegment(ctx.selectSubquery().start.getStartIndex(), ctx.selectSubquery().stop.getStopIndex(), subquery, getOriginalText(ctx.selectSubquery()));
518 }
519
520 @Override
521 public ASTNode visitTableCollectionExpr(final TableCollectionExprContext ctx) {
522 if (null != ctx.collectionExpr().selectSubquery()) {
523 SelectStatement subquery = (SelectStatement) visit(ctx.collectionExpr().selectSubquery());
524 return new SubquerySegment(ctx.collectionExpr().selectSubquery().start.getStartIndex(), ctx.collectionExpr().selectSubquery().stop.getStopIndex(), subquery,
525 getOriginalText(ctx.collectionExpr().selectSubquery()));
526 }
527 if (null != ctx.collectionExpr().functionCall()) {
528 return visit(ctx.collectionExpr().functionCall());
529 }
530 if (null != ctx.collectionExpr().columnName()) {
531 return visit(ctx.collectionExpr().columnName());
532 }
533 if (null != ctx.collectionExpr().expr()) {
534 return visit(ctx.collectionExpr().expr());
535 }
536 throw new UnsupportedOperationException("Unhandled table collection expr");
537 }
538
539 @Override
540 public ASTNode visitConditionalInsertClause(final ConditionalInsertClauseContext ctx) {
541 Collection<MultiTableConditionalIntoWhenThenSegment> whenThenSegments = new LinkedList<>();
542 for (ConditionalInsertWhenPartContext each : ctx.conditionalInsertWhenPart()) {
543 whenThenSegments.add((MultiTableConditionalIntoWhenThenSegment) visit(each));
544 }
545 MultiTableConditionalIntoSegment result = new MultiTableConditionalIntoSegment(ctx.start.getStartIndex(), ctx.stop.getStopIndex());
546 result.getWhenThenSegments().addAll(whenThenSegments);
547 if (null != ctx.conditionalInsertElsePart()) {
548 result.setElseSegment((MultiTableConditionalIntoElseSegment) visit(ctx.conditionalInsertElsePart()));
549 }
550 return result;
551 }
552
553 @Override
554 public ASTNode visitConditionalInsertWhenPart(final ConditionalInsertWhenPartContext ctx) {
555 List<MultiTableElementContext> multiTableElementContexts = ctx.multiTableElement();
556 MultiTableConditionalIntoThenSegment thenSegment = new MultiTableConditionalIntoThenSegment(multiTableElementContexts.get(0).start.getStartIndex(),
557 multiTableElementContexts.get(multiTableElementContexts.size() - 1).stop.getStopIndex(), createInsertIntoSegments(multiTableElementContexts));
558 return new MultiTableConditionalIntoWhenThenSegment(ctx.start.getStartIndex(), ctx.stop.getStopIndex(), (ExpressionSegment) visit(ctx.expr()), thenSegment);
559 }
560
561 @Override
562 public ASTNode visitConditionalInsertElsePart(final ConditionalInsertElsePartContext ctx) {
563 return new MultiTableConditionalIntoElseSegment(ctx.start.getStartIndex(), ctx.stop.getStopIndex(), createInsertIntoSegments(ctx.multiTableElement()));
564 }
565
566 @Override
567 public ASTNode visitAssignmentValues(final AssignmentValuesContext ctx) {
568 List<ExpressionSegment> segments = new LinkedList<>();
569 for (AssignmentValueContext each : ctx.assignmentValue()) {
570 segments.add((ExpressionSegment) visit(each));
571 }
572 return new InsertValuesSegment(ctx.getStart().getStartIndex(), ctx.getStop().getStopIndex(), segments);
573 }
574
575 @Override
576 public ASTNode visitAssignmentValue(final AssignmentValueContext ctx) {
577 ExprContext expr = ctx.expr();
578 return null == expr ? new CommonExpressionSegment(ctx.getStart().getStartIndex(), ctx.getStop().getStopIndex(), ctx.getText()) : visit(expr);
579 }
580
581 @Override
582 public ASTNode visitSelectSubquery(final SelectSubqueryContext ctx) {
583 SelectStatement result;
584 if (null != ctx.combineType()) {
585 result = new SelectStatement();
586 SelectStatement left = (SelectStatement) visit(ctx.selectSubquery(0));
587 result.setProjections(left.getProjections());
588 left.getFrom().ifPresent(result::setFrom);
589 left.getWith().ifPresent(result::setWith);
590 createSelectCombineClause(ctx, result, left);
591 } else {
592 result = null != ctx.queryBlock() ? (SelectStatement) visit(ctx.queryBlock()) : (SelectStatement) visit(ctx.parenthesisSelectSubquery());
593 }
594 if (null != ctx.orderByClause()) {
595 result.setOrderBy((OrderBySegment) visit(ctx.orderByClause()));
596 }
597 result.addParameterMarkers(ctx.getParent() instanceof ExecuteContext ? getGlobalParameterMarkerSegments() : popAllStatementParameterMarkerSegments());
598 result.getVariableNames().addAll(getVariableNames());
599 return result;
600 }
601
602 private void createSelectCombineClause(final SelectSubqueryContext ctx, final SelectStatement result, final SelectStatement left) {
603 CombineType combineType;
604 if (null != ctx.combineType().UNION() && null != ctx.combineType().ALL()) {
605 combineType = CombineType.UNION_ALL;
606 } else if (null != ctx.combineType().UNION()) {
607 combineType = CombineType.UNION;
608 } else if (null != ctx.combineType().INTERSECT()) {
609 combineType = CombineType.INTERSECT;
610 } else {
611 combineType = CombineType.MINUS;
612 }
613 SelectStatement right = (SelectStatement) visit(ctx.selectSubquery(1));
614 result.setCombine(new CombineSegment(ctx.getStart().getStartIndex(), ctx.getStop().getStopIndex(), createSubquerySegment(ctx.selectSubquery(0), left), combineType,
615 createSubquerySegment(ctx.selectSubquery(1), right)));
616 result.addParameterMarkers(left.getParameterMarkers());
617 result.addParameterMarkers(right.getParameterMarkers());
618 }
619
620 private SubquerySegment createSubquerySegment(final SelectSubqueryContext ctx, final SelectStatement selectStatement) {
621 return new SubquerySegment(ctx.start.getStartIndex(), ctx.stop.getStopIndex(), selectStatement, getOriginalText(ctx));
622 }
623
624 @Override
625 public ASTNode visitQueryBlock(final QueryBlockContext ctx) {
626 SelectStatement result = new SelectStatement();
627 result.setProjections((ProjectionsSegment) visit(ctx.selectList()));
628 if (null != ctx.withClause()) {
629 result.setWith((WithSegment) visit(ctx.withClause()));
630 }
631 if (null != ctx.duplicateSpecification()) {
632 result.getProjections().setDistinctRow(isDistinct(ctx));
633 }
634 if (null != ctx.selectFromClause()) {
635 TableSegment tableSegment = (TableSegment) visit(ctx.selectFromClause());
636 result.setFrom(tableSegment);
637 }
638 if (null != ctx.whereClause()) {
639 result.setWhere((WhereSegment) visit(ctx.whereClause()));
640 }
641 if (null != ctx.groupByClause()) {
642 result.setGroupBy((GroupBySegment) visit(ctx.groupByClause()));
643 if (null != ctx.groupByClause().havingClause()) {
644 result.setHaving((HavingSegment) visit(ctx.groupByClause().havingClause()));
645 }
646 }
647 if (null != ctx.modelClause()) {
648 result.setModel((ModelSegment) visit(ctx.modelClause()));
649 }
650 return result;
651 }
652
653 @Override
654 public ASTNode visitHavingClause(final HavingClauseContext ctx) {
655 ExpressionSegment expr = (ExpressionSegment) visit(ctx.expr());
656 return new HavingSegment(ctx.getStart().getStartIndex(), ctx.getStop().getStopIndex(), expr);
657 }
658
659 @Override
660 public ASTNode visitModelClause(final ModelClauseContext ctx) {
661 ModelSegment result = new ModelSegment(ctx.start.getStartIndex(), ctx.stop.getStopIndex());
662 if (null != ctx.referenceModel()) {
663 for (ReferenceModelContext each : ctx.referenceModel()) {
664 result.getReferenceModelSelects().add((SubquerySegment) visit(each));
665 }
666 }
667 if (null != ctx.mainModel().modelRulesClause().orderByClause()) {
668 for (OrderByClauseContext each : ctx.mainModel().modelRulesClause().orderByClause()) {
669 result.getOrderBySegments().add((OrderBySegment) visit(each));
670 }
671 }
672 for (CellAssignmentContext each : ctx.mainModel().modelRulesClause().cellAssignment()) {
673 result.getCellAssignmentColumns().add((ColumnSegment) visit(each.measureColumn().columnName()));
674 if (null != each.singleColumnForLoop()) {
675 result.getCellAssignmentColumns().addAll(extractColumnValuesFromSingleColumnForLoop(each.singleColumnForLoop()));
676 result.getCellAssignmentSelects().addAll(extractSelectSubqueryValuesFromSingleColumnForLoop(each.singleColumnForLoop()));
677 }
678 if (null != each.multiColumnForLoop()) {
679 result.getCellAssignmentColumns().addAll(extractColumnValuesFromMultiColumnForLoop(each.multiColumnForLoop()));
680 result.getCellAssignmentSelects().add(extractSelectSubqueryValueFromMultiColumnForLoop(each.multiColumnForLoop()));
681 }
682 }
683 return result;
684 }
685
686 private Collection<ColumnSegment> extractColumnValuesFromSingleColumnForLoop(final List<SingleColumnForLoopContext> ctx) {
687 Collection<ColumnSegment> result = new LinkedList<>();
688 for (SingleColumnForLoopContext each : ctx) {
689 result.add((ColumnSegment) visit(each.dimensionColumn().columnName()));
690 }
691 return result;
692 }
693
694 private Collection<SubquerySegment> extractSelectSubqueryValuesFromSingleColumnForLoop(final List<SingleColumnForLoopContext> ctx) {
695 Collection<SubquerySegment> result = new LinkedList<>();
696 for (SingleColumnForLoopContext each : ctx) {
697 if (null != each.selectSubquery()) {
698 SelectStatement subquery = (SelectStatement) visit(each.selectSubquery());
699 SubquerySegment subquerySegment = new SubquerySegment(each.selectSubquery().start.getStartIndex(), each.selectSubquery().stop.getStopIndex(), subquery,
700 getOriginalText(each.selectSubquery()));
701 result.add(subquerySegment);
702 }
703 }
704 return result;
705 }
706
707 private Collection<ColumnSegment> extractColumnValuesFromMultiColumnForLoop(final MultiColumnForLoopContext ctx) {
708 Collection<ColumnSegment> result = new LinkedList<>();
709 for (DimensionColumnContext each : ctx.dimensionColumn()) {
710 result.add((ColumnSegment) visit(each.columnName()));
711 }
712 return result;
713 }
714
715 private SubquerySegment extractSelectSubqueryValueFromMultiColumnForLoop(final MultiColumnForLoopContext ctx) {
716 SelectStatement subquery = (SelectStatement) visit(ctx.selectSubquery());
717 return new SubquerySegment(ctx.selectSubquery().start.getStartIndex(), ctx.selectSubquery().stop.getStopIndex(), subquery, getOriginalText(ctx.selectSubquery()));
718 }
719
720 @Override
721 public ASTNode visitReferenceModel(final ReferenceModelContext ctx) {
722 SelectStatement subquery = (SelectStatement) visit(ctx.selectSubquery());
723 return new SubquerySegment(ctx.selectSubquery().start.getStartIndex(), ctx.selectSubquery().stop.getStopIndex(), subquery, getOriginalText(ctx.selectSubquery()));
724 }
725
726 @Override
727 public ASTNode visitParenthesisSelectSubquery(final ParenthesisSelectSubqueryContext ctx) {
728 return visit(ctx.selectSubquery());
729 }
730
731 @Override
732 public ASTNode visitWithClause(final WithClauseContext ctx) {
733 Collection<CommonTableExpressionSegment> commonTableExpressions = new LinkedList<>();
734 if (null != ctx.subqueryFactoringClause()) {
735 for (SubqueryFactoringClauseContext each : ctx.subqueryFactoringClause()) {
736 SubquerySegment subquery = new SubquerySegment(each.selectSubquery().start.getStartIndex(), each.selectSubquery().stop.getStopIndex(), (SelectStatement) visit(each),
737 getOriginalText(each));
738 CommonTableExpressionSegment commonTableExpression = new CommonTableExpressionSegment(each.start.getStartIndex(), each.stop.getStopIndex(),
739 (AliasSegment) visit(each.queryName().alias()), subquery);
740 if (null != each.searchClause()) {
741 ColumnNameContext columnName = each.searchClause().orderingColumn().columnName();
742 commonTableExpression.getColumns().add((ColumnSegment) visit(columnName));
743 }
744 commonTableExpressions.add(commonTableExpression);
745 }
746 }
747 return new WithSegment(ctx.start.getStartIndex(), ctx.stop.getStopIndex(), commonTableExpressions);
748 }
749
750 @Override
751 public ASTNode visitSubqueryFactoringClause(final SubqueryFactoringClauseContext ctx) {
752 return visit(ctx.selectSubquery());
753 }
754
755 private boolean isDistinct(final QueryBlockContext ctx) {
756 return ((BooleanLiteralValue) visit(ctx.duplicateSpecification())).getValue();
757 }
758
759 @Override
760 public ASTNode visitDuplicateSpecification(final DuplicateSpecificationContext ctx) {
761 if (null != ctx.DISTINCT() || null != ctx.UNIQUE()) {
762 return new BooleanLiteralValue(true);
763 }
764 return new BooleanLiteralValue(false);
765 }
766
767 @Override
768 public ASTNode visitSelectList(final SelectListContext ctx) {
769 ProjectionsSegment result = new ProjectionsSegment(ctx.getStart().getStartIndex(), ctx.getStop().getStopIndex());
770 Collection<ProjectionSegment> projections = new LinkedList<>();
771 if (null != ctx.unqualifiedShorthand()) {
772 projections.add(new ShorthandProjectionSegment(ctx.unqualifiedShorthand().getStart().getStartIndex(), ctx.unqualifiedShorthand().getStop().getStopIndex()));
773 result.getProjections().addAll(projections);
774 return result;
775 }
776 for (SelectProjectionContext each : ctx.selectProjection()) {
777 projections.add((ProjectionSegment) visit(each));
778 }
779 result.getProjections().addAll(projections);
780 return result;
781 }
782
783 @Override
784 public ASTNode visitSelectProjection(final SelectProjectionContext ctx) {
785
786 if (null != ctx.queryName()) {
787 QueryNameContext queryName = ctx.queryName();
788 ShorthandProjectionSegment result = new ShorthandProjectionSegment(queryName.getStart().getStartIndex(), ctx.DOT_ASTERISK_().getSymbol().getStopIndex());
789 IdentifierValue identifier = new IdentifierValue(queryName.getText());
790 result.setOwner(new OwnerSegment(queryName.getStart().getStartIndex(), queryName.getStop().getStopIndex(), identifier));
791 return result;
792 }
793 if (null != ctx.tableName()) {
794 TableNameContext tableName = ctx.tableName();
795 ShorthandProjectionSegment result = new ShorthandProjectionSegment(tableName.getStart().getStartIndex(), ctx.DOT_ASTERISK_().getSymbol().getStopIndex());
796 IdentifierValue identifier = new IdentifierValue(tableName.getText());
797 result.setOwner(new OwnerSegment(tableName.getStart().getStartIndex(), tableName.getStop().getStopIndex(), identifier));
798 return result;
799 }
800 if (null != ctx.alias()) {
801 AliasContext aliasContext = ctx.alias();
802 ShorthandProjectionSegment result = new ShorthandProjectionSegment(aliasContext.getStart().getStartIndex(), ctx.DOT_ASTERISK_().getSymbol().getStopIndex());
803 IdentifierValue identifier = new IdentifierValue(aliasContext.getText());
804 result.setOwner(new OwnerSegment(aliasContext.getStart().getStartIndex(), aliasContext.getStop().getStopIndex(), identifier));
805 return result;
806 }
807 return createProjection(ctx.selectProjectionExprClause());
808 }
809
810 @Override
811 public ASTNode visitAlias(final AliasContext ctx) {
812 if (null != ctx.identifier()) {
813 return new AliasSegment(ctx.start.getStartIndex(), ctx.stop.getStopIndex(), (IdentifierValue) visit(ctx.identifier()));
814 }
815 return new AliasSegment(ctx.start.getStartIndex(), ctx.stop.getStopIndex(), new IdentifierValue(ctx.STRING_().getText()));
816 }
817
818 private ASTNode createProjection(final SelectProjectionExprClauseContext ctx) {
819 AliasSegment alias = null == ctx.alias() ? null : (AliasSegment) visit(ctx.alias());
820 ASTNode projection = visit(ctx.expr());
821 if (projection instanceof AliasAvailable) {
822 ((AliasAvailable) projection).setAlias(alias);
823 return projection;
824 }
825 if (projection instanceof ComplexExpressionSegment) {
826 return createProjectionForComplexExpressionSegment(projection, alias);
827 }
828 if (projection instanceof SimpleExpressionSegment) {
829 return createProjectionForSimpleExpressionSegment(projection, alias, ctx);
830 }
831 if (projection instanceof ExpressionSegment) {
832 return createProjectionForExpressionSegment(projection, alias);
833 }
834 throw new UnsupportedOperationException("Unhandled case");
835 }
836
837 private ASTNode createProjectionForComplexExpressionSegment(final ASTNode projection, final AliasSegment alias) {
838 if (projection instanceof FunctionSegment) {
839 FunctionSegment segment = (FunctionSegment) projection;
840 ExpressionProjectionSegment result = new ExpressionProjectionSegment(segment.getStartIndex(), segment.getStopIndex(), segment.getText(), segment);
841 result.setAlias(alias);
842 return result;
843 }
844 if (projection instanceof CommonExpressionSegment) {
845 CommonExpressionSegment segment = (CommonExpressionSegment) projection;
846 ExpressionProjectionSegment result = new ExpressionProjectionSegment(segment.getStartIndex(), segment.getStopIndex(), segment.getText(), segment);
847 result.setAlias(alias);
848 return result;
849 }
850 if (projection instanceof XmlQueryAndExistsFunctionSegment || projection instanceof XmlPiFunctionSegment || projection instanceof XmlSerializeFunctionSegment
851 || projection instanceof XmlElementFunctionSegment) {
852 return projection;
853 }
854 throw new UnsupportedOperationException("Unsupported Complex Expression");
855 }
856
857 private ASTNode createProjectionForSimpleExpressionSegment(final ASTNode projection, final AliasSegment alias, final SelectProjectionExprClauseContext ctx) {
858 if (projection instanceof SubqueryExpressionSegment) {
859 SubqueryExpressionSegment subqueryExpressionSegment = (SubqueryExpressionSegment) projection;
860 String text = ctx.start.getInputStream().getText(new Interval(subqueryExpressionSegment.getStartIndex(), subqueryExpressionSegment.getStopIndex()));
861 SubqueryProjectionSegment result = new SubqueryProjectionSegment(((SubqueryExpressionSegment) projection).getSubquery(), text);
862 result.setAlias(alias);
863 return result;
864 }
865 if (projection instanceof LiteralExpressionSegment) {
866 LiteralExpressionSegment column = (LiteralExpressionSegment) projection;
867 ExpressionProjectionSegment result = null == alias
868 ? new ExpressionProjectionSegment(column.getStartIndex(), column.getStopIndex(), String.valueOf(column.getLiterals()), column)
869 : new ExpressionProjectionSegment(column.getStartIndex(), ctx.alias().stop.getStopIndex(), String.valueOf(column.getLiterals()), column);
870 result.setAlias(alias);
871 return result;
872 }
873 throw new UnsupportedOperationException("Unsupported Simple Expression");
874 }
875
876 private ASTNode createProjectionForExpressionSegment(final ASTNode projection, final AliasSegment alias) {
877
878 if (projection instanceof ColumnSegment) {
879 return createColumnProjectionSegment((ColumnSegment) projection, alias);
880 }
881 if (projection instanceof BinaryOperationExpression) {
882 return createExpressionProjectionSegment((BinaryOperationExpression) projection, alias);
883 }
884 if (projection instanceof MultisetExpression) {
885 return createExpressionProjectionSegment((MultisetExpression) projection, alias);
886 }
887 if (projection instanceof DatetimeExpression) {
888 return createDatetimeProjectionSegment((DatetimeExpression) projection);
889 }
890 if (projection instanceof IntervalExpressionProjection) {
891 return createIntervalExpressionProjection((IntervalExpressionProjection) projection);
892 }
893 if (projection instanceof CaseWhenExpression || projection instanceof VariableSegment
894 || projection instanceof BetweenExpression || projection instanceof InExpression || projection instanceof CollateExpression) {
895 return createExpressionProjectionSegment((ExpressionSegment) projection, alias);
896 }
897 throw new UnsupportedOperationException("Unsupported Expression");
898 }
899
900 private ColumnProjectionSegment createColumnProjectionSegment(final ColumnSegment projection, final AliasSegment alias) {
901 ColumnProjectionSegment result = new ColumnProjectionSegment(projection);
902 result.setAlias(alias);
903 return result;
904 }
905
906 private ExpressionProjectionSegment createExpressionProjectionSegment(final BinaryOperationExpression projection, final AliasSegment alias) {
907 int startIndex = projection.getStartIndex();
908 int stopIndex = null == alias ? projection.getStopIndex() : alias.getStopIndex();
909 ExpressionProjectionSegment result = new ExpressionProjectionSegment(startIndex, stopIndex, projection.getText(), projection);
910 result.setAlias(alias);
911 return result;
912 }
913
914 private ExpressionProjectionSegment createExpressionProjectionSegment(final MultisetExpression projection, final AliasSegment alias) {
915 int startIndex = projection.getStartIndex();
916 int stopIndex = null == alias ? projection.getStopIndex() : alias.getStopIndex();
917 ExpressionProjectionSegment result = new ExpressionProjectionSegment(startIndex, stopIndex, projection.getText(), projection);
918 result.setAlias(alias);
919 return result;
920 }
921
922 private ExpressionProjectionSegment createExpressionProjectionSegment(final ExpressionSegment projection, final AliasSegment alias) {
923 ExpressionProjectionSegment result = new ExpressionProjectionSegment(projection.getStartIndex(), projection.getStopIndex(), projection.getText(), projection);
924 result.setAlias(alias);
925 return result;
926 }
927
928 private DatetimeProjectionSegment createDatetimeProjectionSegment(final DatetimeExpression projection) {
929 return null == projection.getRight()
930 ? new DatetimeProjectionSegment(projection.getStartIndex(), projection.getStopIndex(), projection.getLeft(), projection.getText())
931 : new DatetimeProjectionSegment(projection.getStartIndex(), projection.getStopIndex(), projection.getLeft(), projection.getRight(), projection.getText());
932 }
933
934 private IntervalExpressionProjection createIntervalExpressionProjection(final IntervalExpressionProjection projection) {
935 IntervalExpressionProjection result = new IntervalExpressionProjection(
936 projection.getStartIndex(), projection.getStopIndex(), projection.getLeft(), projection.getMinus(), projection.getRight(), projection.getText());
937 if (null != projection.getDayToSecondExpression()) {
938 result.setDayToSecondExpression(projection.getDayToSecondExpression());
939 } else {
940 result.setYearToMonthExpression(projection.getYearToMonthExpression());
941 }
942 return result;
943 }
944
945 @Override
946 public ASTNode visitSelectFromClause(final SelectFromClauseContext ctx) {
947 return visit(ctx.fromClauseList());
948 }
949
950 @Override
951 public ASTNode visitFromClauseList(final FromClauseListContext ctx) {
952 TableSegment result = (TableSegment) visit(ctx.fromClauseOption(0));
953 if (ctx.fromClauseOption().size() > 1) {
954 for (int i = 1; i < ctx.fromClauseOption().size(); i++) {
955 result = generateJoinTableSourceFromFromClauseOption(ctx.fromClauseOption(i), result);
956 }
957 }
958 return result;
959 }
960
961 private JoinTableSegment generateJoinTableSourceFromFromClauseOption(final FromClauseOptionContext ctx, final TableSegment tableSegment) {
962 JoinTableSegment result = new JoinTableSegment();
963 result.setStartIndex(tableSegment.getStartIndex());
964 result.setStopIndex(ctx.stop.getStopIndex());
965 result.setLeft(tableSegment);
966 result.setJoinType(JoinType.COMMA.name());
967 result.setRight((TableSegment) visit(ctx));
968 return result;
969 }
970
971 @Override
972 public ASTNode visitFromClauseOption(final FromClauseOptionContext ctx) {
973 if (null != ctx.joinClause()) {
974 return visit(ctx.joinClause());
975 }
976 if (null != ctx.regularFunction()) {
977 FunctionSegment functionSegment = (FunctionSegment) visit(ctx.regularFunction());
978 FunctionTableSegment result = new FunctionTableSegment(ctx.start.getStartIndex(), ctx.stop.getStopIndex(), functionSegment);
979 if (null != ctx.alias()) {
980 result.setAlias((AliasSegment) visit(ctx.alias()));
981 }
982 return result;
983 }
984 if (null != ctx.xmlTableFunction()) {
985 XmlTableFunctionSegment functionSegment = (XmlTableFunctionSegment) visit(ctx.xmlTableFunction());
986 FunctionTableSegment result = new FunctionTableSegment(ctx.start.getStartIndex(), ctx.stop.getStopIndex(), functionSegment);
987 if (null != ctx.alias()) {
988 result.setAlias((AliasSegment) visit(ctx.alias()));
989 }
990 return result;
991 }
992 return visit(ctx.selectTableReference());
993 }
994
995 @Override
996 public ASTNode visitJoinClause(final JoinClauseContext ctx) {
997 TableSegment result;
998 TableSegment left;
999 left = (TableSegment) visit(ctx.selectTableReference());
1000 for (SelectJoinOptionContext each : ctx.selectJoinOption()) {
1001 left = visitJoinedTable(each, left);
1002 }
1003 result = left;
1004 return result;
1005 }
1006
1007 private JoinTableSegment visitJoinedTable(final SelectJoinOptionContext ctx, final TableSegment tableSegment) {
1008 JoinTableSegment result = new JoinTableSegment();
1009 result.setLeft(tableSegment);
1010 result.setStartIndex(tableSegment.getStartIndex());
1011 result.setStopIndex(ctx.stop.getStopIndex());
1012 result.setJoinType(getJoinType(ctx));
1013 result.setNatural(isNatural(ctx));
1014 if (null != ctx.innerCrossJoinClause()) {
1015 TableSegment right = (TableSegment) visit(ctx.innerCrossJoinClause().selectTableReference());
1016 result.setRight(right);
1017 if (null != ctx.innerCrossJoinClause().selectJoinSpecification()) {
1018 visitSelectJoinSpecification(ctx.innerCrossJoinClause().selectJoinSpecification(), result);
1019 }
1020 } else if (null != ctx.outerJoinClause()) {
1021 TableSegment right = (TableSegment) visit(ctx.outerJoinClause().selectTableReference());
1022 result.setRight(right);
1023 if (null != ctx.outerJoinClause().selectJoinSpecification()) {
1024 visitSelectJoinSpecification(ctx.outerJoinClause().selectJoinSpecification(), result);
1025 }
1026 } else {
1027 TableSegment right = (TableSegment) visit(ctx.crossOuterApplyClause());
1028 result.setRight(right);
1029 }
1030 return result;
1031 }
1032
1033 private boolean isNatural(final SelectJoinOptionContext ctx) {
1034 if (null != ctx.innerCrossJoinClause()) {
1035 return null != ctx.innerCrossJoinClause().NATURAL();
1036 }
1037 if (null != ctx.outerJoinClause()) {
1038 return null != ctx.outerJoinClause().NATURAL();
1039 }
1040 return false;
1041 }
1042
1043 private String getJoinType(final SelectJoinOptionContext ctx) {
1044 if (null != ctx.innerCrossJoinClause()) {
1045 return getInnerCrossJoinType(ctx.innerCrossJoinClause());
1046 }
1047 if (null != ctx.outerJoinClause()) {
1048 return getOuterJoinType(ctx.outerJoinClause());
1049 }
1050 if (null != ctx.crossOuterApplyClause()) {
1051 return getCrossOuterApplyType(ctx.crossOuterApplyClause());
1052 }
1053 return JoinType.COMMA.name();
1054 }
1055
1056 private String getCrossOuterApplyType(final CrossOuterApplyClauseContext ctx) {
1057 if (null != ctx.CROSS()) {
1058 return JoinType.CROSS.name();
1059 }
1060 return JoinType.LEFT.name();
1061 }
1062
1063 private String getOuterJoinType(final OuterJoinClauseContext ctx) {
1064 if (null != ctx.outerJoinType().FULL()) {
1065 return JoinType.FULL.name();
1066 } else if (null != ctx.outerJoinType().LEFT()) {
1067 return JoinType.LEFT.name();
1068 }
1069 return JoinType.RIGHT.name();
1070 }
1071
1072 private String getInnerCrossJoinType(final InnerCrossJoinClauseContext ctx) {
1073 return null == ctx.CROSS() ? JoinType.INNER.name() : JoinType.CROSS.name();
1074 }
1075
1076 private void visitSelectJoinSpecification(final SelectJoinSpecificationContext ctx, final JoinTableSegment joinTableSource) {
1077 if (null != ctx.expr()) {
1078 ExpressionSegment condition = (ExpressionSegment) visit(ctx.expr());
1079 joinTableSource.setCondition(condition);
1080 }
1081 if (null != ctx.USING()) {
1082 joinTableSource.setUsing(ctx.columnNames().columnName().stream().map(each -> (ColumnSegment) visit(each)).collect(Collectors.toList()));
1083 }
1084 }
1085
1086 @Override
1087 public ASTNode visitCrossOuterApplyClause(final CrossOuterApplyClauseContext ctx) {
1088 TableSegment result;
1089 if (null != ctx.selectTableReference()) {
1090 result = (TableSegment) visit(ctx.selectTableReference());
1091 } else {
1092 SubquerySegment subquerySegment = (SubquerySegment) visit(ctx.collectionExpr());
1093 result = new SubqueryTableSegment(ctx.start.getStartIndex(), ctx.stop.getStopIndex(), subquerySegment);
1094 }
1095 return result;
1096 }
1097
1098 @Override
1099 public ASTNode visitCollectionExpr(final CollectionExprContext ctx) {
1100 SelectStatement subquery = (SelectStatement) visit(ctx.selectSubquery());
1101 return new SubquerySegment(ctx.selectSubquery().start.getStartIndex(), ctx.selectSubquery().stop.getStopIndex(), subquery, getOriginalText(ctx.selectSubquery()));
1102 }
1103
1104 @Override
1105 public ASTNode visitSelectTableReference(final SelectTableReferenceContext ctx) {
1106 TableSegment result;
1107 if (null != ctx.containersClause()) {
1108 result = (TableSegment) visit(ctx.containersClause());
1109 } else if (null != ctx.shardsClause()) {
1110 result = (TableSegment) visit(ctx.shardsClause());
1111 } else if (null != ctx.joinClause()) {
1112 result = (TableSegment) visit(ctx.joinClause());
1113 } else {
1114 result = (TableSegment) visit(ctx.queryTableExprClause());
1115 }
1116 if (null != ctx.alias()) {
1117 result.setAlias((AliasSegment) visit(ctx.alias()));
1118 }
1119 return result;
1120 }
1121
1122 @Override
1123 public ASTNode visitContainersClause(final ContainersClauseContext ctx) {
1124 return visit(ctx.tableName());
1125 }
1126
1127 @Override
1128 public ASTNode visitShardsClause(final ShardsClauseContext ctx) {
1129 return visit(ctx.tableName());
1130 }
1131
1132 @Override
1133 public ASTNode visitQueryTableExprClause(final QueryTableExprClauseContext ctx) {
1134 ASTNode result = visit(ctx.queryTableExpr());
1135 if (null != ctx.pivotClause()) {
1136 PivotSegment pivotClause = (PivotSegment) visit(ctx.pivotClause());
1137 if (result instanceof SubqueryTableSegment) {
1138 ((SubqueryTableSegment) result).setPivot(pivotClause);
1139 }
1140 if (result instanceof SimpleTableSegment) {
1141 ((SimpleTableSegment) result).setPivot(pivotClause);
1142 }
1143 }
1144 if (null != ctx.unpivotClause()) {
1145 PivotSegment pivotClause = (PivotSegment) visit(ctx.unpivotClause());
1146 if (result instanceof SubqueryTableSegment) {
1147 ((SubqueryTableSegment) result).setPivot(pivotClause);
1148 }
1149 if (result instanceof SimpleTableSegment) {
1150 ((SimpleTableSegment) result).setPivot(pivotClause);
1151 }
1152 }
1153 return result;
1154 }
1155
1156 @Override
1157 public ASTNode visitQueryTableExpr(final QueryTableExprContext ctx) {
1158 TableSegment result;
1159 if (null != ctx.queryTableExprSampleClause()) {
1160 result = (SimpleTableSegment) visit(ctx.queryTableExprSampleClause().queryTableExprTableClause().tableName());
1161 } else if (null != ctx.lateralClause()) {
1162 SelectStatement subquery = (SelectStatement) visit(ctx.lateralClause().selectSubquery());
1163 SubquerySegment subquerySegment = new SubquerySegment(ctx.lateralClause().selectSubquery().start.getStartIndex(), ctx.lateralClause().selectSubquery().stop.getStopIndex(), subquery,
1164 getOriginalText(ctx.lateralClause().selectSubquery()));
1165 result = new SubqueryTableSegment(ctx.lateralClause().LP_().getSymbol().getStartIndex(), ctx.lateralClause().RP_().getSymbol().getStopIndex(), subquerySegment);
1166 } else {
1167 if (null != ctx.tableCollectionExpr().collectionExpr().selectSubquery()) {
1168 SubquerySegment subquerySegment = (SubquerySegment) visit(ctx.tableCollectionExpr());
1169 result = new SubqueryTableSegment(ctx.tableCollectionExpr().start.getStartIndex(), ctx.tableCollectionExpr().stop.getStopIndex(), subquerySegment);
1170 } else {
1171 result = new CollectionTableSegment((ExpressionSegment) visit(ctx.tableCollectionExpr()));
1172 }
1173 }
1174 return result;
1175 }
1176
1177 @Override
1178 public ASTNode visitWhereClause(final WhereClauseContext ctx) {
1179 ASTNode segment = visit(ctx.expr());
1180 return new WhereSegment(ctx.getStart().getStartIndex(), ctx.getStop().getStopIndex(), (ExpressionSegment) segment);
1181 }
1182
1183 @Override
1184 public ASTNode visitGroupByClause(final GroupByClauseContext ctx) {
1185 Collection<OrderByItemSegment> items = new LinkedList<>();
1186 for (GroupByItemContext each : ctx.groupByItem()) {
1187 items.addAll(generateOrderByItemsFromGroupByItem(each));
1188 }
1189 return new GroupBySegment(ctx.getStart().getStartIndex(), ctx.getStop().getStopIndex(), items);
1190 }
1191
1192 private Collection<OrderByItemSegment> generateOrderByItemsFromGroupByItem(final GroupByItemContext ctx) {
1193 Collection<OrderByItemSegment> result = new LinkedList<>();
1194 if (null != ctx.expr()) {
1195 OrderByItemSegment item = (OrderByItemSegment) extractValueFromGroupByItemExpression(ctx.expr());
1196 result.add(item);
1197 } else if (null != ctx.rollupCubeClause()) {
1198 result.addAll(generateOrderByItemSegmentsFromRollupCubeClause(ctx.rollupCubeClause()));
1199 } else {
1200 result.addAll(generateOrderByItemSegmentsFromGroupingSetsClause(ctx.groupingSetsClause()));
1201 }
1202 return result;
1203 }
1204
1205 private ASTNode extractValueFromGroupByItemExpression(final ExprContext ctx) {
1206 ASTNode expression = visit(ctx);
1207 if (expression instanceof ColumnSegment) {
1208 ColumnSegment column = (ColumnSegment) expression;
1209 return new ColumnOrderByItemSegment(column, OrderDirection.ASC, null);
1210 }
1211 if (expression instanceof LiteralExpressionSegment) {
1212 LiteralExpressionSegment literalExpression = (LiteralExpressionSegment) expression;
1213 return new IndexOrderByItemSegment(literalExpression.getStartIndex(), literalExpression.getStopIndex(),
1214 SQLUtils.getExactlyNumber(literalExpression.getLiterals().toString(), 10).intValue(), OrderDirection.ASC, null);
1215 }
1216 return new ExpressionOrderByItemSegment(ctx.getStart().getStartIndex(), ctx.getStop().getStopIndex(), getOriginalText(ctx), OrderDirection.ASC, null, (ExpressionSegment) expression);
1217 }
1218
1219 private Collection<OrderByItemSegment> generateOrderByItemSegmentsFromRollupCubeClause(final RollupCubeClauseContext ctx) {
1220 return new LinkedList<>(generateOrderByItemSegmentsFromGroupingExprList(ctx.groupingExprList()));
1221 }
1222
1223 private Collection<OrderByItemSegment> generateOrderByItemSegmentsFromGroupingSetsClause(final GroupingSetsClauseContext ctx) {
1224 Collection<OrderByItemSegment> result = new LinkedList<>();
1225 if (null != ctx.rollupCubeClause()) {
1226 for (RollupCubeClauseContext each : ctx.rollupCubeClause()) {
1227 result.addAll(generateOrderByItemSegmentsFromRollupCubeClause(each));
1228 }
1229 }
1230 if (null != ctx.groupingExprList()) {
1231 for (GroupingExprListContext each : ctx.groupingExprList()) {
1232 result.addAll(generateOrderByItemSegmentsFromGroupingExprList(each));
1233 }
1234 }
1235 return result;
1236 }
1237
1238 private Collection<OrderByItemSegment> generateOrderByItemSegmentsFromGroupingExprList(final GroupingExprListContext ctx) {
1239 Collection<OrderByItemSegment> result = new LinkedList<>();
1240 for (ExpressionListContext each : ctx.expressionList()) {
1241 result.addAll(generateOrderByItemSegmentsFromExpressionList(each));
1242 }
1243 return result;
1244 }
1245
1246 private Collection<OrderByItemSegment> generateOrderByItemSegmentsFromExpressionList(final ExpressionListContext ctx) {
1247 Collection<OrderByItemSegment> result = new LinkedList<>();
1248 if (null != ctx.expr()) {
1249 for (ExprContext each : ctx.expr()) {
1250 result.add((OrderByItemSegment) extractValueFromGroupByItemExpression(each));
1251 }
1252 }
1253 if (null != ctx.exprs()) {
1254 for (ExprContext each : ctx.exprs().expr()) {
1255 result.add((OrderByItemSegment) extractValueFromGroupByItemExpression(each));
1256 }
1257 }
1258 return result;
1259 }
1260
1261 @Override
1262 public ASTNode visitSubquery(final SubqueryContext ctx) {
1263 return visit(ctx.selectSubquery());
1264 }
1265
1266 @Override
1267 public ASTNode visitForUpdateClause(final ForUpdateClauseContext ctx) {
1268 LockSegment result = new LockSegment(ctx.getStart().getStartIndex(), ctx.getStop().getStopIndex());
1269 if (null != ctx.forUpdateClauseList()) {
1270 result.getTables().addAll(generateTablesFromforUpdateClauseOption(ctx.forUpdateClauseList()));
1271 result.getColumns().addAll(generateColumnsFromforUpdateClauseOption(ctx.forUpdateClauseList()));
1272 }
1273 return result;
1274 }
1275
1276 private List<SimpleTableSegment> generateTablesFromforUpdateClauseOption(final ForUpdateClauseListContext ctx) {
1277 List<SimpleTableSegment> result = new LinkedList<>();
1278 for (ForUpdateClauseOptionContext each : ctx.forUpdateClauseOption()) {
1279 if (null != each.tableName()) {
1280 result.add((SimpleTableSegment) visit(each.tableName()));
1281 }
1282 }
1283 return result;
1284 }
1285
1286 private List<ColumnSegment> generateColumnsFromforUpdateClauseOption(final ForUpdateClauseListContext ctx) {
1287 List<ColumnSegment> result = new LinkedList<>();
1288 for (ForUpdateClauseOptionContext each : ctx.forUpdateClauseOption()) {
1289 if (null != each.columnName()) {
1290 result.add((ColumnSegment) visit(each.columnName()));
1291 }
1292 }
1293 return result;
1294 }
1295
1296 @Override
1297 public ASTNode visitMerge(final MergeContext ctx) {
1298 MergeStatement result = new MergeStatement();
1299 result.setTarget((TableSegment) visit(ctx.intoClause()));
1300 result.setSource((TableSegment) visit(ctx.usingClause()));
1301 ExpressionWithParamsSegment onExpression = new ExpressionWithParamsSegment(ctx.usingClause().expr().start.getStartIndex(), ctx.usingClause().expr().stop.getStopIndex(),
1302 (ExpressionSegment) visit(ctx.usingClause().expr()));
1303 onExpression.getParameterMarkerSegments().addAll(popAllStatementParameterMarkerSegments());
1304 result.setExpression(onExpression);
1305 if (null != ctx.mergeUpdateClause() && null != ctx.mergeInsertClause() && ctx.mergeUpdateClause().start.getStartIndex() > ctx.mergeInsertClause().start.getStartIndex()) {
1306 result.setInsert((InsertStatement) visitMergeInsertClause(ctx.mergeInsertClause()));
1307 result.setUpdate((UpdateStatement) visitMergeUpdateClause(ctx.mergeUpdateClause()));
1308 result.addParameterMarkers(ctx.getParent() instanceof ExecuteContext ? getGlobalParameterMarkerSegments() : popAllStatementParameterMarkerSegments());
1309 return result;
1310 }
1311 if (null != ctx.mergeUpdateClause()) {
1312 result.setUpdate((UpdateStatement) visitMergeUpdateClause(ctx.mergeUpdateClause()));
1313 }
1314 if (null != ctx.mergeInsertClause()) {
1315 result.setInsert((InsertStatement) visitMergeInsertClause(ctx.mergeInsertClause()));
1316 }
1317 result.addParameterMarkers(ctx.getParent() instanceof ExecuteContext ? getGlobalParameterMarkerSegments() : popAllStatementParameterMarkerSegments());
1318 return result;
1319 }
1320
1321 @SuppressWarnings("unchecked")
1322 @Override
1323 public ASTNode visitMergeInsertClause(final MergeInsertClauseContext ctx) {
1324 InsertStatement result = new InsertStatement();
1325 if (null != ctx.mergeInsertColumn()) {
1326 result.setInsertColumns((InsertColumnsSegment) visit(ctx.mergeInsertColumn()));
1327 }
1328 if (null != ctx.mergeColumnValue()) {
1329 result.getValues().addAll(((CollectionValue<InsertValuesSegment>) visit(ctx.mergeColumnValue())).getValue());
1330 }
1331 if (null != ctx.whereClause()) {
1332 result.setWhere((WhereSegment) visit(ctx.whereClause()));
1333 }
1334 result.addParameterMarkers(popAllStatementParameterMarkerSegments());
1335 return result;
1336 }
1337
1338 @Override
1339 public ASTNode visitMergeInsertColumn(final MergeInsertColumnContext ctx) {
1340 Collection<ColumnSegment> columnSegments = new ArrayList<>(ctx.columnName().size());
1341 for (ColumnNameContext each : ctx.columnName()) {
1342 if (null != each.name()) {
1343 columnSegments.add((ColumnSegment) visit(each));
1344 }
1345 }
1346 return new InsertColumnsSegment(ctx.start.getStartIndex(), ctx.stop.getStopIndex(), columnSegments);
1347 }
1348
1349 @Override
1350 public ASTNode visitMergeColumnValue(final MergeColumnValueContext ctx) {
1351 CollectionValue<InsertValuesSegment> result = new CollectionValue<>();
1352 List<ExpressionSegment> segments = new LinkedList<>();
1353 for (ExprContext each : ctx.expr()) {
1354 segments.add(null == each ? new CommonExpressionSegment(ctx.getStart().getStartIndex(), ctx.getStop().getStopIndex(), ctx.getText()) : (ExpressionSegment) visit(each));
1355 }
1356 result.getValue().add(new InsertValuesSegment(ctx.LP_().getSymbol().getStartIndex(), ctx.RP_().getSymbol().getStopIndex(), segments));
1357 return result;
1358 }
1359
1360 @Override
1361 public ASTNode visitIntoClause(final IntoClauseContext ctx) {
1362 if (null != ctx.tableName()) {
1363 SimpleTableSegment result = (SimpleTableSegment) visit(ctx.tableName());
1364 if (null != ctx.alias()) {
1365 result.setAlias((AliasSegment) visit(ctx.alias()));
1366 }
1367 return result;
1368 }
1369 if (null != ctx.viewName()) {
1370 SimpleTableSegment result = (SimpleTableSegment) visit(ctx.viewName());
1371 if (null != ctx.alias()) {
1372 result.setAlias((AliasSegment) visit(ctx.alias()));
1373 }
1374 return result;
1375 }
1376 SelectStatement subquery = (SelectStatement) visit(ctx.subquery());
1377 SubquerySegment subquerySegment = new SubquerySegment(ctx.subquery().start.getStartIndex(), ctx.subquery().stop.getStopIndex(), subquery, getOriginalText(ctx.subquery()));
1378 SubqueryTableSegment result = new SubqueryTableSegment(ctx.subquery().start.getStartIndex(), ctx.subquery().stop.getStopIndex(), subquerySegment);
1379 if (null != ctx.alias()) {
1380 result.setAlias((AliasSegment) visit(ctx.alias()));
1381 }
1382 return result;
1383 }
1384
1385 @Override
1386 public ASTNode visitUsingClause(final UsingClauseContext ctx) {
1387 if (null != ctx.tableName()) {
1388 SimpleTableSegment result = (SimpleTableSegment) visit(ctx.tableName());
1389 if (null != ctx.alias()) {
1390 result.setAlias((AliasSegment) visit(ctx.alias()));
1391 }
1392 return result;
1393 }
1394 if (null != ctx.viewName()) {
1395 SimpleTableSegment result = (SimpleTableSegment) visit(ctx.viewName());
1396 if (null != ctx.alias()) {
1397 result.setAlias((AliasSegment) visit(ctx.alias()));
1398 }
1399 return result;
1400 }
1401 SelectStatement subquery = (SelectStatement) visit(ctx.subquery());
1402 SubquerySegment subquerySegment = new SubquerySegment(ctx.subquery().start.getStartIndex(), ctx.subquery().stop.getStopIndex(), subquery, getOriginalText(ctx.subquery()));
1403 subquerySegment.getSelect().addParameterMarkers(popAllStatementParameterMarkerSegments());
1404 SubqueryTableSegment result = new SubqueryTableSegment(ctx.subquery().start.getStartIndex(), ctx.subquery().stop.getStopIndex(), subquerySegment);
1405 if (null != ctx.alias()) {
1406 result.setAlias((AliasSegment) visit(ctx.alias()));
1407 }
1408 return result;
1409 }
1410
1411 @Override
1412 public ASTNode visitMergeUpdateClause(final MergeUpdateClauseContext ctx) {
1413 UpdateStatement result = new UpdateStatement();
1414 result.setSetAssignment((SetAssignmentSegment) visit(ctx.mergeSetAssignmentsClause()));
1415 if (null != ctx.whereClause()) {
1416 result.setWhere((WhereSegment) visit(ctx.whereClause()));
1417 }
1418 if (null != ctx.deleteWhereClause()) {
1419 result.setDeleteWhere((WhereSegment) visit(ctx.deleteWhereClause()));
1420 }
1421 result.addParameterMarkers(popAllStatementParameterMarkerSegments());
1422 return result;
1423 }
1424
1425 @Override
1426 public ASTNode visitMergeSetAssignmentsClause(final MergeSetAssignmentsClauseContext ctx) {
1427 Collection<ColumnAssignmentSegment> assignments = new LinkedList<>();
1428 for (MergeAssignmentContext each : ctx.mergeAssignment()) {
1429 assignments.add((ColumnAssignmentSegment) visit(each));
1430 }
1431 return new SetAssignmentSegment(ctx.getStart().getStartIndex(), ctx.getStop().getStopIndex(), assignments);
1432 }
1433
1434 @Override
1435 public ASTNode visitMergeAssignment(final MergeAssignmentContext ctx) {
1436 ColumnSegment column = (ColumnSegment) visitColumnName(ctx.columnName());
1437 ExpressionSegment value = (ExpressionSegment) visit(ctx.mergeAssignmentValue());
1438 List<ColumnSegment> columnSegments = new LinkedList<>();
1439 columnSegments.add(column);
1440 return new ColumnAssignmentSegment(ctx.getStart().getStartIndex(), ctx.getStop().getStopIndex(), columnSegments, value);
1441 }
1442
1443 @Override
1444 public ASTNode visitMergeAssignmentValue(final MergeAssignmentValueContext ctx) {
1445 ExprContext expr = ctx.expr();
1446 return null == expr ? new CommonExpressionSegment(ctx.getStart().getStartIndex(), ctx.getStop().getStopIndex(), ctx.getText()) : visit(expr);
1447 }
1448
1449 @Override
1450 public ASTNode visitDeleteWhereClause(final DeleteWhereClauseContext ctx) {
1451 ASTNode segment = visit(ctx.whereClause().expr());
1452 return new WhereSegment(ctx.getStart().getStartIndex(), ctx.getStop().getStopIndex(), (ExpressionSegment) segment);
1453 }
1454 }