List of usage examples for org.apache.commons.lang3.mutable Mutable getValue
T getValue();
From source file:org.apache.asterix.optimizer.rules.subplan.InlineSubplanInputForNestedTupleSourceRule.java
private Pair<Boolean, LinkedHashMap<LogicalVariable, LogicalVariable>> applyGeneralFlattening( Mutable<ILogicalOperator> opRef, IOptimizationContext context) throws AlgebricksException { SubplanOperator subplanOp = (SubplanOperator) opRef.getValue(); if (!SubplanFlatteningUtil.containsOperators(subplanOp, ImmutableSet.of(LogicalOperatorTag.DATASOURCESCAN, LogicalOperatorTag.INNERJOIN, // We don't have nested runtime for union-all and distinct hence we have to include them here. LogicalOperatorTag.LEFTOUTERJOIN, LogicalOperatorTag.UNIONALL, LogicalOperatorTag.DISTINCT))) { return new Pair<>(false, new LinkedHashMap<>()); }/*from w ww . j a v a 2 s . com*/ Mutable<ILogicalOperator> inputOpRef = subplanOp.getInputs().get(0); ILogicalOperator inputOpBackup = inputOpRef.getValue(); // Creates parameters for the left outer join operator. Pair<ILogicalOperator, Set<LogicalVariable>> primaryOpAndVars = EquivalenceClassUtils .findOrCreatePrimaryKeyOpAndVariables(inputOpBackup, true, context); ILogicalOperator inputOp = primaryOpAndVars.first; Set<LogicalVariable> primaryKeyVars = primaryOpAndVars.second; inputOpRef.setValue(inputOp); Set<LogicalVariable> inputLiveVars = new HashSet<>(); VariableUtilities.getLiveVariables(inputOp, inputLiveVars); Pair<Map<LogicalVariable, LogicalVariable>, List<Pair<IOrder, Mutable<ILogicalExpression>>>> varMapAndOrderExprs = SubplanFlatteningUtil .inlineAllNestedTupleSource(subplanOp, context); Map<LogicalVariable, LogicalVariable> varMap = varMapAndOrderExprs.first; if (varMap == null) { inputOpRef.setValue(inputOpBackup); return new Pair<>(false, new LinkedHashMap<>()); } Mutable<ILogicalOperator> lowestAggregateRefInSubplan = SubplanFlatteningUtil .findLowestAggregate(subplanOp.getNestedPlans().get(0).getRoots().get(0)); Mutable<ILogicalOperator> rightInputOpRef = lowestAggregateRefInSubplan.getValue().getInputs().get(0); ILogicalOperator rightInputOp = rightInputOpRef.getValue(); // Creates a variable to indicate whether a left input tuple is killed in the plan rooted at rightInputOp. LogicalVariable assignVar = context.newVar(); ILogicalOperator assignOp = new AssignOperator(assignVar, new MutableObject<>(ConstantExpression.TRUE)); assignOp.getInputs().add(rightInputOpRef); context.computeAndSetTypeEnvironmentForOperator(assignOp); rightInputOpRef = new MutableObject<>(assignOp); // Constructs the join predicate for the leftOuter join. List<Mutable<ILogicalExpression>> joinPredicates = new ArrayList<>(); for (LogicalVariable liveVar : primaryKeyVars) { List<Mutable<ILogicalExpression>> arguments = new ArrayList<>(); arguments.add(new MutableObject<>(new VariableReferenceExpression(liveVar))); LogicalVariable rightVar = varMap.get(liveVar); arguments.add(new MutableObject<>(new VariableReferenceExpression(rightVar))); ILogicalExpression expr = new ScalarFunctionCallExpression( FunctionUtil.getFunctionInfo(AlgebricksBuiltinFunctions.EQ), arguments); joinPredicates.add(new MutableObject<>(expr)); } ILogicalExpression joinExpr = joinPredicates.size() > 1 ? new ScalarFunctionCallExpression(FunctionUtil.getFunctionInfo(AlgebricksBuiltinFunctions.AND), joinPredicates) : joinPredicates.size() > 0 ? joinPredicates.get(0).getValue() : ConstantExpression.TRUE; LeftOuterJoinOperator leftOuterJoinOp = new LeftOuterJoinOperator(new MutableObject<>(joinExpr), inputOpRef, rightInputOpRef); OperatorManipulationUtil.computeTypeEnvironmentBottomUp(rightInputOp, context); context.computeAndSetTypeEnvironmentForOperator(leftOuterJoinOp); // Creates group-by operator. List<Pair<LogicalVariable, Mutable<ILogicalExpression>>> groupByList = new ArrayList<Pair<LogicalVariable, Mutable<ILogicalExpression>>>(); List<Pair<LogicalVariable, Mutable<ILogicalExpression>>> groupByDecorList = new ArrayList<Pair<LogicalVariable, Mutable<ILogicalExpression>>>(); List<ILogicalPlan> nestedPlans = new ArrayList<>(); GroupByOperator groupbyOp = new GroupByOperator(groupByList, groupByDecorList, nestedPlans); LinkedHashMap<LogicalVariable, LogicalVariable> replacedVarMap = new LinkedHashMap<>(); for (LogicalVariable liveVar : primaryKeyVars) { LogicalVariable newVar = context.newVar(); groupByList.add(new Pair<>(newVar, new MutableObject<>(new VariableReferenceExpression(liveVar)))); // Adds variables for replacements in ancestors. replacedVarMap.put(liveVar, newVar); } for (LogicalVariable liveVar : inputLiveVars) { if (primaryKeyVars.contains(liveVar)) { continue; } groupByDecorList.add(new Pair<>(null, new MutableObject<>(new VariableReferenceExpression(liveVar)))); } // Sets up the nested plan for the groupby operator. Mutable<ILogicalOperator> aggOpRef = subplanOp.getNestedPlans().get(0).getRoots().get(0); lowestAggregateRefInSubplan.getValue().getInputs().clear(); // Clears the input of the lowest aggregate. Mutable<ILogicalOperator> currentOpRef = lowestAggregateRefInSubplan; // Adds an optional order operator. List<Pair<IOrder, Mutable<ILogicalExpression>>> orderExprs = varMapAndOrderExprs.second; if (!orderExprs.isEmpty()) { OrderOperator orderOp = new OrderOperator(orderExprs); currentOpRef = new MutableObject<>(orderOp); lowestAggregateRefInSubplan.getValue().getInputs().add(currentOpRef); } // Adds a select operator into the nested plan for group-by to remove tuples with NULL on {@code assignVar}, i.e., // subplan input tuples that are filtered out within a subplan. Mutable<ILogicalExpression> filterVarExpr = new MutableObject<>(new VariableReferenceExpression(assignVar)); List<Mutable<ILogicalExpression>> args = new ArrayList<>(); args.add(filterVarExpr); List<Mutable<ILogicalExpression>> argsForNotFunction = new ArrayList<>(); argsForNotFunction.add(new MutableObject<>(new ScalarFunctionCallExpression( FunctionUtil.getFunctionInfo(AsterixBuiltinFunctions.IS_MISSING), args))); SelectOperator selectOp = new SelectOperator( new MutableObject<>(new ScalarFunctionCallExpression( FunctionUtil.getFunctionInfo(AsterixBuiltinFunctions.NOT), argsForNotFunction)), false, null); currentOpRef.getValue().getInputs().add(new MutableObject<>(selectOp)); selectOp.getInputs() .add(new MutableObject<>(new NestedTupleSourceOperator(new MutableObject<>(groupbyOp)))); List<Mutable<ILogicalOperator>> nestedRoots = new ArrayList<>(); nestedRoots.add(aggOpRef); nestedPlans.add(new ALogicalPlanImpl(nestedRoots)); groupbyOp.getInputs().add(new MutableObject<>(leftOuterJoinOp)); // Replaces subplan with the group-by operator. opRef.setValue(groupbyOp); OperatorManipulationUtil.computeTypeEnvironmentBottomUp(groupbyOp, context); // Recursively applys this rule to the nested plan of the subplan operator, // for the case where there are nested subplan operators within {@code subplanOp}. Pair<Boolean, LinkedHashMap<LogicalVariable, LogicalVariable>> result = rewriteSubplanOperator( rightInputOpRef, context); VariableUtilities.substituteVariables(leftOuterJoinOp, result.second, context); VariableUtilities.substituteVariables(groupbyOp, result.second, context); // No var mapping from the right input operator should be populated up. return new Pair<>(true, replacedVarMap); }
From source file:org.apache.asterix.optimizer.rules.subplan.InlineSubplanInputForNestedTupleSourceRule.java
private Pair<Boolean, LinkedHashMap<LogicalVariable, LogicalVariable>> applySpecialFlattening( Mutable<ILogicalOperator> opRef, IOptimizationContext context) throws AlgebricksException { SubplanOperator subplanOp = (SubplanOperator) opRef.getValue(); Mutable<ILogicalOperator> inputOpRef = subplanOp.getInputs().get(0); LinkedHashMap<LogicalVariable, LogicalVariable> replacedVarMap = new LinkedHashMap<>(); // Recursively applies this rule to the nested plan of the subplan operator, // for the case where there are nested subplan operators within {@code subplanOp}. Pair<Boolean, LinkedHashMap<LogicalVariable, LogicalVariable>> result = rewriteSubplanOperator( subplanOp.getNestedPlans().get(0).getRoots().get(0), context); ILogicalOperator inputOpBackup = inputOpRef.getValue(); // Gets live variables and covering variables from the subplan's input operator. Pair<ILogicalOperator, Set<LogicalVariable>> primaryOpAndVars = EquivalenceClassUtils .findOrCreatePrimaryKeyOpAndVariables(inputOpBackup, false, context); ILogicalOperator inputOp = primaryOpAndVars.first; Set<LogicalVariable> primaryKeyVars = primaryOpAndVars.second; inputOpRef.setValue(inputOp);// w w w. jav a 2 s. c o m Set<LogicalVariable> liveVars = new HashSet<>(); VariableUtilities.getLiveVariables(inputOp, liveVars); Pair<Set<LogicalVariable>, Mutable<ILogicalOperator>> notNullVarsAndTopJoinRef = SubplanFlatteningUtil .inlineLeftNtsInSubplanJoin(subplanOp, context); if (notNullVarsAndTopJoinRef.first == null) { inputOpRef.setValue(inputOpBackup); return new Pair<>(false, replacedVarMap); } Set<LogicalVariable> notNullVars = notNullVarsAndTopJoinRef.first; Mutable<ILogicalOperator> topJoinRef = notNullVarsAndTopJoinRef.second; // Creates a group-by operator. List<Pair<LogicalVariable, Mutable<ILogicalExpression>>> groupByList = new ArrayList<Pair<LogicalVariable, Mutable<ILogicalExpression>>>(); List<Pair<LogicalVariable, Mutable<ILogicalExpression>>> groupByDecorList = new ArrayList<Pair<LogicalVariable, Mutable<ILogicalExpression>>>(); GroupByOperator groupbyOp = new GroupByOperator(groupByList, groupByDecorList, subplanOp.getNestedPlans()); for (LogicalVariable coverVar : primaryKeyVars) { LogicalVariable newVar = context.newVar(); groupByList.add(new Pair<>(newVar, new MutableObject<>(new VariableReferenceExpression(coverVar)))); // Adds variables for replacements in ancestors. replacedVarMap.put(coverVar, newVar); } for (LogicalVariable liveVar : liveVars) { if (primaryKeyVars.contains(liveVar)) { continue; } groupByDecorList.add(new Pair<>(null, new MutableObject<>(new VariableReferenceExpression(liveVar)))); } groupbyOp.getInputs().add(new MutableObject<>(topJoinRef.getValue())); if (!notNullVars.isEmpty()) { // Adds a select operator into the nested plan for group-by to remove tuples with NULL on {@code assignVar}, i.e., // subplan input tuples that are filtered out within a subplan. List<Mutable<ILogicalExpression>> nullCheckExprRefs = new ArrayList<>(); for (LogicalVariable notNullVar : notNullVars) { Mutable<ILogicalExpression> filterVarExpr = new MutableObject<>( new VariableReferenceExpression(notNullVar)); List<Mutable<ILogicalExpression>> args = new ArrayList<>(); args.add(filterVarExpr); List<Mutable<ILogicalExpression>> argsForNotFunction = new ArrayList<>(); argsForNotFunction.add(new MutableObject<>(new ScalarFunctionCallExpression( FunctionUtil.getFunctionInfo(AsterixBuiltinFunctions.IS_MISSING), args))); nullCheckExprRefs.add(new MutableObject<>(new ScalarFunctionCallExpression( FunctionUtil.getFunctionInfo(AsterixBuiltinFunctions.NOT), argsForNotFunction))); } Mutable<ILogicalExpression> selectExprRef = nullCheckExprRefs.size() > 1 ? new MutableObject<>(new ScalarFunctionCallExpression( FunctionUtil.getFunctionInfo(AsterixBuiltinFunctions.AND), nullCheckExprRefs)) : nullCheckExprRefs.get(0); SelectOperator selectOp = new SelectOperator(selectExprRef, false, null); topJoinRef.setValue(selectOp); selectOp.getInputs() .add(new MutableObject<>(new NestedTupleSourceOperator(new MutableObject<>(groupbyOp)))); } else { // The original join operator in the Subplan is a left-outer join. // Therefore, no null-check variable is injected and no SelectOperator needs to be added. topJoinRef.setValue(new NestedTupleSourceOperator(new MutableObject<>(groupbyOp))); } opRef.setValue(groupbyOp); OperatorManipulationUtil.computeTypeEnvironmentBottomUp(groupbyOp, context); VariableUtilities.substituteVariables(groupbyOp, result.second, context); replacedVarMap.putAll(result.second); return new Pair<>(true, replacedVarMap); }
From source file:org.apache.asterix.optimizer.rules.subplan.SubplanFlatteningUtil.java
/** * Inline the left NTS in a subplan that satisfies a special condition indicated * by canFlattenSubplanJoinRuleFire(...). * * @param subplanOp//from w w w . j ava2s .c om * the SubplanOperator * @param context * the optimization context * @return A set of variables used for further null-checks, i.e., variables indicating * whether a tuple produced by a transformed left outer join is a non-match; * a reference to the top join operator in the nested subplan. * @throws AlgebricksException */ public static Pair<Set<LogicalVariable>, Mutable<ILogicalOperator>> inlineLeftNtsInSubplanJoin( SubplanOperator subplanOp, IOptimizationContext context) throws AlgebricksException { Pair<Boolean, ILogicalOperator> applicableAndNtsToRewrite = SubplanFlatteningUtil .isQualifiedForSpecialFlattening(subplanOp); if (!applicableAndNtsToRewrite.first) { return new Pair<Set<LogicalVariable>, Mutable<ILogicalOperator>>(null, null); } ILogicalOperator qualifiedNts = applicableAndNtsToRewrite.second; ILogicalOperator subplanInputOp = subplanOp.getInputs().get(0).getValue(); InlineLeftNtsInSubplanJoinFlatteningVisitor specialVisitor = new InlineLeftNtsInSubplanJoinFlatteningVisitor( context, subplanInputOp, qualifiedNts); // Rewrites the query plan. Mutable<ILogicalOperator> topRef = subplanOp.getNestedPlans().get(0).getRoots().get(0); ILogicalOperator result = topRef.getValue().accept(specialVisitor, null); // The special visitor doesn't replace any input or local variables. Mutable<ILogicalOperator> topJoinRef = specialVisitor.getTopJoinReference(); topRef.setValue(result); // Inline the rest Nts's as general cases. InlineAllNtsInSubplanVisitor generalVisitor = new InlineAllNtsInSubplanVisitor(context, subplanOp); ILogicalOperator opToVisit = topJoinRef.getValue(); result = opToVisit.accept(generalVisitor, null); topJoinRef.setValue(result); // Substitute variables in nested pipeline above the top join operator in the nested pipeline if necessary. List<Pair<LogicalVariable, LogicalVariable>> subplanLocalVarMap = generalVisitor.getVariableMapHistory(); ILogicalOperator currentOp = topRef.getValue(); while (currentOp != result) { VariableUtilities.substituteVariables(currentOp, subplanLocalVarMap, context); currentOp = currentOp.getInputs().get(0).getValue(); } return new Pair<Set<LogicalVariable>, Mutable<ILogicalOperator>>(specialVisitor.getNullCheckVariables(), topJoinRef); }
From source file:org.apache.asterix.optimizer.rules.subplan.SubplanFlatteningUtil.java
/** * @param subplanOp//from ww w . j a va 2s.c om * a SubplanOperator * @return whether there is a data source scan in the nested logical plans of {@code subplanOp}. */ public static boolean containsOperators(SubplanOperator subplanOp, Set<LogicalOperatorTag> interestedOperatorTags) { List<ILogicalPlan> nestedPlans = subplanOp.getNestedPlans(); for (ILogicalPlan nestedPlan : nestedPlans) { for (Mutable<ILogicalOperator> opRef : nestedPlan.getRoots()) { if (containsOperatorsInternal(opRef.getValue(), interestedOperatorTags)) { return true; } } } return false; }
From source file:org.apache.asterix.optimizer.rules.subplan.SubplanFlatteningUtil.java
/** * Whether the query plan rooted {@code currentOp} contains a data source scan operator, * with considering nested subplans./*w ww .ja v a2s .c o m*/ * * @param currentOp * the current operator * @return true if {@code currentOp} contains a data source scan operator; false otherwise. */ public static boolean containsOperatorsInternal(ILogicalOperator currentOp, Set<LogicalOperatorTag> interestedOperatorTags) { if (interestedOperatorTags.contains(currentOp.getOperatorTag())) { return true; } if (currentOp.getOperatorTag() == LogicalOperatorTag.SUBPLAN && containsOperators((SubplanOperator) currentOp, interestedOperatorTags)) { return true; } for (Mutable<ILogicalOperator> childRef : currentOp.getInputs()) { if (containsOperatorsInternal(childRef.getValue(), interestedOperatorTags)) { return true; } } return false; }
From source file:org.apache.asterix.optimizer.rules.subplan.SubplanFlatteningUtil.java
/** * Finds the lowest aggregate operator that should be put into a nested aggregation pipeline within a group-by * operator./*from w ww . j a v a 2s . c om*/ * <p/> * Note that neither binary input operators nor data scan can be put into a group by operator. * * @param currentOpRef, * the current root operator reference to look at. * @return the operator reference of the lowest qualified aggregate operator. */ public static Mutable<ILogicalOperator> findLowestAggregate(Mutable<ILogicalOperator> currentOpRef) { ILogicalOperator currentOp = currentOpRef.getValue(); // Neither binary input operators nor data scan can be put into a group by operator. if (currentOp.getInputs().size() != 1 || currentOp.getOperatorTag() == LogicalOperatorTag.DATASOURCESCAN) { return null; } Mutable<ILogicalOperator> childReturn = findLowestAggregate(currentOp.getInputs().get(0)); if (childReturn == null) { return currentOp.getOperatorTag() == LogicalOperatorTag.AGGREGATE ? currentOpRef : null; } return childReturn; }
From source file:org.apache.asterix.optimizer.rules.subplan.SubplanFlatteningUtil.java
/** * Determine whether a subplan could be rewritten as a join-related special case. * The conditions include://from w ww . j a v a 2s . co m * a. there is a join (let's call it J1.) in the nested plan, * b. if J1 is an inner join, one input pipeline of J1 has a NestedTupleSource descendant (let's call it N1), * c. if J1 is a left outer join, the left branch of J1 has a NestedTupleSource descendant (let's call it N1), * d. there is no tuple dropping from N1 to J1. * * @param subplanOp, * the SubplanOperator to consider * @return TRUE if the rewriting is applicable; FALSE otherwise. * @throws AlgebricksException */ private static Pair<Boolean, ILogicalOperator> isQualifiedForSpecialFlattening(SubplanOperator subplanOp) throws AlgebricksException { if (!OperatorManipulationUtil.ancestorOfOperators( subplanOp.getNestedPlans().get(0).getRoots().get(0).getValue(), // we don't need to check recursively for this special rewriting. ImmutableSet.of(LogicalOperatorTag.INNERJOIN, LogicalOperatorTag.LEFTOUTERJOIN))) { return new Pair<Boolean, ILogicalOperator>(false, null); } SubplanSpecialFlatteningCheckVisitor visitor = new SubplanSpecialFlatteningCheckVisitor(); for (ILogicalPlan plan : subplanOp.getNestedPlans()) { for (Mutable<ILogicalOperator> opRef : plan.getRoots()) { if (!opRef.getValue().accept(visitor, null)) { return new Pair<Boolean, ILogicalOperator>(false, null); } } } return new Pair<Boolean, ILogicalOperator>(true, visitor.getQualifiedNts()); }
From source file:org.apache.asterix.optimizer.rules.subplan.SubplanSpecialFlatteningCheckVisitor.java
@Override public Boolean visitInnerJoinOperator(InnerJoinOperator op, Void arg) throws AlgebricksException { for (Mutable<ILogicalOperator> childRef : op.getInputs()) { if (childRef.getValue().accept(this, null) && !rejectPending) { return true; }/*from w w w . ja va 2 s . co m*/ rejectPending = false; } return false; }
From source file:org.apache.asterix.optimizer.rules.subplan.SubplanSpecialFlatteningCheckVisitor.java
private boolean visitInputs(ILogicalOperator op) throws AlgebricksException { for (Mutable<ILogicalOperator> childRef : op.getInputs()) { if (childRef.getValue().accept(this, null)) { // One input is qualified. return true; }// ww w . j a va 2 s. com } // All inputs are disqualified. return false; }
From source file:org.apache.asterix.optimizer.rules.SweepIllegalNonfunctionalFunctions.java
@Override public boolean rewritePost(Mutable<ILogicalOperator> opRef, IOptimizationContext context) throws AlgebricksException { ILogicalOperator op = opRef.getValue(); if (context.checkIfInDontApplySet(this, op)) { return false; }/*w ww . j a v a 2 s .c o m*/ op.accept(visitor, null); context.computeAndSetTypeEnvironmentForOperator(op); context.addToDontApplySet(this, op); return false; }