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

  1. Cap the declared precision at 38 (or coerce to DOUBLE/VARCHAR when the source exceeds 38)
  2. Fix upstream column metadata to a supported precision before type creation
  3. Compute precision defensively so it is always >= 1
  4. 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

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


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