| /* |
| * Licensed to the Apache Software Foundation (ASF) under one |
| * or more contributor license agreements. See the NOTICE file |
| * distributed with this work for additional information |
| * regarding copyright ownership. The ASF licenses this file |
| * to you under the Apache License, Version 2.0 (the |
| * "License"); you may not use this file except in compliance |
| * with the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, |
| * software distributed under the License is distributed on an |
| * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
| * KIND, either express or implied. See the License for the |
| * specific language governing permissions and limitations |
| * under the License. |
| */ |
| package org.apache.asterix.lang.sqlpp.visitor; |
| |
| import java.util.ArrayList; |
| import java.util.HashMap; |
| import java.util.List; |
| import java.util.Map; |
| import java.util.Map.Entry; |
| |
| import org.apache.asterix.common.exceptions.CompilationException; |
| import org.apache.asterix.lang.common.base.AbstractClause; |
| import org.apache.asterix.lang.common.base.Expression; |
| import org.apache.asterix.lang.common.base.ILangExpression; |
| import org.apache.asterix.lang.common.base.IVisitorExtension; |
| import org.apache.asterix.lang.common.clause.GroupbyClause; |
| import org.apache.asterix.lang.common.clause.LetClause; |
| import org.apache.asterix.lang.common.clause.LimitClause; |
| import org.apache.asterix.lang.common.clause.OrderbyClause; |
| import org.apache.asterix.lang.common.clause.WhereClause; |
| import org.apache.asterix.lang.common.expression.CallExpr; |
| import org.apache.asterix.lang.common.expression.FieldAccessor; |
| import org.apache.asterix.lang.common.expression.FieldBinding; |
| import org.apache.asterix.lang.common.expression.GbyVariableExpressionPair; |
| import org.apache.asterix.lang.common.expression.IfExpr; |
| import org.apache.asterix.lang.common.expression.IndexAccessor; |
| import org.apache.asterix.lang.common.expression.ListConstructor; |
| import org.apache.asterix.lang.common.expression.ListSliceExpression; |
| import org.apache.asterix.lang.common.expression.LiteralExpr; |
| import org.apache.asterix.lang.common.expression.OperatorExpr; |
| import org.apache.asterix.lang.common.expression.QuantifiedExpression; |
| import org.apache.asterix.lang.common.expression.RecordConstructor; |
| import org.apache.asterix.lang.common.expression.UnaryExpr; |
| import org.apache.asterix.lang.common.expression.VariableExpr; |
| import org.apache.asterix.lang.common.statement.FunctionDecl; |
| import org.apache.asterix.lang.common.statement.Query; |
| import org.apache.asterix.lang.common.struct.Identifier; |
| import org.apache.asterix.lang.common.struct.QuantifiedPair; |
| import org.apache.asterix.lang.common.struct.VarIdentifier; |
| import org.apache.asterix.lang.sqlpp.clause.AbstractBinaryCorrelateClause; |
| import org.apache.asterix.lang.sqlpp.clause.FromClause; |
| import org.apache.asterix.lang.sqlpp.clause.FromTerm; |
| import org.apache.asterix.lang.sqlpp.clause.HavingClause; |
| import org.apache.asterix.lang.sqlpp.clause.JoinClause; |
| import org.apache.asterix.lang.sqlpp.clause.NestClause; |
| import org.apache.asterix.lang.sqlpp.clause.Projection; |
| import org.apache.asterix.lang.sqlpp.clause.SelectBlock; |
| import org.apache.asterix.lang.sqlpp.clause.SelectClause; |
| import org.apache.asterix.lang.sqlpp.clause.SelectElement; |
| import org.apache.asterix.lang.sqlpp.clause.SelectRegular; |
| import org.apache.asterix.lang.sqlpp.clause.SelectSetOperation; |
| import org.apache.asterix.lang.sqlpp.clause.UnnestClause; |
| import org.apache.asterix.lang.sqlpp.expression.CaseExpression; |
| import org.apache.asterix.lang.sqlpp.expression.SelectExpression; |
| import org.apache.asterix.lang.sqlpp.expression.WindowExpression; |
| import org.apache.asterix.lang.sqlpp.struct.SetOperationInput; |
| import org.apache.asterix.lang.sqlpp.struct.SetOperationRight; |
| import org.apache.asterix.lang.sqlpp.visitor.base.AbstractSqlppQueryExpressionVisitor; |
| import org.apache.hyracks.algebricks.common.utils.Pair; |
| |
| public class DeepCopyVisitor extends AbstractSqlppQueryExpressionVisitor<ILangExpression, Void> { |
| |
| @Override |
| public FromClause visit(FromClause fromClause, Void arg) throws CompilationException { |
| List<FromTerm> fromTerms = new ArrayList<>(); |
| for (FromTerm fromTerm : fromClause.getFromTerms()) { |
| fromTerms.add((FromTerm) fromTerm.accept(this, arg)); |
| } |
| FromClause copy = new FromClause(fromTerms); |
| copy.setSourceLocation(fromClause.getSourceLocation()); |
| return copy; |
| } |
| |
| @Override |
| public FromTerm visit(FromTerm fromTerm, Void arg) throws CompilationException { |
| // Visit the left expression of a from term. |
| Expression fromExpr = (Expression) fromTerm.getLeftExpression().accept(this, arg); |
| VariableExpr fromVar = (VariableExpr) fromTerm.getLeftVariable().accept(this, arg); |
| VariableExpr positionVar = fromTerm.getPositionalVariable() == null ? null |
| : (VariableExpr) fromTerm.getPositionalVariable().accept(this, arg); |
| |
| // Visits join/unnest/nest clauses. |
| List<AbstractBinaryCorrelateClause> correlateClauses = new ArrayList<>(); |
| for (AbstractBinaryCorrelateClause correlateClause : fromTerm.getCorrelateClauses()) { |
| correlateClauses.add((AbstractBinaryCorrelateClause) correlateClause.accept(this, arg)); |
| } |
| FromTerm copy = new FromTerm(fromExpr, fromVar, positionVar, correlateClauses); |
| copy.setSourceLocation(fromTerm.getSourceLocation()); |
| return copy; |
| } |
| |
| @Override |
| public JoinClause visit(JoinClause joinClause, Void arg) throws CompilationException { |
| Expression rightExpression = (Expression) joinClause.getRightExpression().accept(this, arg); |
| VariableExpr rightVar = (VariableExpr) joinClause.getRightVariable().accept(this, arg); |
| VariableExpr rightPositionVar = joinClause.getPositionalVariable() == null ? null |
| : (VariableExpr) joinClause.getPositionalVariable().accept(this, arg); |
| Expression conditionExpresion = (Expression) joinClause.getConditionExpression().accept(this, arg); |
| JoinClause copy = new JoinClause(joinClause.getJoinType(), rightExpression, rightVar, rightPositionVar, |
| conditionExpresion, joinClause.getOuterJoinMissingValueType()); |
| copy.setSourceLocation(joinClause.getSourceLocation()); |
| return copy; |
| } |
| |
| @Override |
| public NestClause visit(NestClause nestClause, Void arg) throws CompilationException { |
| Expression rightExpression = (Expression) nestClause.getRightExpression().accept(this, arg); |
| VariableExpr rightVar = (VariableExpr) nestClause.getRightVariable().accept(this, arg); |
| VariableExpr rightPositionVar = nestClause.getPositionalVariable() == null ? null |
| : (VariableExpr) nestClause.getPositionalVariable().accept(this, arg); |
| Expression conditionExpresion = (Expression) nestClause.getConditionExpression().accept(this, arg); |
| NestClause copy = new NestClause(nestClause.getNestType(), rightExpression, rightVar, rightPositionVar, |
| conditionExpresion); |
| copy.setSourceLocation(nestClause.getSourceLocation()); |
| return copy; |
| } |
| |
| @Override |
| public UnnestClause visit(UnnestClause unnestClause, Void arg) throws CompilationException { |
| Expression rightExpression = (Expression) unnestClause.getRightExpression().accept(this, arg); |
| VariableExpr rightVar = (VariableExpr) unnestClause.getRightVariable().accept(this, arg); |
| VariableExpr rightPositionVar = unnestClause.getPositionalVariable() == null ? null |
| : (VariableExpr) unnestClause.getPositionalVariable().accept(this, arg); |
| UnnestClause copy = new UnnestClause(unnestClause.getUnnestType(), rightExpression, rightVar, rightPositionVar, |
| unnestClause.getOuterUnnestMissingValueType()); |
| copy.setSourceLocation(unnestClause.getSourceLocation()); |
| return copy; |
| } |
| |
| @Override |
| public Projection visit(Projection projection, Void arg) throws CompilationException { |
| Projection copy = new Projection(projection.getKind(), |
| projection.hasExpression() ? (Expression) projection.getExpression().accept(this, arg) : null, |
| projection.getName()); |
| copy.setSourceLocation(projection.getSourceLocation()); |
| return copy; |
| } |
| |
| @Override |
| public SelectBlock visit(SelectBlock selectBlock, Void arg) throws CompilationException { |
| FromClause fromClause = null; |
| List<AbstractClause> letWhereClauses = new ArrayList<>(); |
| GroupbyClause gbyClause = null; |
| List<AbstractClause> gbyLetHavingClauses = new ArrayList<>(); |
| SelectClause selectClause; |
| // Traverses the select block in the order of "from", "let/where"s, "group by", "let/having"s, and "select". |
| if (selectBlock.hasFromClause()) { |
| fromClause = (FromClause) selectBlock.getFromClause().accept(this, arg); |
| } |
| if (selectBlock.hasLetWhereClauses()) { |
| List<AbstractClause> letWhereList = selectBlock.getLetWhereList(); |
| for (AbstractClause letWhereClause : letWhereList) { |
| letWhereClauses.add((AbstractClause) letWhereClause.accept(this, arg)); |
| } |
| } |
| if (selectBlock.hasGroupbyClause()) { |
| gbyClause = (GroupbyClause) selectBlock.getGroupbyClause().accept(this, arg); |
| } |
| if (selectBlock.hasLetHavingClausesAfterGroupby()) { |
| List<AbstractClause> letHavingListAfterGby = selectBlock.getLetHavingListAfterGroupby(); |
| for (AbstractClause letHavingClauseAfterGby : letHavingListAfterGby) { |
| gbyLetHavingClauses.add((AbstractClause) letHavingClauseAfterGby.accept(this, arg)); |
| } |
| } |
| selectClause = (SelectClause) selectBlock.getSelectClause().accept(this, arg); |
| SelectBlock copy = new SelectBlock(selectClause, fromClause, letWhereClauses, gbyClause, gbyLetHavingClauses); |
| copy.setSourceLocation(selectBlock.getSourceLocation()); |
| return copy; |
| } |
| |
| @Override |
| public SelectClause visit(SelectClause selectClause, Void arg) throws CompilationException { |
| SelectElement selectElement = null; |
| SelectRegular selectRegular = null; |
| if (selectClause.selectElement()) { |
| selectElement = (SelectElement) selectClause.getSelectElement().accept(this, arg); |
| } |
| if (selectClause.selectRegular()) { |
| selectRegular = (SelectRegular) selectClause.getSelectRegular().accept(this, arg); |
| } |
| List<List<String>> fieldExclusions = new ArrayList<>(); |
| if (!selectClause.getFieldExclusions().isEmpty()) { |
| for (List<String> fieldExclusion : selectClause.getFieldExclusions()) { |
| List<String> fieldExclusionCopy = new ArrayList<>(fieldExclusion); |
| fieldExclusions.add(fieldExclusionCopy); |
| } |
| } |
| SelectClause copy = new SelectClause(selectElement, selectRegular, fieldExclusions, selectClause.distinct()); |
| copy.setSourceLocation(selectClause.getSourceLocation()); |
| return copy; |
| } |
| |
| @Override |
| public SelectElement visit(SelectElement selectElement, Void arg) throws CompilationException { |
| SelectElement copy = new SelectElement((Expression) selectElement.getExpression().accept(this, arg)); |
| copy.setSourceLocation(selectElement.getSourceLocation()); |
| return copy; |
| } |
| |
| @Override |
| public SelectRegular visit(SelectRegular selectRegular, Void arg) throws CompilationException { |
| List<Projection> projections = new ArrayList<>(); |
| for (Projection projection : selectRegular.getProjections()) { |
| projections.add((Projection) projection.accept(this, arg)); |
| } |
| SelectRegular copy = new SelectRegular(projections); |
| copy.setSourceLocation(selectRegular.getSourceLocation()); |
| return copy; |
| } |
| |
| @Override |
| public SelectSetOperation visit(SelectSetOperation selectSetOperation, Void arg) throws CompilationException { |
| SetOperationInput leftInput = selectSetOperation.getLeftInput(); |
| SetOperationInput newLeftInput; |
| if (leftInput.selectBlock()) { |
| newLeftInput = new SetOperationInput((SelectBlock) leftInput.accept(this, arg), null); |
| } else { |
| newLeftInput = new SetOperationInput(null, (SelectExpression) leftInput.accept(this, arg)); |
| } |
| List<SetOperationRight> rightInputs = new ArrayList<>(); |
| for (SetOperationRight right : selectSetOperation.getRightInputs()) { |
| SetOperationInput newRightInput; |
| SetOperationInput setOpRightInput = right.getSetOperationRightInput(); |
| if (setOpRightInput.selectBlock()) { |
| newRightInput = new SetOperationInput((SelectBlock) setOpRightInput.accept(this, arg), null); |
| } else { |
| newRightInput = new SetOperationInput(null, (SelectExpression) setOpRightInput.accept(this, arg)); |
| } |
| rightInputs.add(new SetOperationRight(right.getSetOpType(), right.isSetSemantics(), newRightInput)); |
| } |
| SelectSetOperation copy = new SelectSetOperation(newLeftInput, rightInputs); |
| copy.setSourceLocation(selectSetOperation.getSourceLocation()); |
| return copy; |
| } |
| |
| @Override |
| public HavingClause visit(HavingClause havingClause, Void arg) throws CompilationException { |
| HavingClause copy = new HavingClause((Expression) havingClause.getFilterExpression().accept(this, arg)); |
| copy.setSourceLocation(havingClause.getSourceLocation()); |
| return copy; |
| } |
| |
| @Override |
| public Query visit(Query q, Void arg) throws CompilationException { |
| Query copy = |
| new Query(q.isExplain(), q.isTopLevel(), (Expression) q.getBody().accept(this, arg), q.getVarCounter()); |
| copy.setSourceLocation(q.getSourceLocation()); |
| return copy; |
| } |
| |
| @Override |
| public FunctionDecl visit(FunctionDecl fd, Void arg) throws CompilationException { |
| FunctionDecl copy = new FunctionDecl(fd.getSignature(), fd.getParamList(), |
| (Expression) fd.getFuncBody().accept(this, arg), fd.isStored()); |
| copy.setSourceLocation(fd.getSourceLocation()); |
| return copy; |
| } |
| |
| @Override |
| public WhereClause visit(WhereClause whereClause, Void arg) throws CompilationException { |
| WhereClause copy = new WhereClause((Expression) whereClause.getWhereExpr().accept(this, arg)); |
| copy.setSourceLocation(whereClause.getSourceLocation()); |
| return copy; |
| } |
| |
| @Override |
| public OrderbyClause visit(OrderbyClause oc, Void arg) throws CompilationException { |
| List<Expression> newOrderbyList = new ArrayList<>(); |
| for (Expression orderExpr : oc.getOrderbyList()) { |
| newOrderbyList.add((Expression) orderExpr.accept(this, arg)); |
| } |
| OrderbyClause copy = new OrderbyClause(newOrderbyList, new ArrayList<>(oc.getModifierList()), |
| new ArrayList<>(oc.getNullModifierList())); |
| copy.setSourceLocation(oc.getSourceLocation()); |
| return copy; |
| } |
| |
| @Override |
| public GroupbyClause visit(GroupbyClause gc, Void arg) throws CompilationException { |
| List<List<GbyVariableExpressionPair>> gbyList = gc.getGbyPairList(); |
| List<List<GbyVariableExpressionPair>> newGbyList = new ArrayList<>(gbyList.size()); |
| for (List<GbyVariableExpressionPair> gbyPairList : gbyList) { |
| List<GbyVariableExpressionPair> newGbyPairList = new ArrayList<>(gbyPairList.size()); |
| for (GbyVariableExpressionPair gbyVarExpr : gbyPairList) { |
| VariableExpr var = gbyVarExpr.getVar(); |
| newGbyPairList |
| .add(new GbyVariableExpressionPair(var == null ? null : (VariableExpr) var.accept(this, arg), |
| (Expression) gbyVarExpr.getExpr().accept(this, arg))); |
| } |
| newGbyList.add(newGbyPairList); |
| } |
| List<GbyVariableExpressionPair> decorPairList = new ArrayList<>(); |
| if (gc.hasDecorList()) { |
| for (GbyVariableExpressionPair gbyVarExpr : gc.getDecorPairList()) { |
| VariableExpr var = gbyVarExpr.getVar(); |
| decorPairList |
| .add(new GbyVariableExpressionPair(var == null ? null : (VariableExpr) var.accept(this, arg), |
| (Expression) gbyVarExpr.getExpr().accept(this, arg))); |
| } |
| } |
| Map<Expression, VariableExpr> withVarMap = new HashMap<>(); |
| if (gc.hasWithMap()) { |
| for (Entry<Expression, VariableExpr> entry : gc.getWithVarMap().entrySet()) { |
| withVarMap.put((Expression) entry.getKey().accept(this, arg), |
| (VariableExpr) entry.getValue().accept(this, arg)); |
| } |
| } |
| VariableExpr groupVarExpr = null; |
| if (gc.hasGroupVar()) { |
| groupVarExpr = (VariableExpr) gc.getGroupVar().accept(this, arg); |
| } |
| List<Pair<Expression, Identifier>> groupFieldList = copyFieldList(gc.getGroupFieldList(), arg); |
| GroupbyClause copy = new GroupbyClause(newGbyList, decorPairList, withVarMap, groupVarExpr, groupFieldList, |
| gc.hasHashGroupByHint(), gc.isGroupAll()); |
| copy.setSourceLocation(gc.getSourceLocation()); |
| return copy; |
| } |
| |
| @Override |
| public LimitClause visit(LimitClause limitClause, Void arg) throws CompilationException { |
| Expression limitExpr = |
| limitClause.hasLimitExpr() ? (Expression) limitClause.getLimitExpr().accept(this, arg) : null; |
| Expression offsetExpr = limitClause.hasOffset() ? (Expression) limitClause.getOffset().accept(this, arg) : null; |
| LimitClause copy = new LimitClause(limitExpr, offsetExpr); |
| copy.setSourceLocation(limitClause.getSourceLocation()); |
| return copy; |
| } |
| |
| @Override |
| public LetClause visit(LetClause letClause, Void arg) throws CompilationException { |
| LetClause copy = new LetClause((VariableExpr) letClause.getVarExpr().accept(this, arg), |
| (Expression) letClause.getBindingExpr().accept(this, arg)); |
| copy.setSourceLocation(letClause.getSourceLocation()); |
| return copy; |
| } |
| |
| @Override |
| public SelectExpression visit(SelectExpression selectExpression, Void arg) throws CompilationException { |
| List<LetClause> lets = new ArrayList<>(); |
| SelectSetOperation select; |
| OrderbyClause orderby = null; |
| LimitClause limit = null; |
| |
| // visit let list |
| if (selectExpression.hasLetClauses()) { |
| for (LetClause letClause : selectExpression.getLetList()) { |
| lets.add((LetClause) letClause.accept(this, arg)); |
| } |
| } |
| |
| // visit the main select. |
| select = (SelectSetOperation) selectExpression.getSelectSetOperation().accept(this, arg); |
| |
| // visit order by |
| if (selectExpression.hasOrderby()) { |
| orderby = (OrderbyClause) selectExpression.getOrderbyClause().accept(this, arg); |
| } |
| |
| // visit limit |
| if (selectExpression.hasLimit()) { |
| limit = (LimitClause) selectExpression.getLimitClause().accept(this, arg); |
| } |
| |
| SelectExpression copy = new SelectExpression(lets, select, orderby, limit, selectExpression.isSubquery()); |
| copy.setSourceLocation(select.getSourceLocation()); |
| copy.addHints(selectExpression.getHints()); |
| |
| return copy; |
| } |
| |
| @Override |
| public LiteralExpr visit(LiteralExpr l, Void arg) throws CompilationException { |
| return l; |
| } |
| |
| @Override |
| public ListConstructor visit(ListConstructor lc, Void arg) throws CompilationException { |
| ListConstructor copy = new ListConstructor(lc.getType(), copyExprList(lc.getExprList(), arg)); |
| copy.setSourceLocation(lc.getSourceLocation()); |
| copy.addHints(lc.getHints()); |
| return copy; |
| } |
| |
| @Override |
| public RecordConstructor visit(RecordConstructor rc, Void arg) throws CompilationException { |
| List<FieldBinding> bindings = new ArrayList<>(); |
| for (FieldBinding binding : rc.getFbList()) { |
| FieldBinding fb = new FieldBinding((Expression) binding.getLeftExpr().accept(this, arg), |
| (Expression) binding.getRightExpr().accept(this, arg)); |
| bindings.add(fb); |
| } |
| RecordConstructor copy = new RecordConstructor(bindings); |
| copy.setSourceLocation(rc.getSourceLocation()); |
| copy.addHints(rc.getHints()); |
| return copy; |
| } |
| |
| @Override |
| public OperatorExpr visit(OperatorExpr operatorExpr, Void arg) throws CompilationException { |
| OperatorExpr copy = new OperatorExpr(copyExprList(operatorExpr.getExprList(), arg), operatorExpr.getOpList(), |
| operatorExpr.isCurrentop()); |
| copy.setSourceLocation(operatorExpr.getSourceLocation()); |
| copy.addHints(operatorExpr.getHints()); |
| return copy; |
| } |
| |
| @Override |
| public IfExpr visit(IfExpr ifExpr, Void arg) throws CompilationException { |
| Expression conditionExpr = (Expression) ifExpr.getCondExpr().accept(this, arg); |
| Expression thenExpr = (Expression) ifExpr.getThenExpr().accept(this, arg); |
| Expression elseExpr = (Expression) ifExpr.getElseExpr().accept(this, arg); |
| IfExpr copy = new IfExpr(conditionExpr, thenExpr, elseExpr); |
| copy.setSourceLocation(ifExpr.getSourceLocation()); |
| copy.addHints(ifExpr.getHints()); |
| return copy; |
| } |
| |
| @Override |
| public QuantifiedExpression visit(QuantifiedExpression qe, Void arg) throws CompilationException { |
| List<QuantifiedPair> quantifiedPairs = new ArrayList<>(); |
| for (QuantifiedPair pair : qe.getQuantifiedList()) { |
| Expression expr = (Expression) pair.getExpr().accept(this, arg); |
| VariableExpr var = (VariableExpr) pair.getVarExpr().accept(this, arg); |
| quantifiedPairs.add(new QuantifiedPair(var, expr)); |
| } |
| Expression condition = (Expression) qe.getSatisfiesExpr().accept(this, arg); |
| QuantifiedExpression copy = new QuantifiedExpression(qe.getQuantifier(), quantifiedPairs, condition); |
| copy.setSourceLocation(qe.getSourceLocation()); |
| copy.addHints(qe.getHints()); |
| return copy; |
| } |
| |
| @Override |
| public CallExpr visit(CallExpr callExpr, Void arg) throws CompilationException { |
| List<Expression> newExprList = new ArrayList<>(); |
| for (Expression expr : callExpr.getExprList()) { |
| newExprList.add((Expression) expr.accept(this, arg)); |
| } |
| Expression newFilterExpr = callExpr.hasAggregateFilterExpr() |
| ? (Expression) callExpr.getAggregateFilterExpr().accept(this, arg) : null; |
| CallExpr copy = new CallExpr(callExpr.getFunctionSignature(), newExprList, newFilterExpr); |
| copy.setSourceLocation(callExpr.getSourceLocation()); |
| copy.addHints(callExpr.getHints()); |
| return copy; |
| } |
| |
| @Override |
| public VariableExpr visit(VariableExpr varExpr, Void arg) throws CompilationException { |
| VariableExpr clonedVar = new VariableExpr(new VarIdentifier(varExpr.getVar())); |
| clonedVar.setSourceLocation(varExpr.getSourceLocation()); |
| clonedVar.setIsNewVar(varExpr.getIsNewVar()); |
| clonedVar.addHints(varExpr.getHints()); |
| return clonedVar; |
| } |
| |
| @Override |
| public UnaryExpr visit(UnaryExpr u, Void arg) throws CompilationException { |
| UnaryExpr copy = new UnaryExpr(u.getExprType(), (Expression) u.getExpr().accept(this, arg)); |
| copy.setSourceLocation(u.getSourceLocation()); |
| copy.addHints(u.getHints()); |
| return copy; |
| } |
| |
| @Override |
| public FieldAccessor visit(FieldAccessor fa, Void arg) throws CompilationException { |
| FieldAccessor copy = new FieldAccessor((Expression) fa.getExpr().accept(this, arg), fa.getIdent()); |
| copy.setSourceLocation(fa.getSourceLocation()); |
| copy.addHints(fa.getHints()); |
| return copy; |
| } |
| |
| @Override |
| public Expression visit(IndexAccessor ia, Void arg) throws CompilationException { |
| Expression expr = (Expression) ia.getExpr().accept(this, arg); |
| Expression indexExpr = null; |
| if (ia.getIndexExpr() != null) { |
| indexExpr = (Expression) ia.getIndexExpr().accept(this, arg); |
| } |
| IndexAccessor copy = new IndexAccessor(expr, ia.getIndexKind(), indexExpr); |
| copy.setSourceLocation(ia.getSourceLocation()); |
| copy.addHints(ia.getHints()); |
| return copy; |
| } |
| |
| @Override |
| public Expression visit(ListSliceExpression expression, Void arg) throws CompilationException { |
| Expression expr = (Expression) expression.getExpr().accept(this, arg); |
| Expression startIndexExpression = (Expression) expression.getStartIndexExpression().accept(this, arg); |
| |
| // End index expression can be null (optional) |
| Expression endIndexExpression = null; |
| if (expression.hasEndExpression()) { |
| endIndexExpression = (Expression) expression.getEndIndexExpression().accept(this, arg); |
| } |
| ListSliceExpression copy = new ListSliceExpression(expr, startIndexExpression, endIndexExpression); |
| copy.setSourceLocation(expression.getSourceLocation()); |
| copy.addHints(expression.getHints()); |
| return copy; |
| } |
| |
| @Override |
| public ILangExpression visit(IVisitorExtension ve, Void arg) throws CompilationException { |
| return ve.deepCopyDispatch(this); |
| } |
| |
| @Override |
| public ILangExpression visit(CaseExpression caseExpr, Void arg) throws CompilationException { |
| Expression conditionExpr = (Expression) caseExpr.getConditionExpr().accept(this, arg); |
| List<Expression> whenExprList = copyExprList(caseExpr.getWhenExprs(), arg); |
| List<Expression> thenExprList = copyExprList(caseExpr.getThenExprs(), arg); |
| Expression elseExpr = (Expression) caseExpr.getElseExpr().accept(this, arg); |
| CaseExpression copy = new CaseExpression(conditionExpr, whenExprList, thenExprList, elseExpr); |
| copy.setSourceLocation(caseExpr.getSourceLocation()); |
| copy.addHints(caseExpr.getHints()); |
| return copy; |
| } |
| |
| @Override |
| public ILangExpression visit(WindowExpression winExpr, Void arg) throws CompilationException { |
| List<Expression> newExprList = copyExprList(winExpr.getExprList(), arg); |
| Expression newAggFilterExpr = winExpr.hasAggregateFilterExpr() |
| ? (Expression) winExpr.getAggregateFilterExpr().accept(this, arg) : null; |
| List<Expression> newPartitionList = |
| winExpr.hasPartitionList() ? copyExprList(winExpr.getPartitionList(), arg) : null; |
| List<Expression> newOrderbyList = winExpr.hasOrderByList() ? copyExprList(winExpr.getOrderbyList(), arg) : null; |
| List<OrderbyClause.OrderModifier> newOrderbyModifierList = |
| winExpr.hasOrderByList() ? new ArrayList<>(winExpr.getOrderbyModifierList()) : null; |
| List<OrderbyClause.NullOrderModifier> newOrderbyNullModifierList = |
| winExpr.hasOrderByList() ? new ArrayList<>(winExpr.getOrderbyNullModifierList()) : null; |
| Expression newFrameStartExpr = |
| winExpr.hasFrameStartExpr() ? (Expression) winExpr.getFrameStartExpr().accept(this, arg) : null; |
| Expression newFrameEndExpr = |
| winExpr.hasFrameEndExpr() ? (Expression) winExpr.getFrameEndExpr().accept(this, arg) : null; |
| VariableExpr newWindowVar = |
| winExpr.hasWindowVar() ? (VariableExpr) winExpr.getWindowVar().accept(this, arg) : null; |
| List<Pair<Expression, Identifier>> newWindowFieldList = |
| winExpr.hasWindowFieldList() ? copyFieldList(winExpr.getWindowFieldList(), arg) : null; |
| WindowExpression copy = new WindowExpression(winExpr.getFunctionSignature(), newExprList, newAggFilterExpr, |
| newPartitionList, newOrderbyList, newOrderbyModifierList, newOrderbyNullModifierList, |
| winExpr.getFrameMode(), winExpr.getFrameStartKind(), newFrameStartExpr, winExpr.getFrameEndKind(), |
| newFrameEndExpr, winExpr.getFrameExclusionKind(), newWindowVar, newWindowFieldList, |
| winExpr.getIgnoreNulls(), winExpr.getFromLast()); |
| copy.setSourceLocation(winExpr.getSourceLocation()); |
| copy.addHints(winExpr.getHints()); |
| return copy; |
| } |
| |
| private List<Expression> copyExprList(List<Expression> exprs, Void arg) throws CompilationException { |
| List<Expression> newExprList = new ArrayList<>(); |
| for (Expression expr : exprs) { |
| newExprList.add((Expression) expr.accept(this, arg)); |
| } |
| return newExprList; |
| } |
| |
| private List<Pair<Expression, Identifier>> copyFieldList(List<Pair<Expression, Identifier>> fieldList, Void arg) |
| throws CompilationException { |
| List<Pair<Expression, Identifier>> newFieldList = new ArrayList<>(fieldList.size()); |
| for (Pair<Expression, Identifier> field : fieldList) { |
| newFieldList.add(new Pair<>((Expression) field.first.accept(this, arg), field.second)); |
| } |
| return newFieldList; |
| } |
| } |