/*
* 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.pig.impl.logicalLayer;
import java.util.Iterator;
import java.util.List;
import java.util.ArrayList;
import java.util.Map;
import org.apache.pig.impl.plan.PlanException;
import org.apache.pig.impl.plan.DependencyOrderWalker;
import org.apache.pig.impl.plan.VisitorException;
import org.apache.pig.impl.util.MultiMap;
/**
* LogicalPlanCloneHelper implements a visitor mechanism to clone a logical plan
* and then patch up the connections held within the operators of the logical plan.
* This class should not be used for cloning the logical plan. Use {@link LogicalPlanCloner}
* instead.
*/
public class LogicalPlanCloneHelper extends LOVisitor {
public static Map<LogicalOperator, LogicalOperator> mOpToCloneMap;
/**
* @param plan logical plan to be cloned
*/
public LogicalPlanCloneHelper(LogicalPlan plan) throws CloneNotSupportedException {
super(plan, new DependencyOrderWalker<LogicalOperator, LogicalPlan>(plan));
//LOVisitor does not have a default constructor and super needs to be the first
//statement in the constructor. As a result, mPlan and mCurrentWalker are being
//re-initialized here
mPlan = plan.clone();
mCurrentWalker = new DependencyOrderWalker<LogicalOperator, LogicalPlan>(mPlan);
}
/**
* @param plan
* @param origCloneMap the lookup table used for tracking operators cloned in the plan
*/
public LogicalPlanCloneHelper(LogicalPlan plan,
Map<LogicalOperator, LogicalOperator> origCloneMap) throws CloneNotSupportedException {
super(plan, new DependencyOrderWalker<LogicalOperator, LogicalPlan>(plan));
mOpToCloneMap = origCloneMap;
//LOVisitor does not have a default constructor and super needs to be the first
//statement in the constructor. As a result, mPlan and mCurrentWalker are being
//re-initialized here
mPlan = plan.clone();
mCurrentWalker = new DependencyOrderWalker<LogicalOperator, LogicalPlan>(mPlan);
}
public LogicalPlan getClonedPlan() throws CloneNotSupportedException {
// set the "mPlan" member of all the Logical operators
// in the cloned plan to the cloned plan
PlanSetter ps = new PlanSetter(mPlan);
try {
ps.visit();
//patch up the connections
this.visit();
} catch (VisitorException e) {
CloneNotSupportedException cnse = new CloneNotSupportedException("Unable to set plan correctly during cloning");
cnse.initCause(e);
throw cnse;
}
return mPlan;
}
public static void resetState() {
mOpToCloneMap.clear();
}
@Override
public void visit(BinaryExpressionOperator binOp) {
}
/**
* @see org.apache.pig.impl.logicalLayer.LOVisitor#visit(org.apache.pig.impl.logicalLayer.LOAdd)
*/
@Override
public void visit(LOAdd op) throws VisitorException {
this.visit((BinaryExpressionOperator)op);
}
/**
* @see org.apache.pig.impl.logicalLayer.LOVisitor#visit(org.apache.pig.impl.logicalLayer.LOAnd)
*/
@Override
public void visit(LOAnd binOp) throws VisitorException {
this.visit((BinaryExpressionOperator)binOp);
}
/**
* @see org.apache.pig.impl.logicalLayer.LOVisitor#visit(org.apache.pig.impl.logicalLayer.LOBinCond)
*/
@Override
protected void visit(LOBinCond binCond) throws VisitorException {
}
/**
* @see org.apache.pig.impl.logicalLayer.LOVisitor#visit(org.apache.pig.impl.logicalLayer.LOCast)
*/
@Override
protected void visit(LOCast cast) throws VisitorException {
}
/**
* @see org.apache.pig.impl.logicalLayer.LOVisitor#visit(org.apache.pig.impl.logicalLayer.LOCogroup)
*/
@Override
protected void visit(LOCogroup cg) throws VisitorException {
MultiMap<LogicalOperator, LogicalPlan> groupByPlans = cg.getGroupByPlans();
MultiMap<LogicalOperator, LogicalPlan> groupByPlansClone = new MultiMap<LogicalOperator, LogicalPlan>();
for(LogicalOperator cgInput: groupByPlans.keySet()) {
LogicalOperator cgInputClone = mOpToCloneMap.get(cgInput);
if(cgInputClone != null) {
groupByPlansClone.put(cgInputClone, groupByPlans.get(cgInput));
} else {
groupByPlansClone.put(cgInput, groupByPlans.get(cgInput));
}
}
cg.setGroupByPlans(groupByPlansClone);
super.visit(cg);
}
/**
* @see org.apache.pig.impl.logicalLayer.LOVisitor#visit(org.apache.pig.impl.logicalLayer.LOConst)
*/
@Override
protected void visit(LOConst constant) throws VisitorException {
}
/**
* @see org.apache.pig.impl.logicalLayer.LOVisitor#visit(org.apache.pig.impl.logicalLayer.LOCross)
*/
@Override
protected void visit(LOCross cs) throws VisitorException {
super.visit(cs);
}
/**
* @see org.apache.pig.impl.logicalLayer.LOVisitor#visit(org.apache.pig.impl.logicalLayer.LODistinct)
*/
@Override
protected void visit(LODistinct dt) throws VisitorException {
super.visit(dt);
}
/**
* @see org.apache.pig.impl.logicalLayer.LOVisitor#visit(org.apache.pig.impl.logicalLayer.LODivide)
*/
@Override
public void visit(LODivide op) throws VisitorException {
this.visit((BinaryExpressionOperator)op);
}
/**
* @see org.apache.pig.impl.logicalLayer.LOVisitor#visit(org.apache.pig.impl.logicalLayer.LOEqual)
*/
@Override
public void visit(LOEqual op) throws VisitorException {
this.visit((BinaryExpressionOperator)op);
}
/**
* @see org.apache.pig.impl.logicalLayer.LOVisitor#visit(org.apache.pig.impl.logicalLayer.LOFilter)
*/
@Override
protected void visit(LOFilter filter) throws VisitorException {
super.visit(filter);
}
/**
* @see org.apache.pig.impl.logicalLayer.LOVisitor#visit(org.apache.pig.impl.logicalLayer.LOForEach)
*/
@Override
protected void visit(LOForEach forEach) throws VisitorException {
super.visit(forEach);
}
/**
* @see org.apache.pig.impl.logicalLayer.LOVisitor#visit(org.apache.pig.impl.logicalLayer.LOGenerate)
*/
@Override
protected void visit(LOGenerate g) throws VisitorException {
super.visit(g);
}
/**
* @see org.apache.pig.impl.logicalLayer.LOVisitor#visit(org.apache.pig.impl.logicalLayer.LogicalOperator)
*/
@Override
protected void visit(LogicalOperator op) throws VisitorException {
super.visit(op);
}
/**
* @see org.apache.pig.impl.logicalLayer.LOVisitor#visit(org.apache.pig.impl.logicalLayer.LOGreaterThan)
*/
@Override
public void visit(LOGreaterThan op) throws VisitorException {
this.visit((BinaryExpressionOperator)op);
}
/**
* @see org.apache.pig.impl.logicalLayer.LOVisitor#visit(org.apache.pig.impl.logicalLayer.LOGreaterThanEqual)
*/
@Override
public void visit(LOGreaterThanEqual op) throws VisitorException {
this.visit((BinaryExpressionOperator)op);
}
/**
* @see org.apache.pig.impl.logicalLayer.LOVisitor#visit(org.apache.pig.impl.logicalLayer.LOIsNull)
*/
@Override
public void visit(LOIsNull uniOp) throws VisitorException {
this.visit((UnaryExpressionOperator) uniOp);
}
/**
* @see org.apache.pig.impl.logicalLayer.LOVisitor#visit(org.apache.pig.impl.logicalLayer.LOLesserThan)
*/
@Override
public void visit(LOLesserThan op) throws VisitorException {
this.visit((BinaryExpressionOperator)op);
}
/**
* @see org.apache.pig.impl.logicalLayer.LOVisitor#visit(org.apache.pig.impl.logicalLayer.LOLesserThanEqual)
*/
@Override
public void visit(LOLesserThanEqual op) throws VisitorException {
this.visit((BinaryExpressionOperator)op);
}
/**
* @see org.apache.pig.impl.logicalLayer.LOVisitor#visit(org.apache.pig.impl.logicalLayer.LOLimit)
*/
@Override
protected void visit(LOLimit limOp) throws VisitorException {
super.visit(limOp);
}
/**
* @see org.apache.pig.impl.logicalLayer.LOVisitor#visit(org.apache.pig.impl.logicalLayer.LOLoad)
*/
@Override
protected void visit(LOLoad load) throws VisitorException {
//TODO
//LOLoad cloning is not implemented
}
/**
* @see org.apache.pig.impl.logicalLayer.LOVisitor#visit(org.apache.pig.impl.logicalLayer.LOMapLookup)
*/
@Override
public void visit(LOMapLookup op) throws VisitorException {
}
/**
* @see org.apache.pig.impl.logicalLayer.LOVisitor#visit(org.apache.pig.impl.logicalLayer.LOMod)
*/
@Override
public void visit(LOMod op) throws VisitorException {
this.visit((BinaryExpressionOperator)op);
}
/**
* @see org.apache.pig.impl.logicalLayer.LOVisitor#visit(org.apache.pig.impl.logicalLayer.LOMultiply)
*/
@Override
public void visit(LOMultiply op) throws VisitorException {
this.visit((BinaryExpressionOperator)op);
}
/**
* @see org.apache.pig.impl.logicalLayer.LOVisitor#visit(org.apache.pig.impl.logicalLayer.LONegative)
*/
@Override
public void visit(LONegative op) throws VisitorException {
this.visit((UnaryExpressionOperator) op);
}
/**
* @see org.apache.pig.impl.logicalLayer.LOVisitor#visit(org.apache.pig.impl.logicalLayer.LONot)
*/
@Override
public void visit(LONot uniOp) throws VisitorException {
this.visit((UnaryExpressionOperator) uniOp);
}
/**
* @see org.apache.pig.impl.logicalLayer.LOVisitor#visit(org.apache.pig.impl.logicalLayer.LONotEqual)
*/
@Override
public void visit(LONotEqual op) throws VisitorException {
this.visit((BinaryExpressionOperator)op);
}
/**
* @see org.apache.pig.impl.logicalLayer.LOVisitor#visit(org.apache.pig.impl.logicalLayer.LOOr)
*/
@Override
public void visit(LOOr binOp) throws VisitorException {
this.visit((BinaryExpressionOperator)binOp);
}
/**
* @see org.apache.pig.impl.logicalLayer.LOVisitor#visit(org.apache.pig.impl.logicalLayer.LOProject)
*/
@Override
protected void visit(LOProject project) throws VisitorException {
LogicalOperator projectInputClone = mOpToCloneMap.get(project.getExpression());
if(projectInputClone != null) {
project.setExpression(projectInputClone);
}
}
/**
* @see org.apache.pig.impl.logicalLayer.LOVisitor#visit(org.apache.pig.impl.logicalLayer.LORegexp)
*/
@Override
protected void visit(LORegexp binOp) throws VisitorException {
this.visit((BinaryExpressionOperator)binOp);
}
/**
* @see org.apache.pig.impl.logicalLayer.LOVisitor#visit(org.apache.pig.impl.logicalLayer.LOSort)
*/
@Override
protected void visit(LOSort s) throws VisitorException {
super.visit(s);
}
/**
* @see org.apache.pig.impl.logicalLayer.LOVisitor#visit(org.apache.pig.impl.logicalLayer.LOSplit)
*/
@Override
protected void visit(LOSplit split) throws VisitorException {
List<LogicalOperator> splitOutputs = split.getOutputs();
ArrayList<LogicalOperator> splitOutputClones = new ArrayList<LogicalOperator>(splitOutputs.size());
for(LogicalOperator splitOutput: splitOutputs) {
LogicalOperator splitOutputClone = mOpToCloneMap.get(splitOutput);
if(splitOutputClone != null) {
splitOutputClones.add(splitOutputClone);
} else {
splitOutputClones.add(splitOutput);
}
}
split.setOutputs(splitOutputClones);
}
/**
* @see org.apache.pig.impl.logicalLayer.LOVisitor#visit(org.apache.pig.impl.logicalLayer.LOSplitOutput)
*/
@Override
protected void visit(LOSplitOutput sop) throws VisitorException {
super.visit(sop);
}
/**
* @see org.apache.pig.impl.logicalLayer.LOVisitor#visit(org.apache.pig.impl.logicalLayer.LOStore)
*/
@Override
protected void visit(LOStore store) throws VisitorException {
//TODO
//LOStore cloning is not implemented
}
/**
* @see org.apache.pig.impl.logicalLayer.LOVisitor#visit(org.apache.pig.impl.logicalLayer.LOStream)
*/
@Override
protected void visit(LOStream stream) throws VisitorException {
//TODO
//LOStream cloning is not implemented
}
/**
* @see org.apache.pig.impl.logicalLayer.LOVisitor#visit(org.apache.pig.impl.logicalLayer.LOSubtract)
*/
@Override
public void visit(LOSubtract op) throws VisitorException {
this.visit((BinaryExpressionOperator)op);
}
/**
* @see org.apache.pig.impl.logicalLayer.LOVisitor#visit(org.apache.pig.impl.logicalLayer.LOUnion)
*/
@Override
protected void visit(LOUnion u) throws VisitorException {
super.visit(u);
}
/**
* @see org.apache.pig.impl.logicalLayer.LOVisitor#visit(org.apache.pig.impl.logicalLayer.LOUserFunc)
*/
@Override
protected void visit(LOUserFunc func) throws VisitorException {
}
/**
* @see org.apache.pig.impl.logicalLayer.LOVisitor#visit(org.apache.pig.impl.logicalLayer.UnaryExpressionOperator)
*/
@Override
protected void visit(UnaryExpressionOperator uniOp) throws VisitorException {
}
}