List of usage examples for org.apache.commons.lang3.mutable Mutable setValue
void setValue(T value);
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; }