use of org.apache.hyracks.algebricks.core.algebra.operators.logical.SelectOperator in project asterixdb by apache.
the class PushSelectDownRule method propagateSelectionRec.
private static boolean propagateSelectionRec(Mutable<ILogicalOperator> sigmaRef, Mutable<ILogicalOperator> opRef2) throws AlgebricksException {
AbstractLogicalOperator op2 = (AbstractLogicalOperator) opRef2.getValue();
if (op2.getInputs().size() != 1 || op2.getOperatorTag() == LogicalOperatorTag.DATASOURCESCAN || !OperatorPropertiesUtil.isMovable(op2)) {
return false;
}
SelectOperator sigma = (SelectOperator) sigmaRef.getValue();
LinkedList<LogicalVariable> usedInSigma = new LinkedList<LogicalVariable>();
sigma.getCondition().getValue().getUsedVariables(usedInSigma);
LinkedList<LogicalVariable> produced2 = new LinkedList<LogicalVariable>();
VariableUtilities.getProducedVariables(op2, produced2);
if (OperatorPropertiesUtil.disjoint(produced2, usedInSigma)) {
// just swap
opRef2.setValue(sigma);
sigmaRef.setValue(op2);
List<Mutable<ILogicalOperator>> sigmaInpList = sigma.getInputs();
sigmaInpList.clear();
sigmaInpList.addAll(op2.getInputs());
List<Mutable<ILogicalOperator>> op2InpList = op2.getInputs();
op2InpList.clear();
op2InpList.add(opRef2);
propagateSelectionRec(opRef2, sigma.getInputs().get(0));
return true;
}
return false;
}
use of org.apache.hyracks.algebricks.core.algebra.operators.logical.SelectOperator in project asterixdb by apache.
the class PushSelectIntoJoinRule method rewritePost.
@Override
public boolean rewritePost(Mutable<ILogicalOperator> opRef, IOptimizationContext context) throws AlgebricksException {
Collection<LogicalVariable> joinLiveVarsLeft = new HashSet<LogicalVariable>();
Collection<LogicalVariable> joinLiveVarsRight = new HashSet<LogicalVariable>();
Collection<LogicalVariable> liveInOpsToPushLeft = new HashSet<LogicalVariable>();
Collection<LogicalVariable> liveInOpsToPushRight = new HashSet<LogicalVariable>();
List<ILogicalOperator> pushedOnLeft = new ArrayList<ILogicalOperator>();
List<ILogicalOperator> pushedOnRight = new ArrayList<ILogicalOperator>();
List<ILogicalOperator> pushedOnEither = new ArrayList<ILogicalOperator>();
LinkedList<ILogicalOperator> notPushedStack = new LinkedList<ILogicalOperator>();
Collection<LogicalVariable> usedVars = new HashSet<LogicalVariable>();
Collection<LogicalVariable> producedVars = new HashSet<LogicalVariable>();
AbstractLogicalOperator op = (AbstractLogicalOperator) opRef.getValue();
if (op.getOperatorTag() != LogicalOperatorTag.SELECT) {
return false;
}
SelectOperator select = (SelectOperator) op;
Mutable<ILogicalOperator> opRef2 = op.getInputs().get(0);
AbstractLogicalOperator son = (AbstractLogicalOperator) opRef2.getValue();
AbstractLogicalOperator op2 = son;
boolean needToPushOps = false;
while (son.isMap()) {
needToPushOps = true;
Mutable<ILogicalOperator> opRefLink = son.getInputs().get(0);
son = (AbstractLogicalOperator) opRefLink.getValue();
}
if (son.getOperatorTag() != LogicalOperatorTag.INNERJOIN && son.getOperatorTag() != LogicalOperatorTag.LEFTOUTERJOIN) {
return false;
}
boolean isLoj = son.getOperatorTag() == LogicalOperatorTag.LEFTOUTERJOIN;
AbstractBinaryJoinOperator join = (AbstractBinaryJoinOperator) son;
Mutable<ILogicalOperator> joinBranchLeftRef = join.getInputs().get(0);
Mutable<ILogicalOperator> joinBranchRightRef = join.getInputs().get(1);
if (needToPushOps) {
ILogicalOperator joinBranchLeft = joinBranchLeftRef.getValue();
ILogicalOperator joinBranchRight = joinBranchRightRef.getValue();
VariableUtilities.getLiveVariables(joinBranchLeft, joinLiveVarsLeft);
VariableUtilities.getLiveVariables(joinBranchRight, joinLiveVarsRight);
Mutable<ILogicalOperator> opIterRef = opRef2;
ILogicalOperator opIter = op2;
while (opIter != join) {
LogicalOperatorTag tag = ((AbstractLogicalOperator) opIter).getOperatorTag();
if (tag == LogicalOperatorTag.PROJECT) {
notPushedStack.addFirst(opIter);
} else {
VariableUtilities.getUsedVariables(opIter, usedVars);
VariableUtilities.getProducedVariables(opIter, producedVars);
if (usedVars.size() == 0) {
pushedOnEither.add(opIter);
} else if (joinLiveVarsLeft.containsAll(usedVars)) {
pushedOnLeft.add(opIter);
liveInOpsToPushLeft.addAll(producedVars);
} else if (joinLiveVarsRight.containsAll(usedVars)) {
pushedOnRight.add(opIter);
liveInOpsToPushRight.addAll(producedVars);
} else {
return false;
}
}
opIterRef = opIter.getInputs().get(0);
opIter = opIterRef.getValue();
}
if (isLoj && pushedOnLeft.isEmpty()) {
return false;
}
}
boolean intersectsAllBranches = true;
boolean[] intersectsBranch = new boolean[join.getInputs().size()];
LinkedList<LogicalVariable> selectVars = new LinkedList<LogicalVariable>();
select.getCondition().getValue().getUsedVariables(selectVars);
int i = 0;
for (Mutable<ILogicalOperator> branch : join.getInputs()) {
LinkedList<LogicalVariable> branchVars = new LinkedList<LogicalVariable>();
VariableUtilities.getLiveVariables(branch.getValue(), branchVars);
if (i == 0) {
branchVars.addAll(liveInOpsToPushLeft);
} else {
branchVars.addAll(liveInOpsToPushRight);
}
if (OperatorPropertiesUtil.disjoint(selectVars, branchVars)) {
intersectsAllBranches = false;
} else {
intersectsBranch[i] = true;
}
i++;
}
if (!intersectsBranch[0] && !intersectsBranch[1]) {
return false;
}
if (needToPushOps) {
//We should push independent ops into the first branch that the selection depends on
if (intersectsBranch[0]) {
pushOps(pushedOnEither, joinBranchLeftRef, context);
} else {
pushOps(pushedOnEither, joinBranchRightRef, context);
}
pushOps(pushedOnLeft, joinBranchLeftRef, context);
pushOps(pushedOnRight, joinBranchRightRef, context);
}
if (intersectsAllBranches) {
addCondToJoin(select, join, context);
} else {
// push down
Iterator<Mutable<ILogicalOperator>> branchIter = join.getInputs().iterator();
ILogicalExpression selectCondition = select.getCondition().getValue();
boolean lojToInner = false;
for (int j = 0; j < intersectsBranch.length; j++) {
Mutable<ILogicalOperator> branch = branchIter.next();
boolean inter = intersectsBranch[j];
if (!inter) {
continue;
}
// to inner join for this case.
if (j > 0 && isLoj && containsNotMissingFiltering(selectCondition)) {
lojToInner = true;
}
if ((j > 0 && isLoj) && containsMissingFiltering(selectCondition)) {
// Select "is-not-missing($$var)" cannot be pushed in the right branch of a LOJ;
notPushedStack.addFirst(select);
} else {
// Conditions for the left branch can always be pushed.
// Other conditions can be pushed to the right branch of a LOJ.
copySelectToBranch(select, branch, context);
}
}
if (lojToInner) {
// Rewrites left outer join to inner join.
InnerJoinOperator innerJoin = new InnerJoinOperator(join.getCondition());
innerJoin.getInputs().addAll(join.getInputs());
join = innerJoin;
context.computeAndSetTypeEnvironmentForOperator(join);
}
}
ILogicalOperator top = join;
for (ILogicalOperator npOp : notPushedStack) {
List<Mutable<ILogicalOperator>> npInpList = npOp.getInputs();
npInpList.clear();
npInpList.add(new MutableObject<ILogicalOperator>(top));
context.computeAndSetTypeEnvironmentForOperator(npOp);
top = npOp;
}
opRef.setValue(top);
return true;
}
use of org.apache.hyracks.algebricks.core.algebra.operators.logical.SelectOperator in project asterixdb by apache.
the class PullSelectOutOfEqJoin method rewritePost.
@Override
public boolean rewritePost(Mutable<ILogicalOperator> opRef, IOptimizationContext context) throws AlgebricksException {
AbstractLogicalOperator op = (AbstractLogicalOperator) opRef.getValue();
if (op.getOperatorTag() != LogicalOperatorTag.INNERJOIN) {
return false;
}
AbstractBinaryJoinOperator join = (AbstractBinaryJoinOperator) op;
ILogicalExpression expr = join.getCondition().getValue();
if (expr.getExpressionTag() != LogicalExpressionTag.FUNCTION_CALL) {
return false;
}
AbstractFunctionCallExpression fexp = (AbstractFunctionCallExpression) expr;
FunctionIdentifier fi = fexp.getFunctionIdentifier();
if (!fi.equals(AlgebricksBuiltinFunctions.AND)) {
return false;
}
List<Mutable<ILogicalExpression>> eqVarVarComps = new ArrayList<Mutable<ILogicalExpression>>();
List<Mutable<ILogicalExpression>> otherPredicates = new ArrayList<Mutable<ILogicalExpression>>();
for (Mutable<ILogicalExpression> arg : fexp.getArguments()) {
if (isEqVarVar(arg.getValue())) {
eqVarVarComps.add(arg);
} else {
otherPredicates.add(arg);
}
}
if (eqVarVarComps.isEmpty() || otherPredicates.isEmpty()) {
return false;
}
// pull up
ILogicalExpression pulledCond = makeCondition(otherPredicates, context);
SelectOperator select = new SelectOperator(new MutableObject<ILogicalExpression>(pulledCond), false, null);
ILogicalExpression newJoinCond = makeCondition(eqVarVarComps, context);
join.getCondition().setValue(newJoinCond);
select.getInputs().add(new MutableObject<ILogicalOperator>(join));
opRef.setValue(select);
context.computeAndSetTypeEnvironmentForOperator(select);
return true;
}
use of org.apache.hyracks.algebricks.core.algebra.operators.logical.SelectOperator in project asterixdb by apache.
the class FuzzyEqRule method rewritePost.
@Override
public boolean rewritePost(Mutable<ILogicalOperator> opRef, IOptimizationContext context) throws AlgebricksException {
AbstractLogicalOperator op = (AbstractLogicalOperator) opRef.getValue();
// current operator is INNERJOIN or LEFTOUTERJOIN or SELECT
Mutable<ILogicalExpression> expRef;
if (op.getOperatorTag() == LogicalOperatorTag.INNERJOIN || op.getOperatorTag() == LogicalOperatorTag.LEFTOUTERJOIN) {
AbstractBinaryJoinOperator joinOp = (AbstractBinaryJoinOperator) op;
expRef = joinOp.getCondition();
} else if (op.getOperatorTag() == LogicalOperatorTag.SELECT) {
SelectOperator selectOp = (SelectOperator) op;
expRef = selectOp.getCondition();
} else {
return false;
}
MetadataProvider metadataProvider = ((MetadataProvider) context.getMetadataProvider());
IVariableTypeEnvironment env = context.getOutputTypeEnvironment(op);
if (expandFuzzyEq(expRef, context, env, metadataProvider)) {
context.computeAndSetTypeEnvironmentForOperator(op);
return true;
}
return false;
}
use of org.apache.hyracks.algebricks.core.algebra.operators.logical.SelectOperator in project asterixdb by apache.
the class AccessMethodUtils method findLOJIsMissingFuncInGroupBy.
public static ScalarFunctionCallExpression findLOJIsMissingFuncInGroupBy(GroupByOperator lojGroupbyOp) throws AlgebricksException {
//find IS_NULL function of which argument has the nullPlaceholder variable in the nested plan of groupby.
ALogicalPlanImpl subPlan = (ALogicalPlanImpl) lojGroupbyOp.getNestedPlans().get(0);
Mutable<ILogicalOperator> subPlanRootOpRef = subPlan.getRoots().get(0);
AbstractLogicalOperator subPlanRootOp = (AbstractLogicalOperator) subPlanRootOpRef.getValue();
boolean foundSelectNonNull = false;
ScalarFunctionCallExpression isNullFuncExpr = null;
AbstractLogicalOperator inputOp = subPlanRootOp;
while (inputOp != null) {
if (inputOp.getOperatorTag() == LogicalOperatorTag.SELECT) {
SelectOperator selectOp = (SelectOperator) inputOp;
if (selectOp.getCondition().getValue().getExpressionTag() == LogicalExpressionTag.FUNCTION_CALL) {
if (((AbstractFunctionCallExpression) selectOp.getCondition().getValue()).getFunctionIdentifier().equals(AlgebricksBuiltinFunctions.NOT)) {
ScalarFunctionCallExpression notFuncExpr = (ScalarFunctionCallExpression) selectOp.getCondition().getValue();
if (notFuncExpr.getArguments().get(0).getValue().getExpressionTag() == LogicalExpressionTag.FUNCTION_CALL) {
if (((AbstractFunctionCallExpression) notFuncExpr.getArguments().get(0).getValue()).getFunctionIdentifier().equals(AlgebricksBuiltinFunctions.IS_MISSING)) {
isNullFuncExpr = (ScalarFunctionCallExpression) notFuncExpr.getArguments().get(0).getValue();
if (isNullFuncExpr.getArguments().get(0).getValue().getExpressionTag() == LogicalExpressionTag.VARIABLE) {
foundSelectNonNull = true;
break;
}
}
}
}
}
}
inputOp = inputOp.getInputs().size() > 0 ? (AbstractLogicalOperator) inputOp.getInputs().get(0).getValue() : null;
}
if (!foundSelectNonNull) {
throw new AlgebricksException("Could not find the non-null select operator in GroupByOperator for LEFTOUTERJOIN plan optimization.");
}
return isNullFuncExpr;
}
Aggregations