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; }
@Override public boolean rewritePost(Mutable<ILogicalOperator> opRef, IOptimizationContext context) throws AlgebricksException { AbstractLogicalOperator op = (AbstractLogicalOperator) opRef.getValue(); if (op.getOperatorTag() != LogicalOperatorTag.INNERJOIN) { return false; } AbstractBinaryJoinOperator join = (AbstractBinaryJoinOperator) op; ILogicalExpression expr = join.getCondition().getValue(); if (expr.getExpressionTag() != LogicalExpressionTag.FUNCTION_CALL) { return false; } AbstractFunctionCallExpression fexp = (AbstractFunctionCallExpression) expr; FunctionIdentifier fi = fexp.getFunctionIdentifier(); if (!fi.equals(AlgebricksBuiltinFunctions.AND)) { return false; } List<Mutable<ILogicalExpression>> eqVarVarComps = new ArrayList<Mutable<ILogicalExpression>>(); List<Mutable<ILogicalExpression>> otherPredicates = new ArrayList<Mutable<ILogicalExpression>>(); for (Mutable<ILogicalExpression> arg : fexp.getArguments()) { if (isEqVarVar(arg.getValue())) { eqVarVarComps.add(arg); } else { otherPredicates.add(arg); } } if (eqVarVarComps.isEmpty() || otherPredicates.isEmpty()) { return false; } // pull up ILogicalExpression pulledCond = makeCondition(otherPredicates, context); SelectOperator select = new SelectOperator(new MutableObject<ILogicalExpression>(pulledCond), false, null); ILogicalExpression newJoinCond = makeCondition(eqVarVarComps, context); join.getCondition().setValue(newJoinCond); select.getInputs().add(new MutableObject<ILogicalOperator>(join)); opRef.setValue(select); context.computeAndSetTypeEnvironmentForOperator(select); return true; }
@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; }
@Override public boolean rewritePost(Mutable<ILogicalOperator> opRef, IOptimizationContext context) throws AlgebricksException { if (!opRef.getValue().getOperatorTag().equals(LogicalOperatorTag.ASSIGN)) { return false; } AssignOperator assignUnion = (AssignOperator) opRef.getValue(); if (assignUnion.getExpressions().get(0).getValue().getExpressionTag() != LogicalExpressionTag.FUNCTION_CALL) return false; AbstractFunctionCallExpression u = (AbstractFunctionCallExpression) assignUnion.getExpressions().get(0).getValue(); if (!AsterixBuiltinFunctions.UNION.equals(u.getFunctionIdentifier())) { return false; } // Retrieving the logical variables for the union from the two aggregates which are inputs to // the join Mutable<ILogicalOperator> join = assignUnion.getInputs().get(0); LogicalOperatorTag tag1 = join.getValue().getOperatorTag(); if (tag1 != LogicalOperatorTag.INNERJOIN && tag1 != LogicalOperatorTag.LEFTOUTERJOIN) { return false; } AbstractBinaryJoinOperator join1 = (AbstractBinaryJoinOperator) join.getValue(); ILogicalExpression cond1 = join1.getCondition().getValue(); // don't try to push a product down if (!OperatorPropertiesUtil.isAlwaysTrueCond(cond1)) { return false; } List<Mutable<ILogicalOperator>> joinInputs = join.getValue().getInputs(); Mutable<ILogicalOperator> left_branch = joinInputs.get(0); Mutable<ILogicalOperator> right_branch = joinInputs.get(1); List<LogicalVariable> input1Var = new ArrayList<LogicalVariable>(); VariableUtilities.getProducedVariables(left_branch.getValue(), input1Var); List<LogicalVariable> input2Var = new ArrayList<LogicalVariable>(); VariableUtilities.getProducedVariables(right_branch.getValue(), input2Var); List<Triple<LogicalVariable, LogicalVariable, LogicalVariable>> varMap = new ArrayList<Triple<LogicalVariable, LogicalVariable, LogicalVariable>>(1); Triple<LogicalVariable, LogicalVariable, LogicalVariable> triple = new Triple<LogicalVariable, LogicalVariable, LogicalVariable>( input1Var.get(0), input2Var.get(0), assignUnion.getVariables().get(0)); varMap.add(triple); UnionAllOperator unionOp = new UnionAllOperator(varMap); unionOp.getInputs().add(left_branch); unionOp.getInputs().add(right_branch); context.computeAndSetTypeEnvironmentForOperator(unionOp); opRef.setValue(unionOp); return true; }