prestodb/presto · error · PrestoException

INVALID_CAST_ARGUMENT

INVALID_CAST_ARGUMENT

Error message

Value %s cannot be represented as varchar(%s)

What it means

Thrown by BigintOperators.castToVarchar when casting a BIGINT to a fixed-length VARCHAR(x) whose length is shorter than the decimal string representation of the value. Since the string is ASCII, String.length() equals the code point count; if it exceeds x, Presto throws INVALID_CAST_ARGUMENT rather than truncating.

Source

Thrown at presto-main-base/src/main/java/com/facebook/presto/type/BigintOperators.java:284

    @SqlType(StandardTypes.REAL)
    public static long castToReal(@SqlType(StandardTypes.BIGINT) long value)
    {
        return (long) floatToRawIntBits((float) value);
    }

    @ScalarOperator(CAST)
    @LiteralParameters("x")
    @SqlType("varchar(x)")
    public static Slice castToVarchar(@LiteralParameter("x") long x, @SqlType(StandardTypes.BIGINT) long value)
    {
        // todo optimize me
        String stringValue = String.valueOf(value);
        // String is all-ASCII, so String.length() here returns actual code points count
        if (stringValue.length() <= x) {
            return utf8Slice(stringValue);
        }

        throw new PrestoException(INVALID_CAST_ARGUMENT, format("Value %s cannot be represented as varchar(%s)", value, x));
    }

    @ScalarOperator(HASH_CODE)
    @SqlType(StandardTypes.BIGINT)
    public static long hashCode(@SqlType(StandardTypes.BIGINT) long value)
    {
        return AbstractLongType.hash(value);
    }

    @ScalarOperator(IS_DISTINCT_FROM)
    public static class BigintDistinctFromOperator
    {
        @SqlType(StandardTypes.BOOLEAN)
        public static boolean isDistinctFrom(
                @SqlType(StandardTypes.BIGINT) long left,
                @IsNull boolean leftNull,
                @SqlType(StandardTypes.BIGINT) long right,
                @IsNull boolean rightNull)

View on GitHub (pinned to 55bb57d202)

Solutions

  1. Cast to an unbounded VARCHAR first: CAST(CAST(col AS VARCHAR) AS VARCHAR(x)) only after ensuring it fits, or enlarge the target length.
  2. Choose a sufficient width: VARCHAR(20) is always enough for signed 64-bit values.
  3. Filter or NULL out rows that don't fit: WHERE length(CAST(col AS VARCHAR)) <= x.
  4. Use TRY(CAST(col AS VARCHAR(x))) to map offenders to NULL.

Example fix

// before
SELECT CAST(id AS VARCHAR(5)) FROM t;

// after
SELECT TRY(CAST(id AS VARCHAR(20))) FROM t; -- width big enough for any bigint
Defensive patterns

Strategy: validation

Validate before calling

-- string form must fit the target varchar length
SELECT * FROM t WHERE length(CAST(col AS VARCHAR)) <= x; -- e.g. x = 20 covers all bigints

Type guard

-- SQL predicate: value fits varchar(n)
length(CAST(col AS VARCHAR)) <= n

Try / catch

SELECT TRY(CAST(col AS VARCHAR(n))) FROM t; -- NULL when too long

Prevention

When it happens

Trigger: Executing CAST(col AS VARCHAR(x)) on a BIGINT whose decimal digit count (plus possible '-' sign) exceeds x, e.g. CAST(123456 AS VARCHAR(3)), via the @ScalarOperator(CAST) bigint-to-varchar operator.

Common situations: Formatting IDs/codes into fixed-width char columns in ETL, migrating to schemas with varchar(n) too small, casting values that can be negative where the '-' sign pushes length over the limit.

Related errors


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