| /* |
| * 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.newplan.logical; |
| |
| import java.util.ArrayList; |
| import java.util.HashMap; |
| import java.util.List; |
| import java.util.Map; |
| import java.util.Map.Entry; |
| |
| import org.apache.pig.impl.logicalLayer.ExpressionOperator; |
| import org.apache.pig.impl.logicalLayer.FrontendException; |
| import org.apache.pig.impl.logicalLayer.LOAdd; |
| import org.apache.pig.impl.logicalLayer.LOAnd; |
| import org.apache.pig.impl.logicalLayer.LOBinCond; |
| import org.apache.pig.impl.logicalLayer.LOCast; |
| import org.apache.pig.impl.logicalLayer.LOConst; |
| import org.apache.pig.impl.logicalLayer.LODivide; |
| import org.apache.pig.impl.logicalLayer.LOEqual; |
| import org.apache.pig.impl.logicalLayer.LOGreaterThan; |
| import org.apache.pig.impl.logicalLayer.LOGreaterThanEqual; |
| import org.apache.pig.impl.logicalLayer.LOIsNull; |
| import org.apache.pig.impl.logicalLayer.LOLesserThan; |
| import org.apache.pig.impl.logicalLayer.LOLesserThanEqual; |
| import org.apache.pig.impl.logicalLayer.LOMapLookup; |
| import org.apache.pig.impl.logicalLayer.LOMod; |
| import org.apache.pig.impl.logicalLayer.LOMultiply; |
| import org.apache.pig.impl.logicalLayer.LONegative; |
| import org.apache.pig.impl.logicalLayer.LONot; |
| import org.apache.pig.impl.logicalLayer.LONotEqual; |
| import org.apache.pig.impl.logicalLayer.LOOr; |
| import org.apache.pig.impl.logicalLayer.LOProject; |
| import org.apache.pig.impl.logicalLayer.LORegexp; |
| import org.apache.pig.impl.logicalLayer.LOSplit; |
| import org.apache.pig.impl.logicalLayer.LOSplitOutput; |
| import org.apache.pig.impl.logicalLayer.LOSubtract; |
| import org.apache.pig.impl.logicalLayer.LOUserFunc; |
| import org.apache.pig.impl.logicalLayer.LOVisitor; |
| import org.apache.pig.impl.logicalLayer.LogicalOperator; |
| import org.apache.pig.impl.logicalLayer.LogicalPlan; |
| import org.apache.pig.impl.logicalLayer.schema.Schema.FieldSchema; |
| import org.apache.pig.impl.plan.DependencyOrderWalkerWOSeenChk; |
| import org.apache.pig.impl.plan.VisitorException; |
| import org.apache.pig.newplan.logical.expression.AddExpression; |
| import org.apache.pig.newplan.logical.expression.AndExpression; |
| import org.apache.pig.newplan.logical.expression.BinCondExpression; |
| import org.apache.pig.newplan.logical.expression.CastExpression; |
| import org.apache.pig.newplan.logical.expression.ConstantExpression; |
| import org.apache.pig.newplan.logical.expression.DereferenceExpression; |
| import org.apache.pig.newplan.logical.expression.DivideExpression; |
| import org.apache.pig.newplan.logical.expression.EqualExpression; |
| import org.apache.pig.newplan.logical.expression.GreaterThanEqualExpression; |
| import org.apache.pig.newplan.logical.expression.GreaterThanExpression; |
| import org.apache.pig.newplan.logical.expression.IsNullExpression; |
| import org.apache.pig.newplan.logical.expression.LessThanEqualExpression; |
| import org.apache.pig.newplan.logical.expression.LessThanExpression; |
| import org.apache.pig.newplan.logical.expression.LogicalExpression; |
| import org.apache.pig.newplan.logical.expression.MapLookupExpression; |
| import org.apache.pig.newplan.logical.expression.ModExpression; |
| import org.apache.pig.newplan.logical.expression.MultiplyExpression; |
| import org.apache.pig.newplan.logical.expression.NegativeExpression; |
| import org.apache.pig.newplan.logical.expression.NotEqualExpression; |
| import org.apache.pig.newplan.logical.expression.NotExpression; |
| import org.apache.pig.newplan.logical.expression.OrExpression; |
| import org.apache.pig.newplan.logical.expression.ProjectExpression; |
| import org.apache.pig.newplan.logical.expression.RegexExpression; |
| import org.apache.pig.newplan.logical.expression.SubtractExpression; |
| import org.apache.pig.newplan.logical.expression.UserFuncExpression; |
| import org.apache.pig.newplan.logical.relational.LogicalRelationalOperator; |
| import org.apache.pig.newplan.logical.relational.LogicalSchema; |
| |
| //visitor to translate expressions |
| public class LogicalExpPlanMigrationVistor extends LOVisitor { |
| |
| protected org.apache.pig.newplan.logical.expression.LogicalExpressionPlan exprPlan; |
| protected HashMap<LogicalOperator, LogicalExpression> exprOpsMap; |
| protected LogicalRelationalOperator attachedRelationalOp; |
| protected LogicalOperator oldAttachedRelationalOp; |
| protected LogicalPlan outerPlan; |
| private Map<LogicalOperator, LogicalRelationalOperator> outerOpsMap; |
| |
| public LogicalExpPlanMigrationVistor(LogicalPlan expressionPlan, LogicalOperator oldAttachedOperator, |
| LogicalRelationalOperator attachedOperator, LogicalPlan outerPlan, |
| Map<LogicalOperator, LogicalRelationalOperator> outerOpsMap) { |
| super(expressionPlan, new DependencyOrderWalkerWOSeenChk<LogicalOperator, LogicalPlan>(expressionPlan)); |
| exprPlan = new org.apache.pig.newplan.logical.expression.LogicalExpressionPlan(); |
| exprOpsMap = new HashMap<LogicalOperator, LogicalExpression>(); |
| attachedRelationalOp = attachedOperator; |
| oldAttachedRelationalOp = oldAttachedOperator; |
| this.outerPlan = outerPlan; |
| this.outerOpsMap = outerOpsMap; |
| } |
| |
| private void translateConnection(LogicalOperator oldOp, org.apache.pig.newplan.Operator newOp) { |
| List<LogicalOperator> preds = mPlan.getPredecessors(oldOp); |
| |
| // the dependency relationship of new expression plan is opposite to the old logical plan |
| // for example, a+b, in old plan, "add" is a leave, and "a" and "b" are roots |
| // in new plan, "add" is root, and "a" and "b" are leaves. |
| if(preds != null) { |
| for(LogicalOperator pred: preds) { |
| org.apache.pig.newplan.Operator newPred = exprOpsMap.get(pred); |
| newOp.getPlan().connect(newOp, newPred); |
| } |
| } |
| |
| List<LogicalOperator> softPreds = mPlan.getSoftLinkPredecessors(oldOp); |
| |
| if(softPreds != null) { |
| for(LogicalOperator softPred: softPreds) { |
| org.apache.pig.newplan.Operator newSoftPred = exprOpsMap.get(softPred); |
| newOp.getPlan().createSoftLink(newOp, newSoftPred); |
| } |
| } |
| } |
| |
| public void visit(LOProject project) throws VisitorException { |
| int col = project.getCol(); |
| |
| LogicalExpression pe; |
| if (project.getPlan().getPredecessors(project)!=null && project.getPlan().getPredecessors(project).get(0) |
| instanceof ExpressionOperator) { |
| List<Integer> columnNums = new ArrayList<Integer>(); |
| columnNums.add(col); |
| pe = new DereferenceExpression(exprPlan, columnNums); |
| } |
| else { |
| LogicalOperator lg = project.getExpression(); |
| int input; |
| if (oldAttachedRelationalOp instanceof LOSplitOutput) { |
| LOSplit split = (LOSplit)outerPlan.getPredecessors(oldAttachedRelationalOp).get(0); |
| input = outerPlan.getPredecessors(split).indexOf(lg); |
| } |
| else { |
| input = outerPlan.getPredecessors(oldAttachedRelationalOp).indexOf(lg); |
| } |
| pe = new ProjectExpression(exprPlan, input, project.isStar()?-1:col, attachedRelationalOp); |
| } |
| |
| exprPlan.add(pe); |
| exprOpsMap.put(project, pe); |
| translateConnection(project, pe); |
| } |
| |
| public void visit(LOConst con) throws VisitorException{ |
| ConstantExpression ce = null; |
| try { |
| ce = new ConstantExpression(exprPlan, con.getValue(), Util.translateFieldSchema(con.getFieldSchema())); |
| } catch (FrontendException e) { |
| throw new VisitorException(e); |
| } |
| |
| exprPlan.add(ce); |
| exprOpsMap.put(con, ce); |
| translateConnection(con, ce); |
| } |
| |
| public void visit(LOGreaterThan op) throws VisitorException { |
| ExpressionOperator left = op.getLhsOperand(); |
| ExpressionOperator right = op.getRhsOperand(); |
| |
| GreaterThanExpression eq = new GreaterThanExpression |
| (exprPlan, exprOpsMap.get(left), exprOpsMap.get(right)); |
| exprOpsMap.put(op, eq); |
| } |
| |
| public void visit(LOLesserThan op) throws VisitorException { |
| ExpressionOperator left = op.getLhsOperand(); |
| ExpressionOperator right = op.getRhsOperand(); |
| |
| LessThanExpression eq = new LessThanExpression |
| (exprPlan, exprOpsMap.get(left), exprOpsMap.get(right)); |
| exprOpsMap.put(op, eq); |
| } |
| |
| public void visit(LOGreaterThanEqual op) throws VisitorException { |
| ExpressionOperator left = op.getLhsOperand(); |
| ExpressionOperator right = op.getRhsOperand(); |
| |
| GreaterThanEqualExpression eq = new GreaterThanEqualExpression |
| (exprPlan, exprOpsMap.get(left), exprOpsMap.get(right)); |
| exprOpsMap.put(op, eq); |
| } |
| |
| public void visit(LOLesserThanEqual op) throws VisitorException { |
| ExpressionOperator left = op.getLhsOperand(); |
| ExpressionOperator right = op.getRhsOperand(); |
| |
| LessThanEqualExpression eq = new LessThanEqualExpression |
| (exprPlan, exprOpsMap.get(left), exprOpsMap.get(right)); |
| exprOpsMap.put(op, eq); |
| } |
| |
| public void visit(LOEqual op) throws VisitorException { |
| ExpressionOperator left = op.getLhsOperand(); |
| ExpressionOperator right = op.getRhsOperand(); |
| |
| EqualExpression eq = new EqualExpression(exprPlan, exprOpsMap.get(left), exprOpsMap.get(right)); |
| exprOpsMap.put(op, eq); |
| } |
| |
| public void visit(LOUserFunc op) throws VisitorException { |
| UserFuncExpression exp = new UserFuncExpression(exprPlan, op.getFuncSpec()); |
| |
| List<ExpressionOperator> args = op.getArguments(); |
| |
| for( ExpressionOperator arg : args ) { |
| LogicalExpression expArg = exprOpsMap.get(arg); |
| exprPlan.connect(exp, expArg); |
| } |
| |
| exprOpsMap.put(op, exp); |
| // We need to track all the scalars |
| if(op.getImplicitReferencedOperator() != null) { |
| exp.setImplicitReferencedOperator(outerOpsMap.get(op.getImplicitReferencedOperator())); |
| } |
| |
| } |
| |
| public void visit(LOBinCond op) throws VisitorException { |
| ExpressionOperator condition = op.getCond(); |
| ExpressionOperator left = op.getLhsOp(); |
| ExpressionOperator right = op.getRhsOp(); |
| |
| BinCondExpression exp = new BinCondExpression(exprPlan, |
| exprOpsMap.get(condition), exprOpsMap.get(left), exprOpsMap.get(right)); |
| exprOpsMap.put(op, exp); |
| } |
| |
| public void visit(LOCast cast) throws VisitorException { |
| ExpressionOperator exp = cast.getExpression(); |
| |
| CastExpression c = null; |
| try { |
| c = new CastExpression(exprPlan, exprOpsMap.get(exp), Util.translateFieldSchema(cast.getFieldSchema())); |
| } catch (FrontendException e) { |
| throw new VisitorException(e); |
| } |
| c.setFuncSpec(cast.getLoadFuncSpec()); |
| exprOpsMap.put(cast, c); |
| } |
| |
| public void visit(LORegexp binOp) throws VisitorException { |
| ExpressionOperator left = binOp.getLhsOperand(); |
| ExpressionOperator right = binOp.getRhsOperand(); |
| |
| RegexExpression ae = new RegexExpression(exprPlan |
| , exprOpsMap.get(left), exprOpsMap.get(right)); |
| exprOpsMap.put(binOp, ae); |
| } |
| |
| public void visit(LONotEqual op) throws VisitorException { |
| ExpressionOperator left = op.getLhsOperand(); |
| ExpressionOperator right = op.getRhsOperand(); |
| |
| NotEqualExpression eq = new NotEqualExpression(exprPlan, |
| exprOpsMap.get(left), exprOpsMap.get(right)); |
| exprOpsMap.put(op, eq); |
| } |
| |
| public void visit(LOAdd binOp) throws VisitorException { |
| ExpressionOperator left = binOp.getLhsOperand(); |
| ExpressionOperator right = binOp.getRhsOperand(); |
| |
| AddExpression ae = new AddExpression(exprPlan, |
| exprOpsMap.get(left), exprOpsMap.get(right)); |
| exprOpsMap.put(binOp, ae); |
| } |
| |
| public void visit(LOSubtract binOp) throws VisitorException { |
| ExpressionOperator left = binOp.getLhsOperand(); |
| ExpressionOperator right = binOp.getRhsOperand(); |
| |
| SubtractExpression ae = new SubtractExpression(exprPlan, |
| exprOpsMap.get(left), exprOpsMap.get(right)); |
| exprOpsMap.put(binOp, ae); |
| } |
| |
| public void visit(LOMultiply binOp) throws VisitorException { |
| ExpressionOperator left = binOp.getLhsOperand(); |
| ExpressionOperator right = binOp.getRhsOperand(); |
| |
| MultiplyExpression ae = new MultiplyExpression(exprPlan, |
| exprOpsMap.get(left), exprOpsMap.get(right)); |
| exprOpsMap.put(binOp, ae); |
| } |
| |
| public void visit(LODivide binOp) throws VisitorException { |
| ExpressionOperator left = binOp.getLhsOperand(); |
| ExpressionOperator right = binOp.getRhsOperand(); |
| |
| DivideExpression ae = new DivideExpression(exprPlan, |
| exprOpsMap.get(left), exprOpsMap.get(right)); |
| exprOpsMap.put(binOp, ae); |
| } |
| |
| public void visit(LOMod binOp) throws VisitorException { |
| ExpressionOperator left = binOp.getLhsOperand(); |
| ExpressionOperator right = binOp.getRhsOperand(); |
| |
| ModExpression ae = new ModExpression(exprPlan, |
| exprOpsMap.get(left), exprOpsMap.get(right)); |
| exprOpsMap.put(binOp, ae); |
| } |
| |
| |
| public void visit(LONegative uniOp) throws VisitorException { |
| ExpressionOperator exp = uniOp.getOperand(); |
| NegativeExpression op = new NegativeExpression(exprPlan, exprOpsMap.get(exp)); |
| exprOpsMap.put(uniOp, op); |
| } |
| |
| public void visit(LOMapLookup colOp) throws VisitorException { |
| FieldSchema fieldSchema; |
| try { |
| fieldSchema = colOp.getFieldSchema(); |
| } catch (FrontendException e) { |
| throw new VisitorException( e.getMessage() ); |
| } |
| |
| LogicalSchema.LogicalFieldSchema logfieldSchema = |
| new LogicalSchema.LogicalFieldSchema( fieldSchema.alias, |
| Util.translateSchema(fieldSchema.schema), fieldSchema.type); |
| |
| LogicalExpression map = exprOpsMap.get( colOp.getMap() ); |
| |
| MapLookupExpression op = new MapLookupExpression(exprPlan, |
| colOp.getLookUpKey(), logfieldSchema); |
| |
| exprPlan.connect(op, map); |
| |
| exprOpsMap.put(colOp, op); |
| } |
| |
| public void visit(LOAnd binOp) throws VisitorException { |
| ExpressionOperator left = binOp.getLhsOperand(); |
| ExpressionOperator right = binOp.getRhsOperand(); |
| |
| AndExpression ae = new AndExpression(exprPlan, exprOpsMap.get(left), exprOpsMap.get(right)); |
| exprOpsMap.put(binOp, ae); |
| } |
| |
| public void visit(LOOr binOp) throws VisitorException { |
| ExpressionOperator left = binOp.getLhsOperand(); |
| ExpressionOperator right = binOp.getRhsOperand(); |
| |
| OrExpression ae = new OrExpression(exprPlan, exprOpsMap.get(left), exprOpsMap.get(right)); |
| exprOpsMap.put(binOp, ae); |
| } |
| |
| public void visit(LONot uniOp) throws VisitorException { |
| ExpressionOperator exp = uniOp.getOperand(); |
| NotExpression not = new NotExpression(exprPlan, exprOpsMap.get(exp)); |
| exprOpsMap.put(uniOp, not); |
| } |
| |
| public void visit(LOIsNull uniOp) throws VisitorException { |
| ExpressionOperator exp = uniOp.getOperand(); |
| IsNullExpression isNull = new IsNullExpression(exprPlan, exprOpsMap.get(exp)); |
| exprOpsMap.put(uniOp, isNull); |
| } |
| } |