Skip to content

[FLINK-37926][table] Support casting from VARIANT to ROW and STRUCTURED - #29092

Merged
twalthr merged 3 commits into
apache:masterfrom
raminqaf:FLINK-37926-variant-to-row
Sep 7, 2026
Merged

twalthr merged 3 commits into
apache:masterfrom
raminqaf:FLINK-37926-variant-to-row

Conversation

@raminqaf

@raminqaf raminqaf commented Sep 3, 2026

Copy link
Copy Markdown
Contributor

What is the purpose of the change

This pull request adds CAST and TRY_CAST from VARIANT to the constructed types ROW and STRUCTURED, so a variant object can be given a schema. It is stacked on #29073 (VARIANT to ARRAY), reuses the same design, and should be reviewed and merged after it.

A constructed cast is the scalar leaf cast applied to every field plus a shape check at each level. The recursion bottoms out at the same scalar casts the primitive and string rules perform, so no new leaf semantics are introduced.

Key semantics:

  • Fields match by name, not by position, since a JSON object is unordered. Name matching is case sensitive. A ROW declared without field names uses the default names f0, f1, and so on, which must then be present in the object.
  • A field absent from the object fails the cast, whether the target field is nullable or not.
  • A field present but set to a variant null maps to SQL NULL when the field is nullable and fails the cast when it is NOT NULL.
  • Object fields the target does not name are dropped, so the row is a projection.
  • A VARIANT target field takes the identity cast and keeps a variant null as a variant null rather than turning it into SQL NULL. This matches ARRAY<VARIANT> and the top level VARIANT cast.
  • Leaves are never parsed. A stored string does not reach an integer target.
  • STRUCTURED shares the RowData representation and is served by the same rule.
  • If any field cast fails, the whole cast fails, and TRY_CAST returns NULL for the entire value.

Brief change log

  • Add VariantToRowCastRule that casts a variant object to ROW or STRUCTURED, matching fields by name and casting each field with the existing VARIANT to leaf rules.
  • Allow the explicit cast in LogicalTypeCasts when VARIANT casts to every target field type.
  • Document the VARIANT to ROW and STRUCTURED cast in the data types reference.

Verifying this change

This change added tests and can be verified as follows:

  • CastRulesTest: by-name matching, free field order, absent field, present variant null in nullable and NOT NULL fields, projection of extra fields, nested rows and arrays, an unnamed ROW, ROW<VARIANT> with and without a variant null, and a STRUCTURED target.
  • CastFunctionITCase: end to end SQL and Table API cases, including ROW<VARIANT> round trips back to a concrete row.
  • LogicalTypeCastsTest and CastRuleProviderTest: castability and rule resolution.

Does this pull request potentially affect one of the following parts:

  • Dependencies (does it add or upgrade a dependency): no
  • The public API, i.e., is any changed class annotated with @Public(Evolving): no
  • The serializers: no
  • The runtime per-record code paths (performance sensitive): no
  • Anything that affects deployment or recovery: JobManager (and its components), Checkpointing, Kubernetes/Yarn, ZooKeeper: no
  • The S3 file system connector: no

Documentation

  • Does this pull request introduce a new feature? yes
  • If yes, how is the feature documented? docs

Was generative AI tooling used to co-author this PR?
  • Yes (please specify the tool below)

Generated-by: Opus 4.8

@flinkbot

flinkbot commented Sep 3, 2026

Copy link
Copy Markdown
Collaborator

CI report:

Bot commands The @flinkbot bot supports the following commands:
  • @flinkbot run azure re-run the last Azure build

@raminqaf
raminqaf force-pushed the FLINK-37926-variant-to-row branch from ae81af5 to 80922ee Compare September 4, 2026 12:49
@raminqaf
raminqaf marked this pull request as ready for review September 4, 2026 12:49

@twalthr twalthr left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you @raminqaf. Overall the PR looks good to me, some comments repeat from previous reviews.

Comment thread docs/content.zh/docs/sql/reference/data-types.md Outdated
Comment thread docs/content.zh/docs/sql/reference/data-types.md Outdated
Comment thread docs/content.zh/docs/sql/reference/data-types.md Outdated
@raminqaf
raminqaf force-pushed the FLINK-37926-variant-to-row branch 2 times, most recently from d2ff425 to 7219b16 Compare September 6, 2026 11:13
@raminqaf
raminqaf force-pushed the FLINK-37926-variant-to-row branch from 7219b16 to bfc1d22 Compare September 7, 2026 06:40

@twalthr twalthr left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM, thanks @raminqaf

@twalthr
twalthr merged commit 4ad8e83 into apache:master Sep 7, 2026
raminqaf added a commit to raminqaf/flink that referenced this pull request Sep 7, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants