in athena-timestream/src/main/java/com/amazonaws/athena/connectors/timestream/query/PredicateBuilder.java [61:142]
private static String toPredicate(String columnName, ValueSet valueSet)
{
List<String> disjuncts = new ArrayList<>();
List<Object> singleValues = new ArrayList<>();
// TODO Add isNone and isAll checks once we have data on nullability.
if (valueSet instanceof SortedRangeSet) {
if (valueSet.isNone() && valueSet.isNullAllowed()) {
return String.format("(%s IS NULL)", columnName);
}
if (valueSet.isNullAllowed()) {
disjuncts.add(String.format("(%s IS NULL)", columnName));
}
Range rangeSpan = ((SortedRangeSet) valueSet).getSpan();
if (!valueSet.isNullAllowed() && rangeSpan.getLow().isLowerUnbounded() && rangeSpan.getHigh().isUpperUnbounded()) {
return String.format("(%s IS NOT NULL)", columnName);
}
for (Range range : valueSet.getRanges().getOrderedRanges()) {
if (range.isSingleValue()) {
singleValues.add(range.getLow().getValue());
}
else {
List<String> rangeConjuncts = new ArrayList<>();
if (!range.getLow().isLowerUnbounded()) {
switch (range.getLow().getBound()) {
case ABOVE:
rangeConjuncts.add(toPredicate(columnName, ">", range.getLow().getValue(), valueSet.getType()));
break;
case EXACTLY:
rangeConjuncts.add(toPredicate(columnName, ">=", range.getLow().getValue(), valueSet.getType()));
break;
case BELOW:
throw new IllegalArgumentException("Low marker should never use BELOW bound");
default:
throw new AssertionError("Unhandled bound: " + range.getLow().getBound());
}
}
if (!range.getHigh().isUpperUnbounded()) {
switch (range.getHigh().getBound()) {
case ABOVE:
throw new IllegalArgumentException("High marker should never use ABOVE bound");
case EXACTLY:
rangeConjuncts.add(toPredicate(columnName, "<=", range.getHigh().getValue(), valueSet.getType()));
break;
case BELOW:
rangeConjuncts.add(toPredicate(columnName, "<", range.getHigh().getValue(), valueSet.getType()));
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
Preconditions.checkState(!rangeConjuncts.isEmpty());
disjuncts.add("(" + Joiner.on(" AND ").join(rangeConjuncts) + ")");
}
}
// Add back all of the possible single values either as an equality or an IN predicate
if (singleValues.size() == 1) {
disjuncts.add(toPredicate(columnName, "=", Iterables.getOnlyElement(singleValues), valueSet.getType()));
}
else if (singleValues.size() > 1) {
List<String> values = singleValues.stream().map(next -> quoteValue(next, valueSet.getType())).collect(Collectors.toList());
String valuesStr = Joiner.on(",").join(values);
disjuncts.add(quoteColumn(columnName) + " IN (" + valuesStr + ")");
}
}
else if (valueSet instanceof EquatableValueSet) {
List<String> values = new ArrayList<>();
for (int i = 0; i < ((EquatableValueSet) valueSet).getValueBlock().getRowCount(); i++) {
values.add(quoteValue(((EquatableValueSet) valueSet).getValue(i), valueSet.getType()));
}
String valuesStr = Joiner.on(",").join(values);
disjuncts.add(quoteColumn(columnName) + " IN (" + valuesStr + ")");
}
return "(" + Joiner.on(" OR ").join(disjuncts) + ")";
}