prestodb/presto · error · InvalidFunctionArgumentException
DECIMAL precision must be in range [1, 38]
Error message
DECIMAL precision must be in range [1, 38]
What it means
DecimalType.validatePrecisionScale checks that DECIMAL precision is between 1 and the maximum precision (38, or 18 for short decimals when callers pass a smaller maxPrecision). Presto stores DECIMAL(p,s) with bounded precision, so any type creation with precision outside [1, MAX_PRECISION] throws InvalidFunctionArgumentException. Note the message always cites MAX_PRECISION=38 even when maxPrecision passed is smaller.
Source
Thrown at presto-common/src/main/java/com/facebook/presto/common/type/DecimalType.java:92
public int getPrecision()
{
return precision;
}
public int getScale()
{
return scale;
}
public boolean isShort()
{
return precision <= MAX_SHORT_PRECISION;
}
void validatePrecisionScale(int precision, int scale, int maxPrecision)
{
if (precision <= 0 || precision > maxPrecision) {
throw new InvalidFunctionArgumentException("DECIMAL precision must be in range [1, " + MAX_PRECISION + "]");
}
if (scale < 0 || scale > precision) {
throw new InvalidFunctionArgumentException("DECIMAL scale must be in range [0, precision]");
}
}
private static List<TypeSignatureParameter> buildTypeParameters(int precision, int scale)
{
List<TypeSignatureParameter> typeParameters = new ArrayList<>();
typeParameters.add(TypeSignatureParameter.of(precision));
typeParameters.add(TypeSignatureParameter.of(scale));
return unmodifiableList(typeParameters);
}
}
View on GitHub (pinned to 55bb57d202)
Solutions
- Cap the declared precision at 38 (or coerce to DOUBLE/VARCHAR when the source exceeds 38)
- Fix upstream column metadata to a supported precision before type creation
- Compute precision defensively so it is always >= 1
- Use Decimals.createDecimalType helpers that pair precision with the right max
Example fix
// before Type type = DecimalType.createDecimalType(sourcePrecision, sourceScale); // sourcePrecision can be 65 // after int precision = Math.min(Math.max(sourcePrecision, 1), DecimalType.MAX_PRECISION); int scale = Math.min(sourceScale, precision); Type type = (precision > DecimalType.MAX_SHORT_PRECISION) ? DoubleType.DOUBLE : DecimalType.createDecimalType(precision, scale);
Defensive patterns
Strategy: validation
Validate before calling
public static boolean isValidPrecision(int precision, int maxPrecision) {
return precision > 0 && precision <= maxPrecision;
}
// before createDecimalType: assert isValidPrecision(p, DecimalType.MAX_PRECISION) Type guard
public static boolean isSupportedDecimalPrecision(Integer p) {
return p != null && p > 0 && p <= 38;
} Try / catch
try {
Type t = DecimalType.createDecimalType(precision, scale);
} catch (InvalidFunctionArgumentException e) {
// degrade to DOUBLE or VARCHAR for out-of-range precision
} Prevention
- Cap foreign precisions (e.g. DECIMAL(65)) at 38 or map to DOUBLE
- Never compute precision with formulas that can return 0 or negatives
- Coerce oversized source columns to DOUBLE/VARCHAR during schema mapping
When it happens
Trigger: Calling DecimalType.createType(precision, scale) or validatePrecisionScale with precision <= 0 or precision > maxPrecision (38 for full decimals, 18 when short-decimal is enforced); a connector declaring a DECIMAL column with precision 0, negative, or > 38.
Common situations: Schema mapping from databases allowing larger precision (e.g. DECIMAL(65) in MySQL) straight into Presto; computed precision from expressions yielding 0 or negatives due to bugs; ORC/Parquet metadata declaring out-of-range precision.
Related errors
- DECIMAL scale must be in range [0, precision]
- CHAR length scale must be in range [0, %s]
- Enum definition expected, got %s
- INVALID_ARGUMENTS
- array1 and array2 cannot be null and should have same length
AI-assisted analysis of prestodb/presto@55bb57d202 (2026-09-04).
Data as JSON: /api/errors/8eec399c6fa86af4.
Report an issue: GitHub.