prestodb/presto · error · IllegalArgumentException

decimal precision larger than column precision

Error message

decimal precision larger than column precision

What it means

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.

Source

Thrown at presto-common/src/main/java/com/facebook/presto/common/type/Decimals.java:266

    public static BigDecimal readBigDecimal(DecimalType type, Block block, int position)
    {
        BigInteger unscaledValue = type.isShort()
                ? BigInteger.valueOf(type.getLong(block, position))
                : decodeUnscaledValue(type.getSlice(block, position));
        return new BigDecimal(unscaledValue, type.getScale(), new MathContext(type.getPrecision()));
    }

    public static void writeBigDecimal(DecimalType decimalType, BlockBuilder blockBuilder, BigDecimal value)
    {
        decimalType.writeSlice(blockBuilder, encodeScaledValue(value));
    }

    public static BigDecimal rescale(BigDecimal value, DecimalType type)
    {
        value = value.setScale(type.getScale(), UNNECESSARY);

        if (value.precision() > type.getPrecision()) {
            throw new IllegalArgumentException("decimal precision larger than column precision");
        }
        return value;
    }

    public static void writeShortDecimal(BlockBuilder blockBuilder, long value)
    {
        blockBuilder.writeLong(value).closeEntry();
    }

    public static long rescale(long value, int fromScale, int toScale)
    {
        if (toScale < fromScale) {
            throw new IllegalArgumentException("target scale must be larger than source scale");
        }
        return value * longTenToNth(toScale - fromScale);
    }

    public static BigInteger rescale(BigInteger value, int fromScale, int toScale)

View on GitHub (pinned to 55bb57d202)

Solutions

  1. Widen the target column's precision (ALTER TABLE or recreate) to accommodate the value
  2. Pre-round explicitly with a rounding mode and cap precision before rescale
  3. Cast the expression to the target DECIMAL type in SQL so rounding/truncation is explicit
  4. Catch the mismatch in ETL and route overflow rows to a rejection path

Example fix

// before
Decimals.rescale(result, DecimalType.createDecimalType(5, 2)); // throws if result needs 8 digits
// after
BigDecimal rounded = result.setScale(2, RoundingMode.HALF_UP)
                           .max(new BigDecimal("-999.99"))
                           .min(new BigDecimal("999.99"));
Decimals.rescale(rounded, DecimalType.createDecimalType(5, 2));
Defensive patterns

Strategy: validation

Validate before calling

public static boolean fitsInColumn(BigDecimal value, DecimalType type) {
    return value.setScale(type.getScale(), RoundingMode.HALF_UP).precision() <= type.getPrecision();
}

Type guard

public static boolean isRescalable(BigDecimal value, DecimalType type) {
    return value != null && type != null && value.precision() <= type.getPrecision();
}

Try / catch

try {
    BigDecimal v = Decimals.rescale(value, columnType);
} catch (IllegalArgumentException | ArithmeticException e) {
    // precision/rounding loss: widen column or apply explicit rounding
}

Prevention

When it happens

Trigger: 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.

Common situations: 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.

Related errors


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