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