Search in sources :

Example 76 with AbstractLogicalOperator

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

the class PushProjectDownRule method rewritePre.

@Override
public boolean rewritePre(Mutable<ILogicalOperator> opRef, IOptimizationContext context) throws AlgebricksException {
    AbstractLogicalOperator op = (AbstractLogicalOperator) opRef.getValue();
    if (op.getOperatorTag() != LogicalOperatorTag.PROJECT) {
        return false;
    }
    ProjectOperator pi = (ProjectOperator) op;
    Mutable<ILogicalOperator> opRef2 = pi.getInputs().get(0);
    HashSet<LogicalVariable> toPush = new HashSet<LogicalVariable>();
    toPush.addAll(pi.getVariables());
    Pair<Boolean, Boolean> p = pushThroughOp(toPush, opRef2, op, context);
    boolean smthWasPushed = p.first;
    if (p.second) {
        // the original projection is redundant
        opRef.setValue(op.getInputs().get(0).getValue());
        smthWasPushed = true;
    }
    return smthWasPushed;
}
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) HashSet(java.util.HashSet)

Example 77 with AbstractLogicalOperator

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

the class PushProjectIntoDataSourceScanRule method rewritePost.

@Override
public boolean rewritePost(Mutable<ILogicalOperator> opRef, IOptimizationContext context) throws AlgebricksException {
    AbstractLogicalOperator op = (AbstractLogicalOperator) opRef.getValue();
    if (op.getInputs().size() <= 0)
        return false;
    AbstractLogicalOperator project = (AbstractLogicalOperator) op.getInputs().get(0).getValue();
    if (project.getOperatorTag() != LogicalOperatorTag.PROJECT)
        return false;
    AbstractLogicalOperator exchange = (AbstractLogicalOperator) project.getInputs().get(0).getValue();
    if (exchange.getOperatorTag() != LogicalOperatorTag.EXCHANGE)
        return false;
    AbstractLogicalOperator inputOp = (AbstractLogicalOperator) exchange.getInputs().get(0).getValue();
    if (inputOp.getOperatorTag() != LogicalOperatorTag.DATASOURCESCAN)
        return false;
    DataSourceScanOperator scanOp = (DataSourceScanOperator) inputOp;
    ProjectOperator projectOp = (ProjectOperator) project;
    scanOp.addProjectVariables(projectOp.getVariables());
    if (op.getOperatorTag() != LogicalOperatorTag.EXCHANGE) {
        op.getInputs().set(0, project.getInputs().get(0));
    } else {
        op.getInputs().set(0, exchange.getInputs().get(0));
    }
    return true;
}
Also used : AbstractLogicalOperator(org.apache.hyracks.algebricks.core.algebra.operators.logical.AbstractLogicalOperator) DataSourceScanOperator(org.apache.hyracks.algebricks.core.algebra.operators.logical.DataSourceScanOperator) ProjectOperator(org.apache.hyracks.algebricks.core.algebra.operators.logical.ProjectOperator)

Example 78 with AbstractLogicalOperator

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

the class PushSelectDownRule method propagateSelectionRec.

private static boolean propagateSelectionRec(Mutable<ILogicalOperator> sigmaRef, Mutable<ILogicalOperator> opRef2) throws AlgebricksException {
    AbstractLogicalOperator op2 = (AbstractLogicalOperator) opRef2.getValue();
    if (op2.getInputs().size() != 1 || op2.getOperatorTag() == LogicalOperatorTag.DATASOURCESCAN || !OperatorPropertiesUtil.isMovable(op2)) {
        return false;
    }
    SelectOperator sigma = (SelectOperator) sigmaRef.getValue();
    LinkedList<LogicalVariable> usedInSigma = new LinkedList<LogicalVariable>();
    sigma.getCondition().getValue().getUsedVariables(usedInSigma);
    LinkedList<LogicalVariable> produced2 = new LinkedList<LogicalVariable>();
    VariableUtilities.getProducedVariables(op2, produced2);
    if (OperatorPropertiesUtil.disjoint(produced2, usedInSigma)) {
        // just swap
        opRef2.setValue(sigma);
        sigmaRef.setValue(op2);
        List<Mutable<ILogicalOperator>> sigmaInpList = sigma.getInputs();
        sigmaInpList.clear();
        sigmaInpList.addAll(op2.getInputs());
        List<Mutable<ILogicalOperator>> op2InpList = op2.getInputs();
        op2InpList.clear();
        op2InpList.add(opRef2);
        propagateSelectionRec(opRef2, sigma.getInputs().get(0));
        return true;
    }
    return false;
}
Also used : LogicalVariable(org.apache.hyracks.algebricks.core.algebra.base.LogicalVariable) Mutable(org.apache.commons.lang3.mutable.Mutable) SelectOperator(org.apache.hyracks.algebricks.core.algebra.operators.logical.SelectOperator) AbstractLogicalOperator(org.apache.hyracks.algebricks.core.algebra.operators.logical.AbstractLogicalOperator) LinkedList(java.util.LinkedList)

Example 79 with AbstractLogicalOperator

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

the class PushSelectIntoJoinRule method rewritePost.

@Override
public boolean rewritePost(Mutable<ILogicalOperator> opRef, IOptimizationContext context) throws AlgebricksException {
    Collection<LogicalVariable> joinLiveVarsLeft = new HashSet<LogicalVariable>();
    Collection<LogicalVariable> joinLiveVarsRight = new HashSet<LogicalVariable>();
    Collection<LogicalVariable> liveInOpsToPushLeft = new HashSet<LogicalVariable>();
    Collection<LogicalVariable> liveInOpsToPushRight = new HashSet<LogicalVariable>();
    List<ILogicalOperator> pushedOnLeft = new ArrayList<ILogicalOperator>();
    List<ILogicalOperator> pushedOnRight = new ArrayList<ILogicalOperator>();
    List<ILogicalOperator> pushedOnEither = new ArrayList<ILogicalOperator>();
    LinkedList<ILogicalOperator> notPushedStack = new LinkedList<ILogicalOperator>();
    Collection<LogicalVariable> usedVars = new HashSet<LogicalVariable>();
    Collection<LogicalVariable> producedVars = new HashSet<LogicalVariable>();
    AbstractLogicalOperator op = (AbstractLogicalOperator) opRef.getValue();
    if (op.getOperatorTag() != LogicalOperatorTag.SELECT) {
        return false;
    }
    SelectOperator select = (SelectOperator) op;
    Mutable<ILogicalOperator> opRef2 = op.getInputs().get(0);
    AbstractLogicalOperator son = (AbstractLogicalOperator) opRef2.getValue();
    AbstractLogicalOperator op2 = son;
    boolean needToPushOps = false;
    while (son.isMap()) {
        needToPushOps = true;
        Mutable<ILogicalOperator> opRefLink = son.getInputs().get(0);
        son = (AbstractLogicalOperator) opRefLink.getValue();
    }
    if (son.getOperatorTag() != LogicalOperatorTag.INNERJOIN && son.getOperatorTag() != LogicalOperatorTag.LEFTOUTERJOIN) {
        return false;
    }
    boolean isLoj = son.getOperatorTag() == LogicalOperatorTag.LEFTOUTERJOIN;
    AbstractBinaryJoinOperator join = (AbstractBinaryJoinOperator) son;
    Mutable<ILogicalOperator> joinBranchLeftRef = join.getInputs().get(0);
    Mutable<ILogicalOperator> joinBranchRightRef = join.getInputs().get(1);
    if (needToPushOps) {
        ILogicalOperator joinBranchLeft = joinBranchLeftRef.getValue();
        ILogicalOperator joinBranchRight = joinBranchRightRef.getValue();
        VariableUtilities.getLiveVariables(joinBranchLeft, joinLiveVarsLeft);
        VariableUtilities.getLiveVariables(joinBranchRight, joinLiveVarsRight);
        Mutable<ILogicalOperator> opIterRef = opRef2;
        ILogicalOperator opIter = op2;
        while (opIter != join) {
            LogicalOperatorTag tag = ((AbstractLogicalOperator) opIter).getOperatorTag();
            if (tag == LogicalOperatorTag.PROJECT) {
                notPushedStack.addFirst(opIter);
            } else {
                VariableUtilities.getUsedVariables(opIter, usedVars);
                VariableUtilities.getProducedVariables(opIter, producedVars);
                if (usedVars.size() == 0) {
                    pushedOnEither.add(opIter);
                } else if (joinLiveVarsLeft.containsAll(usedVars)) {
                    pushedOnLeft.add(opIter);
                    liveInOpsToPushLeft.addAll(producedVars);
                } else if (joinLiveVarsRight.containsAll(usedVars)) {
                    pushedOnRight.add(opIter);
                    liveInOpsToPushRight.addAll(producedVars);
                } else {
                    return false;
                }
            }
            opIterRef = opIter.getInputs().get(0);
            opIter = opIterRef.getValue();
        }
        if (isLoj && pushedOnLeft.isEmpty()) {
            return false;
        }
    }
    boolean intersectsAllBranches = true;
    boolean[] intersectsBranch = new boolean[join.getInputs().size()];
    LinkedList<LogicalVariable> selectVars = new LinkedList<LogicalVariable>();
    select.getCondition().getValue().getUsedVariables(selectVars);
    int i = 0;
    for (Mutable<ILogicalOperator> branch : join.getInputs()) {
        LinkedList<LogicalVariable> branchVars = new LinkedList<LogicalVariable>();
        VariableUtilities.getLiveVariables(branch.getValue(), branchVars);
        if (i == 0) {
            branchVars.addAll(liveInOpsToPushLeft);
        } else {
            branchVars.addAll(liveInOpsToPushRight);
        }
        if (OperatorPropertiesUtil.disjoint(selectVars, branchVars)) {
            intersectsAllBranches = false;
        } else {
            intersectsBranch[i] = true;
        }
        i++;
    }
    if (!intersectsBranch[0] && !intersectsBranch[1]) {
        return false;
    }
    if (needToPushOps) {
        //We should push independent ops into the first branch that the selection depends on
        if (intersectsBranch[0]) {
            pushOps(pushedOnEither, joinBranchLeftRef, context);
        } else {
            pushOps(pushedOnEither, joinBranchRightRef, context);
        }
        pushOps(pushedOnLeft, joinBranchLeftRef, context);
        pushOps(pushedOnRight, joinBranchRightRef, context);
    }
    if (intersectsAllBranches) {
        addCondToJoin(select, join, context);
    } else {
        // push down
        Iterator<Mutable<ILogicalOperator>> branchIter = join.getInputs().iterator();
        ILogicalExpression selectCondition = select.getCondition().getValue();
        boolean lojToInner = false;
        for (int j = 0; j < intersectsBranch.length; j++) {
            Mutable<ILogicalOperator> branch = branchIter.next();
            boolean inter = intersectsBranch[j];
            if (!inter) {
                continue;
            }
            // to inner join for this case.
            if (j > 0 && isLoj && containsNotMissingFiltering(selectCondition)) {
                lojToInner = true;
            }
            if ((j > 0 && isLoj) && containsMissingFiltering(selectCondition)) {
                // Select "is-not-missing($$var)" cannot be pushed in the right branch of a LOJ;
                notPushedStack.addFirst(select);
            } else {
                // Conditions for the left branch can always be pushed.
                // Other conditions can be pushed to the right branch of a LOJ.
                copySelectToBranch(select, branch, context);
            }
        }
        if (lojToInner) {
            // Rewrites left outer join  to inner join.
            InnerJoinOperator innerJoin = new InnerJoinOperator(join.getCondition());
            innerJoin.getInputs().addAll(join.getInputs());
            join = innerJoin;
            context.computeAndSetTypeEnvironmentForOperator(join);
        }
    }
    ILogicalOperator top = join;
    for (ILogicalOperator npOp : notPushedStack) {
        List<Mutable<ILogicalOperator>> npInpList = npOp.getInputs();
        npInpList.clear();
        npInpList.add(new MutableObject<ILogicalOperator>(top));
        context.computeAndSetTypeEnvironmentForOperator(npOp);
        top = npOp;
    }
    opRef.setValue(top);
    return true;
}
Also used : LogicalVariable(org.apache.hyracks.algebricks.core.algebra.base.LogicalVariable) AbstractLogicalOperator(org.apache.hyracks.algebricks.core.algebra.operators.logical.AbstractLogicalOperator) ILogicalOperator(org.apache.hyracks.algebricks.core.algebra.base.ILogicalOperator) ArrayList(java.util.ArrayList) InnerJoinOperator(org.apache.hyracks.algebricks.core.algebra.operators.logical.InnerJoinOperator) LinkedList(java.util.LinkedList) AbstractBinaryJoinOperator(org.apache.hyracks.algebricks.core.algebra.operators.logical.AbstractBinaryJoinOperator) Mutable(org.apache.commons.lang3.mutable.Mutable) ILogicalExpression(org.apache.hyracks.algebricks.core.algebra.base.ILogicalExpression) SelectOperator(org.apache.hyracks.algebricks.core.algebra.operators.logical.SelectOperator) LogicalOperatorTag(org.apache.hyracks.algebricks.core.algebra.base.LogicalOperatorTag) HashSet(java.util.HashSet)

Example 80 with AbstractLogicalOperator

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

the class RemoveUnnecessarySortMergeExchange method rewritePost.

@Override
public boolean rewritePost(Mutable<ILogicalOperator> opRef, IOptimizationContext context) throws AlgebricksException {
    AbstractLogicalOperator op1 = (AbstractLogicalOperator) opRef.getValue();
    if (op1.getPhysicalOperator() == null || (op1.getPhysicalOperator().getOperatorTag() != PhysicalOperatorTag.HASH_PARTITION_EXCHANGE && op1.getPhysicalOperator().getOperatorTag() != PhysicalOperatorTag.HASH_PARTITION_MERGE_EXCHANGE)) {
        return false;
    }
    Mutable<ILogicalOperator> currentOpRef = op1.getInputs().get(0);
    AbstractLogicalOperator currentOp = (AbstractLogicalOperator) currentOpRef.getValue();
    // Goes down the pipeline to find a qualified SortMergeExchange to eliminate.
    while (currentOp != null) {
        IPhysicalOperator physicalOp = currentOp.getPhysicalOperator();
        if (physicalOp == null) {
            return false;
        } else if (physicalOp.getOperatorTag() == PhysicalOperatorTag.SORT_MERGE_EXCHANGE) {
            break;
        } else if (!currentOp.isMap() || currentOp.getOperatorTag() == LogicalOperatorTag.UNNEST || currentOp.getOperatorTag() == LogicalOperatorTag.LIMIT) {
            // we need to use his new property in logical operator to check order sensitivity.
            return false;
        } else if (currentOp.getInputs().size() == 1) {
            currentOpRef = currentOp.getInputs().get(0);
            currentOp = (AbstractLogicalOperator) currentOpRef.getValue();
        } else {
            currentOp = null;
        }
    }
    if (currentOp == null) {
        // There is no such qualified SortMergeExchange.
        return false;
    }
    if (op1.getPhysicalOperator().getOperatorTag() == PhysicalOperatorTag.HASH_PARTITION_MERGE_EXCHANGE) {
        // If op1 is a hash_partition_merge_exchange, the sort_merge_exchange can be simply removed.
        currentOpRef.setValue(currentOp.getInputs().get(0).getValue());
        op1.computeDeliveredPhysicalProperties(context);
        return true;
    }
    // Checks whether sort columns in the SortMergeExchange are still available at op1.
    // If yes, we use HashMergeExchange; otherwise, we use HashExchange.
    SortMergeExchangePOperator sme = (SortMergeExchangePOperator) currentOp.getPhysicalOperator();
    HashPartitionExchangePOperator hpe = (HashPartitionExchangePOperator) op1.getPhysicalOperator();
    Set<LogicalVariable> liveVars = new HashSet<LogicalVariable>();
    VariableUtilities.getLiveVariables(op1, liveVars);
    boolean usingHashMergeExchange = true;
    for (OrderColumn oc : sme.getSortColumns()) {
        if (!liveVars.contains(oc.getColumn())) {
            usingHashMergeExchange = false;
        }
    }
    if (usingHashMergeExchange) {
        // Add sort columns from the SortMergeExchange into a new HashMergeExchange.
        List<OrderColumn> ocList = new ArrayList<OrderColumn>();
        for (OrderColumn oc : sme.getSortColumns()) {
            ocList.add(oc);
        }
        HashPartitionMergeExchangePOperator hpme = new HashPartitionMergeExchangePOperator(ocList, hpe.getHashFields(), hpe.getDomain());
        op1.setPhysicalOperator(hpme);
    }
    // Remove the SortMergeExchange op.
    currentOpRef.setValue(currentOp.getInputs().get(0).getValue());
    // Re-compute delivered properties at op1.
    op1.computeDeliveredPhysicalProperties(context);
    return true;
}
Also used : LogicalVariable(org.apache.hyracks.algebricks.core.algebra.base.LogicalVariable) AbstractLogicalOperator(org.apache.hyracks.algebricks.core.algebra.operators.logical.AbstractLogicalOperator) ILogicalOperator(org.apache.hyracks.algebricks.core.algebra.base.ILogicalOperator) OrderColumn(org.apache.hyracks.algebricks.core.algebra.properties.OrderColumn) ArrayList(java.util.ArrayList) HashPartitionMergeExchangePOperator(org.apache.hyracks.algebricks.core.algebra.operators.physical.HashPartitionMergeExchangePOperator) HashPartitionExchangePOperator(org.apache.hyracks.algebricks.core.algebra.operators.physical.HashPartitionExchangePOperator) IPhysicalOperator(org.apache.hyracks.algebricks.core.algebra.base.IPhysicalOperator) SortMergeExchangePOperator(org.apache.hyracks.algebricks.core.algebra.operators.physical.SortMergeExchangePOperator) HashSet(java.util.HashSet)

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