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

  1. Clamp scale to [0, precision] before createDecimalType
  2. Fix the connector/schema mapping so scale <= precision is guaranteed
  3. If the source genuinely has scale > precision, widen precision (up to 38) or fall back to DOUBLE
  4. 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

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


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