{"record":{"id":"47a13e712064e66a","repo":"prestodb/presto","slug":"unexpected-decimal-type","errorCode":null,"errorMessage":"Unexpected decimal type: ","messagePattern":"Unexpected decimal type: ","errorType":"validation","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"presto-tpcds/src/main/java/com/facebook/presto/tpcds/statistics/TpcdsTableStatisticsFactory.java","lineNumber":112,"sourceCode":"    }\n\n    private static double toDouble(Object value, Type type)\n    {\n        if (value instanceof String && type.equals(DATE)) {\n            return LocalDate.parse((CharSequence) value).toEpochDay();\n        }\n        if (type.equals(BIGINT) || type.equals(INTEGER) || type.equals(DATE)) {\n            return ((Number) value).doubleValue();\n        }\n        if (type instanceof DecimalType) {\n            DecimalType decimalType = (DecimalType) type;\n            if (isShortDecimal(decimalType)) {\n                return parseDouble(Decimals.toString(((Number) value).longValue(), decimalType.getScale()));\n            }\n            if (isLongDecimal(decimalType)) {\n                return parseDouble(Decimals.toString((Slice) value, decimalType.getScale()));\n            }\n            throw new IllegalArgumentException(\"Unexpected decimal type: \" + decimalType);\n        }\n        if (type.equals(DOUBLE)) {\n            return ((Number) value).doubleValue();\n        }\n        throw new IllegalArgumentException(\"unsupported column type \" + type);\n    }\n}\n","sourceCodeStart":94,"sourceCodeEnd":120,"githubUrl":"https://github.com/prestodb/presto/blob/55bb57d202de3b926896fa966c2c4a44c779634e/presto-tpcds/src/main/java/com/facebook/presto/tpcds/statistics/TpcdsTableStatisticsFactory.java#L94-L120","documentation":"TpcdsTableStatisticsFactory.toDouble converts a decoded statistics value to double; for decimal values it only handles short (64-bit) and long (128-bit) decimals via isShortDecimal/isLongDecimal. A decimal value that is neither, or a DecimalType variant it does not recognize, triggers 'Unexpected decimal type'. It is an internal invariant violation in statistics conversion.","triggerScenarios":"toRange building a stats range from a column block value typed as decimal but whose Type instance is not classified as short or long decimal (e.g. an unexpected DecimalType implementation or precision outside 1-38).","commonSituations":"Custom or third-party Type implementations for decimals feeding statistics conversion; internal Presto type-system changes; statistics blocks built with mismatched type metadata.","solutions":["Ensure statistics blocks use standard Presto DecimalType instances (createDecimalType)","Check the decimalType precision is within 1..38 so short/long classification works","Upgrade Presto if a type-system change broke isShortDecimal/isLongDecimal classification","Report/investigate which plugin supplied the non-standard decimal type"],"exampleFix":"// before\nType t = new MyCustomDecimalType(p, s);\n// after\nType t = DecimalType.createDecimalType(p, s);","handlingStrategy":"type-guard","validationCode":"if (type instanceof DecimalType) {\n    DecimalType d = (DecimalType) type;\n    if (d.getPrecision() < 1 || d.getPrecision() > 38) {\n        throw new IllegalArgumentException(\"Decimal precision out of range: \" + d);\n    }\n} else if (!type.equals(DOUBLE)) {\n    throw new IllegalArgumentException(\"Stats conversion requires decimal or double, got \" + type);\n}","typeGuard":"boolean isSupportedNumeric(Type t) {\n    return t.equals(DOUBLE) || (t instanceof DecimalType && ((DecimalType) t).getPrecision() <= 38);\n}","tryCatchPattern":"try {\n    double d = toDouble(type, value);\n} catch (IllegalArgumentException e) {\n    if (e.getMessage().startsWith(\"Unexpected decimal type\")) {\n        throw new IllegalStateException(\"Non-standard decimal type in stats block: \" + e.getMessage(), e);\n    }\n    throw e;\n}","preventionTips":["Use DecimalType.createDecimalType for all decimal stats columns","Keep precision within 1..38 so short/long classification holds","Avoid custom Type implementations in statistics paths"],"tags":["statistics","decimal","type-mapping"],"backgroundTag":"unsupported-decimal-type","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"}