use of org.apache.hyracks.algebricks.core.algebra.operators.logical.SubplanOperator in project asterixdb by apache.
the class PushSubplanIntoGroupByRule method rewritePre.
@Override
public boolean rewritePre(Mutable<ILogicalOperator> opRef, IOptimizationContext context) throws AlgebricksException {
ILogicalOperator parentOperator = opRef.getValue();
if (context.checkIfInDontApplySet(this, parentOperator)) {
return false;
}
context.addToDontApplySet(this, parentOperator);
VariableUtilities.getUsedVariables(parentOperator, usedVarsSoFar);
if (parentOperator.getInputs().size() <= 0) {
return false;
}
boolean changed = false;
GroupByOperator gby = null;
for (Mutable<ILogicalOperator> ref : parentOperator.getInputs()) {
AbstractLogicalOperator op = (AbstractLogicalOperator) ref.getValue();
/** Only processes subplan operator. */
List<SubplanOperator> subplans = new ArrayList<SubplanOperator>();
if (op.getOperatorTag() == LogicalOperatorTag.SUBPLAN) {
while (op.getOperatorTag() == LogicalOperatorTag.SUBPLAN) {
SubplanOperator currentSubplan = (SubplanOperator) op;
subplans.add(currentSubplan);
op = (AbstractLogicalOperator) op.getInputs().get(0).getValue();
}
/** Only processes the case a group-by operator is the input of the subplan operators. */
if (op.getOperatorTag() == LogicalOperatorTag.GROUP) {
gby = (GroupByOperator) op;
List<ILogicalPlan> newGbyNestedPlans = new ArrayList<ILogicalPlan>();
for (SubplanOperator subplan : subplans) {
List<ILogicalPlan> subplanNestedPlans = subplan.getNestedPlans();
List<ILogicalPlan> gbyNestedPlans = gby.getNestedPlans();
List<ILogicalPlan> subplanNestedPlansToRemove = new ArrayList<ILogicalPlan>();
for (ILogicalPlan subplanNestedPlan : subplanNestedPlans) {
List<Mutable<ILogicalOperator>> rootOpRefs = subplanNestedPlan.getRoots();
List<Mutable<ILogicalOperator>> rootOpRefsToRemove = new ArrayList<Mutable<ILogicalOperator>>();
for (Mutable<ILogicalOperator> rootOpRef : rootOpRefs) {
/** Gets free variables in the root operator of a nested plan and its descent. */
Set<LogicalVariable> freeVars = new ListSet<LogicalVariable>();
VariableUtilities.getUsedVariablesInDescendantsAndSelf(rootOpRef.getValue(), freeVars);
Set<LogicalVariable> producedVars = new ListSet<LogicalVariable>();
VariableUtilities.getProducedVariablesInDescendantsAndSelf(rootOpRef.getValue(), producedVars);
freeVars.removeAll(producedVars);
/** * Checks whether the above freeVars are all contained in live variables * of one nested plan inside the group-by operator. * If yes, then the subplan can be pushed into the nested plan of the group-by. */
for (ILogicalPlan gbyNestedPlanOriginal : gbyNestedPlans) {
// add a subplan in the original gby
if (!newGbyNestedPlans.contains(gbyNestedPlanOriginal)) {
newGbyNestedPlans.add(gbyNestedPlanOriginal);
}
// add a pushed subplan
ILogicalPlan gbyNestedPlan = OperatorManipulationUtil.deepCopy(gbyNestedPlanOriginal, context);
List<Mutable<ILogicalOperator>> gbyRootOpRefs = gbyNestedPlan.getRoots();
for (int rootIndex = 0; rootIndex < gbyRootOpRefs.size(); rootIndex++) {
//set the nts for a original subplan
Mutable<ILogicalOperator> originalGbyRootOpRef = gbyNestedPlanOriginal.getRoots().get(rootIndex);
Mutable<ILogicalOperator> originalGbyNtsRef = downToNts(originalGbyRootOpRef);
NestedTupleSourceOperator originalNts = (NestedTupleSourceOperator) originalGbyNtsRef.getValue();
originalNts.setDataSourceReference(new MutableObject<ILogicalOperator>(gby));
//push a new subplan if possible
Mutable<ILogicalOperator> gbyRootOpRef = gbyRootOpRefs.get(rootIndex);
Set<LogicalVariable> liveVars = new ListSet<LogicalVariable>();
VariableUtilities.getLiveVariables(gbyRootOpRef.getValue(), liveVars);
if (liveVars.containsAll(freeVars)) {
/** Does the actual push. */
Mutable<ILogicalOperator> ntsRef = downToNts(rootOpRef);
ntsRef.setValue(gbyRootOpRef.getValue());
// Removes unused vars.
AggregateOperator aggOp = (AggregateOperator) gbyRootOpRef.getValue();
for (int varIndex = aggOp.getVariables().size() - 1; varIndex >= 0; varIndex--) {
if (!freeVars.contains(aggOp.getVariables().get(varIndex))) {
aggOp.getVariables().remove(varIndex);
aggOp.getExpressions().remove(varIndex);
}
}
gbyRootOpRef.setValue(rootOpRef.getValue());
rootOpRefsToRemove.add(rootOpRef);
// Sets the nts for a new pushed plan.
Mutable<ILogicalOperator> oldGbyNtsRef = downToNts(gbyRootOpRef);
NestedTupleSourceOperator nts = (NestedTupleSourceOperator) oldGbyNtsRef.getValue();
nts.setDataSourceReference(new MutableObject<ILogicalOperator>(gby));
newGbyNestedPlans.add(gbyNestedPlan);
changed = true;
continue;
}
}
}
}
rootOpRefs.removeAll(rootOpRefsToRemove);
if (rootOpRefs.size() == 0) {
subplanNestedPlansToRemove.add(subplanNestedPlan);
}
}
subplanNestedPlans.removeAll(subplanNestedPlansToRemove);
}
if (changed) {
ref.setValue(gby);
gby.getNestedPlans().clear();
gby.getNestedPlans().addAll(newGbyNestedPlans);
}
}
}
}
if (changed) {
cleanup(gby);
context.computeAndSetTypeEnvironmentForOperator(gby);
context.computeAndSetTypeEnvironmentForOperator(parentOperator);
}
return changed;
}
use of org.apache.hyracks.algebricks.core.algebra.operators.logical.SubplanOperator in project asterixdb by apache.
the class MoveFreeVariableOperatorOutOfSubplanRule method rewritePost.
@Override
public boolean rewritePost(Mutable<ILogicalOperator> opRef, IOptimizationContext context) throws AlgebricksException {
AbstractLogicalOperator op = (AbstractLogicalOperator) opRef.getValue();
if (op.getOperatorTag() != LogicalOperatorTag.SUBPLAN) {
return false;
}
SubplanOperator subplanOp = (SubplanOperator) op;
ILogicalOperator inputOp = subplanOp.getInputs().get(0).getValue();
Set<LogicalVariable> liveVarsBeforeSubplan = new HashSet<>();
VariableUtilities.getLiveVariables(inputOp, liveVarsBeforeSubplan);
boolean changed = false;
for (ILogicalPlan plan : subplanOp.getNestedPlans()) {
for (Mutable<ILogicalOperator> rootRef : plan.getRoots()) {
//Make sure we are looking at subplan with a scan/join
if (!descOrSelfIsScanOrJoin(rootRef.getValue())) {
continue;
}
Mutable<ILogicalOperator> currentOpRef = rootRef;
ILogicalOperator currentOp = rootRef.getValue();
while (currentOp.getInputs().size() == 1) {
Mutable<ILogicalOperator> childOpRef = currentOp.getInputs().get(0);
ILogicalOperator childOp = childOpRef.getValue();
// Try to move operators that only uses free variables out of the subplan.
if (movableOperator(currentOp.getOperatorTag()) && independentOperator(currentOp, liveVarsBeforeSubplan) && producedVariablesCanbePropagated(currentOp)) {
extractOperator(subplanOp, inputOp, currentOpRef);
inputOp = currentOp;
changed = true;
} else {
// in the case the operator is not moved, move currentOpRef to childOpRef.
currentOpRef = childOpRef;
}
currentOp = childOp;
}
}
}
return changed;
}
use of org.apache.hyracks.algebricks.core.algebra.operators.logical.SubplanOperator in project asterixdb by apache.
the class EliminateSubplanRule method elimOneSubplanWithNoFreeVars.
private boolean elimOneSubplanWithNoFreeVars(Mutable<ILogicalOperator> opRef) {
SubplanOperator subplan = (SubplanOperator) opRef.getValue();
AbstractLogicalOperator rootOp = (AbstractLogicalOperator) subplan.getNestedPlans().get(0).getRoots().get(0).getValue();
if (rootOp.getOperatorTag() == LogicalOperatorTag.EMPTYTUPLESOURCE || rootOp.getOperatorTag() == LogicalOperatorTag.NESTEDTUPLESOURCE) {
opRef.setValue(subplan.getInputs().get(0).getValue());
return true;
} else {
AbstractLogicalOperator botOp = rootOp;
if (botOp.getInputs().size() != 1) {
return false;
}
do {
Mutable<ILogicalOperator> botRef = botOp.getInputs().get(0);
botOp = (AbstractLogicalOperator) botRef.getValue();
if (botOp.getOperatorTag() == LogicalOperatorTag.EMPTYTUPLESOURCE) {
botRef.setValue(subplan.getInputs().get(0).getValue());
opRef.setValue(rootOp);
return true;
}
} while (botOp.getInputs().size() == 1);
return false;
}
}
use of org.apache.hyracks.algebricks.core.algebra.operators.logical.SubplanOperator in project asterixdb by apache.
the class EliminateSubplanRule method elimSubplanOverEts.
private void elimSubplanOverEts(Mutable<ILogicalOperator> opRef, IOptimizationContext ctx) throws AlgebricksException {
SubplanOperator subplan = (SubplanOperator) opRef.getValue();
for (ILogicalPlan p : subplan.getNestedPlans()) {
for (Mutable<ILogicalOperator> r : p.getRoots()) {
OperatorManipulationUtil.ntsToEts(r, ctx);
}
}
LinkedList<Mutable<ILogicalOperator>> allRoots = subplan.allRootsInReverseOrder();
if (allRoots.size() == 1) {
opRef.setValue(allRoots.get(0).getValue());
} else {
ILogicalOperator topOp = null;
for (Mutable<ILogicalOperator> r : allRoots) {
if (topOp == null) {
topOp = r.getValue();
} else {
InnerJoinOperator j = new InnerJoinOperator(new MutableObject<ILogicalExpression>(ConstantExpression.TRUE));
j.getInputs().add(new MutableObject<ILogicalOperator>(topOp));
j.getInputs().add(r);
ctx.setOutputTypeEnvironment(j, j.computeOutputTypeEnvironment(ctx));
topOp = j;
}
}
opRef.setValue(topOp);
}
}
Aggregations