/* * 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.test; import java.io.IOException; import java.util.Iterator; import java.util.List; 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.LogicalExpressionPlan; import org.apache.pig.newplan.logical.expression.LogicalExpressionVisitor; 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.LOCogroup; import org.apache.pig.newplan.logical.relational.LOCross; import org.apache.pig.newplan.logical.relational.LODistinct; import org.apache.pig.newplan.logical.relational.LOFilter; import org.apache.pig.newplan.logical.relational.LOForEach; import org.apache.pig.newplan.logical.relational.LOGenerate; import org.apache.pig.newplan.logical.relational.LOInnerLoad; import org.apache.pig.newplan.logical.relational.LOJoin; import org.apache.pig.newplan.logical.relational.LOLimit; import org.apache.pig.newplan.logical.relational.LOLoad; import org.apache.pig.newplan.logical.relational.LORank; import org.apache.pig.newplan.logical.relational.LOSort; import org.apache.pig.newplan.logical.relational.LOSplit; import org.apache.pig.newplan.logical.relational.LOSplitOutput; import org.apache.pig.newplan.logical.relational.LOStore; import org.apache.pig.newplan.logical.relational.LOStream; import org.apache.pig.newplan.logical.relational.LOUnion; import org.apache.pig.newplan.logical.relational.LogicalPlan; import org.apache.pig.newplan.logical.relational.LogicalRelationalNodesVisitor; import org.apache.pig.newplan.DependencyOrderWalker; import org.apache.pig.newplan.Operator; import org.apache.pig.impl.logicalLayer.FrontendException; import org.apache.pig.impl.plan.VisitorException; /** * This class transforms LogicalPlan to its textual representation * */ public class OptimizeLimitPlanPrinter extends LogicalRelationalNodesVisitor { private StringBuilder sb = null ; public OptimizeLimitPlanPrinter(LogicalPlan plan) throws FrontendException { super( plan, new DependencyOrderWalker( plan ) ); sb = new StringBuilder() ; } @Override public void visit(LOLoad load) throws FrontendException { appendEdges( load ); } @Override public void visit(LOJoin join) throws FrontendException { appendEdges( join ); } @Override public void visit(LOGenerate gen) throws FrontendException { appendEdges( gen ); } @Override public void visit(LOInnerLoad load) throws FrontendException { appendEdges( load ); } @Override public void visit(LOUnion loUnion) throws FrontendException { appendEdges( loUnion ); } @Override public void visit(LOStream loStream) throws FrontendException { appendEdges( loStream ); } @Override public void visit(LOFilter filter) throws FrontendException { LogicalExpressionPlan expPlan = filter.getFilterPlan(); MyLogicalExpressionVisitor visitor = new MyLogicalExpressionVisitor( expPlan ); sb.append("[" + visitor.printToString() + "]" ); appendEdges( filter ); } @Override public void visit(LOStore store) throws FrontendException { appendEdges( store ); } @Override public void visit(LOForEach foreach) throws FrontendException { appendOp( foreach ) ; boolean hasFlatten = false; LogicalPlan inner1 = foreach.getInnerPlan(); Iterator<Operator> it = inner1.getOperators(); while( it.hasNext() ) { Operator op = it.next(); if( op instanceof LOGenerate ) { LOGenerate gen = (LOGenerate)op; boolean[] flattenFlags = gen.getFlattenFlags(); if( flattenFlags != null ) { for( boolean flatten : flattenFlags ) { if( flatten ) { hasFlatten = true; break; } } } } } if (hasFlatten) sb.append(" [hasflat=\"true\"]"); else sb.append(" [hasflat=\"false\"]"); sb.append(";\n"); appendEdges(foreach); } @Override public void visit(LOCogroup loCogroup) throws FrontendException { appendEdges(loCogroup); } @Override public void visit(LOSplit loSplit) throws FrontendException { appendEdges(loSplit); } @Override public void visit(LOSplitOutput loSplitOutput) throws FrontendException { } @Override public void visit(LOSort loSort) throws FrontendException { appendOp(loSort) ; sb.append(" [limit=\"" + loSort.getLimit() + "\"]"); sb.append(";\n"); appendEdges(loSort); } @Override public void visit(LORank loRank) throws FrontendException { appendOp(loRank) ; appendEdges(loRank); } @Override public void visit(LODistinct loDistinct) throws FrontendException { appendEdges(loDistinct); } @Override public void visit(LOLimit loLimit) throws FrontendException { appendOp(loLimit) ; sb.append(" [limit=\""+loLimit.getLimit()+"\"]"); sb.append(";\n"); appendEdges(loLimit); } @Override public void visit(LOCross loCross) throws FrontendException { appendEdges(loCross); } private void appendOp(Operator op) { sb.append(" "+op.getClass().getSimpleName()) ; } private void appendEdges(Operator op) throws FrontendException { List<Operator> list = currentWalker.getPlan().getSuccessors(op) ; if (list!=null) { for(Operator tmp: list) { sb.append(" "+op.getClass().getSimpleName()+" -> "); sb.append(tmp.getClass().getSimpleName()+";\n"); } } } /*** * This method has to be called after the visit is totally finished only * @throws IOException */ public String printToString() throws IOException { try { visit() ; } catch(VisitorException vse) { throw new AssertionError("Error while transforming type graph to text") ; } return sb.toString() ; } } class MyLogicalExpressionVisitor extends LogicalExpressionVisitor { private StringBuilder sb = null ; public MyLogicalExpressionVisitor(LogicalExpressionPlan plan) throws FrontendException { super( plan, new DependencyOrderWalker( plan ) ); sb = new StringBuilder() ; } @Override public void visit(AndExpression op) throws FrontendException { appendEdges( op ); } @Override public void visit(OrExpression op) throws FrontendException { appendEdges( op ); } @Override public void visit(EqualExpression op) throws FrontendException { appendEdges( op ); } @Override public void visit(ProjectExpression op) throws FrontendException { appendEdges( op ); } @Override public void visit(ConstantExpression op) throws FrontendException { appendEdges( op ); } @Override public void visit(CastExpression op) throws FrontendException { appendEdges( op ); } @Override public void visit(GreaterThanExpression op) throws FrontendException { appendEdges( op ); } @Override public void visit(GreaterThanEqualExpression op) throws FrontendException { appendEdges( op ); } @Override public void visit(LessThanExpression op) throws FrontendException { appendEdges( op ); } @Override public void visit(LessThanEqualExpression op) throws FrontendException { appendEdges( op ); } @Override public void visit(NotEqualExpression op) throws FrontendException { appendEdges( op ); } @Override public void visit(NotExpression op ) throws FrontendException { appendEdges( op ); } @Override public void visit(IsNullExpression op) throws FrontendException { appendEdges( op ); } @Override public void visit(NegativeExpression op) throws FrontendException { appendEdges( op ); } @Override public void visit(AddExpression op) throws FrontendException { appendEdges( op ); } @Override public void visit(SubtractExpression op) throws FrontendException { appendEdges( op ); } @Override public void visit(MultiplyExpression op) throws FrontendException { appendEdges( op ); } @Override public void visit(ModExpression op) throws FrontendException { appendEdges( op ); } @Override public void visit(DivideExpression op) throws FrontendException { appendEdges( op ); } @Override public void visit(MapLookupExpression op) throws FrontendException { appendEdges( op ); } @Override public void visit(BinCondExpression op) throws FrontendException { appendEdges(op); } @Override public void visit(UserFuncExpression op) throws FrontendException { appendEdges( op ); } @Override public void visit(DereferenceExpression bagDerefenceExpression) throws FrontendException { appendEdges( bagDerefenceExpression ); } public void visit(RegexExpression op) throws FrontendException { appendEdges( op ); } private void appendEdges(Operator op) throws FrontendException { List<Operator> list = currentWalker.getPlan().getSuccessors(op) ; if (list!=null) { for(Operator tmp: list) { sb.append(" "+op.getClass().getSimpleName()+" -> "); sb.append(tmp.getClass().getSimpleName()+";\n"); } } } public String printToString() throws FrontendException { try { visit() ; } catch(VisitorException vse) { throw new AssertionError("Error while transforming type graph to text") ; } return sb.toString() ; } }