for (PlanNode access : plan.findAllAtOrBelow(Type.ACCESS)) {
// Look for select nodes below an ACCESS node that have a single Comparison constraint,
// and accumulate them keyed by the dynamic operand ...
Multimap<DynamicOperand, PlanNode> selectNodeByOperand = ArrayListMultimap.create();
for (PlanNode select : access.findAllAtOrBelow(Type.SELECT)) {
Constraint constraint = select.getProperty(Property.SELECT_CRITERIA, Constraint.class);
// Look for Comparison constraints that use a range operator
if (constraint instanceof Comparison) {
Comparison comparison = (Comparison)constraint;
if (comparison.getOperator().isRangeOperator()) {
selectNodeByOperand.put(comparison.getOperand1(), select);
}
}
}
if (!selectNodeByOperand.isEmpty()) {
// Go through the constraints we've found ...
for (DynamicOperand operand : selectNodeByOperand.keySet()) {
Collection<PlanNode> nodes = selectNodeByOperand.get(operand);
if (nodes.size() <= 1) continue;
// Extract the constraints from the nodes ...
List<Comparison> rangeConstraints = new ArrayList<Comparison>(nodes.size());
List<PlanNode> selectNodes = new ArrayList<PlanNode>(nodes.size());
Set<SelectorName> selectors = null;
for (PlanNode select : nodes) {
selectNodes.add(select);
Comparison constraint = select.getProperty(Property.SELECT_CRITERIA, Comparison.class);
rangeConstraints.add(constraint);
// Record the selector names (should all be the same) ...
if (selectors == null) selectors = select.getSelectors();
else assert selectors.equals(select.getSelectors());
}
// Attempt to merge the constraints ...
Constraint merged = rewrite(context, rangeConstraints);
if (merged == CONFLICTING_CONSTRAINT) {
// The ANDed constraints cancel each other out, so this whole access node will return no results ...
access.setProperty(Property.ACCESS_NO_RESULTS, Boolean.TRUE);
foundNoResults = true;
break; // don't do anything else under this access node