wgzhao opened a new issue, #12354:
URL: https://github.com/apache/seatunnel/issues/12354

   ### Search before asking
   
   - [X] I had searched in the 
[issues](https://github.com/apache/seatunnel/issues?q=is%3Aissue+label%3A%22bug%22)
 and found no similar issues.
   
   ### What happened
   
   Raised by @DanielLeens while reviewing #10453, and reported separately here 
because it is pre-existing, independent of the fix in that pull request, and 
out of scope for both #10453 and #12333, which touch the same code path.
   
   **Symptom.** A MySQL `SET` or `ENUM` column that reaches the MySQL-CDC 
source through the DDL-event path ends up carrying a bare type name (`SET`, 
`ENUM`) instead of its full definition (`SET('a','b')`). If that column is then 
written to a MySQL sink with auto-create-table enabled, the generated `CREATE 
TABLE` contains `` `col` SET NULL ``, which MySQL rejects with a syntax error.
   
   **Why, layer by layer.**
   
   1. `MySqlTypeUtils.convertToSeaTunnelColumn()` seeds `columnType` from the 
bare Debezium type name:
   
   ```java
   BasicTypeDefine.BasicTypeDefineBuilder builder =
           BasicTypeDefine.builder()
                   .name(column.name())
                   .columnType(column.typeName())   // "SET", not SET('a','b')
                   .dataType(column.typeName())
   ```
   
   2. The switch below it only rebuilds `columnType` for types that carry a 
length or precision; everything else falls through to `default: break;`. `CHAR` 
/ `VARCHAR` / `TIME` / `TIMESTAMP` / `DATETIME` re-append their length, and 
there is even a `TINYINT` case whose comment notes that "Debezium reports the 
bare type name" — but there is no `SET` / `ENUM` case, so those keep the bare 
name.
   
   3. That value is exposed as `Column#getSourceType()`, and 
`MysqlCreateTableSqlBuilder.buildColumnIdentifySql()` uses it verbatim for 
MySQL targets:
   
   ```java
   } else if (StringUtils.equals(catalogName, DatabaseIdentifier.MYSQL)
           && StringUtils.isNotBlank(column.getSourceType())) {
       type = column.getSourceType();
   }
   ```
   
   **Verified.** Bare `SET` / `ENUM` really are invalid DDL (checked against 
MySQL 9.7.2; the grammar is the same on 8.x):
   
   ```
   CREATE TABLE t (c SET);          -> ERROR 1064 (42000): You have an error in 
your SQL syntax
   CREATE TABLE t (c ENUM);         -> ERROR 1064 (42000): You have an error in 
your SQL syntax
   CREATE TABLE t (c SET('a','b')); -> Query OK
   ```
   
   **Scope — narrower than it first looks.** The snapshot path is *not* 
affected: table structures discovered at job start come from the JDBC catalog, 
where `columnType` is the full `information_schema.COLUMN_TYPE` literal 
(`set('a','b')`). Only columns whose schema arrives through the DDL-event path 
— columns added by `ALTER TABLE` while the job runs, and schema-evolution 
events — lose the value list. The trigger is therefore: MySQL-CDC source -> 
MySQL sink with auto-create-table, plus a `SET` / `ENUM` column added after the 
job started.
   
   **What is not verified yet.** I could not confirm by execution which string 
Debezium puts in `Column#typeName()` on this path; an attempt to drive 
`MySqlAntlrDdlParser` with a `CREATE TABLE` did not populate the `Tables` 
object, so the probe returned nothing. The supporting evidence is indirect: the 
`TINYINT` precedent in the same switch, the fact that plain `SET` columns must 
already convert successfully on this path, and Debezium's separate 
`MySqlAntlrDdlParser.extractEnumAndSetOptions(...)`, which shows the option 
list is handled apart from the type name. Confirming this is the first step for 
whoever picks the issue up.
   
   **Suggested fix direction.** Rebuild the type from the value list Debezium 
already carries on the column (`Column#enumValues()`), the same way the 
existing cases rebuild `VARCHAR(n)` from `column.length()`. SeaTunnel already 
relies on that field elsewhere — `ConnectTableChangeSerializer` serializes and 
restores it — so no new dependency is needed.
   
   ### SeaTunnel Version
   
   `dev` branch (`3.0.0-SNAPSHOT`). The code shape is older than the current 
work and the same pattern is present in the 2.3.x line.
   
   ### SeaTunnel Config
   
   Roughly the shape of a job that can hit this. The `SET` column has to be 
added by `ALTER TABLE` while the job is running:
   
   ```conf
   env {
     job.mode = "STREAMING"
     checkpoint.interval = 5000
   }
   
   source {
     MySQL-CDC {
       base-url = "jdbc:mysql://mysql-source:3306/test"
       username = "root"
       password = "password"
       table-names = ["test.t"]
       schema-changes.enabled = true
     }
   }
   
   sink {
     jdbc {
       url = "jdbc:mysql://mysql-sink:3306/test"
       driver = "com.mysql.cj.jdbc.Driver"
       username = "root"
       password = "password"
       generate_sink_sql = true
       database = "test"
       table = "t"
       schema_save_mode = "CREATE_SCHEMA_WHEN_NOT_EXIST"
     }
   }
   ```
   
   ### Running Command
   
   Not applicable. This was found by reading the code path during the review of 
#10453 rather than by running a job; a reproduction needs the `ALTER TABLE` 
step scheduled in the middle of a running CDC job.
   
   ### Error Exception
   
   The sink-side error produced by the generated DDL:
   
   ```
   ERROR 1064 (42000): You have an error in your SQL syntax; check the manual 
that corresponds
   to your MySQL server version for the right syntax to use near ')' at line 1
   ```
   
   ### Zeta or Flink or Spark Version
   
   Zeta (`dev`)
   
   ### Java or Scala Version
   
   Java 8
   
   ### Screenshots
   
   No response
   
   ### Are you willing to submit PR?
   
   - [X] Yes I am willing to submit a PR!
   
   ### Code of Conduct
   
   - [X] I agree to follow this project's [Code of 
Conduct](https://www.apache.org/foundation/policies/conduct)
   
   ---
   
   Related: #10451, #10453, #12333
   


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