/** * 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.Iterator; import java.util.List; 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.OperatorPlan; import org.apache.pig.newplan.OperatorSubPlan; import org.apache.pig.newplan.logical.expression.AndExpression; import org.apache.pig.newplan.logical.expression.LogicalExpression; import org.apache.pig.newplan.logical.expression.LogicalExpressionPlan; import org.apache.pig.newplan.logical.expression.ProjectExpression; import org.apache.pig.newplan.logical.relational.LOFilter; import org.apache.pig.newplan.logical.relational.LogicalPlan; import org.apache.pig.newplan.logical.relational.LogicalRelationalOperator; import org.apache.pig.newplan.optimizer.Rule; import org.apache.pig.newplan.optimizer.Transformer; public class SplitFilter extends Rule { public SplitFilter(String n) { super(n, false); } @Override public Transformer getNewTransformer() { return new SplitFilterTransformer(); } public class SplitFilterTransformer extends Transformer { private OperatorSubPlan subPlan; @Override public boolean check(OperatorPlan matched) throws FrontendException { LOFilter filter = (LOFilter)matched.getSources().get(0); LogicalExpressionPlan cond = filter.getFilterPlan(); LogicalExpression root = (LogicalExpression) cond.getSources().get(0); if (root instanceof AndExpression && currentPlan.getSoftLinkPredecessors(filter)==null) { return true; } return false; } @Override public void transform(OperatorPlan matched) throws FrontendException { subPlan = new OperatorSubPlan(currentPlan); // split one LOFilter into 2 by "AND" LOFilter filter = (LOFilter)matched.getSources().get(0); LogicalExpressionPlan cond = filter.getFilterPlan(); LogicalExpression root = (LogicalExpression) cond.getSources().get(0); if (!(root instanceof AndExpression)) { return; } LogicalExpressionPlan op1 = new LogicalExpressionPlan(); op1.add((LogicalExpression)cond.getSuccessors(root).get(0)); fillSubPlan(cond, op1, (LogicalExpression)cond.getSuccessors(root).get(0)); LogicalExpressionPlan op2 = new LogicalExpressionPlan(); op2.add((LogicalExpression)cond.getSuccessors(root).get(1)); fillSubPlan(cond, op2, (LogicalExpression)cond.getSuccessors(root).get(1)); filter.setFilterPlan(op1); LOFilter filter2 = new LOFilter((LogicalPlan)currentPlan, op2); currentPlan.add(filter2); Operator succed = null; List<Operator> succeds = currentPlan.getSuccessors(filter); if (succeds != null) { succed = succeds.get(0); subPlan.add(succed); currentPlan.insertBetween(filter, filter2, succed); } else { currentPlan.connect(filter, 0, filter2, 0); } subPlan.add(filter); subPlan.add(filter2); Iterator<Operator> iter = filter2.getFilterPlan().getOperators(); while (iter.hasNext()) { Operator oper = iter.next(); if (oper instanceof ProjectExpression) { ((ProjectExpression)oper).setAttachedRelationalOp(filter2); } } } @Override public OperatorPlan reportChanges() { return subPlan; } private void fillSubPlan(OperatorPlan origPlan, OperatorPlan subPlan, Operator startOp) throws FrontendException { List<Operator> l = origPlan.getSuccessors(startOp); if (l != null) { for(Operator le: l) { subPlan.add(le); subPlan.connect(startOp, le); fillSubPlan(origPlan, subPlan, le); } } } } @Override protected OperatorPlan buildPattern() { // the pattern that this rule looks for // is filter LogicalPlan plan = new LogicalPlan(); LogicalRelationalOperator op2 = new LOFilter(plan); plan.add(op2); return plan; } }