use of org.apache.hyracks.algebricks.core.algebra.base.ILogicalPlan 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.base.ILogicalPlan in project asterixdb by apache.
the class IntroJoinInsideSubplanRule method rewritePost.
@Override
public boolean rewritePost(Mutable<ILogicalOperator> opRef, IOptimizationContext context) throws AlgebricksException {
AbstractLogicalOperator op0 = (AbstractLogicalOperator) opRef.getValue();
if (op0.getOperatorTag() != LogicalOperatorTag.SUBPLAN) {
return false;
}
SubplanOperator subplan = (SubplanOperator) op0;
Mutable<ILogicalOperator> leftRef = subplan.getInputs().get(0);
if (((AbstractLogicalOperator) leftRef.getValue()).getOperatorTag() == LogicalOperatorTag.EMPTYTUPLESOURCE) {
return false;
}
ListIterator<ILogicalPlan> plansIter = subplan.getNestedPlans().listIterator();
ILogicalPlan p = null;
while (plansIter.hasNext()) {
p = plansIter.next();
}
if (p == null) {
return false;
}
if (p.getRoots().size() != 1) {
return false;
}
Mutable<ILogicalOperator> opRef1 = p.getRoots().get(0);
while (true) {
AbstractLogicalOperator op1 = (AbstractLogicalOperator) opRef1.getValue();
if (op1.getInputs().size() != 1) {
return false;
}
if (op1.getOperatorTag() == LogicalOperatorTag.SELECT) {
Mutable<ILogicalOperator> op2Ref = op1.getInputs().get(0);
AbstractLogicalOperator op2 = (AbstractLogicalOperator) op2Ref.getValue();
if (op2.getOperatorTag() != LogicalOperatorTag.SELECT && descOrSelfIsScanOrJoin(op2)) {
Set<LogicalVariable> free2 = new HashSet<LogicalVariable>();
OperatorPropertiesUtil.getFreeVariablesInSelfOrDesc(op2, free2);
if (free2.isEmpty()) {
Set<LogicalVariable> free1 = new HashSet<LogicalVariable>();
OperatorPropertiesUtil.getFreeVariablesInSelfOrDesc(op1, free1);
if (!free1.isEmpty()) {
OperatorManipulationUtil.ntsToEts(op2Ref, context);
NestedTupleSourceOperator nts = new NestedTupleSourceOperator(new MutableObject<ILogicalOperator>(subplan));
Mutable<ILogicalOperator> ntsRef = new MutableObject<ILogicalOperator>(nts);
Mutable<ILogicalOperator> innerRef = new MutableObject<ILogicalOperator>(op2);
InnerJoinOperator join = new InnerJoinOperator(new MutableObject<ILogicalExpression>(ConstantExpression.TRUE), ntsRef, innerRef);
op2Ref.setValue(join);
context.computeAndSetTypeEnvironmentForOperator(nts);
context.computeAndSetTypeEnvironmentForOperator(join);
return true;
}
}
}
}
opRef1 = op1.getInputs().get(0);
}
}
use of org.apache.hyracks.algebricks.core.algebra.base.ILogicalPlan in project asterixdb by apache.
the class InlineAssignIntoAggregateRule method rewritePost.
@Override
public boolean rewritePost(Mutable<ILogicalOperator> opRef, IOptimizationContext context) throws AlgebricksException {
AbstractLogicalOperator op = (AbstractLogicalOperator) opRef.getValue();
if (op.getOperatorTag() != LogicalOperatorTag.GROUP) {
return false;
}
boolean changed = false;
GroupByOperator gbyOp = (GroupByOperator) op;
for (ILogicalPlan p : gbyOp.getNestedPlans()) {
for (Mutable<ILogicalOperator> r : p.getRoots()) {
if (inlined(r)) {
changed = true;
}
}
}
return changed;
}
use of org.apache.hyracks.algebricks.core.algebra.base.ILogicalPlan in project asterixdb by apache.
the class EliminateGroupByEmptyKeyRule method rewritePost.
@Override
public boolean rewritePost(Mutable<ILogicalOperator> opRef, IOptimizationContext context) throws AlgebricksException {
AbstractLogicalOperator op = (AbstractLogicalOperator) opRef.getValue();
if (op.getOperatorTag() != LogicalOperatorTag.GROUP) {
return false;
}
GroupByOperator groupOp = (GroupByOperator) op;
// Only groupAll has equivalent semantics to aggregate.
if (!groupOp.isGroupAll()) {
return false;
}
List<LogicalVariable> groupVars = groupOp.getGbyVarList();
List<Pair<LogicalVariable, Mutable<ILogicalExpression>>> decorList = groupOp.getDecorList();
if (!groupVars.isEmpty() || !decorList.isEmpty()) {
return false;
}
List<ILogicalPlan> nestedPlans = groupOp.getNestedPlans();
if (nestedPlans.size() > 1) {
return false;
}
ILogicalPlan nestedPlan = nestedPlans.get(0);
if (nestedPlan.getRoots().size() > 1) {
return false;
}
Mutable<ILogicalOperator> topOpRef = nestedPlan.getRoots().get(0);
ILogicalOperator topOp = nestedPlan.getRoots().get(0).getValue();
Mutable<ILogicalOperator> nestedTupleSourceRef = getNestedTupleSourceReference(topOpRef);
/**
* connect nested top op into the plan
*/
opRef.setValue(topOp);
/**
* connect child op into the plan
*/
nestedTupleSourceRef.setValue(groupOp.getInputs().get(0).getValue());
return true;
}
use of org.apache.hyracks.algebricks.core.algebra.base.ILogicalPlan in project asterixdb by apache.
the class FDsAndEquivClassesVisitor method visitSubplanOperator.
@Override
public Void visitSubplanOperator(SubplanOperator op, IOptimizationContext ctx) throws AlgebricksException {
Map<LogicalVariable, EquivalenceClass> equivalenceClasses = new HashMap<LogicalVariable, EquivalenceClass>();
List<FunctionalDependency> functionalDependencies = new ArrayList<FunctionalDependency>();
ctx.putEquivalenceClassMap(op, equivalenceClasses);
ctx.putFDList(op, functionalDependencies);
for (ILogicalPlan p : op.getNestedPlans()) {
for (Mutable<ILogicalOperator> r : p.getRoots()) {
ILogicalOperator op2 = r.getValue();
equivalenceClasses.putAll(getOrComputeEqClasses(op2, ctx));
functionalDependencies.addAll(getOrComputeFDs(op2, ctx));
}
}
return null;
}
Aggregations