Skip to content

[FLINK-39230] Transform should convert partially filtered UPDATE events to INSERT / DELETE#4319

Merged
lvyanquan merged 2 commits into
apache:masterfrom
yuxiqian:FLINK-39230
Mar 18, 2026
Merged

[FLINK-39230] Transform should convert partially filtered UPDATE events to INSERT / DELETE#4319
lvyanquan merged 2 commits into
apache:masterfrom
yuxiqian:FLINK-39230

Conversation

@yuxiqian
Copy link
Copy Markdown
Member

This closes FLINK-39230.

Currently, transform filter conditions are only applied on the after() part of UPDATE event.

  • UPDATE before satisfied, after satisfied => emit UPDATE
  • UPDATE before not satisfied, after not satisfied => nothing
  • UPDATE before satisfied, after not satisfied => nothing (?)
  • UPDATE before not satisfied, after satisfied => emit UPDATE (?)

A more reasonable solution (like Flink SQL changelog semantics) would be:

  • UPDATE before satisfied, after not satisfied => emit DELETE (with update before)
  • UPDATE before not satisfied, after satisfied => emit INSERT (with update after)

@github-actions github-actions Bot added docs Improvements or additions to documentation composer runtime labels Mar 17, 2026
@yuxiqian yuxiqian requested a review from Copilot March 17, 2026 01:39
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This PR updates post-transform filtering behavior so that when an UPDATE’s before/after images differ in filter outcome, the emitted event is converted accordingly (UPDATE, INSERT, DELETE, or dropped). It aligns unit/integration tests and composer YAML expectations with the new semantics.

Changes:

  • Implement per-row filter evaluation for UPDATE events and convert the downstream op type based on (beforePass, afterPass).
  • Add/adjust runtime and composer tests (plus YAML golden outputs) to reflect op-type conversion.
  • Remove the “classification mapping” (first-match rule) documentation section from the transform docs (EN/ZH).

Reviewed changes

Copilot reviewed 8 out of 8 changed files in this pull request and generated 4 comments.

Show a summary per file
File Description
flink-cdc-runtime/src/main/java/org/apache/flink/cdc/runtime/operators/transform/PostTransformOperator.java Converts UPDATE events into UPDATE/INSERT/DELETE/drop depending on before/after filter results.
flink-cdc-runtime/src/test/java/org/apache/flink/cdc/runtime/operators/transform/PostTransformOperatorTest.java Adds a unit test covering UPDATE filter op-type conversion cases.
flink-cdc-runtime/src/test/java/org/apache/flink/cdc/runtime/operators/transform/UnifiedTransformOperatorTest.java Updates expectations to reflect UPDATE→DELETE conversion when an update moves a row into a filtered-out state.
flink-cdc-composer/src/test/java/org/apache/flink/cdc/composer/flink/FlinkPipelineTransformITCase.java Adds an ITCase for UPDATE op-type conversion under filtering; loosens one Calcite exception-type assertion.
flink-cdc-composer/src/test/resources/specs/basic.yaml Updates expected events to include DELETEs / UPDATE→INSERT conversions in filtered scenarios.
flink-cdc-composer/src/test/resources/specs/nested.yaml Updates expected events to reflect UPDATE→INSERT conversion and adds expected DELETEs in some cases.
docs/content/docs/core-concept/transform.md Removes “Classification mapping” section describing first-match rule semantics.
docs/content.zh/docs/core-concept/transform.md Same documentation removal as EN version.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +334 to +338
if (beforeFilterPassed && afterFilterPassed) {
finalEvent = DataChangeEvent.projectRecords(event, beforeRow, afterRow);
} else if (beforeFilterPassed) {
finalEvent = DataChangeEvent.deleteEvent(tableId, beforeRow, event.meta());
} else if (afterFilterPassed) {
Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

I prefer not to re-evaluate expressions as the filter condition itself may depend on the opType itself, and that might cause inconsistencies.

Also, op_type should represent the original type from source, and keeping it intact should be acceptable.

Comment thread docs/content/docs/core-concept/transform.md
Comment thread docs/content.zh/docs/core-concept/transform.md
Copy link
Copy Markdown
Contributor

@lvyanquan lvyanquan left a comment

Choose a reason for hiding this comment

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

LGTM.

@lvyanquan lvyanquan merged commit 2acf693 into apache:master Mar 18, 2026
35 of 36 checks passed
Mrart pushed a commit to Mrart/flink-cdc that referenced this pull request Mar 26, 2026
ThorneANN pushed a commit to ThorneANN/flink-cdc that referenced this pull request Mar 31, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

approved composer docs Improvements or additions to documentation reviewed runtime

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants