Skip to content

[FLINK-40444][table-common] Preserve attribute order in OBJECT_UPDATE - #28994

Open
SEPURI-SAI-KRISHNA wants to merge 1 commit into
apache:masterfrom
SEPURI-SAI-KRISHNA:flink-object-update-field-order
Open

[FLINK-40444][table-common] Preserve attribute order in OBJECT_UPDATE#28994
SEPURI-SAI-KRISHNA wants to merge 1 commit into
apache:masterfrom
SEPURI-SAI-KRISHNA:flink-object-update-field-order

Conversation

@SEPURI-SAI-KRISHNA

Copy link
Copy Markdown
Contributor

What is the purpose of the change

OBJECT_UPDATE inferred its result type by collecting the attributes of the input
structured type into a HashMap and iterating the entry set, so the resulting type
followed hash order rather than the declaration order of the input type. The runtime
writes updated values at the declared positions, so the inferred type and the
produced row disagreed whenever the attribute names did not happen to hash in
declaration order.

Depending on the attribute types this surfaced either as a ClassCastException at
runtime, or as a query that succeeded while silently returning values under the wrong
attribute names. For example, before this change:

SELECT OBJECT_UPDATE(OBJECT_OF('com.example.Foo', 'b', 'Bob', 'a', 'Amy'), 'a', 'Zed');
-- schema: STRUCTURED<'com.example.Foo', `a` CHAR(3) NOT NULL, `b` CHAR(3) NOT NULL>
-- row   : +I[Bob, Zed]        i.e. a='Bob', b='Zed'

while OBJECT_OF on its own correctly returns the attributes in declaration order
(b, a). This affects release-2.2 and release-2.3.

Brief change log

  • ObjectUpdateTypeStrategy collects the result attributes into a LinkedHashMap, so the inferred attribute order matches the declaration order of the input type
  • TypeStrategiesTestBase sets a DataTypeFactoryMock on the call context mock, mirroring InputTypeStrategiesTestBase; this is required because ObjectUpdateTypeStrategy resolves the structured class through the data type factory's class loader

Verifying this change

This change added tests and can be verified as follows:

  • Added ObjectUpdateTypeStrategyTest with three cases pinning the inferred attribute order, using attribute names whose hash order differs from their declaration order
  • Extended StructuredFunctionsITCase with an end-to-end case asserting both the result values and the resulting structured type
  • Verified that the new ITCase fails without the fix with ClassCastException: BinaryStringData cannot be cast to java.lang.Integer, and passes with it

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? no
  • If yes, how is the feature documented? not applicable

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

Generated-by: Claude Code (Opus 5)

ObjectUpdateTypeStrategy collected the result attributes into a HashMap and
iterated its entry set, so the inferred structured type followed hash order
instead of the declaration order of the input type. The runtime writes updated
values at the declared positions, so the inferred type and the produced row
disagreed whenever the attribute names did not happen to hash in declaration
order. Depending on the attribute types this surfaced either as a
ClassCastException or as values silently appearing under the wrong attributes.

Generated-by: Claude Code (Opus 5)
@flinkbot

flinkbot commented Aug 19, 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

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.

2 participants