Search in sources :

Example 1 with AggregateOperator

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

the class CountVarToCountOneRule method rewritePost.

// It is only for a group-by having just one aggregate which is a count.
@Override
public boolean rewritePost(Mutable<ILogicalOperator> opRef, IOptimizationContext context) throws AlgebricksException {
    AbstractLogicalOperator op1 = (AbstractLogicalOperator) opRef.getValue();
    if (op1.getOperatorTag() != LogicalOperatorTag.GROUP) {
        return false;
    }
    GroupByOperator g = (GroupByOperator) op1;
    if (g.getNestedPlans().size() != 1) {
        return false;
    }
    ILogicalPlan p = g.getNestedPlans().get(0);
    if (p.getRoots().size() != 1) {
        return false;
    }
    AbstractLogicalOperator op2 = (AbstractLogicalOperator) p.getRoots().get(0).getValue();
    if (op2.getOperatorTag() != LogicalOperatorTag.AGGREGATE) {
        return false;
    }
    AggregateOperator agg = (AggregateOperator) op2;
    if (agg.getExpressions().size() != 1) {
        return false;
    }
    ILogicalExpression exp2 = agg.getExpressions().get(0).getValue();
    if (exp2.getExpressionTag() != LogicalExpressionTag.FUNCTION_CALL) {
        return false;
    }
    AbstractFunctionCallExpression fun = (AbstractFunctionCallExpression) exp2;
    if (fun.getFunctionIdentifier() != BuiltinFunctions.COUNT) {
        return false;
    }
    ILogicalExpression exp3 = fun.getArguments().get(0).getValue();
    if (exp3.getExpressionTag() != LogicalExpressionTag.VARIABLE) {
        return false;
    }
    if (((AbstractLogicalOperator) agg.getInputs().get(0).getValue()).getOperatorTag() != LogicalOperatorTag.NESTEDTUPLESOURCE) {
        return false;
    }
    fun.getArguments().get(0).setValue(new ConstantExpression(new AsterixConstantValue(new AInt64(1L))));
    return true;
}
Also used : ILogicalExpression(org.apache.hyracks.algebricks.core.algebra.base.ILogicalExpression) GroupByOperator(org.apache.hyracks.algebricks.core.algebra.operators.logical.GroupByOperator) AbstractLogicalOperator(org.apache.hyracks.algebricks.core.algebra.operators.logical.AbstractLogicalOperator) AsterixConstantValue(org.apache.asterix.om.constants.AsterixConstantValue) AbstractFunctionCallExpression(org.apache.hyracks.algebricks.core.algebra.expressions.AbstractFunctionCallExpression) ConstantExpression(org.apache.hyracks.algebricks.core.algebra.expressions.ConstantExpression) AggregateOperator(org.apache.hyracks.algebricks.core.algebra.operators.logical.AggregateOperator) ILogicalPlan(org.apache.hyracks.algebricks.core.algebra.base.ILogicalPlan) AInt64(org.apache.asterix.om.base.AInt64)

Example 2 with AggregateOperator

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

the class PushAggregateIntoNestedSubplanRule method removeRedundantListifies.

private void removeRedundantListifies(Map<LogicalVariable, Integer> nspAggVars, Map<LogicalVariable, AbstractOperatorWithNestedPlans> nspWithAgg, Map<LogicalVariable, Integer> nspAggVarToPlanIndex) throws AlgebricksException {
    List<Pair<AbstractOperatorWithNestedPlans, Integer>> removeList = new ArrayList<>();
    for (Map.Entry<LogicalVariable, Integer> aggVarEntry : nspAggVars.entrySet()) {
        LogicalVariable aggVar = aggVarEntry.getKey();
        int occurs = aggVarEntry.getValue();
        if (occurs == 0) {
            AbstractOperatorWithNestedPlans nspOp = nspWithAgg.get(aggVar);
            AggregateOperator aggOp = (AggregateOperator) nspOp.getNestedPlans().get(nspAggVarToPlanIndex.get(aggVar)).getRoots().get(0).getValue();
            int pos = aggOp.getVariables().indexOf(aggVar);
            if (pos >= 0) {
                aggOp.getVariables().remove(pos);
                aggOp.getExpressions().remove(pos);
                List<LogicalVariable> producedVarsAtAgg = new ArrayList<>();
                VariableUtilities.getProducedVariablesInDescendantsAndSelf(aggOp, producedVarsAtAgg);
                if (producedVarsAtAgg.isEmpty()) {
                    removeList.add(new Pair<>(nspOp, nspAggVarToPlanIndex.get(aggVar)));
                }
            }
        }
    }
    // Collects subplans that is to be removed.
    Map<AbstractOperatorWithNestedPlans, List<ILogicalPlan>> nspToSubplanListMap = new HashMap<>();
    for (Pair<AbstractOperatorWithNestedPlans, Integer> remove : removeList) {
        AbstractOperatorWithNestedPlans groupByOperator = remove.first;
        ILogicalPlan subplan = remove.first.getNestedPlans().get(remove.second);
        if (nspToSubplanListMap.containsKey(groupByOperator)) {
            List<ILogicalPlan> subplans = nspToSubplanListMap.get(groupByOperator);
            subplans.add(subplan);
        } else {
            List<ILogicalPlan> subplans = new ArrayList<>();
            subplans.add(subplan);
            nspToSubplanListMap.put(groupByOperator, subplans);
        }
    }
    // Removes subplans.
    for (Map.Entry<AbstractOperatorWithNestedPlans, List<ILogicalPlan>> entry : nspToSubplanListMap.entrySet()) {
        entry.getKey().getNestedPlans().removeAll(entry.getValue());
    }
}
Also used : LogicalVariable(org.apache.hyracks.algebricks.core.algebra.base.LogicalVariable) HashMap(java.util.HashMap) ArrayList(java.util.ArrayList) AggregateOperator(org.apache.hyracks.algebricks.core.algebra.operators.logical.AggregateOperator) ILogicalPlan(org.apache.hyracks.algebricks.core.algebra.base.ILogicalPlan) ArrayList(java.util.ArrayList) List(java.util.List) HashMap(java.util.HashMap) Map(java.util.Map) Pair(org.apache.hyracks.algebricks.common.utils.Pair) AbstractOperatorWithNestedPlans(org.apache.hyracks.algebricks.core.algebra.operators.logical.AbstractOperatorWithNestedPlans)

Example 3 with AggregateOperator

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

the class PushAggregateIntoNestedSubplanRule method rewriteAggregateInNestedSubplan.

private void rewriteAggregateInNestedSubplan(LogicalVariable oldAggVar, AbstractOperatorWithNestedPlans nspOp, AggregateFunctionCallExpression aggFun, LogicalVariable newAggVar, IOptimizationContext context) throws AlgebricksException {
    for (int j = 0; j < nspOp.getNestedPlans().size(); j++) {
        AggregateOperator aggOp = (AggregateOperator) nspOp.getNestedPlans().get(j).getRoots().get(0).getValue();
        int n = aggOp.getVariables().size();
        for (int i = 0; i < n; i++) {
            LogicalVariable v = aggOp.getVariables().get(i);
            if (v.equals(oldAggVar)) {
                AbstractFunctionCallExpression oldAggExpr = (AbstractFunctionCallExpression) aggOp.getExpressions().get(i).getValue();
                AggregateFunctionCallExpression newAggFun = BuiltinFunctions.makeAggregateFunctionExpression(aggFun.getFunctionIdentifier(), new ArrayList<>());
                for (Mutable<ILogicalExpression> arg : oldAggExpr.getArguments()) {
                    ILogicalExpression cloned = arg.getValue().cloneExpression();
                    newAggFun.getArguments().add(new MutableObject<>(cloned));
                }
                aggOp.getVariables().add(newAggVar);
                aggOp.getExpressions().add(new MutableObject<>(newAggFun));
                context.computeAndSetTypeEnvironmentForOperator(aggOp);
                break;
            }
        }
    }
}
Also used : LogicalVariable(org.apache.hyracks.algebricks.core.algebra.base.LogicalVariable) AggregateFunctionCallExpression(org.apache.hyracks.algebricks.core.algebra.expressions.AggregateFunctionCallExpression) ILogicalExpression(org.apache.hyracks.algebricks.core.algebra.base.ILogicalExpression) AbstractFunctionCallExpression(org.apache.hyracks.algebricks.core.algebra.expressions.AbstractFunctionCallExpression) AggregateOperator(org.apache.hyracks.algebricks.core.algebra.operators.logical.AggregateOperator)

Example 4 with AggregateOperator

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

the class PushAggregateIntoNestedSubplanRule method pushSubplanAsAggIntoNestedSubplan.

private boolean pushSubplanAsAggIntoNestedSubplan(Mutable<ILogicalOperator> subplanOpRef, AbstractOperatorWithNestedPlans nspOp, LogicalVariable varFromNestedAgg, Map<LogicalVariable, Integer> nspAggVars, Map<LogicalVariable, AbstractOperatorWithNestedPlans> nspWithAgg, Map<LogicalVariable, Integer> nspAggVarToPlanIndex, IOptimizationContext context) throws AlgebricksException {
    SubplanOperator subplan = (SubplanOperator) subplanOpRef.getValue();
    // only free var can be varFromNestedAgg
    HashSet<LogicalVariable> freeVars = new HashSet<>();
    OperatorPropertiesUtil.getFreeVariablesInSubplans(subplan, freeVars);
    for (LogicalVariable vFree : freeVars) {
        if (!vFree.equals(varFromNestedAgg)) {
            return false;
        }
    }
    List<ILogicalPlan> plans = subplan.getNestedPlans();
    if (plans.size() > 1) {
        return false;
    }
    ILogicalPlan p = plans.get(0);
    if (p.getRoots().size() > 1) {
        return false;
    }
    Mutable<ILogicalOperator> opRef = p.getRoots().get(0);
    AbstractLogicalOperator op = (AbstractLogicalOperator) opRef.getValue();
    if (op.getOperatorTag() != LogicalOperatorTag.AGGREGATE) {
        return false;
    }
    AggregateOperator aggInSubplanOp = (AggregateOperator) op;
    LogicalVariable unnestVar = null;
    boolean pushableNestedSubplan = false;
    while (op.getInputs().size() == 1) {
        opRef = op.getInputs().get(0);
        op = (AbstractLogicalOperator) opRef.getValue();
        switch(op.getOperatorTag()) {
            case ASSIGN:
                break;
            case UNNEST:
                UnnestOperator unnest = (UnnestOperator) op;
                if (unnest.getPositionalVariable() != null) {
                    // TODO currently subplan with both accumulating and running aggregate is not supported.
                    return false;
                }
                ILogicalExpression expr = unnest.getExpressionRef().getValue();
                if (expr.getExpressionTag() != LogicalExpressionTag.FUNCTION_CALL) {
                    return false;
                }
                AbstractFunctionCallExpression fun = (AbstractFunctionCallExpression) expr;
                if (fun.getFunctionIdentifier() != BuiltinFunctions.SCAN_COLLECTION) {
                    return false;
                }
                ILogicalExpression arg0 = fun.getArguments().get(0).getValue();
                if (arg0.getExpressionTag() != LogicalExpressionTag.VARIABLE) {
                    return false;
                }
                VariableReferenceExpression varExpr = (VariableReferenceExpression) arg0;
                if (!varExpr.getVariableReference().equals(varFromNestedAgg)) {
                    return false;
                }
                opRef = op.getInputs().get(0);
                op = (AbstractLogicalOperator) opRef.getValue();
                if (op.getOperatorTag() != LogicalOperatorTag.NESTEDTUPLESOURCE) {
                    return false;
                }
                pushableNestedSubplan = true;
                unnestVar = unnest.getVariable();
                break;
            default:
                return false;
        }
    }
    if (!pushableNestedSubplan) {
        return false;
    }
    for (int i = 0; i < nspOp.getNestedPlans().size(); i++) {
        Mutable<ILogicalOperator> nspAggRef = nspOp.getNestedPlans().get(i).getRoots().get(0);
        AggregateOperator nspAgg = (AggregateOperator) nspAggRef.getValue();
        Mutable<ILogicalOperator> nspAggChildRef = nspAgg.getInputs().get(0);
        LogicalVariable listifyVar = findListifiedVariable(nspAgg, varFromNestedAgg);
        if (listifyVar == null) {
            continue;
        }
        OperatorManipulationUtil.substituteVarRec(aggInSubplanOp, unnestVar, listifyVar, true, context);
        nspAgg.getVariables().addAll(aggInSubplanOp.getVariables());
        nspAgg.getExpressions().addAll(aggInSubplanOp.getExpressions());
        for (LogicalVariable v : aggInSubplanOp.getVariables()) {
            nspWithAgg.put(v, nspOp);
            nspAggVars.put(v, 0);
            nspAggVarToPlanIndex.put(v, i);
        }
        Mutable<ILogicalOperator> opRef1InSubplan = aggInSubplanOp.getInputs().get(0);
        if (!opRef1InSubplan.getValue().getInputs().isEmpty()) {
            Mutable<ILogicalOperator> opRef2InSubplan = opRef1InSubplan.getValue().getInputs().get(0);
            AbstractLogicalOperator op2InSubplan = (AbstractLogicalOperator) opRef2InSubplan.getValue();
            if (op2InSubplan.getOperatorTag() != LogicalOperatorTag.NESTEDTUPLESOURCE) {
                List<Mutable<ILogicalOperator>> nspInpList = nspAgg.getInputs();
                nspInpList.clear();
                nspInpList.add(opRef1InSubplan);
                while (true) {
                    opRef2InSubplan = opRef1InSubplan.getValue().getInputs().get(0);
                    op2InSubplan = (AbstractLogicalOperator) opRef2InSubplan.getValue();
                    if (op2InSubplan.getOperatorTag() == LogicalOperatorTag.UNNEST) {
                        List<Mutable<ILogicalOperator>> opInpList = opRef1InSubplan.getValue().getInputs();
                        opInpList.clear();
                        opInpList.add(nspAggChildRef);
                        break;
                    }
                    opRef1InSubplan = opRef2InSubplan;
                    if (opRef1InSubplan.getValue().getInputs().isEmpty()) {
                        throw new IllegalStateException("PushAggregateIntoNestedSubplanRule: could not find UNNEST.");
                    }
                }
            }
        }
        subplanOpRef.setValue(subplan.getInputs().get(0).getValue());
        OperatorPropertiesUtil.typeOpRec(nspAggRef, 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) AbstractFunctionCallExpression(org.apache.hyracks.algebricks.core.algebra.expressions.AbstractFunctionCallExpression) SubplanOperator(org.apache.hyracks.algebricks.core.algebra.operators.logical.SubplanOperator) UnnestOperator(org.apache.hyracks.algebricks.core.algebra.operators.logical.UnnestOperator) 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) ILogicalPlan(org.apache.hyracks.algebricks.core.algebra.base.ILogicalPlan) HashSet(java.util.HashSet)

Example 5 with AggregateOperator

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

the class RemoveRedundantListifyRule method applies.

private boolean applies(Mutable<ILogicalOperator> opRef, Set<LogicalVariable> varUsedAbove, IOptimizationContext context) throws AlgebricksException {
    AbstractLogicalOperator op1 = (AbstractLogicalOperator) opRef.getValue();
    if (op1.getOperatorTag() != LogicalOperatorTag.UNNEST) {
        return false;
    }
    UnnestOperator unnest1 = (UnnestOperator) op1;
    ILogicalExpression expr = unnest1.getExpressionRef().getValue();
    if (expr.getExpressionTag() != LogicalExpressionTag.FUNCTION_CALL) {
        return false;
    }
    if (((AbstractFunctionCallExpression) expr).getFunctionIdentifier() != BuiltinFunctions.SCAN_COLLECTION) {
        return false;
    }
    AbstractFunctionCallExpression functionCall = (AbstractFunctionCallExpression) expr;
    ILogicalExpression functionCallArgExpr = functionCall.getArguments().get(0).getValue();
    if (functionCallArgExpr.getExpressionTag() != LogicalExpressionTag.VARIABLE) {
        return false;
    }
    LogicalVariable unnestedVar = ((VariableReferenceExpression) functionCallArgExpr).getVariableReference();
    if (varUsedAbove.contains(unnestedVar)) {
        return false;
    }
    Mutable<ILogicalOperator> aggregateParentRef = opRef;
    AbstractLogicalOperator r = op1;
    boolean metAggregate = false;
    while (r.getInputs().size() == 1) {
        aggregateParentRef = r.getInputs().get(0);
        r = (AbstractLogicalOperator) aggregateParentRef.getValue();
        if (r.getOperatorTag() == LogicalOperatorTag.ASSIGN) {
            AssignOperator assign = (AssignOperator) r;
            List<LogicalVariable> variables = assign.getVariables();
            // The assign operator doesn't produce any variable that is used by the unnest.
            if (variables.contains(unnestedVar)) {
                return false;
            }
        } else {
            if (r.getOperatorTag() == LogicalOperatorTag.AGGREGATE) {
                metAggregate = true;
            }
            break;
        }
    }
    if (!metAggregate) {
        return false;
    }
    AggregateOperator agg = (AggregateOperator) r;
    if (agg.getVariables().size() > 1) {
        return false;
    }
    LogicalVariable aggVar = agg.getVariables().get(0);
    ILogicalExpression aggFun = agg.getExpressions().get(0).getValue();
    if (!aggVar.equals(unnestedVar) || ((AbstractLogicalExpression) aggFun).getExpressionTag() != LogicalExpressionTag.FUNCTION_CALL) {
        return false;
    }
    AbstractFunctionCallExpression f = (AbstractFunctionCallExpression) aggFun;
    if (!BuiltinFunctions.LISTIFY.equals(f.getFunctionIdentifier())) {
        return false;
    }
    if (f.getArguments().size() != 1) {
        return false;
    }
    ILogicalExpression arg0 = f.getArguments().get(0).getValue();
    if (((AbstractLogicalExpression) arg0).getExpressionTag() != LogicalExpressionTag.VARIABLE) {
        return false;
    }
    LogicalVariable paramVar = ((VariableReferenceExpression) arg0).getVariableReference();
    List<LogicalVariable> assgnVars = new ArrayList<>(1);
    assgnVars.add(unnest1.getVariable());
    List<Mutable<ILogicalExpression>> assgnExprs = new ArrayList<>(1);
    assgnExprs.add(new MutableObject<ILogicalExpression>(new VariableReferenceExpression(paramVar)));
    AssignOperator assign = new AssignOperator(assgnVars, assgnExprs);
    assign.getInputs().add(agg.getInputs().get(0));
    context.computeAndSetTypeEnvironmentForOperator(assign);
    LogicalVariable posVar = unnest1.getPositionalVariable();
    if (posVar == null) {
        // Removes the aggregate operator.
        aggregateParentRef.setValue(assign);
    } else {
        List<LogicalVariable> raggVars = new ArrayList<>(1);
        raggVars.add(posVar);
        List<Mutable<ILogicalExpression>> rAggExprs = new ArrayList<>(1);
        StatefulFunctionCallExpression tidFun = new StatefulFunctionCallExpression(FunctionUtil.getFunctionInfo(BuiltinFunctions.TID), UnpartitionedPropertyComputer.INSTANCE);
        rAggExprs.add(new MutableObject<ILogicalExpression>(tidFun));
        RunningAggregateOperator rAgg = new RunningAggregateOperator(raggVars, rAggExprs);
        rAgg.getInputs().add(new MutableObject<ILogicalOperator>(assign));
        aggregateParentRef.setValue(rAgg);
        context.computeAndSetTypeEnvironmentForOperator(rAgg);
    }
    // Removes the unnest operator.
    opRef.setValue(unnest1.getInputs().get(0).getValue());
    return true;
}
Also used : LogicalVariable(org.apache.hyracks.algebricks.core.algebra.base.LogicalVariable) AbstractLogicalOperator(org.apache.hyracks.algebricks.core.algebra.operators.logical.AbstractLogicalOperator) AbstractLogicalExpression(org.apache.hyracks.algebricks.core.algebra.expressions.AbstractLogicalExpression) StatefulFunctionCallExpression(org.apache.hyracks.algebricks.core.algebra.expressions.StatefulFunctionCallExpression) AbstractFunctionCallExpression(org.apache.hyracks.algebricks.core.algebra.expressions.AbstractFunctionCallExpression) ILogicalOperator(org.apache.hyracks.algebricks.core.algebra.base.ILogicalOperator) ArrayList(java.util.ArrayList) AssignOperator(org.apache.hyracks.algebricks.core.algebra.operators.logical.AssignOperator) UnnestOperator(org.apache.hyracks.algebricks.core.algebra.operators.logical.UnnestOperator) 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) RunningAggregateOperator(org.apache.hyracks.algebricks.core.algebra.operators.logical.RunningAggregateOperator) RunningAggregateOperator(org.apache.hyracks.algebricks.core.algebra.operators.logical.RunningAggregateOperator)

Aggregations

AggregateOperator (org.apache.hyracks.algebricks.core.algebra.operators.logical.AggregateOperator)40 ILogicalOperator (org.apache.hyracks.algebricks.core.algebra.base.ILogicalOperator)28 LogicalVariable (org.apache.hyracks.algebricks.core.algebra.base.LogicalVariable)28 ILogicalExpression (org.apache.hyracks.algebricks.core.algebra.base.ILogicalExpression)23 Mutable (org.apache.commons.lang3.mutable.Mutable)21 ILogicalPlan (org.apache.hyracks.algebricks.core.algebra.base.ILogicalPlan)21 AbstractLogicalOperator (org.apache.hyracks.algebricks.core.algebra.operators.logical.AbstractLogicalOperator)20 ArrayList (java.util.ArrayList)19 VariableReferenceExpression (org.apache.hyracks.algebricks.core.algebra.expressions.VariableReferenceExpression)17 GroupByOperator (org.apache.hyracks.algebricks.core.algebra.operators.logical.GroupByOperator)14 AggregateFunctionCallExpression (org.apache.hyracks.algebricks.core.algebra.expressions.AggregateFunctionCallExpression)13 AbstractFunctionCallExpression (org.apache.hyracks.algebricks.core.algebra.expressions.AbstractFunctionCallExpression)10 AssignOperator (org.apache.hyracks.algebricks.core.algebra.operators.logical.AssignOperator)10 NestedTupleSourceOperator (org.apache.hyracks.algebricks.core.algebra.operators.logical.NestedTupleSourceOperator)10 UnnestOperator (org.apache.hyracks.algebricks.core.algebra.operators.logical.UnnestOperator)10 MutableObject (org.apache.commons.lang3.mutable.MutableObject)9 Pair (org.apache.hyracks.algebricks.common.utils.Pair)9 SubplanOperator (org.apache.hyracks.algebricks.core.algebra.operators.logical.SubplanOperator)7 HashSet (java.util.HashSet)6 AlgebricksException (org.apache.hyracks.algebricks.common.exceptions.AlgebricksException)6