{"record":{"id":"4c84c8313b8fe4f5","repo":"prestodb/presto","slug":"decimal-precision-larger-than-column-precision","errorCode":null,"errorMessage":"decimal precision larger than column precision","messagePattern":"decimal precision larger than column precision","errorType":"validation","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"presto-common/src/main/java/com/facebook/presto/common/type/Decimals.java","lineNumber":266,"sourceCode":"    public static BigDecimal readBigDecimal(DecimalType type, Block block, int position)\n    {\n        BigInteger unscaledValue = type.isShort()\n                ? BigInteger.valueOf(type.getLong(block, position))\n                : decodeUnscaledValue(type.getSlice(block, position));\n        return new BigDecimal(unscaledValue, type.getScale(), new MathContext(type.getPrecision()));\n    }\n\n    public static void writeBigDecimal(DecimalType decimalType, BlockBuilder blockBuilder, BigDecimal value)\n    {\n        decimalType.writeSlice(blockBuilder, encodeScaledValue(value));\n    }\n\n    public static BigDecimal rescale(BigDecimal value, DecimalType type)\n    {\n        value = value.setScale(type.getScale(), UNNECESSARY);\n\n        if (value.precision() > type.getPrecision()) {\n            throw new IllegalArgumentException(\"decimal precision larger than column precision\");\n        }\n        return value;\n    }\n\n    public static void writeShortDecimal(BlockBuilder blockBuilder, long value)\n    {\n        blockBuilder.writeLong(value).closeEntry();\n    }\n\n    public static long rescale(long value, int fromScale, int toScale)\n    {\n        if (toScale < fromScale) {\n            throw new IllegalArgumentException(\"target scale must be larger than source scale\");\n        }\n        return value * longTenToNth(toScale - fromScale);\n    }\n\n    public static BigInteger rescale(BigInteger value, int fromScale, int toScale)","sourceCodeStart":248,"sourceCodeEnd":284,"githubUrl":"https://github.com/prestodb/presto/blob/55bb57d202de3b926896fa966c2c4a44c779634e/presto-common/src/main/java/com/facebook/presto/common/type/Decimals.java#L248-L284","documentation":"Decimals.rescale sets a BigDecimal to the target DecimalType's scale using RoundingMode.UNNECESSARY, then verifies the resulting precision fits the column's declared precision. If value.precision() exceeds type.getPrecision(), an IllegalArgumentException is thrown because the value cannot be stored in the column without loss. UNNECESSARY also means any required rounding itself would throw ArithmeticException first.","triggerScenarios":"Calling Decimals.rescale(value, decimalType) where the value's digit count after rescaling exceeds the column precision (e.g. writing 123456.78 into DECIMAL(5,2)); inserting results of arithmetic whose precision grew beyond the target column.","commonSituations":"INSERT/CTAS into a narrower DECIMAL column than computed expression results; ORC writer enforcing declared column type; moving data between tables where the target column was declared too small.","solutions":["Widen the target column's precision (ALTER TABLE or recreate) to accommodate the value","Pre-round explicitly with a rounding mode and cap precision before rescale","Cast the expression to the target DECIMAL type in SQL so rounding/truncation is explicit","Catch the mismatch in ETL and route overflow rows to a rejection path"],"exampleFix":"// before\nDecimals.rescale(result, DecimalType.createDecimalType(5, 2)); // throws if result needs 8 digits\n// after\nBigDecimal rounded = result.setScale(2, RoundingMode.HALF_UP)\n                           .max(new BigDecimal(\"-999.99\"))\n                           .min(new BigDecimal(\"999.99\"));\nDecimals.rescale(rounded, DecimalType.createDecimalType(5, 2));","handlingStrategy":"validation","validationCode":"public static boolean fitsInColumn(BigDecimal value, DecimalType type) {\n    return value.setScale(type.getScale(), RoundingMode.HALF_UP).precision() <= type.getPrecision();\n}","typeGuard":"public static boolean isRescalable(BigDecimal value, DecimalType type) {\n    return value != null && type != null && value.precision() <= type.getPrecision();\n}","tryCatchPattern":"try {\n    BigDecimal v = Decimals.rescale(value, columnType);\n} catch (IllegalArgumentException | ArithmeticException e) {\n    // precision/rounding loss: widen column or apply explicit rounding\n}","preventionTips":["Declare target columns wide enough for computed expression results","Apply explicit setScale with a rounding mode before rescale","Cast in SQL with the target DECIMAL type so truncation is intentional"],"tags":["presto","decimal","precision","rescale"],"backgroundTag":"decimal-precision-overflow","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"}