Package org.apache.pig.newplan.logical.rules

Source Code of org.apache.pig.newplan.logical.rules.ImplicitSplitInserter$ImplicitSplitInserterTransformer

/**
* 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.rules;

import java.util.ArrayList;
import java.util.List;
import java.util.Iterator;

import org.apache.pig.data.DataType;
import org.apache.pig.impl.logicalLayer.FrontendException;
import org.apache.pig.impl.util.Pair;
import org.apache.pig.newplan.Operator;
import org.apache.pig.newplan.logical.optimizer.SchemaResetter;
import org.apache.pig.newplan.logical.optimizer.UidResetter;
import org.apache.pig.newplan.logical.relational.LogicalPlan;
import org.apache.pig.newplan.OperatorPlan;
import org.apache.pig.newplan.logical.expression.LogicalExpressionPlan;
import org.apache.pig.newplan.logical.expression.ConstantExpression;
import org.apache.pig.newplan.logical.relational.LogicalRelationalOperator;
import org.apache.pig.newplan.optimizer.Rule;
import org.apache.pig.newplan.optimizer.Transformer;
import org.apache.pig.newplan.logical.relational.LOSplit;
import org.apache.pig.newplan.logical.relational.LOStore;
import org.apache.pig.newplan.logical.relational.LOSplitOutput;
import org.apache.pig.newplan.logical.relational.LogicalSchema;


/**
* Super class for all rules that operates on the whole plan. It doesn't look for
* a specific pattern. An example of such kind rule is ColumnPrune.
*
*/
public class ImplicitSplitInserter extends Rule {

    public ImplicitSplitInserter(String n) {
        super(n, true);
        // Skip listener, especially, skip ProjectionPatcher so that we can keep column reference for
        // ProjectExpression (Once ProjectionPatcher is invoked, column reference will be gone in favor of uid reference).
        // There is no need for ProjectionPatcher in this rule since we don't swap columns; however, uid conflict is not solved
        // at this moment (until after DuplicateForEachColumnRewrite), so keep column reference for now
        setSkipListener(true);
    }

    @Override
    public List<OperatorPlan> match(OperatorPlan plan) throws FrontendException {
        // Look to see if this is a non-split node with two outputs.  If so
        // it matches.
        currentPlan = plan;
        List<OperatorPlan> ll = new ArrayList<OperatorPlan>();
        Iterator<Operator> ops = plan.getOperators();
        while (ops.hasNext()) {
            Operator op = ops.next();
            if (op instanceof LOSplit || op instanceof LOStore)
                continue;
            List<Operator> succs = plan.getSuccessors(op);
            if (succs != null && succs.size() >= 2) {
                OperatorPlan match = new LogicalPlan();
                match.add(op);
                ll.add(match);
            }
        }
        return ll;
    }
   
    @Override
    public Transformer getNewTransformer() {
      return new ImplicitSplitInserterTransformer();
    }
   
    public class ImplicitSplitInserterTransformer extends Transformer {
      @Override
      public boolean check(OperatorPlan matched) throws FrontendException {
        return true;
      }
     
      @Override
      public void transform(OperatorPlan matched) throws FrontendException {
        if (matched == null || matched instanceof LOSplit || matched instanceof LOStore
            || matched.size() != 1)
          throw new FrontendException("Invalid match in ImplicitSplitInserter rule.", 2244);

        // For two successors of op here is a pictorial
        // representation of the change required:
        // BEFORE:
        // Succ1  Succ2
        //  \       /
        //      op
       
        //  SHOULD BECOME:
       
        // AFTER:
        // Succ1          Succ2
        //   |              |
        // SplitOutput SplitOutput
        //      \       /
        //        Split
        //          |
        //          op
       
        Operator op = matched.getSources().get(0);
        List<Operator> succs = currentPlan.getSuccessors(op);
        if (succs == null || succs.size() < 2)
          throw new FrontendException("Invalid match in ImplicitSplitInserter rule.", 2243);
        LOSplit splitOp = new LOSplit(currentPlan);
        splitOp.setAlias(((LogicalRelationalOperator) op).getAlias());
        Operator[] sucs = succs.toArray(new Operator[0]);
        currentPlan.add(splitOp);
        currentPlan.connect(op, splitOp);
        for (Operator suc : sucs) {
          // position is remembered in order to maintain the order of the successors
          Pair<Integer, Integer> pos = currentPlan.disconnect(op, suc);
          LogicalExpressionPlan filterPlan = new LogicalExpressionPlan();
          LogicalSchema.LogicalFieldSchema fs = new LogicalSchema.LogicalFieldSchema(null, null, DataType.BOOLEAN);
          new ConstantExpression(filterPlan, Boolean.valueOf(true), fs);
          LOSplitOutput splitOutput = new LOSplitOutput((LogicalPlan) currentPlan, filterPlan);
          splitOutput.setAlias(splitOp.getAlias());
          currentPlan.add(splitOutput);
          currentPlan.connect(splitOp, splitOutput);
          currentPlan.connect(splitOutput, pos.first, suc, pos.second);
        }
       
        // Since we adjust the uid layout, clear all cached uids
        UidResetter uidResetter = new UidResetter(currentPlan);
        uidResetter.visit();

        // Manually regenerate schema since we skip listener
        SchemaResetter schemaResetter = new SchemaResetter(currentPlan);
        schemaResetter.visit();
      }
     
      @Override
      public OperatorPlan reportChanges() {
        return currentPlan;
      }
    }
   
    @Override
    protected OperatorPlan buildPattern() {
        return null;
    }
}
TOP

Related Classes of org.apache.pig.newplan.logical.rules.ImplicitSplitInserter$ImplicitSplitInserterTransformer

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.