private void removeUnusedAssigns( Mutable<ILogicalOperator> opRef, Set<LogicalVariable> toRemove, IOptimizationContext context) throws AlgebricksException { AbstractLogicalOperator op = (AbstractLogicalOperator) opRef.getValue(); while (removeFromAssigns(op, toRemove, context) == 0) { if (op.getOperatorTag() == LogicalOperatorTag.AGGREGATE) { break; } op = (AbstractLogicalOperator) op.getInputs().get(0).getValue(); opRef.setValue(op); } Iterator<Mutable<ILogicalOperator>> childIter = op.getInputs().iterator(); while (childIter.hasNext()) { Mutable<ILogicalOperator> cRef = childIter.next(); removeUnusedAssigns(cRef, toRemove, context); } if (op.hasNestedPlans()) { AbstractOperatorWithNestedPlans opWithNest = (AbstractOperatorWithNestedPlans) op; Iterator<ILogicalPlan> planIter = opWithNest.getNestedPlans().iterator(); while (planIter.hasNext()) { ILogicalPlan p = planIter.next(); for (Mutable<ILogicalOperator> r : p.getRoots()) { removeUnusedAssigns(r, toRemove, context); } } // Removes redundant nested plans that produces nothing for (int i = opWithNest.getNestedPlans().size() - 1; i >= 0; i--) { ILogicalPlan nestedPlan = opWithNest.getNestedPlans().get(i); List<Mutable<ILogicalOperator>> rootsToBeRemoved = new ArrayList<Mutable<ILogicalOperator>>(); for (Mutable<ILogicalOperator> r : nestedPlan.getRoots()) { ILogicalOperator topOp = r.getValue(); Set<LogicalVariable> producedVars = new ListSet<LogicalVariable>(); VariableUtilities.getProducedVariablesInDescendantsAndSelf(topOp, producedVars); if (producedVars.size() == 0) { rootsToBeRemoved.add(r); } } // Makes sure the operator should have at least ONE nested plan even it is empty // (because a lot of places uses this assumption, TODO(yingyib): clean them up). if (nestedPlan.getRoots().size() == rootsToBeRemoved.size() && opWithNest.getNestedPlans().size() > 1) { nestedPlan.getRoots().removeAll(rootsToBeRemoved); opWithNest.getNestedPlans().remove(nestedPlan); } } } }
private void collectUnusedAssignedVars( AbstractLogicalOperator op, Set<LogicalVariable> toRemove, boolean first, IOptimizationContext context) throws AlgebricksException { if (!first) { context.addToDontApplySet(this, op); } for (Mutable<ILogicalOperator> c : op.getInputs()) { collectUnusedAssignedVars((AbstractLogicalOperator) c.getValue(), toRemove, false, context); } if (op.hasNestedPlans()) { AbstractOperatorWithNestedPlans opWithNested = (AbstractOperatorWithNestedPlans) op; for (ILogicalPlan plan : opWithNested.getNestedPlans()) { for (Mutable<ILogicalOperator> r : plan.getRoots()) { collectUnusedAssignedVars( (AbstractLogicalOperator) r.getValue(), toRemove, false, context); } } } boolean removeUsedVars = true; switch (op.getOperatorTag()) { case ASSIGN: { AssignOperator assign = (AssignOperator) op; toRemove.addAll(assign.getVariables()); break; } case AGGREGATE: { AggregateOperator agg = (AggregateOperator) op; toRemove.addAll(agg.getVariables()); break; } case UNNEST: { UnnestOperator uOp = (UnnestOperator) op; LogicalVariable pVar = uOp.getPositionalVariable(); if (pVar != null) { toRemove.add(pVar); } break; } case UNIONALL: { UnionAllOperator unionOp = (UnionAllOperator) op; for (Triple<LogicalVariable, LogicalVariable, LogicalVariable> varMapping : unionOp.getVariableMappings()) { toRemove.add(varMapping.third); } removeUsedVars = false; break; } } if (removeUsedVars) { List<LogicalVariable> used = new LinkedList<LogicalVariable>(); VariableUtilities.getUsedVariables(op, used); toRemove.removeAll(used); } }