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 void removeGroupByAndOuterUnnest(Mutable<ILogicalOperator> opRef, IOptimizationContext context, LeftOuterUnnestOperator outerUnnest, GroupByOperator gbyOperator, LeftOuterJoinOperator lojOperator, LogicalVariable listifyVar) throws AlgebricksException { List<LogicalVariable> lhs = new ArrayList<>(); List<Mutable<ILogicalExpression>> rhs = new ArrayList<>(); lhs.add(outerUnnest.getVariable()); VariableReferenceExpression listifyVarRef = new VariableReferenceExpression(listifyVar); listifyVarRef.setSourceLocation(gbyOperator.getSourceLocation()); rhs.add(new MutableObject<ILogicalExpression>(listifyVarRef)); List<Pair<LogicalVariable, Mutable<ILogicalExpression>>> gbyList = gbyOperator.getGroupByList(); for (Pair<LogicalVariable, Mutable<ILogicalExpression>> gbyPair : gbyList) { lhs.add(gbyPair.first); rhs.add(gbyPair.second); } AssignOperator assignOp = new AssignOperator(lhs, rhs); assignOp.setSourceLocation(outerUnnest.getSourceLocation()); assignOp.getInputs().add(new MutableObject<ILogicalOperator>(lojOperator)); context.computeAndSetTypeEnvironmentForOperator(assignOp); opRef.setValue(assignOp); }
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; }
protected Pair<ILogicalOperator, LogicalVariable> visitAndOrOperator(OperatorExpr op, Mutable<ILogicalOperator> tupSource) throws CompilationException { SourceLocation sourceLoc = op.getSourceLocation(); List<OperatorType> ops = op.getOpList(); int nOps = ops.size(); List<Expression> exprs = op.getExprList(); Mutable<ILogicalOperator> topOp = tupSource; OperatorType opLogical = ops.get(0); AbstractFunctionCallExpression f = createFunctionCallExpressionForBuiltinOperator(opLogical, sourceLoc); for (int i = 0; i <= nOps; i++) { Pair<ILogicalExpression, Mutable<ILogicalOperator>> p = langExprToAlgExpression(exprs.get(i), topOp); topOp = p.second; // now look at the operator if (i < nOps && ops.get(i) != opLogical) { throw new CompilationException(ErrorCode.COMPILATION_UNEXPECTED_OPERATOR, sourceLoc, ops.get(i), opLogical); } f.getArguments().add(new MutableObject<>(p.first)); } LogicalVariable assignedVar = context.newVar(); AssignOperator a = new AssignOperator(assignedVar, new MutableObject<>(f)); a.getInputs().add(topOp); a.setSourceLocation(sourceLoc); return new Pair<>(a, assignedVar); }
@Override public Pair<ILogicalOperator, LogicalVariable> visit(VariableExpr v, Mutable<ILogicalOperator> tupSource) throws CompilationException { // Should we ever get to this method? ILogicalExpression oldVRef = translateVariableRef(v); LogicalVariable var = context.newVar(); AssignOperator a = new AssignOperator(var, new MutableObject<>(oldVRef)); a.getInputs().add(tupSource); a.setSourceLocation(v.getSourceLocation()); return new Pair<>(a, var); }
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 Pair<List<Mutable<ILogicalExpression>>, ILogicalOperator> translateWindowBoundaryExpr( Expression boundaryExpr, List<Pair<OrderOperator.IOrder, Mutable<ILogicalExpression>>> valueExprs, Mutable<ILogicalOperator> tupSource, OperatorType boundaryOperator) throws CompilationException { SourceLocation sourceLoc = boundaryExpr.getSourceLocation(); if (valueExprs.size() != 1) { throw new CompilationException(ErrorCode.COMPILATION_ILLEGAL_STATE, sourceLoc, valueExprs.size()); } ILogicalExpression valueExpr = valueExprs.get(0).second.getValue(); AbstractFunctionCallExpression resultExpr = createFunctionCallExpressionForBuiltinOperator(boundaryOperator, sourceLoc); resultExpr.getArguments().add(new MutableObject<>(valueExpr.cloneExpression())); Pair<ILogicalExpression, Mutable<ILogicalOperator>> eo = langExprToAlgExpression(boundaryExpr, tupSource); resultExpr.getArguments().add(new MutableObject<>(eo.first)); LogicalVariable resultVar = context.newVar(); AssignOperator assignOp = new AssignOperator(resultVar, new MutableObject<>(resultExpr)); assignOp.setSourceLocation(sourceLoc); assignOp.getInputs().add(eo.second); VariableReferenceExpression resultVarRefExpr = new VariableReferenceExpression(resultVar); resultVarRefExpr.setSourceLocation(sourceLoc); return new Pair<>(mkSingletonArrayList(new MutableObject<>(resultVarRefExpr)), assignOp); }
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; }
@Override public Pair<ILogicalOperator, LogicalVariable> visit(LetClause lc, Mutable<ILogicalOperator> tupSource) throws CompilationException { LogicalVariable v; AssignOperator returnedOp; Expression bindingExpr = lc.getBindingExpr(); SourceLocation sourceLoc = bindingExpr.getSourceLocation(); if (bindingExpr.getKind() == Kind.VARIABLE_EXPRESSION) { VariableExpr bindingVarExpr = (VariableExpr) bindingExpr; ILogicalExpression prevVarRef = translateVariableRef(bindingVarExpr); v = context.newVarFromExpression(lc.getVarExpr()); returnedOp = new AssignOperator(v, new MutableObject<>(prevVarRef)); returnedOp.getInputs().add(tupSource); returnedOp.setSourceLocation(sourceLoc); } else { v = context.newVarFromExpression(lc.getVarExpr()); Pair<ILogicalExpression, Mutable<ILogicalOperator>> eo = langExprToAlgExpression(bindingExpr, tupSource); returnedOp = new AssignOperator(v, new MutableObject<>(eo.first)); returnedOp.getInputs().add(eo.second); returnedOp.setSourceLocation(sourceLoc); } return new Pair<>(returnedOp, v); }
@Override public Pair<ILogicalOperator, LogicalVariable> visit(LiteralExpr l, Mutable<ILogicalOperator> tupSource) { SourceLocation sourceLoc = l.getSourceLocation(); LogicalVariable var = context.newVar(); AsterixConstantValue cValue = new AsterixConstantValue(ConstantHelper.objectFromLiteral(l.getValue())); ConstantExpression cExpr = new ConstantExpression(cValue); cExpr.setSourceLocation(sourceLoc); AssignOperator a = new AssignOperator(var, new MutableObject<>(cExpr)); a.setSourceLocation(sourceLoc); if (tupSource != null) { a.getInputs().add(tupSource); } return new Pair<>(a, var); }
@Override public Pair<ILogicalOperator, LogicalVariable> visit(ListConstructor lc, Mutable<ILogicalOperator> tupSource) throws CompilationException { SourceLocation sourceLoc = lc.getSourceLocation(); FunctionIdentifier fid = (lc.getType() == ListConstructor.Type.ORDERED_LIST_CONSTRUCTOR) ? BuiltinFunctions.ORDERED_LIST_CONSTRUCTOR : BuiltinFunctions.UNORDERED_LIST_CONSTRUCTOR; AbstractFunctionCallExpression f = new ScalarFunctionCallExpression(FunctionUtil.getFunctionInfo(fid)); f.setSourceLocation(sourceLoc); LogicalVariable v1 = context.newVar(); AssignOperator a = new AssignOperator(v1, new MutableObject<>(f)); a.setSourceLocation(sourceLoc); Mutable<ILogicalOperator> topOp = tupSource; for (Expression expr : lc.getExprList()) { Pair<ILogicalExpression, Mutable<ILogicalOperator>> eo = langExprToAlgExpression(expr, topOp); f.getArguments().add(new MutableObject<>(eo.first)); topOp = eo.second; } a.getInputs().add(topOp); return new Pair<>(a, v1); }
private AssignOperator processExists(ILogicalExpression inputExpr, LogicalVariable v1, boolean not, SourceLocation sourceLoc) { AbstractFunctionCallExpression count = new ScalarFunctionCallExpression(FunctionUtil.getFunctionInfo(BuiltinFunctions.SCALAR_COUNT)); count.getArguments().add(new MutableObject<>(inputExpr)); count.setSourceLocation(sourceLoc); AbstractFunctionCallExpression comparison = new ScalarFunctionCallExpression( FunctionUtil.getFunctionInfo(not ? BuiltinFunctions.EQ : BuiltinFunctions.NEQ)); ConstantExpression eZero = new ConstantExpression(new AsterixConstantValue(new AInt64(0L))); eZero.setSourceLocation(sourceLoc); comparison.getArguments().add(new MutableObject<>(count)); comparison.getArguments().add(new MutableObject<>(eZero)); comparison.setSourceLocation(sourceLoc); AssignOperator a = new AssignOperator(v1, new MutableObject<>(comparison)); a.setSourceLocation(sourceLoc); return a; }
@Override public Pair<ILogicalOperator, LogicalVariable> visit(IndexAccessor ia, Mutable<ILogicalOperator> tupSource) throws CompilationException { SourceLocation sourceLoc = ia.getSourceLocation(); // Expression pair Pair<ILogicalExpression, Mutable<ILogicalOperator>> expressionPair = langExprToAlgExpression(ia.getExpr(), tupSource); LogicalVariable v = context.newVar(); AbstractFunctionCallExpression f; // Index expression Pair<ILogicalExpression, Mutable<ILogicalOperator>> indexPair = null; if (ia.isAny()) { f = new ScalarFunctionCallExpression(FunctionUtil.getFunctionInfo(BuiltinFunctions.ANY_COLLECTION_MEMBER)); f.getArguments().add(new MutableObject<>(expressionPair.first)); } else { indexPair = langExprToAlgExpression(ia.getIndexExpr(), expressionPair.second); f = new ScalarFunctionCallExpression(FunctionUtil.getFunctionInfo(BuiltinFunctions.GET_ITEM)); f.getArguments().add(new MutableObject<>(expressionPair.first)); f.getArguments().add(new MutableObject<>(indexPair.first)); } f.setSourceLocation(sourceLoc); AssignOperator a = new AssignOperator(v, new MutableObject<>(f)); if (ia.isAny()) { a.getInputs().add(expressionPair.second); } else { a.getInputs().add(indexPair.second); // NOSONAR: Called only if value exists } a.setSourceLocation(sourceLoc); return new Pair<>(a, v); }
@Override public Pair<ILogicalOperator, LogicalVariable> visit(RecordConstructor rc, Mutable<ILogicalOperator> tupSource) throws CompilationException { AbstractFunctionCallExpression f = new ScalarFunctionCallExpression( FunctionUtil.getFunctionInfo(BuiltinFunctions.OPEN_RECORD_CONSTRUCTOR)); f.setSourceLocation(rc.getSourceLocation()); LogicalVariable v1 = context.newVar(); AssignOperator a = new AssignOperator(v1, new MutableObject<>(f)); a.setSourceLocation(rc.getSourceLocation()); Mutable<ILogicalOperator> topOp = tupSource; for (FieldBinding fb : rc.getFbList()) { Pair<ILogicalExpression, Mutable<ILogicalOperator>> eo1 = langExprToAlgExpression(fb.getLeftExpr(), topOp); f.getArguments().add(new MutableObject<>(eo1.first)); topOp = eo1.second; Pair<ILogicalExpression, Mutable<ILogicalOperator>> eo2 = langExprToAlgExpression(fb.getRightExpr(), topOp); f.getArguments().add(new MutableObject<>(eo2.first)); topOp = eo2.second; } a.getInputs().add(topOp); return new Pair<>(a, v1); }
@Override public Pair<ILogicalOperator, LogicalVariable> visit(Query q, Mutable<ILogicalOperator> tupSource) throws CompilationException { Expression queryBody = q.getBody(); SourceLocation sourceLoc = queryBody.getSourceLocation(); if (queryBody.getKind() == Kind.SELECT_EXPRESSION) { SelectExpression selectExpr = (SelectExpression) queryBody; if (q.isTopLevel()) { selectExpr.setSubquery(false); } return queryBody.accept(this, tupSource); } else { LogicalVariable var = context.newVar(); Pair<ILogicalExpression, Mutable<ILogicalOperator>> eo = langExprToAlgExpression(queryBody, tupSource); AssignOperator assignOp = new AssignOperator(var, new MutableObject<>(eo.first)); assignOp.getInputs().add(eo.second); assignOp.setSourceLocation(sourceLoc); ProjectOperator projectOp = new ProjectOperator(var); projectOp.getInputs().add(new MutableObject<>(assignOp)); projectOp.setSourceLocation(sourceLoc); return new Pair<>(projectOp, var); } }
@Override public Pair<ILogicalOperator, LogicalVariable> visit(FieldAccessor fa, Mutable<ILogicalOperator> tupSource) throws CompilationException { SourceLocation sourceLoc = fa.getSourceLocation(); Pair<ILogicalExpression, Mutable<ILogicalOperator>> p = langExprToAlgExpression(fa.getExpr(), tupSource); LogicalVariable v = context.newVarFromExpression(fa); AbstractFunctionCallExpression fldAccess = new ScalarFunctionCallExpression(FunctionUtil.getFunctionInfo(BuiltinFunctions.FIELD_ACCESS_BY_NAME)); fldAccess.setSourceLocation(sourceLoc); fldAccess.getArguments().add(new MutableObject<>(p.first)); ConstantExpression faExpr = new ConstantExpression(new AsterixConstantValue(new AString(fa.getIdent().getValue()))); faExpr.setSourceLocation(sourceLoc); fldAccess.getArguments().add(new MutableObject<>(faExpr)); AssignOperator a = new AssignOperator(v, new MutableObject<>(fldAccess)); a.getInputs().add(p.second); a.setSourceLocation(sourceLoc); return new Pair<>(a, v); }
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; }