prestodb/presto · error · InvalidFunctionArgumentException
DECIMAL scale must be in range [0, precision]
Error message
DECIMAL scale must be in range [0, precision]
What it means
DecimalType.validatePrecisionScale requires the scale to satisfy 0 <= scale <= precision. A negative scale or a scale larger than the precision is not a representable DECIMAL(p,s) in Presto, so InvalidFunctionArgumentException is thrown. This fires only when precision itself was in range, so the caller got precision right but the scale wrong.
Source
Thrown at presto-common/src/main/java/com/facebook/presto/common/type/DecimalType.java:96
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
- Clamp scale to [0, precision] before createDecimalType
- Fix the connector/schema mapping so scale <= precision is guaranteed
- If the source genuinely has scale > precision, widen precision (up to 38) or fall back to DOUBLE
- Validate DDL/derived type parameters before registering the type
Example fix
// before Type type = DecimalType.createDecimalType(precision, scale); // scale may exceed precision // after int safeScale = Math.max(0, Math.min(scale, precision)); Type type = DecimalType.createDecimalType(precision, safeScale);
Defensive patterns
Strategy: validation
Validate before calling
public static boolean isValidScale(int precision, int scale) {
return scale >= 0 && scale <= precision;
}
// clamp: int s = Math.max(0, Math.min(scale, precision)); Type guard
public static boolean hasValidScale(Integer p, Integer s) {
return p != null && s != null && s >= 0 && s <= p;
} Try / catch
try {
Type t = DecimalType.createDecimalType(precision, scale);
} catch (InvalidFunctionArgumentException e) {
// clamp scale and retry, or widen precision
} Prevention
- Always clamp scale to [0, precision] before type creation
- Verify schema-mapping logic preserves scale <= precision
- Test DDL translation with extreme scale/precision combos
When it happens
Trigger: Calling DecimalType.createType(precision, scale) with scale < 0 or scale > precision (e.g. DECIMAL(5,7) or DECIMAL(10,-1)); connector metadata emitting scale greater than precision; arithmetic deriving scale from two operands incorrectly.
Common situations: Hand-translated schemas from systems with different scale semantics; formula computing scale = a+b while precision = a (scale exceeds precision); typos in DDL mapping code.
Related errors
- DECIMAL precision must be in range [1, 38]
- 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/41760d4b2317e1cb.
Report an issue: GitHub.