prestodb/presto · error · IllegalArgumentException

Unexpected type

Error message

Unexpected type: ${type}

What it means

MetastoreHiveStatisticsProvider.convertPartitionValueToDouble converts a raw metastore partition-statistics value into a double for stats aggregation. It only supports BOOLEAN, INTEGER/Bigint-style numeric, DOUBLE, and DATE partitions (plus decimal handled earlier); any other Type reaching the final check means the value's type is not representable as a double, so it throws IllegalArgumentException to fail fast rather than produce wrong statistics.

Solutions

  1. Restrict statistics collection to supported column types (filter unsupported types before calling convertPartitionValueToDouble)
  2. Check the Type whitelist (BOOLEAN, INTEGER/numeric, DOUBLE, DATE) and extend the method if the new type is legitimately needed
  3. Verify the metastore stats schema for the partition column matches the expected types
  4. Upgrade Presto to a version that supports the type in question

Example fix

// before
double d = MetastoreHiveStatisticsProvider.convertPartitionValueToDouble(varcharType, value); // throws
// after
if (type.equals(BOOLEAN) || type instanceof IntegerType || type.equals(DOUBLE) || type.equals(DATE)) {
    double d = MetastoreHiveStatisticsProvider.convertPartitionValueToDouble(type, value);
}
Defensive patterns

Strategy: validation

Validate before calling

private static final Set<Type> SUPPORTED = ImmutableSet.of(BOOLEAN, DOUBLE, DATE, BIGINT, INTEGER, SMALLINT, TINYINT);
if (!SUPPORTED.contains(type) && !(type instanceof DecimalType)) {
    throw new IllegalArgumentException("Type not convertible to double for stats: " + type);
}
double d = MetastoreHiveStatisticsProvider.convertPartitionValueToDouble(type, value);

Type guard

boolean isStatsConvertible(Type type) {
    return type.equals(BOOLEAN) || type.equals(DOUBLE) || type.equals(DATE)
        || type.equals(BIGINT) || type.equals(INTEGER) || type.equals(SMALLINT)
        || type.equals(TINYINT) || type instanceof DecimalType;
}

Try / catch

try {
    double d = convertPartitionValueToDouble(type, value);
} catch (IllegalArgumentException e) {
    LOG.warn(e.getMessage());
    // fall back to unknown statistics for this column
}

Prevention

When it happens

Trigger: Calling values()/statistics aggregation over a partition column whose Type is not BOOLEAN, the supported integer family, DOUBLE, or DATE — e.g. VARCHAR, TIMESTAMP, complex types, or a new Hive type whose value arrived from the metastore.

Common situations: Partition statistics tables containing columns of unsupported types (strings/timestamps); a Presto version upgrade adding a type the provider's whitelist doesn't cover; misconfigured partition column of type varchar being fed into stats computation.

Related errors


AI-assisted analysis of prestodb/presto@55bb57d202 (2026-09-04). Data as JSON: /api/errors/af331d31da95f87b. Report an issue: GitHub.

Appendix: source

Thrown at presto-hive/src/main/java/com/facebook/presto/hive/statistics/MetastoreHiveStatisticsProvider.java:672

            return (Double) value;
        }
        if (type.equals(REAL)) {
            return intBitsToFloat(((Long) value).intValue());
        }
        if (type instanceof DecimalType) {
            DecimalType decimalType = (DecimalType) type;
            if (isShortDecimal(decimalType)) {
                return parseDouble(Decimals.toString((Long) value, decimalType.getScale()));
            }
            if (isLongDecimal(decimalType)) {
                return parseDouble(Decimals.toString((Slice) value, decimalType.getScale()));
            }
            throw new IllegalArgumentException("Unexpected decimal type: " + decimalType);
        }
        if (type.equals(DATE)) {
            return (Long) value;
        }
        throw new IllegalArgumentException("Unexpected type: " + type);
    }

    @VisibleForTesting
    static ColumnStatistics createDataColumnStatistics(String column, Type type, double rowsCount, Collection<PartitionStatistics> partitionStatistics)
    {
        List<HiveColumnStatistics> columnStatistics = partitionStatistics.stream()
                .map(PartitionStatistics::getColumnStatistics)
                .map(statistics -> statistics.get(column))
                .filter(Objects::nonNull)
                .collect(toImmutableList());

        if (columnStatistics.isEmpty()) {
            return ColumnStatistics.empty();
        }

        return ColumnStatistics.builder()
                .setDistinctValuesCount(calculateDistinctValuesCount(columnStatistics))
                .setNullsFraction(calculateNullsFraction(column, partitionStatistics))

View on GitHub (pinned to 55bb57d202)