use of org.apache.hyracks.algebricks.core.algebra.operators.logical.UnionAllOperator in project asterixdb by apache.
the class RemoveRedundantVariablesRule method removeRedundantVariables.
private boolean removeRedundantVariables(Mutable<ILogicalOperator> opRef, IOptimizationContext context) throws AlgebricksException {
AbstractLogicalOperator op = (AbstractLogicalOperator) opRef.getValue();
LogicalOperatorTag opTag = op.getOperatorTag();
boolean modified = false;
// Update equivalence class map.
if (opTag == LogicalOperatorTag.ASSIGN) {
AssignOperator assignOp = (AssignOperator) op;
int numVars = assignOp.getVariables().size();
for (int i = 0; i < numVars; i++) {
ILogicalExpression expr = assignOp.getExpressions().get(i).getValue();
if (expr.getExpressionTag() != LogicalExpressionTag.VARIABLE) {
continue;
}
VariableReferenceExpression rhsVarRefExpr = (VariableReferenceExpression) expr;
// Update equivalence class map.
LogicalVariable lhs = assignOp.getVariables().get(i);
LogicalVariable rhs = rhsVarRefExpr.getVariableReference();
updateEquivalenceClassMap(lhs, rhs);
}
}
// Replace variable references with their first representative.
if (opTag == LogicalOperatorTag.PROJECT) {
// The project operator does not use expressions, so we need to replace it's variables manually.
if (replaceProjectVars((ProjectOperator) op)) {
modified = true;
}
} else if (op.getOperatorTag() == LogicalOperatorTag.UNIONALL) {
// Replace redundant variables manually in the UnionAll operator.
if (replaceUnionAllVars((UnionAllOperator) op)) {
modified = true;
}
} else {
if (op.acceptExpressionTransform(substVisitor)) {
modified = true;
}
}
// Perform variable replacement in nested plans.
if (op.hasNestedPlans()) {
AbstractOperatorWithNestedPlans opWithNestedPlan = (AbstractOperatorWithNestedPlans) op;
for (ILogicalPlan nestedPlan : opWithNestedPlan.getNestedPlans()) {
for (Mutable<ILogicalOperator> rootRef : nestedPlan.getRoots()) {
if (removeRedundantVariables(rootRef, context)) {
modified = true;
}
}
}
}
// Deal with re-mapping of variables in group by.
if (opTag == LogicalOperatorTag.GROUP) {
if (handleGroupByVarRemapping((GroupByOperator) op)) {
modified = true;
}
}
if (modified) {
context.computeAndSetTypeEnvironmentForOperator(op);
context.addToDontApplySet(this, op);
}
// in the query plan.
if (opTag == LogicalOperatorTag.DISTRIBUTE_RESULT || opTag == LogicalOperatorTag.SINK) {
equivalentVarsMap.clear();
}
return modified;
}
use of org.apache.hyracks.algebricks.core.algebra.operators.logical.UnionAllOperator in project asterixdb by apache.
the class RemoveUnusedAssignAndAggregateRule method collectUnusedAssignedVars.
private void collectUnusedAssignedVars(Mutable<ILogicalOperator> opRef, Set<LogicalVariable> accumulatedUsedVarFromRootSet, boolean first, IOptimizationContext context) throws AlgebricksException {
AbstractLogicalOperator op = (AbstractLogicalOperator) opRef.getValue();
if (!first) {
context.addToDontApplySet(this, op);
}
Set<LogicalVariable> assignVarsSetInThisOp = new HashSet<>();
Set<LogicalVariable> usedVarsSetInThisOp = new HashSet<>();
// Add used variables in this operator to the accumulated used variables set?
boolean addUsedVarsInThisOp = true;
// ASSIGN, AGGREGATE, UNNEST, UNIONALL, or GROUP operator found?
boolean targetOpFound = false;
switch(op.getOperatorTag()) {
case ASSIGN:
AssignOperator assign = (AssignOperator) op;
assignVarsSetInThisOp.addAll(assign.getVariables());
targetOpFound = true;
break;
case AGGREGATE:
AggregateOperator agg = (AggregateOperator) op;
assignVarsSetInThisOp.addAll(agg.getVariables());
targetOpFound = true;
break;
case UNNEST:
UnnestOperator uOp = (UnnestOperator) op;
LogicalVariable pVar = uOp.getPositionalVariable();
if (pVar != null) {
assignVarsSetInThisOp.add(pVar);
targetOpFound = true;
}
break;
case UNIONALL:
UnionAllOperator unionOp = (UnionAllOperator) op;
for (Triple<LogicalVariable, LogicalVariable, LogicalVariable> varMapping : unionOp.getVariableMappings()) {
assignVarsSetInThisOp.add(varMapping.third);
}
targetOpFound = true;
// Don't add used variables in UNIONALL.
addUsedVarsInThisOp = false;
break;
case GROUP:
GroupByOperator groupByOp = (GroupByOperator) op;
for (Pair<LogicalVariable, Mutable<ILogicalExpression>> decorMapping : groupByOp.getDecorList()) {
LogicalVariable decorVar = decorMapping.first;
if (decorVar != null) {
assignVarsSetInThisOp.add(decorVar);
targetOpFound = true;
} else {
// A decor var mapping can have a variable reference expression without a new variable
// definition, which is for rebinding the referred variable.
VariableReferenceExpression varExpr = (VariableReferenceExpression) decorMapping.second.getValue();
LogicalVariable reboundDecorVar = varExpr.getVariableReference();
assignVarsSetInThisOp.add(reboundDecorVar);
}
}
break;
default:
break;
}
if (targetOpFound) {
assignedVarMap.put(opRef, assignVarsSetInThisOp);
assignedVarSet.addAll(assignVarsSetInThisOp);
}
if (addUsedVarsInThisOp) {
VariableUtilities.getUsedVariables(op, usedVarsSetInThisOp);
accumulatedUsedVarFromRootSet.addAll(usedVarsSetInThisOp);
// paths in the plan.
if (accumulatedUsedVarFromRootMap.containsKey(opRef)) {
accumulatedUsedVarFromRootMap.get(opRef).addAll(accumulatedUsedVarFromRootSet);
} else {
accumulatedUsedVarFromRootMap.put(opRef, new HashSet<LogicalVariable>(accumulatedUsedVarFromRootSet));
}
} else {
accumulatedUsedVarFromRootMap.put(opRef, new HashSet<LogicalVariable>(accumulatedUsedVarFromRootSet));
}
for (Mutable<ILogicalOperator> c : op.getInputs()) {
collectUnusedAssignedVars(c, new HashSet<LogicalVariable>(accumulatedUsedVarFromRootSet), false, context);
}
if (op.hasNestedPlans()) {
AbstractOperatorWithNestedPlans opWithNested = (AbstractOperatorWithNestedPlans) op;
for (ILogicalPlan plan : opWithNested.getNestedPlans()) {
for (Mutable<ILogicalOperator> r : plan.getRoots()) {
collectUnusedAssignedVars(r, new HashSet<LogicalVariable>(accumulatedUsedVarFromRootSet), false, context);
}
}
}
}
Aggregations