prestodb/presto · warning · IllegalArgumentException
Can't convert value to long:
Error message
Can't convert value to long:
What it means
asLong converts Parquet statistic values (min/max) to long for integer-family types (BIGINT, INTEGER, SMALLINT, TINYINT). It accepts only Byte/Short/Integer/Long; any other value class (e.g. BigDecimal, BigInteger, String from odd statistic decoders) is rejected with IllegalArgumentException naming the actual class.
Source
Thrown at presto-parquet/src/main/java/com/facebook/presto/parquet/predicate/TupleDomainParquetPredicate.java:270
int dictionarySize = dictionaryPage.get().getDictionarySize();
DictionaryValueConverter converter = new DictionaryValueConverter(dictionary);
Function<Integer, Object> convertFunction = converter.getConverter(columnDescriptor.getPrimitiveType());
List<Object> values = new ArrayList<>();
for (int i = 0; i < dictionarySize; i++) {
values.add(convertFunction.apply(i));
}
// TODO: when min == max (i.e., singleton ranges, the construction of Domains can be done more efficiently
return getDomain(columnDescriptor, type, values, values, true);
}
public static long asLong(Object value)
{
if (value instanceof Byte || value instanceof Short || value instanceof Integer || value instanceof Long) {
return ((Number) value).longValue();
}
throw new IllegalArgumentException("Can't convert value to long: " + value.getClass().getName());
}
private static <T extends Comparable<T>> Domain createDomain(Type type, ColumnIndex columnIndex, boolean hasNullValue, List<T> mins, List<T> maxs)
{
if (mins.isEmpty() || maxs.isEmpty() || mins.size() != maxs.size()) {
return Domain.create(ValueSet.all(type), hasNullValue);
}
int pageCount = columnIndex.getMinValues().size();
List<Range> ranges = new ArrayList<>();
for (int i = 0; i < pageCount; i++) {
T min = mins.get(i);
T max = maxs.get(i);
if (min.compareTo(max) > 0) {
return Domain.create(ValueSet.all(type), hasNullValue);
}
if (min instanceof Long) {
if (isStatisticsOverflow(type, asLong(min), asLong(max))) {View on GitHub (pinned to 55bb57d202)
Solutions
- Ensure the parquet statistics deserialization matches the column physical type (upgrade/align parquet library versions)
- Check whether the column's declared type was altered (e.g. INT64 read as DECIMAL) and re-map it correctly
- Validate file statistics with parquet-tools; rewrite the file if the stats are corrupt
- Catch the IllegalArgumentException where statistics are consumed and fall back to an all-values domain
Example fix
// before
throw new IllegalArgumentException("Can't convert value to long: " + value.getClass().getName());
// after
if (value instanceof Number) {
return ((Number) value).longValue();
}
if (value instanceof BigInteger) {
return ((BigInteger) value).longValueExact();
}
throw new IllegalArgumentException("Can't convert value to long: " + value.getClass().getName()); Defensive patterns
Strategy: type-guard
Validate before calling
// check statistic value classes before domain construction
if (stats.getMin() != null && !(stats.getMin() instanceof Number)) {
skipPredicatePushdown(column); // fall back to full scan
} Type guard
boolean isIntegralStat(Object v) {
return v instanceof Byte || v instanceof Short || v instanceof Integer || v instanceof Long;
} Try / catch
try {
domain = TupleDomainParquetPredicate.asLong(minStat);
} catch (IllegalArgumentException e) {
if (e.getMessage().startsWith("Can't convert value to long")) {
domain = Domain.create(ValueSet.all(BIGINT), true);
} else throw e;
} Prevention
- Align parquet statistics deserialization versions between writer and reader
- Validate statistics types with parquet-tools for new data sources
- Guard integer-domain construction with instanceof checks on stat values
When it happens
Trigger: TupleDomainParquetPredicate builds domains for BIGINT/TINYINT/SMALLINT/INTEGER columns and calls asLong on a statistics minimum/maximum whose runtime type is not one of Byte, Short, Integer, or Long — i.e. the statistics deserializer produced an unexpected boxed type.
Common situations: Statistics decoded by a mismatched parquet reader version producing BigInteger/BigDecimal for INT64; corrupted statistics blobs decoded as strings; custom type mappings where min/max are deserialized differently than expected.
Related errors
- Impossible boolean statistics
- Unsupported Parquet primitive type:
- Unsupported Parquet type:
- Can't handle type:
- INVALID_ANALYZE_PROPERTY
AI-assisted analysis of prestodb/presto@55bb57d202 (2026-09-04).
Data as JSON: /api/errors/e6b83eee3bdf0a5b.
Report an issue: GitHub.