use of org.apache.hyracks.algebricks.core.algebra.operators.logical.AbstractLogicalOperator in project asterixdb by apache.
the class EliminateSubplanRule method rewritePre.
/**
* Eliminate Subplan above ETS
* and Subplan that has only ops. with one input and no free vars.
*/
@Override
public boolean rewritePre(Mutable<ILogicalOperator> opRef, IOptimizationContext context) throws AlgebricksException {
AbstractLogicalOperator op = (AbstractLogicalOperator) opRef.getValue();
if (op.getOperatorTag() != LogicalOperatorTag.SUBPLAN) {
return false;
}
SubplanOperator subplan = (SubplanOperator) op;
Mutable<ILogicalOperator> outerRef = subplan.getInputs().get(0);
AbstractLogicalOperator outerRefOp = (AbstractLogicalOperator) outerRef.getValue();
if (outerRefOp.getOperatorTag() == LogicalOperatorTag.EMPTYTUPLESOURCE) {
elimSubplanOverEts(opRef, context);
return true;
}
if (subplan.getNestedPlans().size() == 1 && subplan.getNestedPlans().get(0).getRoots().size() == 1 && !OperatorPropertiesUtil.hasFreeVariables(subplan)) {
if (elimOneSubplanWithNoFreeVars(opRef)) {
return true;
}
}
return false;
}
use of org.apache.hyracks.algebricks.core.algebra.operators.logical.AbstractLogicalOperator in project asterixdb by apache.
the class EliminateSubplanWithInputCardinalityOneRule method rewritePre.
@Override
public boolean rewritePre(Mutable<ILogicalOperator> opRef, IOptimizationContext context) throws AlgebricksException {
if (!invoked) {
rootRef = opRef;
invoked = true;
}
AbstractLogicalOperator op = (AbstractLogicalOperator) opRef.getValue();
if (op.getInputs().size() <= 0) {
return false;
}
boolean changed = false;
for (Mutable<ILogicalOperator> subplanRef : op.getInputs()) {
AbstractLogicalOperator op1 = (AbstractLogicalOperator) subplanRef.getValue();
if (op1.getOperatorTag() != LogicalOperatorTag.SUBPLAN) {
continue;
}
SubplanOperator subplan = (SubplanOperator) op1;
Set<LogicalVariable> usedVarsUp = new ListSet<LogicalVariable>();
OperatorPropertiesUtil.getFreeVariablesInPath(rootRef.getValue(), subplan, usedVarsUp);
// TODO(buyingyi): figure out the rewriting for subplan operators with multiple subplans.
if (subplan.getNestedPlans().size() != 1) {
continue;
}
ILogicalOperator subplanInputOperator = subplan.getInputs().get(0).getValue();
Set<LogicalVariable> subplanInputVars = new ListSet<LogicalVariable>();
VariableUtilities.getLiveVariables(subplanInputOperator, subplanInputVars);
int subplanInputVarSize = subplanInputVars.size();
subplanInputVars.removeAll(usedVarsUp);
// Makes sure the free variables are only used in the subplan.
if (subplanInputVars.size() < subplanInputVarSize) {
continue;
}
Set<LogicalVariable> freeVars = new ListSet<LogicalVariable>();
OperatorPropertiesUtil.getFreeVariablesInSubplans(subplan, freeVars);
boolean cardinalityOne = isCardinalityOne(subplan.getInputs().get(0), freeVars);
if (cardinalityOne) {
/** If the cardinality of freeVars in the subplan is one, the subplan can be removed. */
ILogicalPlan plan = subplan.getNestedPlans().get(0);
List<Mutable<ILogicalOperator>> rootRefs = plan.getRoots();
// TODO(buyingyi): investigate the case of multi-root plans.
if (rootRefs.size() != 1) {
continue;
}
// Replaces all Nts' in the nested plan with the Subplan input operator or its deep copy.
ILogicalOperator topOperator = rootRefs.get(0).getValue();
ReplaceNtsWithSubplanInputOperatorVisitor visitor = new ReplaceNtsWithSubplanInputOperatorVisitor(context, subplan);
ILogicalOperator newTopOperator = topOperator.accept(visitor, null);
subplanRef.setValue(newTopOperator);
OperatorManipulationUtil.computeTypeEnvironmentBottomUp(newTopOperator, context);
changed = true;
} else {
continue;
}
}
return changed;
}
use of org.apache.hyracks.algebricks.core.algebra.operators.logical.AbstractLogicalOperator in project asterixdb by apache.
the class EliminateSubplanWithInputCardinalityOneRule method isCardinalityOne.
/**
* Recursively adding variables which has cardinality one into the input free variable set.
*
* @param opRef
* , the current operator reference.
* @param freeVars
* , a set of variables.
* @param varsWithCardinalityOne
* , variables in the free variable set with cardinality one at the time they are created.
* @param varsLiveAtUnnestAndJoin
* , live variables at Unnest and Join. The cardinalities of those variables can become more than one
* even if their cardinalities were one at the time those variables were created.
* @throws AlgebricksException
*/
private void isCardinalityOne(Mutable<ILogicalOperator> opRef, Set<LogicalVariable> freeVars, Set<LogicalVariable> varsWithCardinalityOne, Set<LogicalVariable> varsLiveAtUnnestAndJoin) throws AlgebricksException {
AbstractLogicalOperator operator = (AbstractLogicalOperator) opRef.getValue();
List<LogicalVariable> liveVars = new ArrayList<LogicalVariable>();
VariableUtilities.getLiveVariables(operator, liveVars);
if (OperatorPropertiesUtil.isCardinalityZeroOrOne(operator)) {
for (LogicalVariable liveVar : liveVars) {
if (freeVars.contains(liveVar)) {
varsWithCardinalityOne.add(liveVar);
}
}
} else {
// hence they are in this "else" branch.
if (operator.getOperatorTag() == LogicalOperatorTag.UNNEST || operator.getOperatorTag() == LogicalOperatorTag.INNERJOIN || operator.getOperatorTag() == LogicalOperatorTag.LEFTOUTERJOIN) {
VariableUtilities.getLiveVariables(operator, varsLiveAtUnnestAndJoin);
}
}
if (varsWithCardinalityOne.size() == freeVars.size()) {
return;
}
for (Mutable<ILogicalOperator> childRef : operator.getInputs()) {
isCardinalityOne(childRef, freeVars, varsWithCardinalityOne, varsLiveAtUnnestAndJoin);
}
}
use of org.apache.hyracks.algebricks.core.algebra.operators.logical.AbstractLogicalOperator in project asterixdb by apache.
the class PushUnnestDownThroughUnionRule method rewritePost.
@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;
}
use of org.apache.hyracks.algebricks.core.algebra.operators.logical.AbstractLogicalOperator in project asterixdb by apache.
the class ReinferAllTypesRule method typeOpRec.
private void typeOpRec(Mutable<ILogicalOperator> r, IOptimizationContext context) throws AlgebricksException {
AbstractLogicalOperator op = (AbstractLogicalOperator) r.getValue();
for (Mutable<ILogicalOperator> i : op.getInputs()) {
typeOpRec(i, context);
}
if (op.hasNestedPlans()) {
for (ILogicalPlan p : ((AbstractOperatorWithNestedPlans) op).getNestedPlans()) {
typePlan(p, context);
}
}
context.computeAndSetTypeEnvironmentForOperator(op);
context.addToDontApplySet(this, op);
}
Aggregations