private int removeFromAssigns( AbstractLogicalOperator op, Set<LogicalVariable> toRemove, IOptimizationContext context) throws AlgebricksException { switch (op.getOperatorTag()) { case ASSIGN: { AssignOperator assign = (AssignOperator) op; if (removeUnusedVarsAndExprs(toRemove, assign.getVariables(), assign.getExpressions())) { context.computeAndSetTypeEnvironmentForOperator(assign); } return assign.getVariables().size(); } case AGGREGATE: { AggregateOperator agg = (AggregateOperator) op; if (removeUnusedVarsAndExprs(toRemove, agg.getVariables(), agg.getExpressions())) { context.computeAndSetTypeEnvironmentForOperator(agg); } return agg.getVariables().size(); } case UNNEST: { UnnestOperator uOp = (UnnestOperator) op; LogicalVariable pVar = uOp.getPositionalVariable(); if (pVar != null && toRemove.contains(pVar)) { uOp.setPositionalVariable(null); } break; } case UNIONALL: { UnionAllOperator unionOp = (UnionAllOperator) op; if (removeUnusedVarsFromUnionAll(unionOp, toRemove)) { context.computeAndSetTypeEnvironmentForOperator(unionOp); } return unionOp.getVariableMappings().size(); } } return -1; }
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); } }
@Override public boolean rewritePost(Mutable<ILogicalOperator> opRef, IOptimizationContext context) throws AlgebricksException { AbstractLogicalOperator unnest = (AbstractLogicalOperator) opRef.getValue(); if (unnest.getOperatorTag() != LogicalOperatorTag.UNNEST) { return false; } UnnestOperator unnestOpRef = (UnnestOperator) opRef.getValue(); Mutable<ILogicalOperator> unionOp = unnest.getInputs().get(0); AbstractLogicalOperator unionAbstractOp = (AbstractLogicalOperator) unionOp.getValue(); if (unionAbstractOp.getOperatorTag() != LogicalOperatorTag.UNIONALL) { return false; } LogicalVariable unnestVar1 = context.newVar(); UnnestOperator unnest1 = new UnnestOperator( unnestVar1, new MutableObject<ILogicalExpression>( unnestOpRef.getExpressionRef().getValue().cloneExpression())); LogicalVariable unnestVar2 = context.newVar(); UnnestOperator unnest2 = new UnnestOperator( unnestVar2, new MutableObject<ILogicalExpression>( unnestOpRef.getExpressionRef().getValue().cloneExpression())); // Getting the two topmost branched and adding them as an input to the unnests: Mutable<ILogicalOperator> branch1 = unionAbstractOp.getInputs().get(0); ILogicalOperator agg1 = branch1.getValue(); List<LogicalVariable> agg1_var = new ArrayList<LogicalVariable>(); VariableUtilities.getLiveVariables(agg1, agg1_var); Mutable<ILogicalOperator> branch2 = unionAbstractOp.getInputs().get(1); ILogicalOperator agg2 = branch2.getValue(); List<LogicalVariable> agg2_var = new ArrayList<LogicalVariable>(); VariableUtilities.getLiveVariables(agg2, agg2_var); // Modifying the unnest so it has the right variable List<LogicalVariable> var_unnest_1 = new ArrayList<LogicalVariable>(); unnest1.getExpressionRef().getValue().getUsedVariables(var_unnest_1); unnest1.getExpressionRef().getValue().substituteVar(var_unnest_1.get(0), agg1_var.get(0)); List<LogicalVariable> var_unnest2 = new ArrayList<LogicalVariable>(); unnest2.getExpressionRef().getValue().getUsedVariables(var_unnest2); unnest2.getExpressionRef().getValue().substituteVar(var_unnest2.get(0), agg2_var.get(0)); unnest1.getInputs().add(branch1); unnest2.getInputs().add(branch2); context.computeAndSetTypeEnvironmentForOperator(unnest1); context.computeAndSetTypeEnvironmentForOperator(unnest2); // creating a new union operator with the updated logical variables List<Triple<LogicalVariable, LogicalVariable, LogicalVariable>> varMap = new ArrayList<Triple<LogicalVariable, LogicalVariable, LogicalVariable>>(1); Triple<LogicalVariable, LogicalVariable, LogicalVariable> union_triple_vars = new Triple<LogicalVariable, LogicalVariable, LogicalVariable>( unnestVar1, unnestVar2, unnestOpRef.getVariables().get(0)); varMap.add(union_triple_vars); UnionAllOperator unionOpFinal = new UnionAllOperator(varMap); unionOpFinal.getInputs().add(new MutableObject<ILogicalOperator>(unnest1)); unionOpFinal.getInputs().add(new MutableObject<ILogicalOperator>(unnest2)); context.computeAndSetTypeEnvironmentForOperator(unionOpFinal); opRef.setValue(unionOpFinal); return true; }