fatmanverse opened a new pull request, #12803:
URL: https://github.com/apache/seatunnel/pull/12803

   Fixes #12799
   
   ### Purpose of this pull request
   
   When the Jdbc sink writes with a key, `BufferReducedBatchStatementExecutor` 
buffers rows in a `LinkedHashMap` keyed by the extracted key row, so that only 
the last change of a key is written in a batch. `SeaTunnelRow#equals` uses 
`Arrays.deepEquals`, so all rows whose key contains NULL are equal and collapse 
into one entry. The other rows are dropped before any SQL runs.
   
   A key can contain NULL when it comes from a nullable unique key, either 
derived from the upstream table (no primary key) or configured in 
`primary_keys`. In SQL, NULL never equals NULL: the database keeps every such 
row, `INSERT ... ON CONFLICT (k)` does not conflict on them, and `DELETE ... 
WHERE k = ?` does not match them.
   
   This PR buffers a row whose key contains a NULL field under its own 
identity, so it is not merged with other rows. Rows with a complete key are 
reduced exactly as before. Insertion order of the buffer, and so the order of 
upserts and deletes, is unchanged.
   
   The first approach considered was to stop deriving `primary_keys` from a 
nullable unique key. It was not taken because it switches such tables to the 
plain-insert executor, which writes every row kind as an INSERT and would break 
UPDATE/DELETE events from CDC sources. The issue is in the buffer, not in the 
choice of key.
   
   ### Does this PR introduce _any_ user-facing change?
   
   Yes. Rows whose sink key contains NULL are no longer silently dropped. In 
the reported case (30 rows, 10 with a NULL unique key), all 30 rows are written 
instead of 21.
   
   ### How was this patch tested?
   
   - Added 
`BufferReducedBatchStatementExecutorTest#testRowsWithSameKeyAreReduced`, 
`#testRowsWithNullKeyAreNotReduced` and 
`#testDeleteWithNullKeyKeepsOrderWithUpserts`.
   - `./mvnw -pl seatunnel-connectors-v2/connector-jdbc test` on JDK 17: all 
tests pass.
   - On a deployed Zeta cluster, Jdbc MySQL -> Jdbc PostgreSQL with a 
no-primary-key table and a nullable unique key (30 rows, 10 NULL) wrote 21 rows 
before this change and 30 after it, with the same `ON CONFLICT ("code")` 
statement.
   
   ### Check list
   
   * [ ] If any new Jar binary package adding in your PR, please add License 
Notice according
     [New License 
Guide](https://github.com/apache/seatunnel/blob/dev/docs/en/developer/new-license.md)
   * [x] If necessary, please update the documentation to describe the new 
feature. https://github.com/apache/seatunnel/tree/dev/docs (not needed)
   * [x] If necessary, please update `incompatible-changes.md` to describe the 
incompatibility caused by this PR. (not needed, this only fixes data loss)
   


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]

Reply via email to