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

   Closes #12599
   
   ### Purpose of this pull request
   
   For a MySQL table **without a primary key** that has a **nullable unique 
key**, MySQL-CDC emits the type default (`0`) instead of `NULL` for the key 
column, in the snapshot and in binlog events. Silent data corruption: the sink 
gets `0` and no error is reported.
   
   **Root cause:** `MySqlSchema#parseSnapshotDdl` builds the table with 
Debezium 1.9.8. For a table without a primary key, Debezium promotes the first 
`UNIQUE KEY` to the primary key and forces all of its columns to 
`optional(false)` (`CreateTableParserListener#enterUniqueKeyTableConstraint` -> 
`MySqlAntlrDdlParser#parsePrimaryIndexColumnNames`), although MySQL allows NULL 
in them. The value converters then substitute the default for NULL.
   
   **Fix** (as suggested in #12599): after parsing, 
`MySqlSchema#restoreNullableColumns` re-applies the nullability of the catalog 
table, which is read from the database metadata. A column Debezium marked NOT 
NULL but the database reports as nullable is made optional again. Real primary 
key columns are NOT NULL in the database, so they are unchanged; columns 
declared as `primaryKeys` in `table-names-config` are also unchanged (the 
catalog table marks them NOT NULL).
   
   **Composite unique key** (question from #12599): affected too. With `UNIQUE 
KEY (a, b)`, `a NOT NULL`, `b NULL`, Debezium marks both columns NOT NULL and 
`b`'s NULLs were emitted as `0`. The fix restores `b` and keeps `a` required.
   
   ### Does this PR introduce _any_ user-facing change?
   
   Yes, a bug fix: NULL values in a nullable unique key column of a MySQL table 
without a primary key are now emitted as NULL instead of `0`, in the snapshot 
and binlog phases. No option or default changes.
   
   ### How was this patch tested?
   
   - **Unit tests** (`MySqlSchemaTest`, extended): a single nullable unique key 
column stays optional (Debezium still promotes it to the primary key), and in a 
composite unique key only the nullable column is optional. Without the fix both 
tests fail.
   - **E2E** 
(`AbstractMysqlCDCITBase#testMysqlCdcNullInNullableUniqueKeyWithoutPrimaryKey`):
 two tables without a primary key, one with a single and one with a composite 
nullable unique key; compares complete rows (including NULLs) between source 
and sink after the snapshot phase and after binlog inserts of NULL rows.
   - **Manual, real MySQL 8.0**, before / after:
   
     | | before | after |
     |---|---|---|
     | single key, snapshot | `2, 0` | `2, NULL` |
     | single key, binlog | `4, 0` | `4, NULL` |
     | composite key, snapshot | `2, 1, 0` | `2, 1, NULL` |
     | composite key, binlog | `4, 3, 0` | `4, 3, NULL` |
   
   Related: #12597 (fix for #12598), the same Debezium promotion causing the 
snapshot to skip NULL rows. The two PRs are independent.
   
   ### Check list
   
   * [x] 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)
 — N/A, no new jar.
   * [x] If necessary, please update the documentation to describe the new 
feature. — N/A, bug fix.
   * [x] If necessary, please update `incompatible-changes.md` to describe the 
incompatibility caused by this PR. — N/A, values that were wrongly `0` are now 
NULL as stored in the database.
   * [x] If you are contributing the connector code, please check that the 
following files are updated: — N/A, fix to an existing connector.
   


-- 
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