[FLINK-40580][table] Render a VARIANT object or array as JSON when casting to a character string - #29125
Open
raminqaf wants to merge 2 commits into
Open
[FLINK-40580][table] Render a VARIANT object or array as JSON when casting to a character string#29125raminqaf wants to merge 2 commits into
raminqaf wants to merge 2 commits into
Conversation
raminqaf
force-pushed
the
FLINK-40580
branch
from
September 7, 2026 13:34
a37759c to
37b868a
Compare
raminqaf
force-pushed
the
FLINK-40580
branch
2 times, most recently
from
September 8, 2026 07:22
fb6bcc1 to
1fb7336
Compare
twalthr
reviewed
Sep 8, 2026
| if (i > 0) { | ||
| sb.append(", "); | ||
| } | ||
| sb.append(renderElement(variant.getElement(i), sessionZone, targetDescription)); |
Contributor
There was a problem hiding this comment.
the targetDescription should not be reused across elements. The target needs to be precise per value. same for map key and value.
Contributor
Author
There was a problem hiding this comment.
Good catch. Fixed. Nested values now report an unbounded "a character string" target instead of the container's CHAR(n)/VARCHAR(n), since an element is rendered in full and only the whole result is trimmed. Only a top-level scalar keeps its real bounded target. Added regression tests for a byte value nested in both an array element and an object value.
… when casting to a character string
Casting a VARIANT to a character string rendered a stored scalar the way a regular SQL cast of that kind would, but an object or array had no scalar form and failed with a message pointing to JSON_STRING. This renders an object or array the way a regular ARRAY or MAP to string cast does: an array as [e1, e2] and an object as {k1=v1, k2=v2}, with each value rendered by the same rules and a nested variant null shown as NULL. Strings are unquoted at every depth, so the result is a SQL rendering rather than JSON.
The printing path is unchanged and still renders JSON, so a VARIANT result column displays as JSON while an explicit CAST AS STRING extracts SQL text, matching how a scalar string already differs between the two. A bounded CHAR(n)/VARCHAR(n) target trims the rendered string like any other over-length value, TRY_CAST returns the same text rather than NULL, and a VARIANT storing a JSON null still casts to SQL NULL. Only OBJECT and ARRAY change; other unsupported scalar kinds keep failing. Use JSON_STRING for the JSON form with quoted strings.
raminqaf
force-pushed
the
FLINK-40580
branch
from
September 8, 2026 09:50
1fb7336 to
6d2a38e
Compare
raminqaf
force-pushed
the
FLINK-40580
branch
from
September 8, 2026 14:56
d39406a to
aa20b8a
Compare
twalthr
approved these changes
Sep 8, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Description:
What is the purpose of the change
Casting a
VARIANTto a character string renders a stored scalar the way a regular SQL cast of that kind would (a boolean becomesTRUE, a timestamp uses the SQL format, a binary value is read as UTF-8). AVARIANTholding an object or an array had no scalar form, so the cast failed and pointed the user atJSON_STRING.This makes
CAST(v AS STRING)render an object or array the way a regularARRAYorMAPto string cast does, rather than failing: an array as[e1, e2]and an object as{k1=v1, k2=v2}, with each value rendered by the same rules and a nested variant null shown asNULL. Strings are unquoted at every depth, so the result is a SQL rendering and not JSON.The printing path is unchanged and still renders JSON via
toJson(), so a VARIANT result column displays as JSON while an explicitCAST AS STRINGextracts SQL text. This matches how a scalar string already differs between the two paths. For theJSONform with quoted strings, useJSON_STRING.Only
OBJECTandARRAYchange here. Scalar kinds whose string rendering is still unsupported (TIMEand nanosecond timestamps, tracked in FLINK-40492) keep failing.Brief change log
VariantCastUtilsrenders an object/array by walking the variant at runtime (renderValue), reusing the existing scalar rendering per element or field; a variant's structure is dynamic, so the collection-to-string cast rules (which are codegen over a static element type) cannot be reused.CHAR(n)/VARCHAR(n)target trims the rendered string like any other over-length value;TRY_CASTreturns the string rather thanNULL; a storedJSONnull still casts to SQL NULL.Verifying this change
This change added tests and can be verified as follows:
CastRulesTest:VARIANT→STRINGfor an object and an array assert the SQL rendering (unquoted strings, nested null as NULL), with theJSONrendering kept for the printing path.CastFunctionITCase:CAST/TRY_CASTof an object and an array to STRING, a nested null and a nested container, and a container cast to a boundedVARCHAR(n)that trims the rendered string.Does this pull request potentially affect one of the following parts:
@Public(Evolving): noDocumentation
VARIANT)Was generative AI tooling used to co-author this PR?
Generated-by: Claude Code (Claude Opus 4.8)