Search in sources :

Example 51 with AbstractLogicalOperator

use of org.apache.hyracks.algebricks.core.algebra.operators.logical.AbstractLogicalOperator in project asterixdb by apache.

the class IntroduceProjectsRule method introduceProjects.

protected boolean introduceProjects(AbstractLogicalOperator parentOp, int parentInputIndex, Mutable<ILogicalOperator> opRef, Set<LogicalVariable> parentUsedVars, IOptimizationContext context) throws AlgebricksException {
    AbstractLogicalOperator op = (AbstractLogicalOperator) opRef.getValue();
    boolean modified = false;
    usedVars.clear();
    VariableUtilities.getUsedVariables(op, usedVars);
    // In the top-down pass, maintain a set of variables that are used in op and all its parents.
    // This is a necessary step for the newly created project operator during this optimization,
    // since we already have all information from collectUsedVars() method for the other operators.
    HashSet<LogicalVariable> parentsUsedVars = new HashSet<>();
    parentsUsedVars.addAll(parentUsedVars);
    parentsUsedVars.addAll(usedVars);
    if (allUsedVarsAfterOpMap.get(op) != null) {
        parentsUsedVars.addAll(allUsedVarsAfterOpMap.get(op));
    }
    // Descend into children.
    for (int i = 0; i < op.getInputs().size(); i++) {
        Mutable<ILogicalOperator> inputOpRef = op.getInputs().get(i);
        if (introduceProjects(op, i, inputOpRef, parentsUsedVars, context)) {
            modified = true;
        }
    }
    if (modified) {
        context.computeAndSetTypeEnvironmentForOperator(op);
    }
    // In the bottom-up pass, determine which live variables are not used by op's parents.
    // Such variables are be projected away.
    liveVars.clear();
    VariableUtilities.getLiveVariables(op, liveVars);
    producedVars.clear();
    VariableUtilities.getProducedVariables(op, producedVars);
    liveVars.removeAll(producedVars);
    projectVars.clear();
    for (LogicalVariable liveVar : liveVars) {
        if (parentsUsedVars.contains(liveVar)) {
            projectVars.add(liveVar);
        }
    }
    // Some of the variables that are live at this op are not used above.
    if (projectVars.size() != liveVars.size()) {
        // Add a project operator under each of op's qualifying input branches.
        for (int i = 0; i < op.getInputs().size(); i++) {
            ILogicalOperator childOp = op.getInputs().get(i).getValue();
            liveVars.clear();
            VariableUtilities.getLiveVariables(childOp, liveVars);
            List<LogicalVariable> vars = new ArrayList<>();
            vars.addAll(projectVars);
            // Only retain those variables that are live in the i-th input branch.
            vars.retainAll(liveVars);
            if (vars.size() != liveVars.size()) {
                ProjectOperator projectOp = new ProjectOperator(vars);
                projectOp.getInputs().add(new MutableObject<ILogicalOperator>(childOp));
                op.getInputs().get(i).setValue(projectOp);
                context.computeAndSetTypeEnvironmentForOperator(projectOp);
                modified = true;
            }
        }
    } else if (op.getOperatorTag() == LogicalOperatorTag.PROJECT) {
        // Check if the existing project has become useless.
        liveVars.clear();
        VariableUtilities.getLiveVariables(op.getInputs().get(0).getValue(), liveVars);
        ProjectOperator projectOp = (ProjectOperator) op;
        List<LogicalVariable> projectVarsTemp = projectOp.getVariables();
        if (liveVars.size() == projectVarsTemp.size() && liveVars.containsAll(projectVarsTemp)) {
            boolean eliminateProject = true;
            // For UnionAll the variables must also be in exactly the correct order.
            if (parentOp.getOperatorTag() == LogicalOperatorTag.UNIONALL) {
                eliminateProject = canEliminateProjectBelowUnion((UnionAllOperator) parentOp, projectOp, parentInputIndex);
            }
            if (eliminateProject) {
                // The existing project has become useless. Remove it.
                parentOp.getInputs().get(parentInputIndex).setValue(op.getInputs().get(0).getValue());
            }
        }
    }
    if (modified) {
        context.computeAndSetTypeEnvironmentForOperator(op);
    }
    return modified;
}
Also used : LogicalVariable(org.apache.hyracks.algebricks.core.algebra.base.LogicalVariable) AbstractLogicalOperator(org.apache.hyracks.algebricks.core.algebra.operators.logical.AbstractLogicalOperator) ProjectOperator(org.apache.hyracks.algebricks.core.algebra.operators.logical.ProjectOperator) ILogicalOperator(org.apache.hyracks.algebricks.core.algebra.base.ILogicalOperator) ArrayList(java.util.ArrayList) ArrayList(java.util.ArrayList) List(java.util.List) HashSet(java.util.HashSet)

Example 52 with AbstractLogicalOperator

use of org.apache.hyracks.algebricks.core.algebra.operators.logical.AbstractLogicalOperator in project asterixdb by apache.

the class AbstractIntroduceGroupByCombinerRule method tryToPushRoot.

private boolean tryToPushRoot(Mutable<ILogicalOperator> root, GroupByOperator oldGbyOp, GroupByOperator newGbyOp, BookkeepingInfo bi, List<LogicalVariable> gbyVars, IOptimizationContext context, List<Mutable<ILogicalOperator>> toPushAccumulate, Set<SimilarAggregatesInfo> toReplaceSet) throws AlgebricksException {
    AbstractLogicalOperator op1 = (AbstractLogicalOperator) root.getValue();
    if (op1.getOperatorTag() != LogicalOperatorTag.AGGREGATE) {
        return false;
    }
    AbstractLogicalOperator op2 = (AbstractLogicalOperator) op1.getInputs().get(0).getValue();
    // Finds nested group-by if any.
    AbstractLogicalOperator op3 = op2;
    while (op3.getOperatorTag() != LogicalOperatorTag.GROUP && op3.getInputs().size() == 1) {
        op3 = (AbstractLogicalOperator) op3.getInputs().get(0).getValue();
    }
    if (op3.getOperatorTag() != LogicalOperatorTag.GROUP) {
        AggregateOperator initAgg = (AggregateOperator) op1;
        Pair<Boolean, Mutable<ILogicalOperator>> pOpRef = tryToPushAgg(initAgg, newGbyOp, toReplaceSet, context);
        if (!pOpRef.first) {
            return false;
        }
        Mutable<ILogicalOperator> opRef = pOpRef.second;
        if (opRef != null) {
            toPushAccumulate.add(opRef);
        }
        bi.modifyGbyMap.put(oldGbyOp, gbyVars);
        return true;
    } else {
        GroupByOperator nestedGby = (GroupByOperator) op3;
        List<LogicalVariable> gbyVars2 = nestedGby.getGbyVarList();
        Set<LogicalVariable> freeVars = new HashSet<>();
        // Removes non-free variables defined in the nested plan.
        OperatorPropertiesUtil.getFreeVariablesInSelfOrDesc(nestedGby, freeVars);
        gbyVars2.retainAll(freeVars);
        List<LogicalVariable> concatGbyVars = new ArrayList<LogicalVariable>(gbyVars);
        concatGbyVars.addAll(gbyVars2);
        for (ILogicalPlan p : nestedGby.getNestedPlans()) {
            for (Mutable<ILogicalOperator> r2 : p.getRoots()) {
                if (!tryToPushRoot(r2, nestedGby, newGbyOp, bi, concatGbyVars, context, toPushAccumulate, toReplaceSet)) {
                    return false;
                }
            }
        }
        /***
             * Push the nested pipeline which provides the input to the nested group operator into newGbyOp (the combined gby op).
             * The change is to fix asterixdb issue 782.
             */
        // Finds the reference of the bottom-most operator in the pipeline that
        // should not be pushed to the combiner group-by.
        Mutable<ILogicalOperator> currentOpRef = new MutableObject<ILogicalOperator>(nestedGby);
        Mutable<ILogicalOperator> bottomOpRef = findBottomOpRefStayInOldGby(currentOpRef);
        // Adds the used variables in the pipeline from <code>currentOpRef</code> to <code>bottomOpRef</code>
        // into the group-by keys for the introduced combiner group-by operator.
        Set<LogicalVariable> usedVars = collectUsedFreeVariables(currentOpRef, bottomOpRef);
        for (LogicalVariable usedVar : usedVars) {
            if (!concatGbyVars.contains(usedVar)) {
                concatGbyVars.add(usedVar);
            }
        }
        // Retains the nested pipeline above the identified operator in the old group-by operator.
        // Pushes the nested pipeline under the select operator into the new group-by operator.
        Mutable<ILogicalOperator> oldNtsRef = findNtsRef(currentOpRef);
        ILogicalOperator opToCombiner = bottomOpRef.getValue().getInputs().get(0).getValue();
        if (opToCombiner.getOperatorTag() == LogicalOperatorTag.NESTEDTUPLESOURCE) {
            // No pipeline other than the aggregate operator needs to push to combiner.
            return true;
        }
        bottomOpRef.getValue().getInputs().set(0, new MutableObject<ILogicalOperator>(oldNtsRef.getValue()));
        Mutable<ILogicalOperator> newGbyNestedOpRef = findNtsRef(toPushAccumulate.get(0));
        NestedTupleSourceOperator newNts = (NestedTupleSourceOperator) newGbyNestedOpRef.getValue();
        newGbyNestedOpRef.setValue(opToCombiner);
        oldNtsRef.setValue(newNts);
        return true;
    }
}
Also used : LogicalVariable(org.apache.hyracks.algebricks.core.algebra.base.LogicalVariable) NestedTupleSourceOperator(org.apache.hyracks.algebricks.core.algebra.operators.logical.NestedTupleSourceOperator) GroupByOperator(org.apache.hyracks.algebricks.core.algebra.operators.logical.GroupByOperator) AbstractLogicalOperator(org.apache.hyracks.algebricks.core.algebra.operators.logical.AbstractLogicalOperator) ILogicalOperator(org.apache.hyracks.algebricks.core.algebra.base.ILogicalOperator) ArrayList(java.util.ArrayList) Mutable(org.apache.commons.lang3.mutable.Mutable) AggregateOperator(org.apache.hyracks.algebricks.core.algebra.operators.logical.AggregateOperator) ILogicalPlan(org.apache.hyracks.algebricks.core.algebra.base.ILogicalPlan) HashSet(java.util.HashSet) MutableObject(org.apache.commons.lang3.mutable.MutableObject)

Example 53 with AbstractLogicalOperator

use of org.apache.hyracks.algebricks.core.algebra.operators.logical.AbstractLogicalOperator in project asterixdb by apache.

the class ExtractCommonOperatorsRule method rewritePost.

@Override
public boolean rewritePost(Mutable<ILogicalOperator> opRef, IOptimizationContext context) throws AlgebricksException {
    AbstractLogicalOperator op = (AbstractLogicalOperator) opRef.getValue();
    if (op.getOperatorTag() != LogicalOperatorTag.WRITE && op.getOperatorTag() != LogicalOperatorTag.WRITE_RESULT && op.getOperatorTag() != LogicalOperatorTag.DISTRIBUTE_RESULT) {
        return false;
    }
    boolean rewritten = false;
    boolean changed;
    if (!roots.isEmpty()) {
        do {
            changed = false;
            // applying the rewriting until fixpoint
            topDownMaterialization(roots);
            genCandidates(context);
            removeTrivialShare();
            if (!equivalenceClasses.isEmpty()) {
                changed = rewrite(context);
            }
            if (!rewritten) {
                rewritten = changed;
            }
            equivalenceClasses.clear();
            childrenToParents.clear();
            opToCandidateInputs.clear();
            clusterMap.clear();
            clusterWaitForMap.clear();
            // Resets lastUsedClusterId to 0.
            lastUsedClusterId = 0;
        } while (changed);
        roots.clear();
    }
    return rewritten;
}
Also used : AbstractLogicalOperator(org.apache.hyracks.algebricks.core.algebra.operators.logical.AbstractLogicalOperator)

Example 54 with AbstractLogicalOperator

use of org.apache.hyracks.algebricks.core.algebra.operators.logical.AbstractLogicalOperator in project asterixdb by apache.

the class ExtractCommonOperatorsRule method rewritePre.

@Override
public boolean rewritePre(Mutable<ILogicalOperator> opRef, IOptimizationContext context) throws AlgebricksException {
    AbstractLogicalOperator op = (AbstractLogicalOperator) opRef.getValue();
    if (op.getOperatorTag() != LogicalOperatorTag.WRITE && op.getOperatorTag() != LogicalOperatorTag.WRITE_RESULT && op.getOperatorTag() != LogicalOperatorTag.DISTRIBUTE_RESULT) {
        return false;
    }
    MutableObject<ILogicalOperator> mutableOp = new MutableObject<>(op);
    if (!roots.contains(mutableOp)) {
        roots.add(mutableOp);
    }
    return false;
}
Also used : AbstractLogicalOperator(org.apache.hyracks.algebricks.core.algebra.operators.logical.AbstractLogicalOperator) ILogicalOperator(org.apache.hyracks.algebricks.core.algebra.base.ILogicalOperator) MutableObject(org.apache.commons.lang3.mutable.MutableObject)

Example 55 with AbstractLogicalOperator

use of org.apache.hyracks.algebricks.core.algebra.operators.logical.AbstractLogicalOperator in project asterixdb by apache.

the class ExtractCommonOperatorsRule method removeTrivialShare.

private void removeTrivialShare() {
    for (List<Mutable<ILogicalOperator>> candidates : equivalenceClasses) {
        for (int i = candidates.size() - 1; i >= 0; i--) {
            Mutable<ILogicalOperator> opRef = candidates.get(i);
            AbstractLogicalOperator aop = (AbstractLogicalOperator) opRef.getValue();
            if (aop.getOperatorTag() == LogicalOperatorTag.EXCHANGE) {
                aop = (AbstractLogicalOperator) aop.getInputs().get(0).getValue();
            }
            if (aop.getOperatorTag() == LogicalOperatorTag.EMPTYTUPLESOURCE) {
                candidates.remove(i);
            }
        }
    }
    for (int i = equivalenceClasses.size() - 1; i >= 0; i--) {
        if (equivalenceClasses.get(i).size() < 2) {
            equivalenceClasses.remove(i);
        }
    }
}
Also used : Mutable(org.apache.commons.lang3.mutable.Mutable) AbstractLogicalOperator(org.apache.hyracks.algebricks.core.algebra.operators.logical.AbstractLogicalOperator) ILogicalOperator(org.apache.hyracks.algebricks.core.algebra.base.ILogicalOperator)

Aggregations

AbstractLogicalOperator (org.apache.hyracks.algebricks.core.algebra.operators.logical.AbstractLogicalOperator)236 ILogicalOperator (org.apache.hyracks.algebricks.core.algebra.base.ILogicalOperator)116 LogicalVariable (org.apache.hyracks.algebricks.core.algebra.base.LogicalVariable)91 ILogicalExpression (org.apache.hyracks.algebricks.core.algebra.base.ILogicalExpression)82 ArrayList (java.util.ArrayList)65 Mutable (org.apache.commons.lang3.mutable.Mutable)60 ILogicalPlan (org.apache.hyracks.algebricks.core.algebra.base.ILogicalPlan)44 AssignOperator (org.apache.hyracks.algebricks.core.algebra.operators.logical.AssignOperator)41 AbstractFunctionCallExpression (org.apache.hyracks.algebricks.core.algebra.expressions.AbstractFunctionCallExpression)34 VariableReferenceExpression (org.apache.hyracks.algebricks.core.algebra.expressions.VariableReferenceExpression)32 HashSet (java.util.HashSet)27 GroupByOperator (org.apache.hyracks.algebricks.core.algebra.operators.logical.GroupByOperator)24 AggregateOperator (org.apache.hyracks.algebricks.core.algebra.operators.logical.AggregateOperator)20 AbstractOperatorWithNestedPlans (org.apache.hyracks.algebricks.core.algebra.operators.logical.AbstractOperatorWithNestedPlans)19 SelectOperator (org.apache.hyracks.algebricks.core.algebra.operators.logical.SelectOperator)19 StructuralPropertiesVector (org.apache.hyracks.algebricks.core.algebra.properties.StructuralPropertiesVector)19 AbstractBinaryJoinOperator (org.apache.hyracks.algebricks.core.algebra.operators.logical.AbstractBinaryJoinOperator)18 SubplanOperator (org.apache.hyracks.algebricks.core.algebra.operators.logical.SubplanOperator)16 UnnestOperator (org.apache.hyracks.algebricks.core.algebra.operators.logical.UnnestOperator)16 LinkedList (java.util.LinkedList)14