}
private static Expression toPredicate(Domain domain, QualifiedNameReference reference)
{
if (domain.getRanges().isNone()) {
return domain.isNullAllowed() ? new IsNullPredicate(reference) : FALSE_LITERAL;
}
if (domain.getRanges().isAll()) {
return domain.isNullAllowed() ? TRUE_LITERAL : new IsNotNullPredicate(reference);
}
// Add disjuncts for ranges
List<Expression> disjuncts = new ArrayList<>();
List<Expression> singleValues = new ArrayList<>();
for (Range range : domain.getRanges()) {
checkState(!range.isAll()); // Already checked
if (range.isSingleValue()) {
singleValues.add(toExpression(range.getLow().getValue()));
}
else {
List<Expression> rangeConjuncts = new ArrayList<>();
if (!range.getLow().isLowerUnbounded()) {
switch (range.getLow().getBound()) {
case ABOVE:
rangeConjuncts.add(new ComparisonExpression(ComparisonExpression.Type.GREATER_THAN, reference, toExpression(range.getLow().getValue())));
break;
case EXACTLY:
rangeConjuncts.add(new ComparisonExpression(ComparisonExpression.Type.GREATER_THAN_OR_EQUAL, reference, toExpression(range.getLow().getValue())));
break;
case BELOW:
throw new IllegalStateException("Low Marker should never use BELOW bound: " + range);
default:
throw new AssertionError("Unhandled bound: " + range.getLow().getBound());
}
}
if (!range.getHigh().isUpperUnbounded()) {
switch (range.getHigh().getBound()) {
case ABOVE:
throw new IllegalStateException("High Marker should never use ABOVE bound: " + range);
case EXACTLY:
rangeConjuncts.add(new ComparisonExpression(ComparisonExpression.Type.LESS_THAN_OR_EQUAL, reference, toExpression(range.getHigh().getValue())));
break;
case BELOW:
rangeConjuncts.add(new ComparisonExpression(ComparisonExpression.Type.LESS_THAN, reference, toExpression(range.getHigh().getValue())));
break;
default:
throw new AssertionError("Unhandled bound: " + range.getHigh().getBound());
}
}
// If rangeConjuncts is null, then the range was ALL, which should already have been checked for
checkState(!rangeConjuncts.isEmpty());
disjuncts.add(combineConjuncts(rangeConjuncts));
}
}
// Add back all of the possible single values either as an equality or an IN predicate
if (singleValues.size() == 1) {
disjuncts.add(new ComparisonExpression(EQUAL, reference, getOnlyElement(singleValues)));
}
else if (singleValues.size() > 1) {
disjuncts.add(new InPredicate(reference, new InListExpression(singleValues)));
}
// Add nullability disjuncts
checkState(!disjuncts.isEmpty());
if (domain.isNullAllowed()) {
disjuncts.add(new IsNullPredicate(reference));
}
return combineDisjunctsWithDefault(disjuncts, TRUE_LITERAL);
}