use of org.apache.hyracks.algebricks.core.algebra.operators.logical.AssignOperator in project asterixdb by apache.
the class LangExpressionToPlanTranslator method visit.
@Override
public Pair<ILogicalOperator, LogicalVariable> visit(VariableExpr v, Mutable<ILogicalOperator> tupSource) {
// Should we ever get to this method?
LogicalVariable var = context.newVar();
LogicalVariable oldV = context.getVar(v.getVar().getId());
AssignOperator a = new AssignOperator(var, new MutableObject<>(new VariableReferenceExpression(oldV)));
a.getInputs().add(tupSource);
return new Pair<>(a, var);
}
use of org.apache.hyracks.algebricks.core.algebra.operators.logical.AssignOperator in project asterixdb by apache.
the class ExtractCommonExpressionsRule method removeCommonExpressions.
private boolean removeCommonExpressions(Mutable<ILogicalOperator> opRef, IOptimizationContext context) throws AlgebricksException {
AbstractLogicalOperator op = (AbstractLogicalOperator) opRef.getValue();
if (context.checkIfInDontApplySet(this, opRef.getValue())) {
return false;
}
boolean modified = false;
// Recurse into children.
for (Mutable<ILogicalOperator> inputOpRef : op.getInputs()) {
if (removeCommonExpressions(inputOpRef, context)) {
modified = true;
}
}
// (the resulting new variables should be assigned live below a replicate/split).
if (op.getOperatorTag() == LogicalOperatorTag.REPLICATE || op.getOperatorTag() == LogicalOperatorTag.SPLIT) {
exprEqClassMap.clear();
return modified;
}
// Exclude these operators.
if (ignoreOps.contains(op.getOperatorTag())) {
return modified;
}
// after replacing expressions within the assign operator itself.
if (op.getOperatorTag() == LogicalOperatorTag.ASSIGN) {
AssignOperator assignOp = (AssignOperator) op;
originalAssignExprs.clear();
int numVars = assignOp.getVariables().size();
for (int i = 0; i < numVars; i++) {
Mutable<ILogicalExpression> exprRef = assignOp.getExpressions().get(i);
ILogicalExpression expr = exprRef.getValue();
originalAssignExprs.add(expr.cloneExpression());
}
}
// Perform common subexpression elimination.
substVisitor.setOperator(op);
if (op.acceptExpressionTransform(substVisitor)) {
modified = true;
}
// Update equivalence class map.
if (op.getOperatorTag() == LogicalOperatorTag.ASSIGN) {
AssignOperator assignOp = (AssignOperator) op;
int numVars = assignOp.getVariables().size();
for (int i = 0; i < numVars; i++) {
Mutable<ILogicalExpression> exprRef = assignOp.getExpressions().get(i);
ILogicalExpression expr = exprRef.getValue();
if (expr.getExpressionTag() == LogicalExpressionTag.VARIABLE || expr.getExpressionTag() == LogicalExpressionTag.CONSTANT) {
continue;
}
// Update equivalence class map.
LogicalVariable lhs = assignOp.getVariables().get(i);
updateEquivalenceClassMap(lhs, exprRef, exprRef.getValue(), op);
// Update equivalence class map with original assign expression.
updateEquivalenceClassMap(lhs, exprRef, originalAssignExprs.get(i), op);
}
}
if (modified) {
context.computeAndSetTypeEnvironmentForOperator(op);
context.addToDontApplySet(this, op);
}
return modified;
}
use of org.apache.hyracks.algebricks.core.algebra.operators.logical.AssignOperator in project asterixdb by apache.
the class ExtractCommonOperatorsRule method rewriteForOneEquivalentClass.
private boolean rewriteForOneEquivalentClass(List<Mutable<ILogicalOperator>> members, IOptimizationContext context) throws AlgebricksException {
List<Mutable<ILogicalOperator>> group = new ArrayList<Mutable<ILogicalOperator>>();
boolean rewritten = false;
while (members.size() > 0) {
group.clear();
Mutable<ILogicalOperator> candidate = members.remove(members.size() - 1);
group.add(candidate);
for (int i = members.size() - 1; i >= 0; i--) {
Mutable<ILogicalOperator> peer = members.get(i);
if (IsomorphismUtilities.isOperatorIsomorphic(candidate.getValue(), peer.getValue())) {
group.add(peer);
members.remove(i);
}
}
boolean[] materializationFlags = computeMaterilizationFlags(group);
if (group.isEmpty()) {
continue;
}
candidate = group.get(0);
ReplicateOperator rop = new ReplicateOperator(group.size(), materializationFlags);
rop.setPhysicalOperator(new ReplicatePOperator());
Mutable<ILogicalOperator> ropRef = new MutableObject<ILogicalOperator>(rop);
AbstractLogicalOperator aopCandidate = (AbstractLogicalOperator) candidate.getValue();
List<Mutable<ILogicalOperator>> originalCandidateParents = childrenToParents.get(candidate);
rop.setExecutionMode(((AbstractLogicalOperator) candidate.getValue()).getExecutionMode());
if (aopCandidate.getOperatorTag() == LogicalOperatorTag.EXCHANGE) {
rop.getInputs().add(candidate);
} else {
AbstractLogicalOperator beforeExchange = new ExchangeOperator();
beforeExchange.setPhysicalOperator(new OneToOneExchangePOperator());
beforeExchange.setExecutionMode(rop.getExecutionMode());
Mutable<ILogicalOperator> beforeExchangeRef = new MutableObject<ILogicalOperator>(beforeExchange);
beforeExchange.getInputs().add(candidate);
context.computeAndSetTypeEnvironmentForOperator(beforeExchange);
rop.getInputs().add(beforeExchangeRef);
}
context.computeAndSetTypeEnvironmentForOperator(rop);
for (Mutable<ILogicalOperator> parentRef : originalCandidateParents) {
AbstractLogicalOperator parent = (AbstractLogicalOperator) parentRef.getValue();
int index = parent.getInputs().indexOf(candidate);
if (parent.getOperatorTag() == LogicalOperatorTag.EXCHANGE) {
parent.getInputs().set(index, ropRef);
rop.getOutputs().add(parentRef);
} else {
AbstractLogicalOperator exchange = new ExchangeOperator();
exchange.setPhysicalOperator(new OneToOneExchangePOperator());
exchange.setExecutionMode(rop.getExecutionMode());
MutableObject<ILogicalOperator> exchangeRef = new MutableObject<ILogicalOperator>(exchange);
exchange.getInputs().add(ropRef);
rop.getOutputs().add(exchangeRef);
context.computeAndSetTypeEnvironmentForOperator(exchange);
parent.getInputs().set(index, exchangeRef);
context.computeAndSetTypeEnvironmentForOperator(parent);
}
}
List<LogicalVariable> liveVarsNew = new ArrayList<LogicalVariable>();
VariableUtilities.getLiveVariables(candidate.getValue(), liveVarsNew);
ArrayList<Mutable<ILogicalExpression>> assignExprs = new ArrayList<Mutable<ILogicalExpression>>();
for (LogicalVariable liveVar : liveVarsNew) {
assignExprs.add(new MutableObject<ILogicalExpression>(new VariableReferenceExpression(liveVar)));
}
for (Mutable<ILogicalOperator> ref : group) {
if (ref.equals(candidate)) {
continue;
}
ArrayList<LogicalVariable> liveVars = new ArrayList<LogicalVariable>();
Map<LogicalVariable, LogicalVariable> variableMappingBack = new HashMap<LogicalVariable, LogicalVariable>();
IsomorphismUtilities.mapVariablesTopDown(ref.getValue(), candidate.getValue(), variableMappingBack);
for (int i = 0; i < liveVarsNew.size(); i++) {
liveVars.add(variableMappingBack.get(liveVarsNew.get(i)));
}
AbstractLogicalOperator assignOperator = new AssignOperator(liveVars, assignExprs);
assignOperator.setExecutionMode(rop.getExecutionMode());
assignOperator.setPhysicalOperator(new AssignPOperator());
AbstractLogicalOperator projectOperator = new ProjectOperator(liveVars);
projectOperator.setPhysicalOperator(new StreamProjectPOperator());
projectOperator.setExecutionMode(rop.getExecutionMode());
AbstractLogicalOperator exchOp = new ExchangeOperator();
exchOp.setPhysicalOperator(new OneToOneExchangePOperator());
exchOp.setExecutionMode(rop.getExecutionMode());
exchOp.getInputs().add(ropRef);
MutableObject<ILogicalOperator> exchOpRef = new MutableObject<ILogicalOperator>(exchOp);
rop.getOutputs().add(exchOpRef);
assignOperator.getInputs().add(exchOpRef);
projectOperator.getInputs().add(new MutableObject<ILogicalOperator>(assignOperator));
// set the types
context.computeAndSetTypeEnvironmentForOperator(exchOp);
context.computeAndSetTypeEnvironmentForOperator(assignOperator);
context.computeAndSetTypeEnvironmentForOperator(projectOperator);
List<Mutable<ILogicalOperator>> parentOpList = childrenToParents.get(ref);
for (Mutable<ILogicalOperator> parentOpRef : parentOpList) {
AbstractLogicalOperator parentOp = (AbstractLogicalOperator) parentOpRef.getValue();
int index = parentOp.getInputs().indexOf(ref);
ILogicalOperator childOp = parentOp.getOperatorTag() == LogicalOperatorTag.PROJECT ? assignOperator : projectOperator;
if (!HeuristicOptimizer.isHyracksOp(parentOp.getPhysicalOperator().getOperatorTag())) {
parentOp.getInputs().set(index, new MutableObject<ILogicalOperator>(childOp));
} else {
// If the parent operator is a hyracks operator,
// an extra one-to-one exchange is needed.
AbstractLogicalOperator exchg = new ExchangeOperator();
exchg.setPhysicalOperator(new OneToOneExchangePOperator());
exchg.setExecutionMode(childOp.getExecutionMode());
exchg.getInputs().add(new MutableObject<ILogicalOperator>(childOp));
parentOp.getInputs().set(index, new MutableObject<ILogicalOperator>(exchg));
context.computeAndSetTypeEnvironmentForOperator(exchg);
}
context.computeAndSetTypeEnvironmentForOperator(parentOp);
}
}
rewritten = true;
}
return rewritten;
}
use of org.apache.hyracks.algebricks.core.algebra.operators.logical.AssignOperator in project asterixdb by apache.
the class InlineVariablesRule method inlineVariables.
protected boolean inlineVariables(Mutable<ILogicalOperator> opRef, IOptimizationContext context) throws AlgebricksException {
AbstractLogicalOperator op = (AbstractLogicalOperator) opRef.getValue();
// Update mapping from variables to expressions during top-down traversal.
if (op.getOperatorTag() == LogicalOperatorTag.ASSIGN) {
AssignOperator assignOp = (AssignOperator) op;
List<LogicalVariable> vars = assignOp.getVariables();
List<Mutable<ILogicalExpression>> exprs = assignOp.getExpressions();
for (int i = 0; i < vars.size(); i++) {
ILogicalExpression expr = exprs.get(i).getValue();
// Ignore functions that are either in the doNotInline set or are non-functional
if (expr.getExpressionTag() == LogicalExpressionTag.FUNCTION_CALL) {
AbstractFunctionCallExpression funcExpr = (AbstractFunctionCallExpression) expr;
if (doNotInlineFuncs.contains(funcExpr.getFunctionIdentifier()) || !funcExpr.isFunctional()) {
continue;
}
}
varAssignRhs.put(vars.get(i), exprs.get(i).getValue());
}
}
// Descend into children removing projects on the way.
boolean modified = false;
for (Mutable<ILogicalOperator> inputOpRef : op.getInputs()) {
if (inlineVariables(inputOpRef, context)) {
modified = true;
}
}
// Descend into subplan
if (op.getOperatorTag() == LogicalOperatorTag.SUBPLAN) {
SubplanOperator subplanOp = (SubplanOperator) op;
for (ILogicalPlan nestedPlan : subplanOp.getNestedPlans()) {
for (Mutable<ILogicalOperator> root : nestedPlan.getRoots()) {
if (inlineVariables(root, context)) {
modified = true;
}
// Variables produced by a nested subplan cannot be inlined
// in operators above the subplan.
Set<LogicalVariable> producedVars = new HashSet<>();
VariableUtilities.getProducedVariables(root.getValue(), producedVars);
varAssignRhs.keySet().removeAll(producedVars);
}
}
}
// in operators above the left-outer-join.
if (op.getOperatorTag() == LogicalOperatorTag.LEFTOUTERJOIN) {
Set<LogicalVariable> rightLiveVars = new HashSet<>();
VariableUtilities.getLiveVariables(op.getInputs().get(1).getValue(), rightLiveVars);
varAssignRhs.keySet().removeAll(rightLiveVars);
}
if (performBottomUpAction(op)) {
modified = true;
}
if (modified) {
context.computeAndSetTypeEnvironmentForOperator(op);
context.addToDontApplySet(this, op);
// Re-enable rules that we may have already tried. They could be applicable now after inlining.
context.removeFromAlreadyCompared(opRef.getValue());
}
return modified;
}
use of org.apache.hyracks.algebricks.core.algebra.operators.logical.AssignOperator in project asterixdb by apache.
the class PushAssignBelowUnionAllRule method createAssignBelowUnionAllBranch.
private AssignOperator createAssignBelowUnionAllBranch(UnionAllOperator unionOp, int inputIndex, AssignOperator originalAssignOp, Set<LogicalVariable> assignUsedVars, IOptimizationContext context) throws AlgebricksException {
AssignOperator newAssignOp = cloneAssignOperator(originalAssignOp, context);
newAssignOp.getInputs().add(new MutableObject<ILogicalOperator>(unionOp.getInputs().get(inputIndex).getValue()));
unionOp.getInputs().get(inputIndex).setValue(newAssignOp);
int numVarMappings = unionOp.getVariableMappings().size();
for (int i = 0; i < numVarMappings; i++) {
Triple<LogicalVariable, LogicalVariable, LogicalVariable> varMapping = unionOp.getVariableMappings().get(i);
if (assignUsedVars.contains(varMapping.third)) {
LogicalVariable replacementVar;
if (inputIndex == 0) {
replacementVar = varMapping.first;
} else {
replacementVar = varMapping.second;
}
VariableUtilities.substituteVariables(newAssignOp, varMapping.third, replacementVar, context);
}
}
context.computeAndSetTypeEnvironmentForOperator(newAssignOp);
return newAssignOp;
}
Aggregations