Search in sources :

Example 46 with MutableObject

use of org.apache.commons.lang3.mutable.MutableObject in project asterixdb by apache.

the class SqlppExpressionToPlanTranslator method visit.

@Override
public Pair<ILogicalOperator, LogicalVariable> visit(HavingClause havingClause, Mutable<ILogicalOperator> tupSource) throws CompilationException {
    Pair<ILogicalExpression, Mutable<ILogicalOperator>> p = langExprToAlgExpression(havingClause.getFilterExpression(), tupSource);
    SelectOperator s = new SelectOperator(new MutableObject<ILogicalExpression>(p.first), false, null);
    s.getInputs().add(p.second);
    return new Pair<>(s, null);
}
Also used : 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) GbyVariableExpressionPair(org.apache.asterix.lang.common.expression.GbyVariableExpressionPair) Pair(org.apache.hyracks.algebricks.common.utils.Pair)

Example 47 with MutableObject

use of org.apache.commons.lang3.mutable.MutableObject in project asterixdb by apache.

the class EnforceOrderByAfterSubplan method rewritePost.

@Override
public boolean rewritePost(Mutable<ILogicalOperator> opRef, IOptimizationContext context) throws AlgebricksException {
    AbstractLogicalOperator op1 = (AbstractLogicalOperator) opRef.getValue();
    if (context.checkIfInDontApplySet(this, op1)) {
        return false;
    }
    List<Mutable<ILogicalOperator>> inputs = op1.getInputs();
    context.addToDontApplySet(this, op1);
    if (op1.getOperatorTag() == LogicalOperatorTag.ORDER || inputs == null) {
        /**
             * does not apply if
             * 1. there is yet-another order operator on-top-of the subplan, because the downstream order operator's ordering will be broken anyway
             * 2. the input operator(s) is null
             */
        return false;
    }
    boolean changed = false;
    for (int i = 0; i < inputs.size(); i++) {
        Mutable<ILogicalOperator> inputOpRef = inputs.get(i);
        AbstractLogicalOperator op = (AbstractLogicalOperator) inputOpRef.getValue();
        context.addToDontApplySet(this, op);
        if (op.getOperatorTag() != LogicalOperatorTag.SUBPLAN) {
            continue;
        }
        /**
             * check the order operators whose ordering is not broken before the subplan operator, and then
             * duplicate them on-top-of the subplan operator
             */
        boolean foundTarget = true;
        boolean orderSensitive = false;
        Mutable<ILogicalOperator> childRef = op.getInputs().get(0);
        AbstractLogicalOperator child = (AbstractLogicalOperator) childRef.getValue();
        while (child.getOperatorTag() != LogicalOperatorTag.ORDER) {
            context.addToDontApplySet(this, child);
            if (orderBreakingOps.contains(child.getOperatorTag())) {
                foundTarget = false;
                break;
            }
            if (child.getOperatorTag() == LogicalOperatorTag.GROUP) {
                foundTarget = false;
                break;
            }
            if (orderSensitiveOps.contains(child.getOperatorTag())) {
                orderSensitive = true;
            }
            List<Mutable<ILogicalOperator>> childInputs = child.getInputs();
            if (childInputs == null || childInputs.size() > 2 || childInputs.size() < 1) {
                foundTarget = false;
                break;
            } else {
                childRef = childInputs.get(0);
                child = (AbstractLogicalOperator) childRef.getValue();
            }
        }
        /** the target order-by operator has not been found. */
        if (!foundTarget) {
            return false;
        }
        /** copy the original order-by operator and insert on-top-of the subplan operator */
        context.addToDontApplySet(this, child);
        OrderOperator sourceOrderOp = (OrderOperator) child;
        for (Pair<IOrder, Mutable<ILogicalExpression>> expr : sourceOrderOp.getOrderExpressions()) {
            if (!expr.second.getValue().isFunctional()) {
                return false;
            }
        }
        List<Pair<IOrder, Mutable<ILogicalExpression>>> orderExprs = deepCopyOrderAndExpression(sourceOrderOp.getOrderExpressions());
        OrderOperator newOrderOp = new OrderOperator(orderExprs);
        context.addToDontApplySet(this, newOrderOp);
        inputs.set(i, new MutableObject<ILogicalOperator>(newOrderOp));
        newOrderOp.getInputs().add(inputOpRef);
        context.computeAndSetTypeEnvironmentForOperator(newOrderOp);
        if (!orderSensitive) {
            /** remove the original order-by */
            childRef.setValue(sourceOrderOp.getInputs().get(0).getValue());
        }
        changed = true;
    }
    return changed;
}
Also used : AbstractLogicalOperator(org.apache.hyracks.algebricks.core.algebra.operators.logical.AbstractLogicalOperator) IOrder(org.apache.hyracks.algebricks.core.algebra.operators.logical.OrderOperator.IOrder) ILogicalOperator(org.apache.hyracks.algebricks.core.algebra.base.ILogicalOperator) OrderOperator(org.apache.hyracks.algebricks.core.algebra.operators.logical.OrderOperator) Mutable(org.apache.commons.lang3.mutable.Mutable) ILogicalExpression(org.apache.hyracks.algebricks.core.algebra.base.ILogicalExpression) Pair(org.apache.hyracks.algebricks.common.utils.Pair)

Example 48 with MutableObject

use of org.apache.commons.lang3.mutable.MutableObject 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 49 with MutableObject

use of org.apache.commons.lang3.mutable.MutableObject 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 50 with MutableObject

use of org.apache.commons.lang3.mutable.MutableObject in project asterixdb by apache.

the class AbstractIntroduceCombinerRule method tryToPushAgg.

protected Pair<Boolean, Mutable<ILogicalOperator>> tryToPushAgg(AggregateOperator initAgg, GroupByOperator newGbyOp, Set<SimilarAggregatesInfo> toReplaceSet, IOptimizationContext context) throws AlgebricksException {
    ArrayList<LogicalVariable> pushedVars = new ArrayList<LogicalVariable>();
    ArrayList<Mutable<ILogicalExpression>> pushedExprs = new ArrayList<Mutable<ILogicalExpression>>();
    List<LogicalVariable> initVars = initAgg.getVariables();
    List<Mutable<ILogicalExpression>> initExprs = initAgg.getExpressions();
    int numExprs = initVars.size();
    // First make sure that all agg funcs are two step, otherwise we cannot use local aggs.
    for (int i = 0; i < numExprs; i++) {
        AggregateFunctionCallExpression aggFun = (AggregateFunctionCallExpression) initExprs.get(i).getValue();
        if (!aggFun.isTwoStep()) {
            return new Pair<Boolean, Mutable<ILogicalOperator>>(false, null);
        }
    }
    boolean haveAggToReplace = false;
    for (int i = 0; i < numExprs; i++) {
        Mutable<ILogicalExpression> expRef = initExprs.get(i);
        AggregateFunctionCallExpression aggFun = (AggregateFunctionCallExpression) expRef.getValue();
        IFunctionInfo fi1 = aggFun.getStepOneAggregate();
        // Clone the aggregate's args.
        List<Mutable<ILogicalExpression>> newArgs = new ArrayList<Mutable<ILogicalExpression>>(aggFun.getArguments().size());
        for (Mutable<ILogicalExpression> er : aggFun.getArguments()) {
            newArgs.add(new MutableObject<ILogicalExpression>(er.getValue().cloneExpression()));
        }
        IFunctionInfo fi2 = aggFun.getStepTwoAggregate();
        SimilarAggregatesInfo inf = new SimilarAggregatesInfo();
        LogicalVariable newAggVar = context.newVar();
        pushedVars.add(newAggVar);
        inf.stepOneResult = new VariableReferenceExpression(newAggVar);
        inf.simAggs = new ArrayList<AggregateExprInfo>();
        toReplaceSet.add(inf);
        AggregateFunctionCallExpression aggLocal = new AggregateFunctionCallExpression(fi1, false, newArgs);
        pushedExprs.add(new MutableObject<ILogicalExpression>(aggLocal));
        AggregateExprInfo aei = new AggregateExprInfo();
        aei.aggExprRef = expRef;
        aei.newFunInfo = fi2;
        inf.simAggs.add(aei);
        haveAggToReplace = true;
    }
    if (!pushedVars.isEmpty()) {
        AggregateOperator pushedAgg = new AggregateOperator(pushedVars, pushedExprs);
        pushedAgg.setExecutionMode(ExecutionMode.LOCAL);
        // If newGbyOp is null, then we optimizing an aggregate without group by.
        if (newGbyOp != null) {
            // Cut and paste nested input pipelines of initAgg to pushedAgg's input
            Mutable<ILogicalOperator> inputRef = initAgg.getInputs().get(0);
            Mutable<ILogicalOperator> bottomRef = inputRef;
            while (bottomRef.getValue().getInputs().size() > 0) {
                bottomRef = bottomRef.getValue().getInputs().get(0);
            }
            ILogicalOperator oldNts = bottomRef.getValue();
            initAgg.getInputs().clear();
            initAgg.getInputs().add(new MutableObject<ILogicalOperator>(oldNts));
            // Hook up the nested aggregate op with the outer group by.
            NestedTupleSourceOperator nts = new NestedTupleSourceOperator(new MutableObject<ILogicalOperator>(newGbyOp));
            nts.setExecutionMode(ExecutionMode.LOCAL);
            bottomRef.setValue(nts);
            pushedAgg.getInputs().add(inputRef);
        } else {
            // The local aggregate operator is fed by the input of the original aggregate operator.
            pushedAgg.getInputs().add(new MutableObject<ILogicalOperator>(initAgg.getInputs().get(0).getValue()));
            // Reintroduce assign op for the global agg partitioning var.
            initAgg.getInputs().get(0).setValue(pushedAgg);
            pushedAgg.setGlobal(false);
            context.computeAndSetTypeEnvironmentForOperator(pushedAgg);
        }
        return new Pair<Boolean, Mutable<ILogicalOperator>>(true, new MutableObject<ILogicalOperator>(pushedAgg));
    } else {
        return new Pair<Boolean, Mutable<ILogicalOperator>>(haveAggToReplace, null);
    }
}
Also used : LogicalVariable(org.apache.hyracks.algebricks.core.algebra.base.LogicalVariable) AggregateFunctionCallExpression(org.apache.hyracks.algebricks.core.algebra.expressions.AggregateFunctionCallExpression) NestedTupleSourceOperator(org.apache.hyracks.algebricks.core.algebra.operators.logical.NestedTupleSourceOperator) IFunctionInfo(org.apache.hyracks.algebricks.core.algebra.functions.IFunctionInfo) 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) VariableReferenceExpression(org.apache.hyracks.algebricks.core.algebra.expressions.VariableReferenceExpression) AggregateOperator(org.apache.hyracks.algebricks.core.algebra.operators.logical.AggregateOperator) Pair(org.apache.hyracks.algebricks.common.utils.Pair)

Aggregations

Mutable (org.apache.commons.lang3.mutable.Mutable)119 ILogicalExpression (org.apache.hyracks.algebricks.core.algebra.base.ILogicalExpression)113 MutableObject (org.apache.commons.lang3.mutable.MutableObject)111 LogicalVariable (org.apache.hyracks.algebricks.core.algebra.base.LogicalVariable)101 ArrayList (java.util.ArrayList)93 ILogicalOperator (org.apache.hyracks.algebricks.core.algebra.base.ILogicalOperator)91 VariableReferenceExpression (org.apache.hyracks.algebricks.core.algebra.expressions.VariableReferenceExpression)78 ScalarFunctionCallExpression (org.apache.hyracks.algebricks.core.algebra.expressions.ScalarFunctionCallExpression)54 AssignOperator (org.apache.hyracks.algebricks.core.algebra.operators.logical.AssignOperator)49 Pair (org.apache.hyracks.algebricks.common.utils.Pair)47 AbstractFunctionCallExpression (org.apache.hyracks.algebricks.core.algebra.expressions.AbstractFunctionCallExpression)46 ConstantExpression (org.apache.hyracks.algebricks.core.algebra.expressions.ConstantExpression)35 AbstractLogicalOperator (org.apache.hyracks.algebricks.core.algebra.operators.logical.AbstractLogicalOperator)29 GbyVariableExpressionPair (org.apache.asterix.lang.common.expression.GbyVariableExpressionPair)26 ILogicalPlan (org.apache.hyracks.algebricks.core.algebra.base.ILogicalPlan)25 List (java.util.List)23 AsterixConstantValue (org.apache.asterix.om.constants.AsterixConstantValue)23 AggregateFunctionCallExpression (org.apache.hyracks.algebricks.core.algebra.expressions.AggregateFunctionCallExpression)23 UnnestingFunctionCallExpression (org.apache.hyracks.algebricks.core.algebra.expressions.UnnestingFunctionCallExpression)23 AlgebricksException (org.apache.hyracks.algebricks.common.exceptions.AlgebricksException)22