Search in sources :

Example 86 with ILogicalOperator

use of org.apache.hyracks.algebricks.core.algebra.base.ILogicalOperator in project asterixdb by apache.

the class ComplexUnnestToProductRule method rewritePost.

@Override
public boolean rewritePost(Mutable<ILogicalOperator> opRef, IOptimizationContext context) throws AlgebricksException {
    AbstractLogicalOperator op = (AbstractLogicalOperator) opRef.getValue();
    if (op.getOperatorTag() != LogicalOperatorTag.DATASOURCESCAN && op.getOperatorTag() != LogicalOperatorTag.UNNEST) {
        return false;
    }
    //stop rewriting if the operators originates from a nested tuple source
    if (insideSubplan(opRef)) {
        return false;
    }
    // We may pull selects above the join we create in order to eliminate possible dependencies between
    // the outer and inner input plans of the join.
    List<ILogicalOperator> topSelects = new ArrayList<ILogicalOperator>();
    // Keep track of the operators and used variables participating in the inner input plan.
    HashSet<LogicalVariable> innerUsedVars = new HashSet<LogicalVariable>();
    List<ILogicalOperator> innerOps = new ArrayList<ILogicalOperator>();
    HashSet<LogicalVariable> outerUsedVars = new HashSet<LogicalVariable>();
    List<ILogicalOperator> outerOps = new ArrayList<ILogicalOperator>();
    innerOps.add(op);
    VariableUtilities.getUsedVariables(op, innerUsedVars);
    Mutable<ILogicalOperator> opRef2 = op.getInputs().get(0);
    AbstractLogicalOperator op2 = (AbstractLogicalOperator) opRef2.getValue();
    // Find an unnest or join and partition the plan between the first unnest and that operator into independent parts.
    if (!findPlanPartition(op2, innerUsedVars, outerUsedVars, innerOps, outerOps, topSelects, false)) {
        // We could not find an unnest or join.
        return false;
    }
    // The last operator must be an unnest or join.
    AbstractLogicalOperator unnestOrJoin = (AbstractLogicalOperator) outerOps.get(outerOps.size() - 1);
    ILogicalOperator outerRoot = null;
    ILogicalOperator innerRoot = null;
    EmptyTupleSourceOperator ets = new EmptyTupleSourceOperator();
    // If we found a join, simply use it as the outer root.
    if (unnestOrJoin.getOperatorTag() != LogicalOperatorTag.INNERJOIN && unnestOrJoin.getOperatorTag() != LogicalOperatorTag.LEFTOUTERJOIN) {
        // We've found a second unnest. First, sanity check that the unnest does not output any live variables
        // that are used by the plan above (until the first unnest).
        List<LogicalVariable> liveVars = new ArrayList<>();
        VariableUtilities.getLiveVariables(unnestOrJoin, liveVars);
        for (LogicalVariable liveVar : liveVars) {
            if (innerUsedVars.contains(liveVar)) {
                return false;
            }
        }
        // Continue finding a partitioning of the plan such that the inner and outer partitions are independent, in order to feed a join.
        // Now, we look below the second unnest or join.
        VariableUtilities.getUsedVariables(unnestOrJoin, outerUsedVars);
        AbstractLogicalOperator unnestChild = (AbstractLogicalOperator) unnestOrJoin.getInputs().get(0).getValue();
        if (!findPlanPartition(unnestChild, innerUsedVars, outerUsedVars, innerOps, outerOps, topSelects, true)) {
            // We could not find a suitable partitioning.
            return false;
        }
    }
    innerRoot = buildOperatorChain(innerOps, ets, context);
    context.computeAndSetTypeEnvironmentForOperator(innerRoot);
    outerRoot = buildOperatorChain(outerOps, null, context);
    context.computeAndSetTypeEnvironmentForOperator(outerRoot);
    InnerJoinOperator product = new InnerJoinOperator(new MutableObject<ILogicalExpression>(ConstantExpression.TRUE));
    // Outer branch.
    product.getInputs().add(new MutableObject<ILogicalOperator>(outerRoot));
    // Inner branch.
    product.getInputs().add(new MutableObject<ILogicalOperator>(innerRoot));
    context.computeAndSetTypeEnvironmentForOperator(product);
    // Put the selects on top of the join.
    ILogicalOperator topOp = product;
    if (!topSelects.isEmpty()) {
        topOp = buildOperatorChain(topSelects, product, context);
    }
    // Plug the selects + product in the plan.
    opRef.setValue(topOp);
    context.computeAndSetTypeEnvironmentForOperator(topOp);
    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) ILogicalExpression(org.apache.hyracks.algebricks.core.algebra.base.ILogicalExpression) EmptyTupleSourceOperator(org.apache.hyracks.algebricks.core.algebra.operators.logical.EmptyTupleSourceOperator) HashSet(java.util.HashSet)

Example 87 with ILogicalOperator

use of org.apache.hyracks.algebricks.core.algebra.base.ILogicalOperator in project asterixdb by apache.

the class ComplexUnnestToProductRule method insideSubplan.

/**
     * check whether the operator is inside a sub-plan
     *
     * @param nestedRootRef
     * @return true-if it is; false otherwise.
     */
private boolean insideSubplan(Mutable<ILogicalOperator> nestedRootRef) {
    AbstractLogicalOperator nestedRoot = (AbstractLogicalOperator) nestedRootRef.getValue();
    if (nestedRoot.getOperatorTag() == LogicalOperatorTag.NESTEDTUPLESOURCE) {
        return true;
    }
    List<Mutable<ILogicalOperator>> inputs = nestedRoot.getInputs();
    for (Mutable<ILogicalOperator> input : inputs) {
        if (insideSubplan(input)) {
            return true;
        }
    }
    return false;
}
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)

Example 88 with ILogicalOperator

use of org.apache.hyracks.algebricks.core.algebra.base.ILogicalOperator 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 89 with ILogicalOperator

use of org.apache.hyracks.algebricks.core.algebra.base.ILogicalOperator in project asterixdb by apache.

the class AbstractDecorrelationRule method buildVarExprList.

protected void buildVarExprList(Collection<LogicalVariable> vars, IOptimizationContext context, GroupByOperator g, List<Pair<LogicalVariable, Mutable<ILogicalExpression>>> outVeList) throws AlgebricksException {
    for (LogicalVariable ov : vars) {
        LogicalVariable newVar = context.newVar();
        ILogicalExpression varExpr = new VariableReferenceExpression(newVar);
        outVeList.add(new Pair<LogicalVariable, Mutable<ILogicalExpression>>(ov, new MutableObject<ILogicalExpression>(varExpr)));
        for (ILogicalPlan p : g.getNestedPlans()) {
            for (Mutable<ILogicalOperator> r : p.getRoots()) {
                OperatorManipulationUtil.substituteVarRec((AbstractLogicalOperator) r.getValue(), ov, newVar, true, context);
            }
        }
    }
}
Also used : LogicalVariable(org.apache.hyracks.algebricks.core.algebra.base.LogicalVariable) Mutable(org.apache.commons.lang3.mutable.Mutable) ILogicalExpression(org.apache.hyracks.algebricks.core.algebra.base.ILogicalExpression) VariableReferenceExpression(org.apache.hyracks.algebricks.core.algebra.expressions.VariableReferenceExpression) ILogicalOperator(org.apache.hyracks.algebricks.core.algebra.base.ILogicalOperator) ILogicalPlan(org.apache.hyracks.algebricks.core.algebra.base.ILogicalPlan) MutableObject(org.apache.commons.lang3.mutable.MutableObject)

Example 90 with ILogicalOperator

use of org.apache.hyracks.algebricks.core.algebra.base.ILogicalOperator in project asterixdb by apache.

the class AbstractExtractExprRule method extractExprIntoAssignOpRef.

protected LogicalVariable extractExprIntoAssignOpRef(ILogicalExpression gExpr, Mutable<ILogicalOperator> opRef2, IOptimizationContext context) throws AlgebricksException {
    LogicalVariable v = context.newVar();
    AssignOperator a = new AssignOperator(v, new MutableObject<ILogicalExpression>(gExpr));
    a.getInputs().add(new MutableObject<ILogicalOperator>(opRef2.getValue()));
    opRef2.setValue(a);
    if (gExpr.getExpressionTag() == LogicalExpressionTag.CONSTANT) {
        context.addNotToBeInlinedVar(v);
    }
    context.computeAndSetTypeEnvironmentForOperator(a);
    return v;
}
Also used : LogicalVariable(org.apache.hyracks.algebricks.core.algebra.base.LogicalVariable) ILogicalExpression(org.apache.hyracks.algebricks.core.algebra.base.ILogicalExpression) ILogicalOperator(org.apache.hyracks.algebricks.core.algebra.base.ILogicalOperator) AssignOperator(org.apache.hyracks.algebricks.core.algebra.operators.logical.AssignOperator)

Aggregations

ILogicalOperator (org.apache.hyracks.algebricks.core.algebra.base.ILogicalOperator)355 LogicalVariable (org.apache.hyracks.algebricks.core.algebra.base.LogicalVariable)196 ILogicalExpression (org.apache.hyracks.algebricks.core.algebra.base.ILogicalExpression)130 Mutable (org.apache.commons.lang3.mutable.Mutable)125 ArrayList (java.util.ArrayList)119 AbstractLogicalOperator (org.apache.hyracks.algebricks.core.algebra.operators.logical.AbstractLogicalOperator)117 VariableReferenceExpression (org.apache.hyracks.algebricks.core.algebra.expressions.VariableReferenceExpression)86 ILogicalPlan (org.apache.hyracks.algebricks.core.algebra.base.ILogicalPlan)73 AssignOperator (org.apache.hyracks.algebricks.core.algebra.operators.logical.AssignOperator)57 Pair (org.apache.hyracks.algebricks.common.utils.Pair)53 MutableObject (org.apache.commons.lang3.mutable.MutableObject)51 HashSet (java.util.HashSet)46 AbstractFunctionCallExpression (org.apache.hyracks.algebricks.core.algebra.expressions.AbstractFunctionCallExpression)43 ScalarFunctionCallExpression (org.apache.hyracks.algebricks.core.algebra.expressions.ScalarFunctionCallExpression)36 GroupByOperator (org.apache.hyracks.algebricks.core.algebra.operators.logical.GroupByOperator)36 RecordDescriptor (org.apache.hyracks.api.dataflow.value.RecordDescriptor)33 AlgebricksException (org.apache.hyracks.algebricks.common.exceptions.AlgebricksException)29 AggregateOperator (org.apache.hyracks.algebricks.core.algebra.operators.logical.AggregateOperator)28 SubplanOperator (org.apache.hyracks.algebricks.core.algebra.operators.logical.SubplanOperator)26 AggregateFunctionCallExpression (org.apache.hyracks.algebricks.core.algebra.expressions.AggregateFunctionCallExpression)25