From dbc9705307f7d292b09295d4feb0bd011fae6086 Mon Sep 17 00:00:00 2001 From: Mihai Budiu Date: Thu, 2 Jul 2026 14:13:06 -0700 Subject: [PATCH] [connectors] Do not ignore fractional seconds in Debezium timestamps Signed-off-by: Mihai Budiu --- .../src/serde_with_context/serde_config.rs | 6 +++--- crates/sqllib/src/timestamp.rs | 19 +++++++++++++++++++ 2 files changed, 22 insertions(+), 3 deletions(-) diff --git a/crates/feldera-types/src/serde_with_context/serde_config.rs b/crates/feldera-types/src/serde_with_context/serde_config.rs index f0b265a4ea0..a9dbe279cf5 100644 --- a/crates/feldera-types/src/serde_with_context/serde_config.rs +++ b/crates/feldera-types/src/serde_with_context/serde_config.rs @@ -201,9 +201,9 @@ impl From for SqlSerdeConfig { JsonFlavor::DebeziumMySql => Self { time_format: TimeFormat::Micros, date_format: DateFormat::DaysSinceEpoch, - // Why is this missing fractions of second? - timestamp_format: TimestampFormat::String("%Y-%m-%dT%H:%M:%S%Z"), - timestamp_tz_format: TimestampFormat::String("%Y-%m-%dT%H:%M:%S%Z"), + // `2018-06-20T13:37:03Z` and `2018-06-20T13:37:03.123456Z`. + timestamp_format: TimestampFormat::String("%Y-%m-%dT%H:%M:%S%.f%Z"), + timestamp_tz_format: TimestampFormat::String("%Y-%m-%dT%H:%M:%S%.f%Z"), decimal_format: DecimalFormat::String, variant_format: VariantFormat::JsonString, binary_format: BinaryFormat::Array, diff --git a/crates/sqllib/src/timestamp.rs b/crates/sqllib/src/timestamp.rs index 3b7e3d8554b..6f9ed1917f2 100644 --- a/crates/sqllib/src/timestamp.rs +++ b/crates/sqllib/src/timestamp.rs @@ -4054,6 +4054,25 @@ mod test { ); } + /// Debezium MySQL emits `io.debezium.time.ZonedTimestamp` values with + /// fractional seconds when the column has sub-second precision. + /// The fraction must be preserved, not silently dropped. + #[test] + fn debezium_fractional_seconds() { + assert_eq!( + deserialize_with_debezium_config::( + r#"{"date": 16816, "time": 10800000000, "timestamp": "2018-06-20T13:37:03.123456Z", "timestampTz": "2018-06-20T13:37:03.123456Z" }"# + ) + .unwrap(), + TestStruct { + date: Date::from_days(16816), + time: Time::from_nanoseconds(10800000000000), + timestamp: Timestamp::from_microseconds(1529501823123456), + timestampTz: TimestampTz::from_microseconds(1529501823123456), + } + ); + } + #[test] fn snowflake_json() { assert_eq!(