{"record":{"id":"e6b83eee3bdf0a5b","repo":"prestodb/presto","slug":"can-t-convert-value-to-long","errorCode":null,"errorMessage":"Can't convert value to long: ","messagePattern":"Can't convert value to long: ","errorType":"exception","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"warning","filePath":"presto-parquet/src/main/java/com/facebook/presto/parquet/predicate/TupleDomainParquetPredicate.java","lineNumber":270,"sourceCode":"        int dictionarySize = dictionaryPage.get().getDictionarySize();\n        DictionaryValueConverter converter = new DictionaryValueConverter(dictionary);\n        Function<Integer, Object> convertFunction = converter.getConverter(columnDescriptor.getPrimitiveType());\n        List<Object> values = new ArrayList<>();\n        for (int i = 0; i < dictionarySize; i++) {\n            values.add(convertFunction.apply(i));\n        }\n\n        // TODO: when min == max (i.e., singleton ranges, the construction of Domains can be done more efficiently\n        return getDomain(columnDescriptor, type, values, values, true);\n    }\n\n    public static long asLong(Object value)\n    {\n        if (value instanceof Byte || value instanceof Short || value instanceof Integer || value instanceof Long) {\n            return ((Number) value).longValue();\n        }\n\n        throw new IllegalArgumentException(\"Can't convert value to long: \" + value.getClass().getName());\n    }\n\n    private static <T extends Comparable<T>> Domain createDomain(Type type, ColumnIndex columnIndex, boolean hasNullValue, List<T> mins, List<T> maxs)\n    {\n        if (mins.isEmpty() || maxs.isEmpty() || mins.size() != maxs.size()) {\n            return Domain.create(ValueSet.all(type), hasNullValue);\n        }\n        int pageCount = columnIndex.getMinValues().size();\n        List<Range> ranges = new ArrayList<>();\n        for (int i = 0; i < pageCount; i++) {\n            T min = mins.get(i);\n            T max = maxs.get(i);\n            if (min.compareTo(max) > 0) {\n                return Domain.create(ValueSet.all(type), hasNullValue);\n            }\n\n            if (min instanceof Long) {\n                if (isStatisticsOverflow(type, asLong(min), asLong(max))) {","sourceCodeStart":252,"sourceCodeEnd":288,"githubUrl":"https://github.com/prestodb/presto/blob/55bb57d202de3b926896fa966c2c4a44c779634e/presto-parquet/src/main/java/com/facebook/presto/parquet/predicate/TupleDomainParquetPredicate.java#L252-L288","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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"],"exampleFix":"// before\nthrow new IllegalArgumentException(\"Can't convert value to long: \" + value.getClass().getName());\n// after\nif (value instanceof Number) {\n    return ((Number) value).longValue();\n}\nif (value instanceof BigInteger) {\n    return ((BigInteger) value).longValueExact();\n}\nthrow new IllegalArgumentException(\"Can't convert value to long: \" + value.getClass().getName());","handlingStrategy":"type-guard","validationCode":"// check statistic value classes before domain construction\nif (stats.getMin() != null && !(stats.getMin() instanceof Number)) {\n    skipPredicatePushdown(column); // fall back to full scan\n}","typeGuard":"boolean isIntegralStat(Object v) {\n    return v instanceof Byte || v instanceof Short || v instanceof Integer || v instanceof Long;\n}","tryCatchPattern":"try {\n    domain = TupleDomainParquetPredicate.asLong(minStat);\n} catch (IllegalArgumentException e) {\n    if (e.getMessage().startsWith(\"Can't convert value to long\")) {\n        domain = Domain.create(ValueSet.all(BIGINT), true);\n    } else throw e;\n}","preventionTips":["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"],"tags":["parquet","statistics","type-conversion","predicate-pushdown"],"backgroundTag":"statistics-value-type-mismatch","analyzedSha":"55bb57d202de3b926896fa966c2c4a44c779634e","analyzedAt":"2026-09-04T12:50:26.162Z","contentChangedAt":"2026-09-04T12:50:26.162Z","schemaVersion":2},"datasetVersion":"2026-09-11T21:17:09.523Z"}