Search in sources :

Example 6 with AbstractLogicalOperator

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

the class ConsolidateSelectsRule method rewritePre.

@Override
public boolean rewritePre(Mutable<ILogicalOperator> opRef, IOptimizationContext context) throws AlgebricksException {
    AbstractLogicalOperator op = (AbstractLogicalOperator) opRef.getValue();
    if (op.getOperatorTag() != LogicalOperatorTag.SELECT) {
        return false;
    }
    SelectOperator firstSelect = (SelectOperator) op;
    IFunctionInfo andFn = context.getMetadataProvider().lookupFunction(AlgebricksBuiltinFunctions.AND);
    // New conjuncts for consolidated select.
    AbstractFunctionCallExpression conj = null;
    AbstractLogicalOperator topMostOp = null;
    AbstractLogicalOperator selectParent = null;
    AbstractLogicalOperator nextSelect = firstSelect;
    do {
        // Skip through assigns.
        do {
            selectParent = nextSelect;
            nextSelect = (AbstractLogicalOperator) selectParent.getInputs().get(0).getValue();
        } while (nextSelect.getOperatorTag() == LogicalOperatorTag.ASSIGN && OperatorPropertiesUtil.isMovable(nextSelect));
        // Stop if the child op is not a select.
        if (nextSelect.getOperatorTag() != LogicalOperatorTag.SELECT) {
            break;
        }
        // Remember the top-most op that we are not removing.
        topMostOp = selectParent;
        // Initialize the new conjuncts, if necessary.
        if (conj == null) {
            conj = new ScalarFunctionCallExpression(andFn);
            // Add the first select's condition.
            conj.getArguments().add(new MutableObject<ILogicalExpression>(firstSelect.getCondition().getValue()));
        }
        // Consolidate all following selects.
        do {
            // Add the condition nextSelect to the new list of conjuncts.
            conj.getArguments().add(((SelectOperator) nextSelect).getCondition());
            selectParent = nextSelect;
            nextSelect = (AbstractLogicalOperator) nextSelect.getInputs().get(0).getValue();
        } while (nextSelect.getOperatorTag() == LogicalOperatorTag.SELECT);
        // Hook up the input of the top-most remaining op if necessary.
        if (topMostOp.getOperatorTag() == LogicalOperatorTag.ASSIGN || topMostOp == firstSelect) {
            topMostOp.getInputs().set(0, selectParent.getInputs().get(0));
        }
        // Prepare for next iteration.
        nextSelect = selectParent;
    } while (true);
    // Did we consolidate any selects?
    if (conj == null) {
        return false;
    }
    // Set the new conjuncts.
    firstSelect.getCondition().setValue(conj);
    context.computeAndSetTypeEnvironmentForOperator(firstSelect);
    return true;
}
Also used : ILogicalExpression(org.apache.hyracks.algebricks.core.algebra.base.ILogicalExpression) SelectOperator(org.apache.hyracks.algebricks.core.algebra.operators.logical.SelectOperator) IFunctionInfo(org.apache.hyracks.algebricks.core.algebra.functions.IFunctionInfo) AbstractLogicalOperator(org.apache.hyracks.algebricks.core.algebra.operators.logical.AbstractLogicalOperator) AbstractFunctionCallExpression(org.apache.hyracks.algebricks.core.algebra.expressions.AbstractFunctionCallExpression) ScalarFunctionCallExpression(org.apache.hyracks.algebricks.core.algebra.expressions.ScalarFunctionCallExpression)

Example 7 with AbstractLogicalOperator

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

the class CopyLimitDownRule method rewritePre.

@Override
public boolean rewritePre(Mutable<ILogicalOperator> opRef, IOptimizationContext context) throws AlgebricksException {
    AbstractLogicalOperator op = (AbstractLogicalOperator) opRef.getValue();
    if (op.getOperatorTag() != LogicalOperatorTag.LIMIT) {
        return false;
    }
    LimitOperator limitOp = (LimitOperator) op;
    if (!limitOp.isTopmostLimitOp()) {
        return false;
    }
    List<LogicalVariable> limitUsedVars = new ArrayList<>();
    VariableUtilities.getUsedVariables(limitOp, limitUsedVars);
    Mutable<ILogicalOperator> safeOpRef = null;
    Mutable<ILogicalOperator> candidateOpRef = limitOp.getInputs().get(0);
    List<LogicalVariable> candidateProducedVars = new ArrayList<>();
    while (true) {
        candidateProducedVars.clear();
        ILogicalOperator candidateOp = candidateOpRef.getValue();
        LogicalOperatorTag candidateOpTag = candidateOp.getOperatorTag();
        if (candidateOp.getInputs().size() > 1 || !candidateOp.isMap() || candidateOpTag == LogicalOperatorTag.SELECT || candidateOpTag == LogicalOperatorTag.LIMIT || candidateOpTag == LogicalOperatorTag.UNNEST_MAP || !OperatorPropertiesUtil.disjoint(limitUsedVars, candidateProducedVars)) {
            break;
        }
        safeOpRef = candidateOpRef;
        candidateOpRef = safeOpRef.getValue().getInputs().get(0);
    }
    if (safeOpRef != null) {
        ILogicalOperator safeOp = safeOpRef.getValue();
        Mutable<ILogicalOperator> unsafeOpRef = safeOp.getInputs().get(0);
        ILogicalOperator unsafeOp = unsafeOpRef.getValue();
        LimitOperator limitCloneOp = null;
        if (limitOp.getOffset().getValue() == null) {
            limitCloneOp = new LimitOperator(limitOp.getMaxObjects().getValue(), false);
        } else {
            // Need to add an offset to the given limit value
            // since the original topmost limit will use the offset value.
            // We can't apply the offset multiple times.
            IFunctionInfo finfoAdd = context.getMetadataProvider().lookupFunction(AlgebricksBuiltinFunctions.NUMERIC_ADD);
            List<Mutable<ILogicalExpression>> addArgs = new ArrayList<>();
            addArgs.add(new MutableObject<ILogicalExpression>(limitOp.getMaxObjects().getValue().cloneExpression()));
            addArgs.add(new MutableObject<ILogicalExpression>(limitOp.getOffset().getValue().cloneExpression()));
            ScalarFunctionCallExpression maxPlusOffset = new ScalarFunctionCallExpression(finfoAdd, addArgs);
            limitCloneOp = new LimitOperator(maxPlusOffset, false);
        }
        limitCloneOp.setPhysicalOperator(new StreamLimitPOperator());
        limitCloneOp.getInputs().add(new MutableObject<ILogicalOperator>(unsafeOp));
        limitCloneOp.setExecutionMode(unsafeOp.getExecutionMode());
        OperatorPropertiesUtil.computeSchemaRecIfNull((AbstractLogicalOperator) unsafeOp);
        limitCloneOp.recomputeSchema();
        unsafeOpRef.setValue(limitCloneOp);
        context.computeAndSetTypeEnvironmentForOperator(limitCloneOp);
        context.addToDontApplySet(this, limitOp);
    }
    return safeOpRef != null;
}
Also used : LogicalVariable(org.apache.hyracks.algebricks.core.algebra.base.LogicalVariable) IFunctionInfo(org.apache.hyracks.algebricks.core.algebra.functions.IFunctionInfo) 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) ILogicalExpression(org.apache.hyracks.algebricks.core.algebra.base.ILogicalExpression) LimitOperator(org.apache.hyracks.algebricks.core.algebra.operators.logical.LimitOperator) LogicalOperatorTag(org.apache.hyracks.algebricks.core.algebra.base.LogicalOperatorTag) StreamLimitPOperator(org.apache.hyracks.algebricks.core.algebra.operators.physical.StreamLimitPOperator) ScalarFunctionCallExpression(org.apache.hyracks.algebricks.core.algebra.expressions.ScalarFunctionCallExpression)

Example 8 with AbstractLogicalOperator

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

the class ExtractFunctionsFromJoinConditionRule method rewritePost.

@Override
public boolean rewritePost(Mutable<ILogicalOperator> opRef, IOptimizationContext context) throws AlgebricksException {
    AbstractLogicalOperator op = (AbstractLogicalOperator) opRef.getValue();
    if (op.getOperatorTag() != LogicalOperatorTag.INNERJOIN && op.getOperatorTag() != LogicalOperatorTag.LEFTOUTERJOIN) {
        return false;
    }
    AbstractBinaryJoinOperator joinOp = (AbstractBinaryJoinOperator) op;
    ILogicalExpression expr = joinOp.getCondition().getValue();
    return assignFunctionExpressions(joinOp, expr, context);
}
Also used : ILogicalExpression(org.apache.hyracks.algebricks.core.algebra.base.ILogicalExpression) AbstractLogicalOperator(org.apache.hyracks.algebricks.core.algebra.operators.logical.AbstractLogicalOperator) AbstractBinaryJoinOperator(org.apache.hyracks.algebricks.core.algebra.operators.logical.AbstractBinaryJoinOperator)

Example 9 with AbstractLogicalOperator

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

the class IntroduceAggregateCombinerRule method rewritePost.

@Override
public boolean rewritePost(Mutable<ILogicalOperator> opRef, IOptimizationContext context) throws AlgebricksException {
    AbstractLogicalOperator op = (AbstractLogicalOperator) opRef.getValue();
    if (context.checkIfInDontApplySet(this, op)) {
        return false;
    }
    context.addToDontApplySet(this, op);
    if (op.getOperatorTag() != LogicalOperatorTag.AGGREGATE) {
        return false;
    }
    AggregateOperator aggOp = (AggregateOperator) op;
    if (!aggOp.isGlobal() || aggOp.getExecutionMode() == ExecutionMode.LOCAL) {
        return false;
    }
    Set<SimilarAggregatesInfo> toReplaceSet = new HashSet<SimilarAggregatesInfo>();
    Pair<Boolean, Mutable<ILogicalOperator>> result = tryToPushAgg(aggOp, null, toReplaceSet, context);
    if (!result.first || result.second == null) {
        return false;
    }
    replaceOriginalAggFuncs(toReplaceSet);
    context.computeAndSetTypeEnvironmentForOperator(aggOp);
    return true;
}
Also used : Mutable(org.apache.commons.lang3.mutable.Mutable) AbstractLogicalOperator(org.apache.hyracks.algebricks.core.algebra.operators.logical.AbstractLogicalOperator) AggregateOperator(org.apache.hyracks.algebricks.core.algebra.operators.logical.AggregateOperator) HashSet(java.util.HashSet)

Example 10 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)

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