private void addKeyVarsAndExprs(IOptimizableFuncExpr optFuncExpr, ArrayList<LogicalVariable> keyVarList, ArrayList<Mutable<ILogicalExpression>> keyExprList, IOptimizationContext context) throws AlgebricksException { // For now we are assuming a single secondary index key. // 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>(optFuncExpr.getConstantExpr(0))); return; }
private void propagateFilterInSecondaryUnnsetMap(UnnestMapOperator secondaryUnnest, IAType filterType, IOptimizationContext context) throws AlgebricksException { LogicalVariable minIndexFilterVar = context.newVar(); LogicalVariable maxIndexFilterVar = context.newVar(); secondaryUnnest.markPropagageIndexFilter(); secondaryUnnest.getVariables().add(minIndexFilterVar); secondaryUnnest.getVariableTypes().add(filterType); secondaryUnnest.getVariables().add(maxIndexFilterVar); secondaryUnnest.getVariableTypes().add(filterType); context.computeAndSetTypeEnvironmentForOperator(secondaryUnnest); }
private int createKeyVarsAndExprs(int numKeys, LimitType[] keyLimits, ILogicalExpression[] searchKeyExprs, ArrayList<LogicalVariable> assignKeyVarList, ArrayList<Mutable<ILogicalExpression>> assignKeyExprList, ArrayList<LogicalVariable> keyVarList, IOptimizationContext context, ILogicalExpression[] constExpressions, LogicalVariable[] constExprVars) { if (keyLimits[0] == null) { return 0; } for (int i = 0; i < numKeys; i++) { ILogicalExpression searchKeyExpr = searchKeyExprs[i]; ILogicalExpression constExpression = constExpressions[i]; LogicalVariable keyVar = null; if (searchKeyExpr.getExpressionTag() == LogicalExpressionTag.CONSTANT) { keyVar = context.newVar(); assignKeyExprList.add(new MutableObject<>(searchKeyExpr)); assignKeyVarList.add(keyVar); } else { keyVar = ((VariableReferenceExpression) searchKeyExpr).getVariableReference(); if (constExpression != null) { assignKeyExprList.add(new MutableObject<>(constExpression)); assignKeyVarList.add(constExprVars[i]); } } keyVarList.add(keyVar); } return numKeys; }
private AssignOperator createAssignOperator(List<IOptimizableFuncExpr> optFuncExprs, List<LogicalVariable> minFilterVars, List<LogicalVariable> maxFilterVars, IOptimizationContext context, SourceLocation sourceLoc) { List<LogicalVariable> assignKeyVarList = new ArrayList<>(); List<Mutable<ILogicalExpression>> assignKeyExprList = new ArrayList<>(); for (IOptimizableFuncExpr optFuncExpr : optFuncExprs) { ComparisonKind ck = AlgebricksBuiltinFunctions.getComparisonType(optFuncExpr.getFuncExpr().getFunctionIdentifier()); ILogicalExpression searchKeyExpr = optFuncExpr.getConstantExpr(0); LogicalVariable var = context.newVar(); assignKeyExprList.add(new MutableObject<>(searchKeyExpr)); assignKeyVarList.add(var); if (ck == ComparisonKind.GE || ck == ComparisonKind.GT) { minFilterVars.add(var); } else if (ck == ComparisonKind.LE || ck == ComparisonKind.LT) { maxFilterVars.add(var); } else if (ck == ComparisonKind.EQ) { minFilterVars.add(var); maxFilterVars.add(var); } } AssignOperator assignOp = new AssignOperator(assignKeyVarList, assignKeyExprList); assignOp.setSourceLocation(sourceLoc); return assignOp; }
/** * Clones the given assign operator changing the returned variables to be new ones. * Also, leaves the inputs of the clone clear. */ private AssignOperator cloneAssignOperator(AssignOperator assignOp, IOptimizationContext context) { List<LogicalVariable> vars = new ArrayList<LogicalVariable>(); List<Mutable<ILogicalExpression>> exprs = new ArrayList<Mutable<ILogicalExpression>>(); int numVars = assignOp.getVariables().size(); for (int i = 0; i < numVars; i++) { vars.add(context.newVar()); exprs.add(new MutableObject<ILogicalExpression>( assignOp.getExpressions().get(i).getValue().cloneExpression())); } AssignOperator assignCloneOp = new AssignOperator(vars, exprs); assignCloneOp.setSourceLocation(assignOp.getSourceLocation()); assignCloneOp.setExecutionMode(assignOp.getExecutionMode()); return assignCloneOp; } }
/** * Inject variables to indicate non-matches for the right branch of a left-outer join. * * @param joinOp * the leftouter join operator. */ private void injectNullCheckVars(AbstractBinaryJoinOperator joinOp) { LogicalVariable assignVar = context.newVar(); AssignOperator assignOp = new AssignOperator(assignVar, new MutableObject<ILogicalExpression>(ConstantExpression.TRUE)); assignOp.setSourceLocation(joinOp.getSourceLocation()); assignOp.getInputs().add(joinOp.getInputs().get(1)); joinOp.getInputs().set(1, new MutableObject<ILogicalOperator>(assignOp)); nullCheckVars.add(assignVar); }
private boolean extractFirstArg(AbstractFunctionCallExpression fce, ILogicalOperator op, IOptimizationContext context) throws AlgebricksException { ILogicalExpression firstArg = fce.getArguments().get(0).getValue(); if (firstArg.getExpressionTag() != LogicalExpressionTag.FUNCTION_CALL) { return false; } SourceLocation sourceLoc = firstArg.getSourceLocation(); LogicalVariable var1 = context.newVar(); AssignOperator assignOp = new AssignOperator(new ArrayList<>(Collections.singletonList(var1)), new ArrayList<>(Collections.singletonList(new MutableObject<>(firstArg)))); assignOp.setSourceLocation(sourceLoc); VariableReferenceExpression var1Ref = new VariableReferenceExpression(var1); var1Ref.setSourceLocation(sourceLoc); fce.getArguments().get(0).setValue(var1Ref); assignOp.getInputs().add(new MutableObject<>(op.getInputs().get(0).getValue())); op.getInputs().get(0).setValue(assignOp); context.computeAndSetTypeEnvironmentForOperator(assignOp); return true; }
LogicalVariable replacementVar = context.newVar(); assignVars.add(replacementVar); assignExprs.add(new MutableObject<ILogicalExpression>(funcExpr));
for (LogicalVariable keyVar : correlatedKeyVars) { if (!groupKeyVars.contains(keyVar)) { LogicalVariable newVar = context.newVar(); VariableReferenceExpression keyVarRef = new VariableReferenceExpression(keyVar); keyVarRef.setSourceLocation(op.getSourceLocation());
/** * Creates output variables for the given unnest-map or left-outer-unnestmap operator * that does a secondary index lookup. * The order: SK, PK, [Optional: the result of a instantTryLock on PK] */ public static void appendSecondaryIndexOutputVars(Dataset dataset, ARecordType recordType, ARecordType metaRecordType, Index index, IOptimizationContext context, List<LogicalVariable> dest, boolean requireResultOfInstantTryLock) throws AlgebricksException { int numPrimaryKeys; if (dataset.getDatasetType() == DatasetType.EXTERNAL) { numPrimaryKeys = IndexingConstants .getRIDSize(((ExternalDatasetDetails) dataset.getDatasetDetails()).getProperties()); } else { numPrimaryKeys = dataset.getPrimaryKeys().size(); } int numSecondaryKeys = KeyFieldTypeUtil.getNumSecondaryKeys(index, recordType, metaRecordType); // In case of an inverted-index search, secondary keys will not be generated. int numVars = isInvertedIndex(index) ? numPrimaryKeys : numPrimaryKeys + numSecondaryKeys; // If it's an index-only plan, add one more variable to put the result of instantTryLock on PK - // whether this lock can be granted on a primary key. // If it is granted, then we don't need to do a post verification (select). // If it is not granted, then we need to do a secondary index lookup, do a primary index lookup, and select. if (requireResultOfInstantTryLock) { numVars += 1; } for (int i = 0; i < numVars; i++) { dest.add(context.newVar()); } }
private Pair<ILogicalOperator, LogicalVariable> createUnnestForAggregatedList(LogicalVariable aggVar, SourceLocation sourceLoc) { LogicalVariable unnestVar = context.newVar(); // Creates an unnest function expression. VariableReferenceExpression aggVarRef = new VariableReferenceExpression(aggVar); aggVarRef.setSourceLocation(sourceLoc); Mutable<ILogicalExpression> unnestArg = new MutableObject<>(aggVarRef); List<Mutable<ILogicalExpression>> unnestArgList = new ArrayList<>(); unnestArgList.add(unnestArg); UnnestingFunctionCallExpression unnestExpr = new UnnestingFunctionCallExpression( FunctionUtil.getFunctionInfo(BuiltinFunctions.SCAN_COLLECTION), unnestArgList); unnestExpr.setSourceLocation(sourceLoc); UnnestOperator unnestOp = new UnnestOperator(unnestVar, new MutableObject<>(unnestExpr)); unnestOp.setSourceLocation(sourceLoc); return new Pair<>(unnestOp, unnestVar); }
private ILogicalOperator createFieldAccessAssignOperator(LogicalVariable recordVar, Set<LogicalVariable> inputLiveVars, SourceLocation sourceLoc) { List<LogicalVariable> fieldAccessVars = new ArrayList<>(); List<Mutable<ILogicalExpression>> fieldAccessExprs = new ArrayList<>(); // Adds field access by name. for (LogicalVariable inputLiveVar : inputLiveVars) { if (!correlatedKeyVars.contains(inputLiveVar)) { // field Var LogicalVariable newVar = context.newVar(); fieldAccessVars.add(newVar); // fieldAcess expr List<Mutable<ILogicalExpression>> argRefs = new ArrayList<>(); VariableReferenceExpression recordVarRef = new VariableReferenceExpression(recordVar); recordVarRef.setSourceLocation(sourceLoc); argRefs.add(new MutableObject<>(recordVarRef)); argRefs.add(new MutableObject<>(new ConstantExpression( new AsterixConstantValue(new AString(Integer.toString(inputLiveVar.getId())))))); ScalarFunctionCallExpression faExpr = new ScalarFunctionCallExpression( FunctionUtil.getFunctionInfo(BuiltinFunctions.FIELD_ACCESS_BY_NAME), argRefs); faExpr.setSourceLocation(sourceLoc); fieldAccessExprs.add(new MutableObject<>(faExpr)); // Updates variable mapping for ancestor operators. updateInputToOutputVarMapping(inputLiveVar, newVar, false); } } AssignOperator assignOp = new AssignOperator(fieldAccessVars, fieldAccessExprs); assignOp.setSourceLocation(sourceLoc); return assignOp; }
private Map<LogicalVariable, LogicalVariable> buildVarExprList(Collection<LogicalVariable> vars, IOptimizationContext context, GroupByOperator g, List<Pair<LogicalVariable, Mutable<ILogicalExpression>>> outVeList) throws AlgebricksException { SourceLocation sourceLoc = g.getSourceLocation(); Map<LogicalVariable, LogicalVariable> m = new HashMap<LogicalVariable, LogicalVariable>(); for (LogicalVariable ov : vars) { LogicalVariable newVar = context.newVar(); ILogicalExpression varExpr = new VariableReferenceExpression(newVar); ((VariableReferenceExpression) varExpr).setSourceLocation(sourceLoc); outVeList.add(new Pair<LogicalVariable, Mutable<ILogicalExpression>>(ov, new MutableObject<ILogicalExpression>(varExpr))); for (ILogicalPlan p : g.getNestedPlans()) { for (Mutable<ILogicalOperator> r : p.getRoots()) { OperatorManipulationUtil.substituteVarRec((AbstractLogicalOperator) r.getValue(), ov, newVar, true, context); } } AbstractLogicalOperator opUnder = (AbstractLogicalOperator) g.getInputs().get(0).getValue(); OperatorManipulationUtil.substituteVarRec(opUnder, ov, newVar, true, context); m.put(ov, newVar); } return m; } }
LogicalVariable newVar = context.newVar(); vars.add(newVar); exprs.add(exprRef);
protected void buildVarExprList(Collection<LogicalVariable> vars, IOptimizationContext context, GroupByOperator g, List<Pair<LogicalVariable, Mutable<ILogicalExpression>>> outVeList) throws AlgebricksException { SourceLocation sourceLoc = g.getSourceLocation(); for (LogicalVariable ov : vars) { LogicalVariable newVar = context.newVar(); VariableReferenceExpression varExpr = new VariableReferenceExpression(newVar); varExpr.setSourceLocation(sourceLoc); outVeList.add(new Pair<LogicalVariable, Mutable<ILogicalExpression>>(ov, new MutableObject<ILogicalExpression>(varExpr))); for (ILogicalPlan p : g.getNestedPlans()) { for (Mutable<ILogicalOperator> r : p.getRoots()) { OperatorManipulationUtil.substituteVarRec((AbstractLogicalOperator) r.getValue(), ov, newVar, true, context); } } } }
private Pair<ILogicalOperator, LogicalVariable> createRecordConstructorAssignOp(Set<LogicalVariable> inputLiveVars, SourceLocation sourceLoc) { // Creates a nested record. List<Mutable<ILogicalExpression>> recordConstructorArgs = new ArrayList<>(); for (LogicalVariable inputLiveVar : inputLiveVars) { if (!correlatedKeyVars.contains(inputLiveVar)) { recordConstructorArgs.add(new MutableObject<>(new ConstantExpression( new AsterixConstantValue(new AString(Integer.toString(inputLiveVar.getId())))))); VariableReferenceExpression inputLiveVarRef = new VariableReferenceExpression(inputLiveVar); inputLiveVarRef.setSourceLocation(sourceLoc); recordConstructorArgs.add(new MutableObject<>(inputLiveVarRef)); } } LogicalVariable recordVar = context.newVar(); ScalarFunctionCallExpression openRecConstr = new ScalarFunctionCallExpression( FunctionUtil.getFunctionInfo(BuiltinFunctions.OPEN_RECORD_CONSTRUCTOR), recordConstructorArgs); openRecConstr.setSourceLocation(sourceLoc); Mutable<ILogicalExpression> recordExprRef = new MutableObject<ILogicalExpression>(openRecConstr); AssignOperator assignOp = new AssignOperator(recordVar, recordExprRef); assignOp.setSourceLocation(sourceLoc); return new Pair<>(assignOp, recordVar); }
protected static LogicalVariable extractExprIntoAssignOpRef(ILogicalExpression gExpr, Mutable<ILogicalOperator> opRef2, IOptimizationContext context) throws AlgebricksException { LogicalVariable v = context.newVar(); AssignOperator a = new AssignOperator(v, new MutableObject<>(gExpr)); a.setSourceLocation(gExpr.getSourceLocation()); a.getInputs().add(new MutableObject<>(opRef2.getValue())); opRef2.setValue(a); if (gExpr.getExpressionTag() == LogicalExpressionTag.CONSTANT) { context.addNotToBeInlinedVar(v); } context.computeAndSetTypeEnvironmentForOperator(a); return v; }
LogicalVariable assignVariable = context.newVar(); AssignOperator aOp = new AssignOperator(assignVariable, assignExpression); for (Mutable<ILogicalOperator> input : aggregate.getInputs()) {
private boolean assignCommonExpression(ExprEquivalenceClass exprEqClass, ILogicalExpression expr) throws AlgebricksException { SourceLocation sourceLoc = expr.getSourceLocation(); AbstractLogicalOperator firstOp = (AbstractLogicalOperator) exprEqClass.getFirstOperator(); Mutable<ILogicalExpression> firstExprRef = exprEqClass.getFirstExpression(); // We don't consider to eliminate common exprs in join operators by doing a cartesian production // and pulling the condition in to a select. This will negatively impact the performance. if (firstOp.getInputs().size() > 1) { // Bail for any non-join operator with multiple inputs. return false; } LogicalVariable newVar = context.newVar(); AssignOperator newAssign = new AssignOperator(newVar, new MutableObject<ILogicalExpression>(firstExprRef.getValue().cloneExpression())); newAssign.setSourceLocation(sourceLoc); // Place assign below firstOp. newAssign.getInputs().add(new MutableObject<ILogicalOperator>(firstOp.getInputs().get(0).getValue())); newAssign.setExecutionMode(firstOp.getExecutionMode()); firstOp.getInputs().get(0).setValue(newAssign); // Replace original expr with variable reference, and set var in expression equivalence class. VariableReferenceExpression newVarRef = new VariableReferenceExpression(newVar); newVarRef.setSourceLocation(sourceLoc); firstExprRef.setValue(newVarRef); exprEqClass.setVariable(newVar); context.computeAndSetTypeEnvironmentForOperator(newAssign); context.computeAndSetTypeEnvironmentForOperator(firstOp); return true; }
LogicalVariable v = context.newVar(); AssignOperator assignOperator = new AssignOperator(v, new MutableObject<ILogicalExpression>(selectOperator.getCondition().getValue()));