Skip to content

core: VarCharLiteral accepts a value longer than the length it declares #1174

Description

@nielspardon

Expression.VarCharLiteral documents length() as "the maximum length of the string value of this literal" and derives its type as varChar(length()), but nothing checks value() against it, so a literal whose value is longer than the length it declares is constructible and round-trips through proto unchallenged.

ExpressionCreator.varChar(false, "abcdef", 3)  // builds; type is varchar<3>, value is 6 chars

Converting one to Calcite yields a plan that truncates it at execution with no diagnostic — CAST('abcdef'):VARCHAR(3) NOT NULL — and there is nowhere upstream that would have rejected it. FixedCharLiteral needs nothing here: it derives its type from value().length(), so it cannot disagree with itself.

A @Value.Check on VarCharLiteral is the natural place, consistent with #1047 moving validation off assert. Same family as #1129, which covers the interval literals and types; this one is not in its scope.

Found reviewing #1153, whose LiteralNullabilityRoundtripTest.tupleUnwrapLeavesATruncatingCastAlone now documents the gap rather than guarding it.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions