use of org.apache.hyracks.algebricks.core.algebra.operators.logical.AbstractOperatorWithNestedPlans in project asterixdb by apache.
the class PushProjectDownRule method pushThroughOp.
private static Pair<Boolean, Boolean> pushThroughOp(HashSet<LogicalVariable> toPush, Mutable<ILogicalOperator> opRef2, ILogicalOperator initialOp, IOptimizationContext context) throws AlgebricksException {
List<LogicalVariable> initProjectList = new ArrayList<LogicalVariable>(toPush);
AbstractLogicalOperator op2 = (AbstractLogicalOperator) opRef2.getValue();
do {
if (op2.getOperatorTag() == LogicalOperatorTag.EMPTYTUPLESOURCE || op2.getOperatorTag() == LogicalOperatorTag.NESTEDTUPLESOURCE || op2.getOperatorTag() == LogicalOperatorTag.PROJECT || op2.getOperatorTag() == LogicalOperatorTag.REPLICATE || op2.getOperatorTag() == LogicalOperatorTag.SPLIT || op2.getOperatorTag() == LogicalOperatorTag.UNIONALL) {
return new Pair<Boolean, Boolean>(false, false);
}
if (!op2.isMap()) {
break;
}
LinkedList<LogicalVariable> usedVars = new LinkedList<LogicalVariable>();
VariableUtilities.getUsedVariables(op2, usedVars);
toPush.addAll(usedVars);
LinkedList<LogicalVariable> producedVars = new LinkedList<LogicalVariable>();
VariableUtilities.getProducedVariables(op2, producedVars);
toPush.removeAll(producedVars);
// we assume pipelineable ops. have only one input
opRef2 = op2.getInputs().get(0);
op2 = (AbstractLogicalOperator) opRef2.getValue();
} while (true);
LinkedList<LogicalVariable> produced2 = new LinkedList<LogicalVariable>();
VariableUtilities.getProducedVariables(op2, produced2);
LinkedList<LogicalVariable> used2 = new LinkedList<LogicalVariable>();
VariableUtilities.getUsedVariables(op2, used2);
boolean canCommuteProjection = initProjectList.containsAll(toPush) && initProjectList.containsAll(produced2) && initProjectList.containsAll(used2);
// get rid of useless decor vars.
if (!canCommuteProjection && op2.getOperatorTag() == LogicalOperatorTag.GROUP) {
boolean gbyChanged = false;
GroupByOperator gby = (GroupByOperator) op2;
List<Pair<LogicalVariable, Mutable<ILogicalExpression>>> newDecorList = new ArrayList<Pair<LogicalVariable, Mutable<ILogicalExpression>>>();
for (Pair<LogicalVariable, Mutable<ILogicalExpression>> p : gby.getDecorList()) {
LogicalVariable decorVar = GroupByOperator.getDecorVariable(p);
if (!toPush.contains(decorVar)) {
used2.remove(decorVar);
gbyChanged = true;
} else {
newDecorList.add(p);
}
}
gby.getDecorList().clear();
gby.getDecorList().addAll(newDecorList);
if (gbyChanged) {
context.computeAndSetTypeEnvironmentForOperator(gby);
}
}
used2.clear();
VariableUtilities.getUsedVariables(op2, used2);
// remember that toPush is a Set
toPush.addAll(used2);
toPush.removeAll(produced2);
if (toPush.isEmpty()) {
return new Pair<Boolean, Boolean>(false, false);
}
boolean smthWasPushed = false;
for (Mutable<ILogicalOperator> c : op2.getInputs()) {
if (pushNeededProjections(toPush, c, context, initialOp)) {
smthWasPushed = true;
}
}
if (op2.hasNestedPlans()) {
AbstractOperatorWithNestedPlans n = (AbstractOperatorWithNestedPlans) op2;
for (ILogicalPlan p : n.getNestedPlans()) {
for (Mutable<ILogicalOperator> r : p.getRoots()) {
if (pushNeededProjections(toPush, r, context, initialOp)) {
smthWasPushed = true;
}
}
}
}
return new Pair<Boolean, Boolean>(smthWasPushed, canCommuteProjection);
}
Aggregations