use of org.apache.hyracks.algebricks.core.algebra.base.ILogicalOperator in project asterixdb by apache.
the class AbstractIntroduceCombinerRule method tryToPushAgg.
protected Pair<Boolean, Mutable<ILogicalOperator>> tryToPushAgg(AggregateOperator initAgg, GroupByOperator newGbyOp, Set<SimilarAggregatesInfo> toReplaceSet, IOptimizationContext context) throws AlgebricksException {
ArrayList<LogicalVariable> pushedVars = new ArrayList<LogicalVariable>();
ArrayList<Mutable<ILogicalExpression>> pushedExprs = new ArrayList<Mutable<ILogicalExpression>>();
List<LogicalVariable> initVars = initAgg.getVariables();
List<Mutable<ILogicalExpression>> initExprs = initAgg.getExpressions();
int numExprs = initVars.size();
// First make sure that all agg funcs are two step, otherwise we cannot use local aggs.
for (int i = 0; i < numExprs; i++) {
AggregateFunctionCallExpression aggFun = (AggregateFunctionCallExpression) initExprs.get(i).getValue();
if (!aggFun.isTwoStep()) {
return new Pair<Boolean, Mutable<ILogicalOperator>>(false, null);
}
}
boolean haveAggToReplace = false;
for (int i = 0; i < numExprs; i++) {
Mutable<ILogicalExpression> expRef = initExprs.get(i);
AggregateFunctionCallExpression aggFun = (AggregateFunctionCallExpression) expRef.getValue();
IFunctionInfo fi1 = aggFun.getStepOneAggregate();
// Clone the aggregate's args.
List<Mutable<ILogicalExpression>> newArgs = new ArrayList<Mutable<ILogicalExpression>>(aggFun.getArguments().size());
for (Mutable<ILogicalExpression> er : aggFun.getArguments()) {
newArgs.add(new MutableObject<ILogicalExpression>(er.getValue().cloneExpression()));
}
IFunctionInfo fi2 = aggFun.getStepTwoAggregate();
SimilarAggregatesInfo inf = new SimilarAggregatesInfo();
LogicalVariable newAggVar = context.newVar();
pushedVars.add(newAggVar);
inf.stepOneResult = new VariableReferenceExpression(newAggVar);
inf.simAggs = new ArrayList<AggregateExprInfo>();
toReplaceSet.add(inf);
AggregateFunctionCallExpression aggLocal = new AggregateFunctionCallExpression(fi1, false, newArgs);
pushedExprs.add(new MutableObject<ILogicalExpression>(aggLocal));
AggregateExprInfo aei = new AggregateExprInfo();
aei.aggExprRef = expRef;
aei.newFunInfo = fi2;
inf.simAggs.add(aei);
haveAggToReplace = true;
}
if (!pushedVars.isEmpty()) {
AggregateOperator pushedAgg = new AggregateOperator(pushedVars, pushedExprs);
pushedAgg.setExecutionMode(ExecutionMode.LOCAL);
// If newGbyOp is null, then we optimizing an aggregate without group by.
if (newGbyOp != null) {
// Cut and paste nested input pipelines of initAgg to pushedAgg's input
Mutable<ILogicalOperator> inputRef = initAgg.getInputs().get(0);
Mutable<ILogicalOperator> bottomRef = inputRef;
while (bottomRef.getValue().getInputs().size() > 0) {
bottomRef = bottomRef.getValue().getInputs().get(0);
}
ILogicalOperator oldNts = bottomRef.getValue();
initAgg.getInputs().clear();
initAgg.getInputs().add(new MutableObject<ILogicalOperator>(oldNts));
// Hook up the nested aggregate op with the outer group by.
NestedTupleSourceOperator nts = new NestedTupleSourceOperator(new MutableObject<ILogicalOperator>(newGbyOp));
nts.setExecutionMode(ExecutionMode.LOCAL);
bottomRef.setValue(nts);
pushedAgg.getInputs().add(inputRef);
} else {
// The local aggregate operator is fed by the input of the original aggregate operator.
pushedAgg.getInputs().add(new MutableObject<ILogicalOperator>(initAgg.getInputs().get(0).getValue()));
// Reintroduce assign op for the global agg partitioning var.
initAgg.getInputs().get(0).setValue(pushedAgg);
pushedAgg.setGlobal(false);
context.computeAndSetTypeEnvironmentForOperator(pushedAgg);
}
return new Pair<Boolean, Mutable<ILogicalOperator>>(true, new MutableObject<ILogicalOperator>(pushedAgg));
} else {
return new Pair<Boolean, Mutable<ILogicalOperator>>(haveAggToReplace, null);
}
}
use of org.apache.hyracks.algebricks.core.algebra.base.ILogicalOperator in project asterixdb by apache.
the class ExtractFunctionsFromJoinConditionRule method assignFunctionExpressions.
private boolean assignFunctionExpressions(AbstractLogicalOperator joinOp, ILogicalExpression expr, IOptimizationContext context) throws AlgebricksException {
if (expr.getExpressionTag() != LogicalExpressionTag.FUNCTION_CALL) {
return false;
}
AbstractFunctionCallExpression fexp = (AbstractFunctionCallExpression) expr;
FunctionIdentifier fi = fexp.getFunctionIdentifier();
boolean modified = false;
if (fi.equals(AlgebricksBuiltinFunctions.AND) || fi.equals(AlgebricksBuiltinFunctions.OR) || processArgumentsToFunction(fi)) {
for (Mutable<ILogicalExpression> a : fexp.getArguments()) {
if (assignFunctionExpressions(joinOp, a.getValue(), context)) {
modified = true;
}
}
return modified;
} else if (AlgebricksBuiltinFunctions.isComparisonFunction(fi) || isComparisonFunction(fi)) {
for (Mutable<ILogicalExpression> exprRef : fexp.getArguments()) {
if (exprRef.getValue().getExpressionTag() == LogicalExpressionTag.FUNCTION_CALL) {
LogicalVariable newVar = context.newVar();
AssignOperator newAssign = new AssignOperator(newVar, new MutableObject<ILogicalExpression>(exprRef.getValue().cloneExpression()));
newAssign.setExecutionMode(joinOp.getExecutionMode());
// Place assign below joinOp.
List<LogicalVariable> used = new ArrayList<LogicalVariable>();
VariableUtilities.getUsedVariables(newAssign, used);
Mutable<ILogicalOperator> leftBranchRef = joinOp.getInputs().get(0);
ILogicalOperator leftBranch = leftBranchRef.getValue();
List<LogicalVariable> leftBranchVariables = new ArrayList<LogicalVariable>();
VariableUtilities.getLiveVariables(leftBranch, leftBranchVariables);
if (leftBranchVariables.containsAll(used)) {
// place assign on left branch
newAssign.getInputs().add(new MutableObject<ILogicalOperator>(leftBranch));
leftBranchRef.setValue(newAssign);
modified = true;
} else {
Mutable<ILogicalOperator> rightBranchRef = joinOp.getInputs().get(1);
ILogicalOperator rightBranch = rightBranchRef.getValue();
List<LogicalVariable> rightBranchVariables = new ArrayList<LogicalVariable>();
VariableUtilities.getLiveVariables(rightBranch, rightBranchVariables);
if (rightBranchVariables.containsAll(used)) {
// place assign on right branch
newAssign.getInputs().add(new MutableObject<ILogicalOperator>(rightBranch));
rightBranchRef.setValue(newAssign);
modified = true;
}
}
if (modified) {
// Replace original expr with variable reference.
exprRef.setValue(new VariableReferenceExpression(newVar));
context.computeAndSetTypeEnvironmentForOperator(newAssign);
context.computeAndSetTypeEnvironmentForOperator(joinOp);
}
}
}
return modified;
} else {
return false;
}
}
use of org.apache.hyracks.algebricks.core.algebra.base.ILogicalOperator in project asterixdb by apache.
the class ExtractGbyExpressionsRule method gbyExprWasRewritten.
private boolean gbyExprWasRewritten(GroupByOperator g, IOptimizationContext context) throws AlgebricksException {
if (!gbyHasComplexExpr(g)) {
return false;
}
Mutable<ILogicalOperator> opRef2 = g.getInputs().get(0);
for (Pair<LogicalVariable, Mutable<ILogicalExpression>> gbyPair : g.getGroupByList()) {
ILogicalExpression expr = gbyPair.second.getValue();
if (expr.getExpressionTag() != LogicalExpressionTag.VARIABLE) {
LogicalVariable v = extractExprIntoAssignOpRef(expr, opRef2, context);
gbyPair.second.setValue(new VariableReferenceExpression(v));
}
}
return true;
}
use of org.apache.hyracks.algebricks.core.algebra.base.ILogicalOperator in project asterixdb by apache.
the class ExtractGroupByDecorVariablesRule method rewritePost.
@Override
public boolean rewritePost(Mutable<ILogicalOperator> opRef, IOptimizationContext context) throws AlgebricksException {
ILogicalOperator op = opRef.getValue();
if (op.getOperatorTag() != LogicalOperatorTag.GROUP) {
return false;
}
GroupByOperator groupByOperator = (GroupByOperator) op;
List<Pair<LogicalVariable, Mutable<ILogicalExpression>>> decorList = groupByOperator.getDecorList();
// Returns immediately if there is no decoration entry.
if (groupByOperator.getDecorList() == null || groupByOperator.getDecorList().isEmpty()) {
return false;
}
// Goes over the decoration list and performs the rewrite.
boolean changed = false;
List<LogicalVariable> vars = new ArrayList<>();
List<Mutable<ILogicalExpression>> exprs = new ArrayList<>();
for (Pair<LogicalVariable, Mutable<ILogicalExpression>> decorVarExpr : decorList) {
Mutable<ILogicalExpression> exprRef = decorVarExpr.second;
ILogicalExpression expr = exprRef.getValue();
if (expr == null || expr.getExpressionTag() == LogicalExpressionTag.VARIABLE) {
continue;
}
// Rewrites the decoration entry if the decoration expression is not a variable reference expression.
changed = true;
LogicalVariable newVar = context.newVar();
vars.add(newVar);
exprs.add(exprRef);
// Normalizes the decor entry -- expression be a variable reference
decorVarExpr.second = new MutableObject<>(new VariableReferenceExpression(newVar));
}
if (!changed) {
return false;
}
// Injects an assign operator to evaluate the decoration expression.
AssignOperator assignOperator = new AssignOperator(vars, exprs);
assignOperator.getInputs().addAll(op.getInputs());
op.getInputs().set(0, new MutableObject<>(assignOperator));
return changed;
}
use of org.apache.hyracks.algebricks.core.algebra.base.ILogicalOperator in project asterixdb by apache.
the class InsertProjectBeforeUnionRule method insertProjectOperator.
private void insertProjectOperator(UnionAllOperator opUnion, int branch, ArrayList<LogicalVariable> usedVariables, IOptimizationContext context) throws AlgebricksException {
ProjectOperator projectOp = new ProjectOperator(usedVariables);
ILogicalOperator parentOp = opUnion.getInputs().get(branch).getValue();
projectOp.getInputs().add(new MutableObject<ILogicalOperator>(parentOp));
opUnion.getInputs().get(branch).setValue(projectOp);
projectOp.setPhysicalOperator(new StreamProjectPOperator());
context.computeAndSetTypeEnvironmentForOperator(projectOp);
context.computeAndSetTypeEnvironmentForOperator(parentOp);
}
Aggregations