use of org.apache.hyracks.algebricks.core.algebra.operators.logical.SubplanOperator in project asterixdb by apache.
the class ComplexJoinInferenceRule method rewritePost.
@Override
public boolean rewritePost(Mutable<ILogicalOperator> opRef, IOptimizationContext context) throws AlgebricksException {
ILogicalOperator op = opRef.getValue();
if (!(op instanceof AbstractScanOperator)) {
return false;
}
Mutable<ILogicalOperator> opRef2 = op.getInputs().get(0);
AbstractLogicalOperator op2 = (AbstractLogicalOperator) opRef2.getValue();
if (op2.getOperatorTag() != LogicalOperatorTag.SUBPLAN) {
return false;
}
SubplanOperator subplan = (SubplanOperator) op2;
Mutable<ILogicalOperator> opRef3 = subplan.getInputs().get(0);
AbstractLogicalOperator op3 = (AbstractLogicalOperator) opRef3.getValue();
if (op3.getOperatorTag() == LogicalOperatorTag.EMPTYTUPLESOURCE || op3.getOperatorTag() == LogicalOperatorTag.NESTEDTUPLESOURCE) {
return false;
}
if (subplanHasFreeVariables(subplan)) {
return false;
}
HashSet<LogicalVariable> varsUsedInUnnest = new HashSet<LogicalVariable>();
VariableUtilities.getUsedVariables(op, varsUsedInUnnest);
HashSet<LogicalVariable> producedInSubplan = new HashSet<LogicalVariable>();
VariableUtilities.getProducedVariables(subplan, producedInSubplan);
if (!producedInSubplan.containsAll(varsUsedInUnnest)) {
return false;
}
ntsToEtsInSubplan(subplan, context);
cleanupJoins(subplan);
InnerJoinOperator join = new InnerJoinOperator(new MutableObject<ILogicalExpression>(ConstantExpression.TRUE));
join.getInputs().add(opRef3);
opRef2.setValue(OperatorManipulationUtil.eliminateSingleSubplanOverEts(subplan));
join.getInputs().add(new MutableObject<ILogicalOperator>(op));
opRef.setValue(join);
context.computeAndSetTypeEnvironmentForOperator(join);
return true;
}
use of org.apache.hyracks.algebricks.core.algebra.operators.logical.SubplanOperator in project asterixdb by apache.
the class OperatorDeepCopyVisitor method visitSubplanOperator.
@Override
public ILogicalOperator visitSubplanOperator(SubplanOperator op, Void arg) throws AlgebricksException {
ArrayList<ILogicalPlan> newSubplans = new ArrayList<>();
SubplanOperator subplanOp = new SubplanOperator(newSubplans);
for (ILogicalPlan plan : op.getNestedPlans()) {
newSubplans.add(OperatorManipulationUtil.deepCopy(plan, subplanOp));
}
return subplanOp;
}
use of org.apache.hyracks.algebricks.core.algebra.operators.logical.SubplanOperator 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.SubplanOperator 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.operators.logical.SubplanOperator in project asterixdb by apache.
the class LogicalOperatorDeepCopyWithNewVariablesVisitor method visitSubplanOperator.
@Override
public ILogicalOperator visitSubplanOperator(SubplanOperator op, ILogicalOperator arg) throws AlgebricksException {
List<ILogicalPlan> nestedPlansCopy = new ArrayList<ILogicalPlan>();
SubplanOperator opCopy = new SubplanOperator(nestedPlansCopy);
deepCopyInputsAnnotationsAndExecutionMode(op, arg, opCopy);
deepCopyPlanList(op.getNestedPlans(), nestedPlansCopy, opCopy);
return opCopy;
}
Aggregations