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
- 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
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
- 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
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
- DECIMAL precision must be in range [1, 38]
- DECIMAL scale must be in range [0, precision]
- Invalid decimal value '{stringValue}'
- NUMERIC_VALUE_OUT_OF_RANGE
- Expected 0, 1 or 2 parameters for DECIMAL type constructor.
AI-assisted analysis of prestodb/presto@55bb57d202 (2026-09-04).
Data as JSON: /api/errors/4c84c8313b8fe4f5.
Report an issue: GitHub.