Example usage for org.apache.commons.lang3.mutable Mutable setValue

List of usage examples for org.apache.commons.lang3.mutable Mutable setValue

Introduction

In this page you can find the example usage for org.apache.commons.lang3.mutable Mutable setValue.

Prototype

void setValue(T value);

Source Link

Document

Sets the value of this mutable.

Usage

From source file:org.apache.asterix.optimizer.rules.am.RTreeAccessMethod.java

@Override
public boolean applyJoinPlanTransformation(Mutable<ILogicalOperator> joinRef,
        OptimizableOperatorSubTree leftSubTree, OptimizableOperatorSubTree rightSubTree, Index chosenIndex,
        AccessMethodAnalysisContext analysisCtx, IOptimizationContext context, boolean isLeftOuterJoin,
        boolean hasGroupBy) throws AlgebricksException {
    // Determine if the index is applicable on the left or right side (if both, we arbitrarily prefer the left
    // side)./*w  w  w  . j a v  a  2 s.  c  om*/
    Dataset dataset = analysisCtx.indexDatasetMap.get(chosenIndex);
    OptimizableOperatorSubTree indexSubTree;
    OptimizableOperatorSubTree probeSubTree;

    // We assume that the left subtree is the outer branch and the right subtree is the inner branch.
    // This assumption holds true since we only use an index from the right subtree.
    // The following is just a sanity check.
    if (rightSubTree.hasDataSourceScan()
            && dataset.getDatasetName().equals(rightSubTree.getDataset().getDatasetName())) {
        indexSubTree = rightSubTree;
        probeSubTree = leftSubTree;
    } else {
        return false;
    }

    LogicalVariable newNullPlaceHolderVar = null;
    if (isLeftOuterJoin) {
        // get a new null place holder variable that is the first field variable of the primary key
        // from the indexSubTree's datasourceScanOp
        newNullPlaceHolderVar = indexSubTree.getDataSourceVariables().get(0);
    }

    // TODO: We can probably do something smarter here based on selectivity or MBR area.
    ILogicalOperator primaryIndexUnnestOp = createSecondaryToPrimaryPlan(indexSubTree, probeSubTree,
            chosenIndex, analysisCtx, true, isLeftOuterJoin, true, context);
    if (primaryIndexUnnestOp == null) {
        return false;
    }

    if (isLeftOuterJoin && hasGroupBy) {
        // reset the null place holder variable
        AccessMethodUtils.resetLOJNullPlaceholderVariableInGroupByOp(analysisCtx, newNullPlaceHolderVar,
                context);
    }

    indexSubTree.getDataSourceRef().setValue(primaryIndexUnnestOp);
    // Change join into a select with the same condition.
    AbstractBinaryJoinOperator joinOp = (AbstractBinaryJoinOperator) joinRef.getValue();
    SelectOperator topSelect = new SelectOperator(joinOp.getCondition(), isLeftOuterJoin,
            newNullPlaceHolderVar);
    topSelect.getInputs().add(indexSubTree.getRootRef());
    topSelect.setExecutionMode(ExecutionMode.LOCAL);
    context.computeAndSetTypeEnvironmentForOperator(topSelect);
    // Replace the original join with the new subtree rooted at the select op.
    joinRef.setValue(topSelect);
    return true;
}

From source file:org.apache.asterix.optimizer.rules.ByNameToByIndexFieldAccessRule.java

private boolean rewriteFieldAccess(Mutable<ILogicalExpression> exprRef, AbstractFunctionCallExpression fce,
        IAType t) throws AlgebricksException {
    if (t.getTypeTag() != ATypeTag.RECORD) {
        return false;
    }//from   w  w  w.  j a  v  a  2 s  .  com
    ILogicalExpression fai = createFieldAccessByIndex((ARecordType) t, fce);
    boolean changed = fai != null;
    if (changed) {
        exprRef.setValue(fai);
    }
    return changed;
}

From source file:org.apache.asterix.optimizer.rules.CancelUnnestWithNestedListifyRule.java

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;
    }/*from  ww  w  .j  a va2 s  .co m*/
    UnnestOperator unnest1 = (UnnestOperator) op1;
    ILogicalExpression expr = unnest1.getExpressionRef().getValue();
    LogicalVariable unnestedVar;
    switch (expr.getExpressionTag()) {
    case VARIABLE:
        unnestedVar = ((VariableReferenceExpression) expr).getVariableReference();
        break;
    case FUNCTION_CALL:
        if (((AbstractFunctionCallExpression) expr)
                .getFunctionIdentifier() != AsterixBuiltinFunctions.SCAN_COLLECTION) {
            return false;
        }
        AbstractFunctionCallExpression functionCall = (AbstractFunctionCallExpression) expr;
        ILogicalExpression functionCallArgExpr = functionCall.getArguments().get(0).getValue();
        if (functionCallArgExpr.getExpressionTag() != LogicalExpressionTag.VARIABLE) {
            return false;
        }
        unnestedVar = ((VariableReferenceExpression) functionCallArgExpr).getVariableReference();
        break;
    default:
        return false;
    }
    if (varUsedAbove.contains(unnestedVar)) {
        return false;
    }

    Mutable<ILogicalOperator> opRef2 = op1.getInputs().get(0);
    AbstractLogicalOperator r = (AbstractLogicalOperator) opRef2.getValue();

    if (r.getOperatorTag() != LogicalOperatorTag.GROUP) {
        return false;
    }

    // go inside of a group-by plan
    GroupByOperator gby = (GroupByOperator) r;
    if (gby.getNestedPlans().size() != 1) {
        return false;
    }
    if (gby.getNestedPlans().get(0).getRoots().size() != 1) {
        return false;
    }

    AbstractLogicalOperator nestedPlanRoot = (AbstractLogicalOperator) gby.getNestedPlans().get(0).getRoots()
            .get(0).getValue();
    if (nestedPlanRoot.getOperatorTag() != LogicalOperatorTag.AGGREGATE) {
        return false;
    }
    AggregateOperator agg = (AggregateOperator) nestedPlanRoot;
    Mutable<ILogicalOperator> aggInputOpRef = agg.getInputs().get(0);

    if (agg.getVariables().size() > 1) {
        return false;
    }

    if (OperatorManipulationUtil.ancestorOfOperators(agg, ImmutableSet.of(LogicalOperatorTag.LIMIT,
            LogicalOperatorTag.ORDER, LogicalOperatorTag.GROUP, LogicalOperatorTag.DISTINCT))) {
        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 (!AsterixBuiltinFunctions.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();

    ArrayList<LogicalVariable> assgnVars = new ArrayList<LogicalVariable>(1);
    assgnVars.add(unnest1.getVariable());
    ArrayList<Mutable<ILogicalExpression>> assgnExprs = new ArrayList<Mutable<ILogicalExpression>>(1);
    assgnExprs.add(new MutableObject<ILogicalExpression>(new VariableReferenceExpression(paramVar)));
    AssignOperator assign = new AssignOperator(assgnVars, assgnExprs);

    LogicalVariable posVar = unnest1.getPositionalVariable();
    if (posVar == null) {
        // Creates assignment for group-by keys.
        ArrayList<LogicalVariable> gbyKeyAssgnVars = new ArrayList<LogicalVariable>();
        ArrayList<Mutable<ILogicalExpression>> gbyKeyAssgnExprs = new ArrayList<Mutable<ILogicalExpression>>();
        for (int i = 0; i < gby.getGroupByList().size(); i++) {
            if (gby.getGroupByList().get(i).first != null) {
                gbyKeyAssgnVars.add(gby.getGroupByList().get(i).first);
                gbyKeyAssgnExprs.add(gby.getGroupByList().get(i).second);
            }
        }

        // Moves the nested pipeline before aggregation out of the group-by op.
        Mutable<ILogicalOperator> bottomOpRef = aggInputOpRef;
        AbstractLogicalOperator bottomOp = (AbstractLogicalOperator) bottomOpRef.getValue();
        while (bottomOp.getOperatorTag() != LogicalOperatorTag.NESTEDTUPLESOURCE) {
            bottomOpRef = bottomOp.getInputs().get(0);
            bottomOp = (AbstractLogicalOperator) bottomOpRef.getValue();
        }

        // Removes the group-by operator.
        opRef.setValue(assign);
        assign.getInputs().add(aggInputOpRef);
        AssignOperator gbyKeyAssign = new AssignOperator(gbyKeyAssgnVars, gbyKeyAssgnExprs);
        gbyKeyAssign.getInputs().add(gby.getInputs().get(0));
        bottomOpRef.setValue(gbyKeyAssign);

        context.computeAndSetTypeEnvironmentForOperator(gbyKeyAssign);
        context.computeAndSetTypeEnvironmentForOperator(assign);
    } else {
        // if positional variable is used in unnest, the unnest will be pushed into the group-by as a running-aggregate

        // First create assign for the unnest variable
        List<LogicalVariable> nestedAssignVars = new ArrayList<LogicalVariable>();
        List<Mutable<ILogicalExpression>> nestedAssignExprs = new ArrayList<Mutable<ILogicalExpression>>();
        nestedAssignVars.add(unnest1.getVariable());
        nestedAssignExprs.add(new MutableObject<ILogicalExpression>(arg0));
        AssignOperator nestedAssign = new AssignOperator(nestedAssignVars, nestedAssignExprs);
        nestedAssign.getInputs().add(opRef2);

        // Then create running aggregation for the positional variable
        List<LogicalVariable> raggVars = new ArrayList<LogicalVariable>();
        List<Mutable<ILogicalExpression>> raggExprs = new ArrayList<Mutable<ILogicalExpression>>();
        raggVars.add(posVar);
        StatefulFunctionCallExpression fce = new StatefulFunctionCallExpression(
                FunctionUtil.getFunctionInfo(AsterixBuiltinFunctions.TID),
                UnpartitionedPropertyComputer.INSTANCE);
        raggExprs.add(new MutableObject<ILogicalExpression>(fce));
        RunningAggregateOperator raggOp = new RunningAggregateOperator(raggVars, raggExprs);
        raggOp.setExecutionMode(unnest1.getExecutionMode());
        RunningAggregatePOperator raggPOp = new RunningAggregatePOperator();
        raggOp.setPhysicalOperator(raggPOp);
        raggOp.getInputs().add(nestedPlanRoot.getInputs().get(0));
        gby.getNestedPlans().get(0).getRoots().set(0, new MutableObject<ILogicalOperator>(raggOp));

        opRef.setValue(nestedAssign);

        context.computeAndSetTypeEnvironmentForOperator(nestedAssign);
        context.computeAndSetTypeEnvironmentForOperator(raggOp);
        context.computeAndSetTypeEnvironmentForOperator(gby);

    }

    return true;
}

From source file:org.apache.asterix.optimizer.rules.FuzzyEqRule.java

private boolean expandFuzzyEq(Mutable<ILogicalExpression> expRef, IOptimizationContext context,
        IVariableTypeEnvironment env, AqlMetadataProvider metadataProvider) throws AlgebricksException {
    ILogicalExpression exp = expRef.getValue();

    if (exp.getExpressionTag() != LogicalExpressionTag.FUNCTION_CALL) {
        return false;
    }//w  w  w .j a  va2 s  .  c o m

    boolean expanded = false;
    AbstractFunctionCallExpression funcExp = (AbstractFunctionCallExpression) exp;
    FunctionIdentifier fi = funcExp.getFunctionIdentifier();
    if (fi.equals(AsterixBuiltinFunctions.FUZZY_EQ)) {
        List<Mutable<ILogicalExpression>> inputExps = funcExp.getArguments();

        String simFuncName = FuzzyUtils.getSimFunction(metadataProvider);
        ArrayList<Mutable<ILogicalExpression>> similarityArgs = new ArrayList<Mutable<ILogicalExpression>>();
        for (int i = 0; i < inputExps.size(); ++i) {
            Mutable<ILogicalExpression> inputExpRef = inputExps.get(i);
            similarityArgs.add(inputExpRef);
        }

        FunctionIdentifier simFunctionIdentifier = FuzzyUtils.getFunctionIdentifier(simFuncName);
        ScalarFunctionCallExpression similarityExp = new ScalarFunctionCallExpression(
                FunctionUtil.getFunctionInfo(simFunctionIdentifier), similarityArgs);
        // Add annotations from the original fuzzy-eq function.
        similarityExp.getAnnotations().putAll(funcExp.getAnnotations());
        ArrayList<Mutable<ILogicalExpression>> cmpArgs = new ArrayList<Mutable<ILogicalExpression>>();
        cmpArgs.add(new MutableObject<ILogicalExpression>(similarityExp));
        IAObject simThreshold = FuzzyUtils.getSimThreshold(metadataProvider, simFuncName);
        cmpArgs.add(new MutableObject<ILogicalExpression>(
                new ConstantExpression(new AsterixConstantValue(simThreshold))));
        ScalarFunctionCallExpression cmpExpr = FuzzyUtils.getComparisonExpr(simFuncName, cmpArgs);
        expRef.setValue(cmpExpr);
        return true;
    } else if (fi.equals(AlgebricksBuiltinFunctions.AND) || fi.equals(AlgebricksBuiltinFunctions.OR)) {
        for (int i = 0; i < 2; i++) {
            if (expandFuzzyEq(funcExp.getArguments().get(i), context, env, metadataProvider)) {
                expanded = true;
            }
        }
    }
    return expanded;
}

From source file:org.apache.asterix.optimizer.rules.FuzzyJoinRule.java

@Override
public boolean rewritePost(Mutable<ILogicalOperator> opRef, IOptimizationContext context)
        throws AlgebricksException {
    AbstractLogicalOperator op = (AbstractLogicalOperator) opRef.getValue();
    // current opperator is join
    if (op.getOperatorTag() != LogicalOperatorTag.INNERJOIN
            && op.getOperatorTag() != LogicalOperatorTag.LEFTOUTERJOIN) {
        return false;
    }//from  ww  w.  ja v a2 s . co  m

    // Find GET_ITEM function.
    AbstractBinaryJoinOperator joinOp = (AbstractBinaryJoinOperator) op;
    Mutable<ILogicalExpression> expRef = joinOp.getCondition();
    Mutable<ILogicalExpression> getItemExprRef = getSimilarityExpression(expRef);
    if (getItemExprRef == null) {
        return false;
    }
    // Check if the GET_ITEM function is on one of the supported similarity-check functions.
    AbstractFunctionCallExpression getItemFuncExpr = (AbstractFunctionCallExpression) getItemExprRef.getValue();
    Mutable<ILogicalExpression> argRef = getItemFuncExpr.getArguments().get(0);
    AbstractFunctionCallExpression simFuncExpr = (AbstractFunctionCallExpression) argRef.getValue();
    if (!simFuncs.contains(simFuncExpr.getFunctionIdentifier())) {
        return false;
    }
    // Skip this rule based on annotations.
    if (simFuncExpr.getAnnotations().containsKey(IndexedNLJoinExpressionAnnotation.INSTANCE)) {
        return false;
    }

    List<Mutable<ILogicalOperator>> inputOps = joinOp.getInputs();
    ILogicalOperator leftInputOp = inputOps.get(0).getValue();
    ILogicalOperator rightInputOp = inputOps.get(1).getValue();

    List<Mutable<ILogicalExpression>> inputExps = simFuncExpr.getArguments();

    ILogicalExpression inputExp0 = inputExps.get(0).getValue();
    ILogicalExpression inputExp1 = inputExps.get(1).getValue();

    // left and right expressions are variables
    if (inputExp0.getExpressionTag() != LogicalExpressionTag.VARIABLE
            || inputExp1.getExpressionTag() != LogicalExpressionTag.VARIABLE) {
        return false;
    }

    LogicalVariable inputVar0 = ((VariableReferenceExpression) inputExp0).getVariableReference();
    LogicalVariable inputVar1 = ((VariableReferenceExpression) inputExp1).getVariableReference();

    LogicalVariable leftInputVar;
    LogicalVariable rightInputVar;

    liveVars.clear();
    VariableUtilities.getLiveVariables(leftInputOp, liveVars);
    if (liveVars.contains(inputVar0)) {
        leftInputVar = inputVar0;
        rightInputVar = inputVar1;
    } else {
        leftInputVar = inputVar1;
        rightInputVar = inputVar0;
    }

    List<LogicalVariable> leftInputPKs = context.findPrimaryKey(leftInputVar);
    List<LogicalVariable> rightInputPKs = context.findPrimaryKey(rightInputVar);
    // Bail if primary keys could not be inferred.
    if (leftInputPKs == null || rightInputPKs == null) {
        return false;
    }
    // primary key has only one variable
    if (leftInputPKs.size() != 1 || rightInputPKs.size() != 1) {
        return false;
    }
    IAType leftType = (IAType) context.getOutputTypeEnvironment(leftInputOp).getVarType(leftInputVar);
    IAType rightType = (IAType) context.getOutputTypeEnvironment(rightInputOp).getVarType(rightInputVar);
    // left-hand side and right-hand side of "~=" has the same type
    IAType left2 = TypeComputeUtils.getActualType(leftType);
    IAType right2 = TypeComputeUtils.getActualType(rightType);
    if (!left2.deepEqual(right2)) {
        return false;
    }
    //
    // -- - FIRE - --
    //
    AqlMetadataProvider metadataProvider = ((AqlMetadataProvider) context.getMetadataProvider());
    FunctionIdentifier funcId = FuzzyUtils.getTokenizer(leftType.getTypeTag());
    String tokenizer;
    if (funcId == null) {
        tokenizer = "";
    } else {
        tokenizer = funcId.getName();
    }

    float simThreshold = FuzzyUtils.getSimThreshold(metadataProvider);
    String simFunction = FuzzyUtils.getSimFunction(metadataProvider);

    // finalize AQL+ query
    String prepareJoin;
    switch (joinOp.getJoinKind()) {
    case INNER: {
        prepareJoin = "join" + AQLPLUS;
        break;
    }
    case LEFT_OUTER: {
        // TODO To make it work for Left Outer Joins, we should permute
        // the #LEFT and #RIGHT at the top of the AQL+ query. But, when
        // doing this, the
        // fuzzyjoin/user-vis-int-vis-user-lot-aqlplus_1.aql (the one
        // doing 3-way fuzzy joins) gives a different result. But even
        // if we don't change the FuzzyJoinRule, permuting the for
        // clauses in fuzzyjoin/user-vis-int-vis-user-lot-aqlplus_1.aql
        // leads to different results, which suggests there is some
        // other sort of bug.
        return false;
        // prepareJoin = "loj" + AQLPLUS;
        // break;
    }
    default: {
        throw new IllegalStateException();
    }
    }
    String aqlPlus = String.format(Locale.US, prepareJoin, tokenizer, tokenizer, simFunction, simThreshold,
            tokenizer, tokenizer, simFunction, simThreshold, simFunction, simThreshold, simThreshold);

    LogicalVariable leftPKVar = leftInputPKs.get(0);
    LogicalVariable rightPKVar = rightInputPKs.get(0);

    Counter counter = new Counter(context.getVarCounter());

    AQLPlusParser parser = new AQLPlusParser(new StringReader(aqlPlus));
    parser.initScope();
    parser.setVarCounter(counter);
    List<Clause> clauses;
    try {
        clauses = parser.Clauses();
    } catch (ParseException e) {
        throw new AlgebricksException(e);
    }
    // The translator will compile metadata internally. Run this compilation
    // under the same transaction id as the "outer" compilation.
    AqlPlusExpressionToPlanTranslator translator = new AqlPlusExpressionToPlanTranslator(
            metadataProvider.getJobId(), metadataProvider, counter, null, null);
    context.setVarCounter(counter.get());

    LogicalOperatorDeepCopyWithNewVariablesVisitor deepCopyVisitor = new LogicalOperatorDeepCopyWithNewVariablesVisitor(
            context, context);

    translator.addOperatorToMetaScope(new Identifier("#LEFT"), leftInputOp);
    translator.addVariableToMetaScope(new Identifier("$$LEFT"), leftInputVar);
    translator.addVariableToMetaScope(new Identifier("$$LEFTPK"), leftPKVar);

    translator.addOperatorToMetaScope(new Identifier("#RIGHT"), rightInputOp);
    translator.addVariableToMetaScope(new Identifier("$$RIGHT"), rightInputVar);
    translator.addVariableToMetaScope(new Identifier("$$RIGHTPK"), rightPKVar);

    translator.addOperatorToMetaScope(new Identifier("#LEFT_1"), deepCopyVisitor.deepCopy(leftInputOp));
    translator.addVariableToMetaScope(new Identifier("$$LEFT_1"), deepCopyVisitor.varCopy(leftInputVar));
    translator.addVariableToMetaScope(new Identifier("$$LEFTPK_1"), deepCopyVisitor.varCopy(leftPKVar));
    deepCopyVisitor.updatePrimaryKeys(context);
    deepCopyVisitor.reset();

    // translator.addOperatorToMetaScope(new Identifier("#LEFT_2"),
    // deepCopyVisitor.deepCopy(leftInputOp, null));
    // translator.addVariableToMetaScope(new Identifier("$$LEFT_2"),
    // deepCopyVisitor.varCopy(leftInputVar));
    // translator.addVariableToMetaScope(new Identifier("$$LEFTPK_2"),
    // deepCopyVisitor.varCopy(leftPKVar));
    // deepCopyVisitor.updatePrimaryKeys(context);
    // deepCopyVisitor.reset();
    //
    // translator.addOperatorToMetaScope(new Identifier("#LEFT_3"),
    // deepCopyVisitor.deepCopy(leftInputOp, null));
    // translator.addVariableToMetaScope(new Identifier("$$LEFT_3"),
    // deepCopyVisitor.varCopy(leftInputVar));
    // translator.addVariableToMetaScope(new Identifier("$$LEFTPK_3"),
    // deepCopyVisitor.varCopy(leftPKVar));
    // deepCopyVisitor.updatePrimaryKeys(context);
    // deepCopyVisitor.reset();

    translator.addOperatorToMetaScope(new Identifier("#RIGHT_1"), deepCopyVisitor.deepCopy(rightInputOp));
    translator.addVariableToMetaScope(new Identifier("$$RIGHT_1"), deepCopyVisitor.varCopy(rightInputVar));
    translator.addVariableToMetaScope(new Identifier("$$RIGHTPK_1"), deepCopyVisitor.varCopy(rightPKVar));
    deepCopyVisitor.updatePrimaryKeys(context);
    deepCopyVisitor.reset();

    // TODO pick side to run Stage 1, currently always picks RIGHT side
    translator.addOperatorToMetaScope(new Identifier("#RIGHT_2"), deepCopyVisitor.deepCopy(rightInputOp));
    translator.addVariableToMetaScope(new Identifier("$$RIGHT_2"), deepCopyVisitor.varCopy(rightInputVar));
    translator.addVariableToMetaScope(new Identifier("$$RIGHTPK_2"), deepCopyVisitor.varCopy(rightPKVar));
    deepCopyVisitor.updatePrimaryKeys(context);
    deepCopyVisitor.reset();

    translator.addOperatorToMetaScope(new Identifier("#RIGHT_3"), deepCopyVisitor.deepCopy(rightInputOp));
    translator.addVariableToMetaScope(new Identifier("$$RIGHT_3"), deepCopyVisitor.varCopy(rightInputVar));
    translator.addVariableToMetaScope(new Identifier("$$RIGHTPK_3"), deepCopyVisitor.varCopy(rightPKVar));
    deepCopyVisitor.updatePrimaryKeys(context);
    deepCopyVisitor.reset();

    ILogicalPlan plan;
    try {
        plan = translator.translate(clauses);
    } catch (AsterixException e) {
        throw new AlgebricksException(e);
    }
    context.setVarCounter(counter.get());

    ILogicalOperator outputOp = plan.getRoots().get(0).getValue();

    SelectOperator extraSelect = null;
    if (getItemExprRef != expRef) {
        // more than one join condition
        getItemExprRef.setValue(ConstantExpression.TRUE);
        switch (joinOp.getJoinKind()) {
        case INNER: {
            extraSelect = new SelectOperator(expRef, false, null);
            extraSelect.getInputs().add(new MutableObject<ILogicalOperator>(outputOp));
            outputOp = extraSelect;
            break;
        }
        case LEFT_OUTER: {
            if (((AbstractLogicalOperator) outputOp).getOperatorTag() != LogicalOperatorTag.LEFTOUTERJOIN) {
                throw new IllegalStateException();
            }
            LeftOuterJoinOperator topJoin = (LeftOuterJoinOperator) outputOp;
            topJoin.getCondition().setValue(expRef.getValue());
            break;
        }
        default: {
            throw new IllegalStateException();
        }
        }
    }
    opRef.setValue(outputOp);
    OperatorPropertiesUtil.typeOpRec(opRef, context);
    return true;
}

From source file:org.apache.asterix.optimizer.rules.InjectTypeCastForSwitchCaseRule.java

private boolean rewriteSwitchCase(ILogicalOperator op, AbstractFunctionCallExpression func,
        IOptimizationContext context) throws AlgebricksException {
    IVariableTypeEnvironment env = context.getOutputTypeEnvironment(op.getInputs().get(0).getValue());
    IAType producedType = (IAType) env.getType(func);
    List<Mutable<ILogicalExpression>> argRefs = func.getArguments();
    int argSize = argRefs.size();
    boolean rewritten = false;
    for (int argIndex = 2; argIndex < argSize; argIndex += (argIndex + 2 == argSize) ? 1 : 2) {
        Mutable<ILogicalExpression> argRef = argRefs.get(argIndex);
        IAType type = (IAType) env.getType(argRefs.get(argIndex).getValue());
        if (TypeResolverUtil.needsCast(producedType, type)) {
            ILogicalExpression argExpr = argRef.getValue();
            // Injects a cast call to cast the data type to the produced type of the switch-case function call.
            ScalarFunctionCallExpression castFunc = new ScalarFunctionCallExpression(
                    FunctionUtil.getFunctionInfo(AsterixBuiltinFunctions.CAST_TYPE),
                    new ArrayList<>(Collections.singletonList(new MutableObject<>(argExpr))));
            TypeCastUtils.setRequiredAndInputTypes(castFunc, producedType, type);
            argRef.setValue(castFunc);
            rewritten = true;//  w w w  . j  a  v  a  2  s  .  c  o m
        }
    }
    return rewritten;
}

From source file:org.apache.asterix.optimizer.rules.InjectTypeCastForUnionRule.java

private boolean injectCast(UnionAllOperator op, int childIndex, IOptimizationContext context)
        throws AlgebricksException {
    // Gets the type environments for the union all operator and its child operator with the right child index.
    IVariableTypeEnvironment env = context.getOutputTypeEnvironment(op);
    Mutable<ILogicalOperator> branchOpRef = op.getInputs().get(childIndex);
    IVariableTypeEnvironment childEnv = context.getOutputTypeEnvironment(branchOpRef.getValue());

    // The two lists are used for the assign operator that calls cast functions.
    List<LogicalVariable> varsToCast = new ArrayList<>();
    List<Mutable<ILogicalExpression>> castFunctionsForLeft = new ArrayList<>();

    // Iterate through all triples.
    List<Triple<LogicalVariable, LogicalVariable, LogicalVariable>> triples = op.getVariableMappings();
    for (Triple<LogicalVariable, LogicalVariable, LogicalVariable> triple : triples) {
        LogicalVariable producedVar = triple.third;
        IAType producedType = (IAType) env.getVarType(producedVar);
        LogicalVariable varToCast = childIndex == 0 ? triple.first : triple.second;
        IAType inputType = (IAType) childEnv.getVarType(varToCast);
        if (!TypeResolverUtil.needsCast(producedType, inputType)) {
            // Continues to the next triple if no cast is neeeded.
            continue;
        }//from ww w.j a v a2s .com
        LogicalVariable castedVar = context.newVar();
        // Resets triple variables to new variables that bind to the results of type casting.
        triple.first = childIndex == 0 ? castedVar : triple.first;
        triple.second = childIndex > 0 ? castedVar : triple.second;
        ScalarFunctionCallExpression castFunc = new ScalarFunctionCallExpression(
                FunctionUtil.getFunctionInfo(AsterixBuiltinFunctions.CAST_TYPE), new ArrayList<>(Collections
                        .singletonList(new MutableObject<>(new VariableReferenceExpression(varToCast)))));
        TypeCastUtils.setRequiredAndInputTypes(castFunc, producedType, inputType);

        // Adds the variable and function expression into lists, for the assign operator.
        varsToCast.add(castedVar);
        castFunctionsForLeft.add(new MutableObject<>(castFunc));
    }
    if (castFunctionsForLeft.isEmpty()) {
        return false;
    }
    // Injects an assign operator to perform type casts.
    AssignOperator assignOp = new AssignOperator(varsToCast, castFunctionsForLeft);
    assignOp.getInputs().add(new MutableObject<>(branchOpRef.getValue()));
    branchOpRef.setValue(assignOp);
    context.computeAndSetTypeEnvironmentForOperator(assignOp);

    // Returns true to indicate that rewriting happens.
    return true;
}

From source file:org.apache.asterix.optimizer.rules.IntroduceDynamicTypeCastRule.java

/**
 * Inject a function to wrap a variable when necessary
 *
 * @param requiredRecordType//w w w  . ja  v a 2  s . c  o  m
 *            the required record type
 * @param recordVar
 *            the record variable
 * @param parent
 *            the current parent operator to be rewritten
 * @param context
 *            the optimization context
 * @param fd
 *            the function to be injected
 * @return true if cast is injected; false otherwise.
 * @throws AlgebricksException
 */
public static LogicalVariable addWrapperFunction(ARecordType requiredRecordType, LogicalVariable recordVar,
        ILogicalOperator parent, IOptimizationContext context, FunctionIdentifier fd)
        throws AlgebricksException {
    List<Mutable<ILogicalOperator>> opRefs = parent.getInputs();
    for (int index = 0; index < opRefs.size(); index++) {
        Mutable<ILogicalOperator> opRef = opRefs.get(index);
        ILogicalOperator op = opRef.getValue();

        /** get produced vars */
        List<LogicalVariable> producedVars = new ArrayList<LogicalVariable>();
        VariableUtilities.getProducedVariables(op, producedVars);
        IVariableTypeEnvironment env = op.computeOutputTypeEnvironment(context);
        for (int i = 0; i < producedVars.size(); i++) {
            LogicalVariable var = producedVars.get(i);
            if (var.equals(recordVar)) {
                /** insert an assign operator to call the function on-top-of the variable */
                IAType actualType = (IAType) env.getVarType(var);
                AbstractFunctionCallExpression cast = new ScalarFunctionCallExpression(
                        FunctionUtil.getFunctionInfo(fd));
                cast.getArguments()
                        .add(new MutableObject<ILogicalExpression>(new VariableReferenceExpression(var)));
                /** enforce the required record type */
                TypeCastUtils.setRequiredAndInputTypes(cast, requiredRecordType, actualType);
                LogicalVariable newAssignVar = context.newVar();
                AssignOperator newAssignOperator = new AssignOperator(newAssignVar,
                        new MutableObject<ILogicalExpression>(cast));
                newAssignOperator.getInputs().add(new MutableObject<ILogicalOperator>(op));
                opRef.setValue(newAssignOperator);
                context.computeAndSetTypeEnvironmentForOperator(newAssignOperator);
                newAssignOperator.computeOutputTypeEnvironment(context);
                VariableUtilities.substituteVariables(parent, recordVar, newAssignVar, context);
                return newAssignVar;
            }
        }
        /** recursive descend to the operator who produced the recordVar */
        LogicalVariable replacedVar = addWrapperFunction(requiredRecordType, recordVar, op, context, fd);
        if (replacedVar != null) {
            /** substitute the recordVar by the replacedVar for operators who uses recordVar */
            VariableUtilities.substituteVariables(parent, recordVar, replacedVar, context);
            return replacedVar;
        }
    }
    return null;
}

From source file:org.apache.asterix.optimizer.rules.IntroduceUnnestForCollectionToSequenceRule.java

@Override
public boolean rewritePost(Mutable<ILogicalOperator> opRef, IOptimizationContext context)
        throws AlgebricksException {
    AbstractLogicalOperator op = (AbstractLogicalOperator) opRef.getValue();
    if (op.getOperatorTag() != LogicalOperatorTag.ASSIGN) {
        return false;
    }/*  ww  w.j a v a 2 s .c o m*/
    AssignOperator assign = (AssignOperator) op;
    List<Mutable<ILogicalExpression>> exprs = assign.getExpressions();
    if (exprs.size() != 1) {
        return false;
    }
    ILogicalExpression expr = exprs.get(0).getValue();
    if (expr.getExpressionTag() != LogicalExpressionTag.FUNCTION_CALL) {
        return false;
    }
    AbstractFunctionCallExpression func = (AbstractFunctionCallExpression) expr;
    if (func.getFunctionIdentifier() != AsterixBuiltinFunctions.COLLECTION_TO_SEQUENCE) {
        return false;
    }

    IVariableTypeEnvironment env = assign.computeInputTypeEnvironment(context);
    ILogicalExpression argExpr = func.getArguments().get(0).getValue();
    IAType outerExprType = (IAType) env.getType(expr);
    IAType innerExprType = (IAType) env.getType(argExpr);
    if (outerExprType.equals(innerExprType)) {
        /** nothing is changed with the collection-to-sequence function, remove the collection-sequence function call */
        assign.getExpressions().set(0, new MutableObject<ILogicalExpression>(argExpr));
        return true;
    }
    /** change the assign operator to an unnest operator */
    LogicalVariable var = assign.getVariables().get(0);
    @SuppressWarnings("unchecked")
    UnnestOperator unnest = new UnnestOperator(var,
            new MutableObject<ILogicalExpression>(new UnnestingFunctionCallExpression(
                    FunctionUtil.getFunctionInfo(AsterixBuiltinFunctions.SCAN_COLLECTION),
                    new MutableObject<ILogicalExpression>(argExpr))));
    unnest.getInputs().addAll(assign.getInputs());
    opRef.setValue(unnest);
    context.computeAndSetTypeEnvironmentForOperator(unnest);
    return true;
}

From source file:org.apache.asterix.optimizer.rules.ListifyUnnestingFunctionRule.java

private boolean listifyUnnestingFunction(ILogicalOperator op, Mutable<ILogicalExpression> exprRef,
        AbstractFunctionCallExpression func, IOptimizationContext context) throws AlgebricksException {
    IFunctionInfo functionInfo = func.getFunctionInfo();

    // Checks if the function is an unnesting function.
    if (!AsterixBuiltinFunctions.isBuiltinUnnestingFunction(functionInfo.getFunctionIdentifier())) {
        return false;
    }/*  w w  w . ja v a  2s .c om*/

    // Generates the listified collection in a subplan.
    SubplanOperator subplanOperator = new SubplanOperator();
    // Creates a nested tuple source operator.
    NestedTupleSourceOperator ntsOperator = new NestedTupleSourceOperator(new MutableObject<>(subplanOperator));

    // Unnests the dataset.
    LogicalVariable unnestVar = context.newVar();
    ILogicalExpression unnestExpr = new UnnestingFunctionCallExpression(functionInfo, func.getArguments());
    UnnestOperator unnestOperator = new UnnestOperator(unnestVar, new MutableObject<>(unnestExpr));
    unnestOperator.getInputs().add(new MutableObject<>(ntsOperator));

    // Listify the dataset into one collection.
    LogicalVariable aggVar = context.newVar();
    Mutable<ILogicalExpression> aggArgExprRef = new MutableObject<>(new VariableReferenceExpression(unnestVar));
    ILogicalExpression aggExpr = new AggregateFunctionCallExpression(
            FunctionUtil.getFunctionInfo(AsterixBuiltinFunctions.LISTIFY), false,
            new ArrayList<>(Collections.singletonList(aggArgExprRef)));
    AggregateOperator aggregateOperator = new AggregateOperator(
            new ArrayList<>(Collections.singletonList(aggVar)),
            new ArrayList<>(Collections.singletonList(new MutableObject<>(aggExpr))));
    aggregateOperator.getInputs().add(new MutableObject<>(unnestOperator));

    // Adds the aggregate operator as the root of the subplan.
    subplanOperator.setRootOp(new MutableObject<>(aggregateOperator));

    // Sticks a subplan operator into the query plan.
    // Note: given the way we compile JOINs, the unnesting function expression cannot appear in
    // any binary operators.
    // Example test queries:
    // asterixdb/asterix-app/src/test/resources/runtimets/results/list/query-ASTERIXDB-159-2
    // asterixdb/asterix-app/src/test/resources/runtimets/results/list/query-ASTERIXDB-159-3
    subplanOperator.getInputs().add(op.getInputs().get(0));
    op.getInputs().set(0, new MutableObject<>(subplanOperator));
    exprRef.setValue(new VariableReferenceExpression(aggVar));

    // Computes type environments for new operators.
    context.computeAndSetTypeEnvironmentForOperator(ntsOperator);
    context.computeAndSetTypeEnvironmentForOperator(unnestOperator);
    context.computeAndSetTypeEnvironmentForOperator(aggregateOperator);
    context.computeAndSetTypeEnvironmentForOperator(subplanOperator);
    return true;
}