use of com.facebook.presto.common.predicate.Range in project presto by prestodb.
the class IonSqlQueryBuilder method toPredicate.
private String toPredicate(Domain domain, Type type, int position) {
checkArgument(domain.getType().isOrderable(), "Domain type must be orderable");
if (domain.getValues().isNone()) {
if (domain.isNullAllowed()) {
return format("s._%d", position + 1) + " = '' ";
}
return "FALSE";
}
if (domain.getValues().isAll()) {
if (domain.isNullAllowed()) {
return "TRUE";
}
return format("s._%d", position + 1) + " <> '' ";
}
List<String> disjuncts = new ArrayList<>();
List<Object> singleValues = new ArrayList<>();
for (Range range : domain.getValues().getRanges().getOrderedRanges()) {
checkState(!range.isAll());
if (range.isSingleValue()) {
singleValues.add(range.getSingleValue());
continue;
}
List<String> rangeConjuncts = new ArrayList<>();
if (!range.isLowUnbounded()) {
rangeConjuncts.add(toPredicate(range.isLowInclusive() ? ">=" : ">", range.getLowBoundedValue(), type, position));
}
if (!range.isHighUnbounded()) {
rangeConjuncts.add(toPredicate(range.isHighInclusive() ? "<=" : "<", range.getHighBoundedValue(), type, position));
}
// If rangeConjuncts is null, then the range was ALL, which should already have been checked for
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("=", getOnlyElement(singleValues), type, position));
} else if (singleValues.size() > 1) {
List<String> values = new ArrayList<>();
for (Object value : singleValues) {
checkType(type);
values.add(valueToQuery(type, value));
}
disjuncts.add(createColumn(type, position) + " IN (" + Joiner.on(",").join(values) + ")");
}
// Add nullability disjuncts
checkState(!disjuncts.isEmpty());
if (domain.isNullAllowed()) {
disjuncts.add(format("s._%d", position + 1) + " = '' ");
}
return "(" + Joiner.on(" OR ").join(disjuncts) + ")";
}
use of com.facebook.presto.common.predicate.Range in project presto by prestodb.
the class TestPrometheusSplit method testPredicatePushDownSetsUpperBoundOnly.
@Test
public void testPredicatePushDownSetsUpperBoundOnly() {
long predicateHighValue = 1568638171999L;
Range highRange = Range.lessThanOrEqual(TIMESTAMP_WITH_TIME_ZONE, packDateTimeWithZone(predicateHighValue, UTC_KEY));
ValueSet valueSet = ValueSet.ofRanges(highRange);
Domain testDomain = Domain.create(valueSet, false);
TupleDomain<ColumnHandle> testTupleDomain = TupleDomain.withColumnDomains(ImmutableMap.of(new PrometheusColumnHandle("timestamp", TIMESTAMP_WITH_TIME_ZONE, 2), testDomain));
PrometheusTableHandle prometheusTableHandle = new PrometheusTableHandle("schemaName", "tableName").withPredicate(testTupleDomain);
io.airlift.units.Duration maxQueryRangeDuration = new io.airlift.units.Duration(120, TimeUnit.SECONDS);
io.airlift.units.Duration queryChunkSizeDuration = new io.airlift.units.Duration(30, TimeUnit.SECONDS);
Instant now = ofEpochMilli(1568638171999L + 600000L);
List<String> splitTimes = PrometheusSplitManager.generateTimesForSplits(now, maxQueryRangeDuration, queryChunkSizeDuration, prometheusTableHandle);
TemporalAmount expectedMaxQueryAsTime = java.time.Duration.ofMillis(maxQueryRangeDuration.toMillis() + ((splitTimes.size() - 1) * OFFSET_MILLIS));
String lastSplit = splitTimes.get(splitTimes.size() - 1);
Instant lastSplitAsTime = ofEpochMilli(longFromDecimalSecondString(lastSplit));
String earliestSplit = splitTimes.get(0);
Instant earliestSplitAsTime = ofEpochMilli(longFromDecimalSecondString(earliestSplit));
TemporalAmount queryChunkAsTime = java.time.Duration.ofMillis(queryChunkSizeDuration.toMillis());
java.time.Duration actualMaxDuration = Duration.between(earliestSplitAsTime.minus(queryChunkAsTime), lastSplitAsTime);
assertEquals(lastSplitAsTime.toEpochMilli(), 1568638171999L);
assertEquals(actualMaxDuration, expectedMaxQueryAsTime);
}
use of com.facebook.presto.common.predicate.Range in project presto by prestodb.
the class TestPrometheusSplit method testPredicatePushDownSetsLowerBoundOnly.
@Test
public void testPredicatePushDownSetsLowerBoundOnly() {
long predicateLowValue = 1568638171999L - 600000L;
Range lowRange = Range.greaterThanOrEqual(TIMESTAMP_WITH_TIME_ZONE, packDateTimeWithZone(predicateLowValue, UTC_KEY));
ValueSet valueSet = ValueSet.ofRanges(lowRange);
Domain testDomain = Domain.create(valueSet, false);
TupleDomain<ColumnHandle> testTupleDomain = TupleDomain.withColumnDomains(ImmutableMap.of(new PrometheusColumnHandle("timestamp", TIMESTAMP_WITH_TIME_ZONE, 2), testDomain));
PrometheusTableHandle prometheusTableHandle = new PrometheusTableHandle("schemaName", "tableName").withPredicate(testTupleDomain);
io.airlift.units.Duration maxQueryRangeDuration = new io.airlift.units.Duration(120, TimeUnit.SECONDS);
io.airlift.units.Duration queryChunkSizeDuration = new io.airlift.units.Duration(30, TimeUnit.SECONDS);
Instant now = ofEpochMilli(1568638171999L);
TemporalAmount maxQueryAsTime = java.time.Duration.ofMillis(maxQueryRangeDuration.toMillis());
List<String> splitTimes = PrometheusSplitManager.generateTimesForSplits(now, maxQueryRangeDuration, queryChunkSizeDuration, prometheusTableHandle);
String earliestSplit = splitTimes.get(0);
Instant earliestSplitAsTime = ofEpochMilli(longFromDecimalSecondString(earliestSplit));
TemporalAmount queryChunkAsTime = java.time.Duration.ofMillis(queryChunkSizeDuration.toMillis());
Instant startOfQuery = earliestSplitAsTime.minus(queryChunkAsTime);
assertNotEquals(startOfQuery, now.minus(maxQueryAsTime).minus(java.time.Duration.ofMillis((splitTimes.size() - 1) * OFFSET_MILLIS)));
assertEquals(startOfQuery.toEpochMilli(), ofEpochMilli(predicateLowValue).toEpochMilli() - ((splitTimes.size() - 1) * OFFSET_MILLIS));
}
use of com.facebook.presto.common.predicate.Range in project presto by prestodb.
the class TestPrometheusSplit method testPredicatePushDownSetsUpperAndLowerBound.
@Test
public void testPredicatePushDownSetsUpperAndLowerBound() {
long predicateHighValue = 1568638171999L;
Range highRange = Range.equal(TIMESTAMP_WITH_TIME_ZONE, packDateTimeWithZone(predicateHighValue, UTC_KEY));
long predicateLowValue = 1568638171999L - 600000L;
Range lowRange = Range.equal(TIMESTAMP_WITH_TIME_ZONE, packDateTimeWithZone(predicateLowValue, UTC_KEY));
ValueSet valueSet = ValueSet.ofRanges(lowRange, highRange);
Domain testDomain = Domain.create(valueSet, false);
TupleDomain<ColumnHandle> testTupleDomain = TupleDomain.withColumnDomains(ImmutableMap.of(new PrometheusColumnHandle("timestamp", TIMESTAMP_WITH_TIME_ZONE, 2), testDomain));
PrometheusTableHandle prometheusTableHandle = new PrometheusTableHandle("schemaName", "tableName").withPredicate(testTupleDomain);
io.airlift.units.Duration maxQueryRangeDuration = new io.airlift.units.Duration(120, TimeUnit.SECONDS);
io.airlift.units.Duration queryChunkSizeDuration = new io.airlift.units.Duration(30, TimeUnit.SECONDS);
Instant now = ofEpochMilli(1568638171999L + 1200000L);
List<String> splitTimes = PrometheusSplitManager.generateTimesForSplits(now, maxQueryRangeDuration, queryChunkSizeDuration, prometheusTableHandle);
TemporalAmount expectedMaxQueryAsTime = java.time.Duration.ofMillis(new io.airlift.units.Duration(10, TimeUnit.MINUTES).toMillis() + ((splitTimes.size() - 1) * OFFSET_MILLIS));
String lastSplit = splitTimes.get(splitTimes.size() - 1);
Instant lastSplitAsTime = ofEpochMilli(longFromDecimalSecondString(lastSplit));
String earliestSplit = splitTimes.get(0);
Instant earliestSplitAsTime = ofEpochMilli(longFromDecimalSecondString(earliestSplit));
TemporalAmount queryChunkAsTime = java.time.Duration.ofMillis(queryChunkSizeDuration.toMillis());
java.time.Duration actualMaxDuration = Duration.between(earliestSplitAsTime.minus(queryChunkAsTime), lastSplitAsTime);
assertEquals(lastSplitAsTime.toEpochMilli(), 1568638171999L);
assertEquals(actualMaxDuration, expectedMaxQueryAsTime);
}
use of com.facebook.presto.common.predicate.Range in project presto by prestodb.
the class ShardPredicate method create.
public static ShardPredicate create(TupleDomain<RaptorColumnHandle> tupleDomain) {
StringJoiner predicate = new StringJoiner(" AND ").setEmptyValue("true");
ImmutableList.Builder<JDBCType> types = ImmutableList.builder();
ImmutableList.Builder<Object> values = ImmutableList.builder();
for (Entry<RaptorColumnHandle, Domain> entry : tupleDomain.getDomains().get().entrySet()) {
Domain domain = entry.getValue();
if (domain.isNullAllowed() || domain.isAll()) {
continue;
}
RaptorColumnHandle handle = entry.getKey();
Type type = handle.getColumnType();
JDBCType jdbcType = jdbcType(type);
if (jdbcType == null) {
continue;
}
if (handle.isShardUuid()) {
predicate.add(createShardPredicate(types, values, domain, jdbcType));
continue;
}
if (!domain.getType().isOrderable()) {
continue;
}
StringJoiner columnPredicate = new StringJoiner(" OR ", "(", ")").setEmptyValue("true");
Ranges ranges = domain.getValues().getRanges();
// prevent generating complicated metadata queries
if (ranges.getRangeCount() > MAX_RANGE_COUNT) {
continue;
}
for (Range range : ranges.getOrderedRanges()) {
String min;
String max;
if (handle.isBucketNumber()) {
min = "bucket_number";
max = "bucket_number";
} else {
min = minColumn(handle.getColumnId());
max = maxColumn(handle.getColumnId());
}
StringJoiner rangePredicate = new StringJoiner(" AND ", "(", ")").setEmptyValue("true");
if (!range.isLowUnbounded()) {
rangePredicate.add(format("(%s >= ? OR %s IS NULL)", max, max));
types.add(jdbcType);
values.add(range.getLowBoundedValue());
}
if (!range.isHighUnbounded()) {
rangePredicate.add(format("(%s <= ? OR %s IS NULL)", min, min));
types.add(jdbcType);
values.add(range.getHighBoundedValue());
}
columnPredicate.add(rangePredicate.toString());
}
predicate.add(columnPredicate.toString());
}
return new ShardPredicate(predicate.toString(), types.build(), values.build());
}
Aggregations