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.
Expression.VarCharLiteraldocumentslength()as "the maximum length of the string value of this literal" and derives its type asvarChar(length()), but nothing checksvalue()against it, so a literal whose value is longer than the length it declares is constructible and round-trips through proto unchallenged.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.FixedCharLiteralneeds nothing here: it derives its type fromvalue().length(), so it cannot disagree with itself.A
@Value.CheckonVarCharLiteralis the natural place, consistent with #1047 moving validation offassert. Same family as #1129, which covers the interval literals and types; this one is not in its scope.Found reviewing #1153, whose
LiteralNullabilityRoundtripTest.tupleUnwrapLeavesATruncatingCastAlonenow documents the gap rather than guarding it.