prestodb/presto · error · SemanticException

INVALID_LITERAL

INVALID_LITERAL

Error message

Invalid formatted generic ${type} literal: ${node}

What it means

After visitGenericLiteral resolves the type (e.g. BIGINT), parsing the literal's value string with the type's parser throws NumberFormatException; the translator rethrows as SemanticException INVALID_LITERAL because the value does not match the declared type's format.

Source

Thrown at presto-main-base/src/main/java/com/facebook/presto/sql/relational/SqlToRowExpressionTranslator.java:461

                throw new PrestoException(NOT_SUPPORTED, "Unsupported type: " + node.getType());
            }

            try {
                if (TINYINT.equals(type)) {
                    return constant((long) Byte.parseByte(node.getValue()), TINYINT);
                }
                else if (SMALLINT.equals(type)) {
                    return constant((long) Short.parseShort(node.getValue()), SMALLINT);
                }
                else if (INTEGER.equals(type)) {
                    return constant((long) Integer.parseInt(node.getValue()), INTEGER);
                }
                else if (BIGINT.equals(type)) {
                    return constant(Long.parseLong(node.getValue()), BIGINT);
                }
            }
            catch (NumberFormatException e) {
                throw new SemanticException(SemanticErrorCode.INVALID_LITERAL, node, format("Invalid formatted generic %s literal: %s", type, node));
            }

            if (JSON.equals(type)) {
                return call(
                        getSourceLocation(node),
                        "json_parse",
                        functionAndTypeResolver.lookupFunction("json_parse", fromTypes(VARCHAR)),
                        getType(node),
                        constant(utf8Slice(node.getValue()), VARCHAR));
            }

            return call(
                    getSourceLocation(node),
                    CAST.name(),
                    functionAndTypeResolver.lookupCast("CAST", VARCHAR, getType(node)),
                    getType(node),
                    constant(utf8Slice(node.getValue()), VARCHAR));
        }

View on GitHub (pinned to 55bb57d202)

Solutions

  1. Correct the literal value so it parses for the declared type (e.g. `BIGINT '123'`).
  2. Remove characters like underscores, units, or whitespace from the literal.
  3. Use CAST('123' AS BIGINT) instead of a typed literal to get a clearer cast error path.
  4. Validate/normalize values in the code that generates the SQL.

Example fix

// before
SELECT BIGINT '12,345'
// after
SELECT BIGINT '12345'
Defensive patterns

Strategy: validation

Validate before calling

// Validate literal value against the declared type before generating SQL
static String typedLiteral(String type, String value) {
    switch (type.toLowerCase()) {
        case "bigint": Long.parseLong(value); break;
        case "tinyint": Byte.parseByte(value); break;
        default: throw new IllegalArgumentException("unsupported");
    }
    return type + " '" + value + "'";
}

Prevention

When it happens

Trigger: A typed literal whose value cannot be parsed by the type, e.g. `BIGINT '12abc'` or `TINYINT '9999'` (out of byte range), during expression translation.

Common situations: Hand-written literals with stray characters; query builders interpolating unvalidated strings into typed literals; locale/precision mismatches when generating SQL.

Related errors


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