Search in sources :

Example 51 with MutableObject

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

the class ExtractFunctionsFromJoinConditionRule method assignFunctionExpressions.

private boolean assignFunctionExpressions(AbstractLogicalOperator joinOp, ILogicalExpression expr, IOptimizationContext context) throws AlgebricksException {
    if (expr.getExpressionTag() != LogicalExpressionTag.FUNCTION_CALL) {
        return false;
    }
    AbstractFunctionCallExpression fexp = (AbstractFunctionCallExpression) expr;
    FunctionIdentifier fi = fexp.getFunctionIdentifier();
    boolean modified = false;
    if (fi.equals(AlgebricksBuiltinFunctions.AND) || fi.equals(AlgebricksBuiltinFunctions.OR) || processArgumentsToFunction(fi)) {
        for (Mutable<ILogicalExpression> a : fexp.getArguments()) {
            if (assignFunctionExpressions(joinOp, a.getValue(), context)) {
                modified = true;
            }
        }
        return modified;
    } else if (AlgebricksBuiltinFunctions.isComparisonFunction(fi) || isComparisonFunction(fi)) {
        for (Mutable<ILogicalExpression> exprRef : fexp.getArguments()) {
            if (exprRef.getValue().getExpressionTag() == LogicalExpressionTag.FUNCTION_CALL) {
                LogicalVariable newVar = context.newVar();
                AssignOperator newAssign = new AssignOperator(newVar, new MutableObject<ILogicalExpression>(exprRef.getValue().cloneExpression()));
                newAssign.setExecutionMode(joinOp.getExecutionMode());
                // Place assign below joinOp.
                List<LogicalVariable> used = new ArrayList<LogicalVariable>();
                VariableUtilities.getUsedVariables(newAssign, used);
                Mutable<ILogicalOperator> leftBranchRef = joinOp.getInputs().get(0);
                ILogicalOperator leftBranch = leftBranchRef.getValue();
                List<LogicalVariable> leftBranchVariables = new ArrayList<LogicalVariable>();
                VariableUtilities.getLiveVariables(leftBranch, leftBranchVariables);
                if (leftBranchVariables.containsAll(used)) {
                    // place assign on left branch
                    newAssign.getInputs().add(new MutableObject<ILogicalOperator>(leftBranch));
                    leftBranchRef.setValue(newAssign);
                    modified = true;
                } else {
                    Mutable<ILogicalOperator> rightBranchRef = joinOp.getInputs().get(1);
                    ILogicalOperator rightBranch = rightBranchRef.getValue();
                    List<LogicalVariable> rightBranchVariables = new ArrayList<LogicalVariable>();
                    VariableUtilities.getLiveVariables(rightBranch, rightBranchVariables);
                    if (rightBranchVariables.containsAll(used)) {
                        // place assign on right branch
                        newAssign.getInputs().add(new MutableObject<ILogicalOperator>(rightBranch));
                        rightBranchRef.setValue(newAssign);
                        modified = true;
                    }
                }
                if (modified) {
                    // Replace original expr with variable reference.
                    exprRef.setValue(new VariableReferenceExpression(newVar));
                    context.computeAndSetTypeEnvironmentForOperator(newAssign);
                    context.computeAndSetTypeEnvironmentForOperator(joinOp);
                }
            }
        }
        return modified;
    } else {
        return false;
    }
}
Also used : LogicalVariable(org.apache.hyracks.algebricks.core.algebra.base.LogicalVariable) AbstractFunctionCallExpression(org.apache.hyracks.algebricks.core.algebra.expressions.AbstractFunctionCallExpression) ILogicalOperator(org.apache.hyracks.algebricks.core.algebra.base.ILogicalOperator) AssignOperator(org.apache.hyracks.algebricks.core.algebra.operators.logical.AssignOperator) FunctionIdentifier(org.apache.hyracks.algebricks.core.algebra.functions.FunctionIdentifier) 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) ArrayList(java.util.ArrayList) List(java.util.List) MutableObject(org.apache.commons.lang3.mutable.MutableObject)

Example 52 with MutableObject

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

the class ExtractGroupByDecorVariablesRule method rewritePost.

@Override
public boolean rewritePost(Mutable<ILogicalOperator> opRef, IOptimizationContext context) throws AlgebricksException {
    ILogicalOperator op = opRef.getValue();
    if (op.getOperatorTag() != LogicalOperatorTag.GROUP) {
        return false;
    }
    GroupByOperator groupByOperator = (GroupByOperator) op;
    List<Pair<LogicalVariable, Mutable<ILogicalExpression>>> decorList = groupByOperator.getDecorList();
    // Returns immediately if there is no decoration entry.
    if (groupByOperator.getDecorList() == null || groupByOperator.getDecorList().isEmpty()) {
        return false;
    }
    // Goes over the decoration list and performs the rewrite.
    boolean changed = false;
    List<LogicalVariable> vars = new ArrayList<>();
    List<Mutable<ILogicalExpression>> exprs = new ArrayList<>();
    for (Pair<LogicalVariable, Mutable<ILogicalExpression>> decorVarExpr : decorList) {
        Mutable<ILogicalExpression> exprRef = decorVarExpr.second;
        ILogicalExpression expr = exprRef.getValue();
        if (expr == null || expr.getExpressionTag() == LogicalExpressionTag.VARIABLE) {
            continue;
        }
        // Rewrites the decoration entry if the decoration expression is not a variable reference expression.
        changed = true;
        LogicalVariable newVar = context.newVar();
        vars.add(newVar);
        exprs.add(exprRef);
        // Normalizes the decor entry -- expression be a variable reference
        decorVarExpr.second = new MutableObject<>(new VariableReferenceExpression(newVar));
    }
    if (!changed) {
        return false;
    }
    // Injects an assign operator to evaluate the decoration expression.
    AssignOperator assignOperator = new AssignOperator(vars, exprs);
    assignOperator.getInputs().addAll(op.getInputs());
    op.getInputs().set(0, new MutableObject<>(assignOperator));
    return changed;
}
Also used : LogicalVariable(org.apache.hyracks.algebricks.core.algebra.base.LogicalVariable) GroupByOperator(org.apache.hyracks.algebricks.core.algebra.operators.logical.GroupByOperator) ILogicalOperator(org.apache.hyracks.algebricks.core.algebra.base.ILogicalOperator) ArrayList(java.util.ArrayList) AssignOperator(org.apache.hyracks.algebricks.core.algebra.operators.logical.AssignOperator) 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) Pair(org.apache.hyracks.algebricks.common.utils.Pair)

Example 53 with MutableObject

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

the class AbstractIntroduceGroupByCombinerRule method tryToPushRoot.

private boolean tryToPushRoot(Mutable<ILogicalOperator> root, GroupByOperator oldGbyOp, GroupByOperator newGbyOp, BookkeepingInfo bi, List<LogicalVariable> gbyVars, IOptimizationContext context, List<Mutable<ILogicalOperator>> toPushAccumulate, Set<SimilarAggregatesInfo> toReplaceSet) throws AlgebricksException {
    AbstractLogicalOperator op1 = (AbstractLogicalOperator) root.getValue();
    if (op1.getOperatorTag() != LogicalOperatorTag.AGGREGATE) {
        return false;
    }
    AbstractLogicalOperator op2 = (AbstractLogicalOperator) op1.getInputs().get(0).getValue();
    // Finds nested group-by if any.
    AbstractLogicalOperator op3 = op2;
    while (op3.getOperatorTag() != LogicalOperatorTag.GROUP && op3.getInputs().size() == 1) {
        op3 = (AbstractLogicalOperator) op3.getInputs().get(0).getValue();
    }
    if (op3.getOperatorTag() != LogicalOperatorTag.GROUP) {
        AggregateOperator initAgg = (AggregateOperator) op1;
        Pair<Boolean, Mutable<ILogicalOperator>> pOpRef = tryToPushAgg(initAgg, newGbyOp, toReplaceSet, context);
        if (!pOpRef.first) {
            return false;
        }
        Mutable<ILogicalOperator> opRef = pOpRef.second;
        if (opRef != null) {
            toPushAccumulate.add(opRef);
        }
        bi.modifyGbyMap.put(oldGbyOp, gbyVars);
        return true;
    } else {
        GroupByOperator nestedGby = (GroupByOperator) op3;
        List<LogicalVariable> gbyVars2 = nestedGby.getGbyVarList();
        Set<LogicalVariable> freeVars = new HashSet<>();
        // Removes non-free variables defined in the nested plan.
        OperatorPropertiesUtil.getFreeVariablesInSelfOrDesc(nestedGby, freeVars);
        gbyVars2.retainAll(freeVars);
        List<LogicalVariable> concatGbyVars = new ArrayList<LogicalVariable>(gbyVars);
        concatGbyVars.addAll(gbyVars2);
        for (ILogicalPlan p : nestedGby.getNestedPlans()) {
            for (Mutable<ILogicalOperator> r2 : p.getRoots()) {
                if (!tryToPushRoot(r2, nestedGby, newGbyOp, bi, concatGbyVars, context, toPushAccumulate, toReplaceSet)) {
                    return false;
                }
            }
        }
        /***
             * Push the nested pipeline which provides the input to the nested group operator into newGbyOp (the combined gby op).
             * The change is to fix asterixdb issue 782.
             */
        // Finds the reference of the bottom-most operator in the pipeline that
        // should not be pushed to the combiner group-by.
        Mutable<ILogicalOperator> currentOpRef = new MutableObject<ILogicalOperator>(nestedGby);
        Mutable<ILogicalOperator> bottomOpRef = findBottomOpRefStayInOldGby(currentOpRef);
        // Adds the used variables in the pipeline from <code>currentOpRef</code> to <code>bottomOpRef</code>
        // into the group-by keys for the introduced combiner group-by operator.
        Set<LogicalVariable> usedVars = collectUsedFreeVariables(currentOpRef, bottomOpRef);
        for (LogicalVariable usedVar : usedVars) {
            if (!concatGbyVars.contains(usedVar)) {
                concatGbyVars.add(usedVar);
            }
        }
        // Retains the nested pipeline above the identified operator in the old group-by operator.
        // Pushes the nested pipeline under the select operator into the new group-by operator.
        Mutable<ILogicalOperator> oldNtsRef = findNtsRef(currentOpRef);
        ILogicalOperator opToCombiner = bottomOpRef.getValue().getInputs().get(0).getValue();
        if (opToCombiner.getOperatorTag() == LogicalOperatorTag.NESTEDTUPLESOURCE) {
            // No pipeline other than the aggregate operator needs to push to combiner.
            return true;
        }
        bottomOpRef.getValue().getInputs().set(0, new MutableObject<ILogicalOperator>(oldNtsRef.getValue()));
        Mutable<ILogicalOperator> newGbyNestedOpRef = findNtsRef(toPushAccumulate.get(0));
        NestedTupleSourceOperator newNts = (NestedTupleSourceOperator) newGbyNestedOpRef.getValue();
        newGbyNestedOpRef.setValue(opToCombiner);
        oldNtsRef.setValue(newNts);
        return true;
    }
}
Also used : LogicalVariable(org.apache.hyracks.algebricks.core.algebra.base.LogicalVariable) NestedTupleSourceOperator(org.apache.hyracks.algebricks.core.algebra.operators.logical.NestedTupleSourceOperator) GroupByOperator(org.apache.hyracks.algebricks.core.algebra.operators.logical.GroupByOperator) 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) AggregateOperator(org.apache.hyracks.algebricks.core.algebra.operators.logical.AggregateOperator) ILogicalPlan(org.apache.hyracks.algebricks.core.algebra.base.ILogicalPlan) HashSet(java.util.HashSet) MutableObject(org.apache.commons.lang3.mutable.MutableObject)

Example 54 with MutableObject

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

the class ExtractCommonOperatorsRule method rewritePre.

@Override
public boolean rewritePre(Mutable<ILogicalOperator> opRef, IOptimizationContext context) throws AlgebricksException {
    AbstractLogicalOperator op = (AbstractLogicalOperator) opRef.getValue();
    if (op.getOperatorTag() != LogicalOperatorTag.WRITE && op.getOperatorTag() != LogicalOperatorTag.WRITE_RESULT && op.getOperatorTag() != LogicalOperatorTag.DISTRIBUTE_RESULT) {
        return false;
    }
    MutableObject<ILogicalOperator> mutableOp = new MutableObject<>(op);
    if (!roots.contains(mutableOp)) {
        roots.add(mutableOp);
    }
    return false;
}
Also used : AbstractLogicalOperator(org.apache.hyracks.algebricks.core.algebra.operators.logical.AbstractLogicalOperator) ILogicalOperator(org.apache.hyracks.algebricks.core.algebra.base.ILogicalOperator) MutableObject(org.apache.commons.lang3.mutable.MutableObject)

Example 55 with MutableObject

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

the class RTreeAccessMethod method createSecondaryToPrimaryPlan.

private ILogicalOperator createSecondaryToPrimaryPlan(OptimizableOperatorSubTree indexSubTree, OptimizableOperatorSubTree probeSubTree, Index chosenIndex, AccessMethodAnalysisContext analysisCtx, boolean retainInput, boolean retainNull, boolean requiresBroadcast, IOptimizationContext context) throws AlgebricksException {
    IOptimizableFuncExpr optFuncExpr = AccessMethodUtils.chooseFirstOptFuncExpr(chosenIndex, analysisCtx);
    Dataset dataset = indexSubTree.getDataset();
    ARecordType recordType = indexSubTree.getRecordType();
    ARecordType metaRecordType = indexSubTree.getMetaRecordType();
    int optFieldIdx = AccessMethodUtils.chooseFirstOptFuncVar(chosenIndex, analysisCtx);
    Pair<IAType, Boolean> keyPairType = Index.getNonNullableOpenFieldType(optFuncExpr.getFieldType(optFieldIdx), optFuncExpr.getFieldName(optFieldIdx), recordType);
    if (keyPairType == null) {
        return null;
    }
    // Get the number of dimensions corresponding to the field indexed by chosenIndex.
    IAType spatialType = keyPairType.first;
    int numDimensions = NonTaggedFormatUtil.getNumDimensions(spatialType.getTypeTag());
    int numSecondaryKeys = numDimensions * 2;
    // we made sure indexSubTree has datasource scan
    AbstractDataSourceOperator dataSourceOp = (AbstractDataSourceOperator) indexSubTree.getDataSourceRef().getValue();
    RTreeJobGenParams jobGenParams = new RTreeJobGenParams(chosenIndex.getIndexName(), IndexType.RTREE, dataset.getDataverseName(), dataset.getDatasetName(), retainInput, requiresBroadcast);
    // A spatial object is serialized in the constant of the func expr we are optimizing.
    // The R-Tree expects as input an MBR represented with 1 field per dimension.
    // Here we generate vars and funcs for extracting MBR fields from the constant into fields of a tuple (as the
    // R-Tree expects them).
    // List of variables for the assign.
    ArrayList<LogicalVariable> keyVarList = new ArrayList<>();
    // List of expressions for the assign.
    ArrayList<Mutable<ILogicalExpression>> keyExprList = new ArrayList<>();
    Pair<ILogicalExpression, Boolean> returnedSearchKeyExpr = AccessMethodUtils.createSearchKeyExpr(optFuncExpr, indexSubTree, probeSubTree);
    ILogicalExpression searchKeyExpr = returnedSearchKeyExpr.first;
    for (int i = 0; i < numSecondaryKeys; i++) {
        // The create MBR function "extracts" one field of an MBR around the given spatial object.
        AbstractFunctionCallExpression createMBR = new ScalarFunctionCallExpression(FunctionUtil.getFunctionInfo(BuiltinFunctions.CREATE_MBR));
        // Spatial object is the constant from the func expr we are optimizing.
        createMBR.getArguments().add(new MutableObject<>(searchKeyExpr));
        // The number of dimensions.
        createMBR.getArguments().add(new MutableObject<ILogicalExpression>(new ConstantExpression(new AsterixConstantValue(new AInt32(numDimensions)))));
        // Which part of the MBR to extract.
        createMBR.getArguments().add(new MutableObject<ILogicalExpression>(new ConstantExpression(new AsterixConstantValue(new AInt32(i)))));
        // Add a variable and its expr to the lists which will be passed into an assign op.
        LogicalVariable keyVar = context.newVar();
        keyVarList.add(keyVar);
        keyExprList.add(new MutableObject<ILogicalExpression>(createMBR));
    }
    jobGenParams.setKeyVarList(keyVarList);
    // Assign operator that "extracts" the MBR fields from the func-expr constant into a tuple.
    AssignOperator assignSearchKeys = new AssignOperator(keyVarList, keyExprList);
    if (probeSubTree == null) {
        // We are optimizing a selection query.
        // Input to this assign is the EmptyTupleSource (which the dataSourceScan also must have had as input).
        assignSearchKeys.getInputs().add(new MutableObject<>(OperatorManipulationUtil.deepCopy(dataSourceOp.getInputs().get(0).getValue())));
        assignSearchKeys.setExecutionMode(dataSourceOp.getExecutionMode());
    } else {
        // We are optimizing a join, place the assign op top of the probe subtree.
        assignSearchKeys.getInputs().add(probeSubTree.getRootRef());
    }
    ILogicalOperator secondaryIndexUnnestOp = AccessMethodUtils.createSecondaryIndexUnnestMap(dataset, recordType, metaRecordType, chosenIndex, assignSearchKeys, jobGenParams, context, false, retainInput, retainNull);
    // Generate the rest of the upstream plan which feeds the search results into the primary index.
    return dataset.getDatasetType() == DatasetType.EXTERNAL ? AccessMethodUtils.createExternalDataLookupUnnestMap(dataSourceOp, dataset, recordType, secondaryIndexUnnestOp, context, retainInput, retainNull) : AccessMethodUtils.createPrimaryIndexUnnestMap(dataSourceOp, dataset, recordType, metaRecordType, secondaryIndexUnnestOp, context, true, retainInput, false, false);
}
Also used : ConstantExpression(org.apache.hyracks.algebricks.core.algebra.expressions.ConstantExpression) ArrayList(java.util.ArrayList) AsterixConstantValue(org.apache.asterix.om.constants.AsterixConstantValue) ScalarFunctionCallExpression(org.apache.hyracks.algebricks.core.algebra.expressions.ScalarFunctionCallExpression) LogicalVariable(org.apache.hyracks.algebricks.core.algebra.base.LogicalVariable) AbstractDataSourceOperator(org.apache.hyracks.algebricks.core.algebra.operators.logical.AbstractDataSourceOperator) Dataset(org.apache.asterix.metadata.entities.Dataset) AbstractFunctionCallExpression(org.apache.hyracks.algebricks.core.algebra.expressions.AbstractFunctionCallExpression) ILogicalOperator(org.apache.hyracks.algebricks.core.algebra.base.ILogicalOperator) AssignOperator(org.apache.hyracks.algebricks.core.algebra.operators.logical.AssignOperator) AInt32(org.apache.asterix.om.base.AInt32) Mutable(org.apache.commons.lang3.mutable.Mutable) ILogicalExpression(org.apache.hyracks.algebricks.core.algebra.base.ILogicalExpression) ARecordType(org.apache.asterix.om.types.ARecordType) IAType(org.apache.asterix.om.types.IAType)

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