ricky2129 opened a new issue, #12955: URL: https://github.com/apache/seatunnel/issues/12955
### 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 A CDC job fails as soon as it reads a `DATETIME(4..6)` value before 1970 whose microseconds are not a whole number of milliseconds, e.g. MySQL `1969-12-31 23:59:59.999999`: ``` java.time.DateTimeException: Invalid value for NanoOfDay (valid values 0 - 86399999999999): -1000 ``` Debezium sends such a column as `MicroTimestamp`, epoch microseconds, which is negative before 1970. `SeaTunnelRowDebeziumDeserializationConverters#convertToTimestamp` splits it with `micro / 1000` and `micro % 1000 * 1000`. Java's `/` and `%` round toward zero, so for `-1` micro the millisecond part is `0` and the remainder is `-1000` nanos, which `LocalTime.ofNanoOfDay` rejects. `NanoTimestamp` has the same split. `toLocalDateTime(long, int)` itself already handles a negative millisecond value; only the sub-millisecond part goes wrong. It affects every connector built on this converter (MySQL, PostgreSQL, SQL Server, Oracle, ...), in both the snapshot and the incremental phase. The Jdbc source reads the same rows fine. ### SeaTunnel Version 2.3.12, dev (4dcfa28ccc) ### SeaTunnel Config ```conf env { job.mode = "STREAMING", checkpoint.interval = 5000 } source { MySQL-CDC { url = "jdbc:mysql://host:3306/db", username = "...", password = "...", table-names = ["db.t"], startup.mode = "initial" } } sink { Console {} } ``` with `CREATE TABLE t (id INT PRIMARY KEY, dt6 DATETIME(6)); INSERT INTO t VALUES (1, '1969-12-31 23:59:59.999999');` ### Running Command ```shell ./bin/seatunnel.sh -c job.conf ``` ### Error Exception ```log java.time.DateTimeException: Invalid value for NanoOfDay (valid values 0 - 86399999999999): -1000 at java.time.temporal.ValueRange.checkValidValue(ValueRange.java:311) at java.time.temporal.ChronoField.checkValidValue(ChronoField.java:703) at java.time.LocalTime.ofNanoOfDay(LocalTime.java:376) at org.apache.seatunnel.connectors.cdc.debezium.row.SeaTunnelRowDebeziumDeserializationConverters.toLocalDateTime(SeaTunnelRowDebeziumDeserializationConverters.java:438) at org.apache.seatunnel.connectors.cdc.debezium.row.SeaTunnelRowDebeziumDeserializationConverters$11.convert(SeaTunnelRowDebeziumDeserializationConverters.java:415) at org.apache.seatunnel.connectors.cdc.debezium.row.SeaTunnelRowDebeziumDeserializationConverters$17.convert(SeaTunnelRowDebeziumDeserializationConverters.java:584) at org.apache.seatunnel.connectors.cdc.debezium.row.SeaTunnelRowDebeziumDeserializationConverters.convertField(SeaTunnelRowDebeziumDeserializationConverters.java:570) at org.apache.seatunnel.connectors.cdc.debezium.row.SeaTunnelRowDebeziumDeserializationConverters.convert(SeaTunnelRowDebeziumDeserializationConverters.java:104) at org.apache.seatunnel.connectors.cdc.debezium.row.SeaTunnelRowDebeziumDeserializeSchema.extractAfterRow(SeaTunnelRowDebeziumDeserializeSchema.java:321) at org.apache.seatunnel.connectors.cdc.debezium.row.SeaTunnelRowDebeziumDeserializeSchema.deserializeDataChangeRecord(SeaTunnelRowDebeziumDeserializeSchema.java:260) at org.apache.seatunnel.connectors.cdc.debezium.row.SeaTunnelRowDebeziumDeserializeSchema.deserialize(SeaTunnelRowDebeziumDeserializeSchema.java:144) at org.apache.seatunnel.connectors.cdc.base.source.reader.IncrementalSourceRecordEmitter.emitElement(IncrementalSourceRecordEmitter.java:201) at org.apache.seatunnel.connectors.cdc.base.source.reader.IncrementalSourceRecordEmitter.processElement(IncrementalSourceRecordEmitter.java:153) at org.apache.seatunnel.connectors.cdc.base.source.reader.IncrementalSourceRecordEmitter.emitRecord(IncrementalSourceRecordEmitter.java:102) at org.apache.seatunnel.connectors.cdc.base.source.reader.IncrementalSourceRecordEmitter.emitRecord(IncrementalSourceRecordEmitter.java:62) at org.apache.seatunnel.connectors.seatunnel.common.source.reader.SourceReaderBase.pollNext(SourceReaderBase.java:110) at org.apache.seatunnel.connectors.cdc.base.source.reader.IncrementalSourceReader.pollNext(IncrementalSourceReader.java:119) at org.apache.seatunnel.engine.server.task.flow.SourceFlowLifeCycle.collect(SourceFlowLifeCycle.java:168) at org.apache.seatunnel.engine.server.task.SourceSeaTunnelTask.collect(SourceSeaTunnelTask.java:144) at org.apache.seatunnel.engine.server.task.SeaTunnelTask.stateProcess(SeaTunnelTask.java:165) at org.apache.seatunnel.engine.server.task.SourceSeaTunnelTask.call(SourceSeaTunnelTask.java:149) at org.apache.seatunnel.engine.server.TaskExecutionService$BlockingWorker.run(TaskExecutionService.java:706) at org.apache.seatunnel.engine.server.TaskExecutionService$NamedTaskWrapper.run(TaskExecutionService.java:1035) at org.apache.seatunnel.api.tracing.MDCRunnable.run(MDCRunnable.java:43) at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511) at java.util.concurrent.FutureTask.run(FutureTask.java:266) at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149) at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624) at java.lang.Thread.run(Thread.java:750) ``` ### Zeta or Flink or Spark Version Zeta ### 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) -- 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]
