Skip to content

Commit aeddef3

Browse files
authored
fix: avro timestamp_mills and timestamp_micros parse to timestamptz (risingwavelabs#8730)
Signed-off-by: tabVersion <[email protected]>
1 parent 24ecd4d commit aeddef3

File tree

3 files changed

+30
-52
lines changed

3 files changed

+30
-52
lines changed

e2e_test/source/basic/kafka.slt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -384,7 +384,7 @@ select id, first_name, last_name, email from s8;
384384
query IITFFBTT
385385
select id, sequence_id, name, score, avg_score, is_lasted, entrance_date, birthday, passed from s9;
386386
----
387-
32 64 str_value 32 64 t 1970-01-01 1970-01-01 00:00:00 1 mon 1 day 00:00:01
387+
32 64 str_value 32 64 t 1970-01-01 1970-01-01 00:00:00+00:00 1 mon 1 day 00:00:01
388388

389389
query ITITT
390390
select id, code, timestamp, xfas, contacts, sex from s10;

src/connector/src/parser/avro/parser.rs

Lines changed: 7 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -300,9 +300,7 @@ mod test {
300300
use risingwave_common::catalog::ColumnId;
301301
use risingwave_common::error;
302302
use risingwave_common::row::Row;
303-
use risingwave_common::types::{
304-
DataType, IntervalUnit, NaiveDateTimeWrapper, NaiveDateWrapper, ScalarImpl,
305-
};
303+
use risingwave_common::types::{DataType, IntervalUnit, NaiveDateWrapper, ScalarImpl};
306304
use url::Url;
307305

308306
use super::{
@@ -423,24 +421,12 @@ mod test {
423421
assert_eq!(row[i], date);
424422
}
425423
Value::TimestampMillis(millis) => {
426-
let datetime = Some(ScalarImpl::NaiveDateTime(
427-
NaiveDateTimeWrapper::with_secs_nsecs(
428-
millis / 1000,
429-
(millis % 1000) as u32 * 1_000_000,
430-
)
431-
.unwrap(),
432-
));
433-
assert_eq!(row[i], datetime);
424+
let millis = Some(ScalarImpl::Int64(millis * 1000));
425+
assert_eq!(row[i], millis);
434426
}
435427
Value::TimestampMicros(micros) => {
436-
let datetime = Some(ScalarImpl::NaiveDateTime(
437-
NaiveDateTimeWrapper::with_secs_nsecs(
438-
micros / 1_000_000,
439-
(micros % 1_000_000) as u32 * 1_000,
440-
)
441-
.unwrap(),
442-
));
443-
assert_eq!(row[i], datetime);
428+
let micros = Some(ScalarImpl::Int64(micros));
429+
assert_eq!(row[i], micros);
444430
}
445431
Value::Duration(duration) => {
446432
let months = u32::from(duration.months()) as i32;
@@ -467,8 +453,8 @@ mod test {
467453
SourceColumnDesc::simple("avg_score", DataType::Float64, ColumnId::from(4)),
468454
SourceColumnDesc::simple("is_lasted", DataType::Boolean, ColumnId::from(5)),
469455
SourceColumnDesc::simple("entrance_date", DataType::Date, ColumnId::from(6)),
470-
SourceColumnDesc::simple("birthday", DataType::Timestamp, ColumnId::from(7)),
471-
SourceColumnDesc::simple("anniversary", DataType::Timestamp, ColumnId::from(8)),
456+
SourceColumnDesc::simple("birthday", DataType::Timestamptz, ColumnId::from(7)),
457+
SourceColumnDesc::simple("anniversary", DataType::Timestamptz, ColumnId::from(8)),
472458
SourceColumnDesc::simple("passed", DataType::Interval, ColumnId::from(9)),
473459
]
474460
}

src/connector/src/parser/avro/util.rs

Lines changed: 22 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -20,8 +20,7 @@ use risingwave_common::array::{ListValue, StructValue};
2020
use risingwave_common::error::ErrorCode::{InternalError, ProtocolError};
2121
use risingwave_common::error::{Result, RwError};
2222
use risingwave_common::types::{
23-
DataType, Datum, IntervalUnit, NaiveDateTimeWrapper, NaiveDateWrapper, OrderedF32, OrderedF64,
24-
ScalarImpl,
23+
DataType, Datum, IntervalUnit, NaiveDateWrapper, OrderedF32, OrderedF64, ScalarImpl,
2524
};
2625
use risingwave_pb::plan_common::ColumnDesc;
2726

@@ -74,8 +73,8 @@ fn avro_type_mapping(schema: &Schema) -> Result<DataType> {
7473
Schema::Double => DataType::Float64,
7574
Schema::Decimal { .. } => DataType::Decimal,
7675
Schema::Date => DataType::Date,
77-
Schema::TimestampMillis => DataType::Timestamp,
78-
Schema::TimestampMicros => DataType::Timestamp,
76+
Schema::TimestampMillis => DataType::Timestamptz,
77+
Schema::TimestampMicros => DataType::Timestamptz,
7978
Schema::Duration => DataType::Interval,
8079
Schema::Enum { .. } => DataType::Varchar,
8180
Schema::Record { fields, .. } => {
@@ -281,32 +280,13 @@ pub(crate) fn from_avro_value(value: Value, value_schema: &Schema) -> Result<Dat
281280
RwError::from(InternalError(err_msg))
282281
})?,
283282
),
284-
Value::TimestampMillis(millis) => ScalarImpl::NaiveDateTime(
285-
NaiveDateTimeWrapper::with_secs_nsecs(
286-
millis / 1_000,
287-
(millis % 1_000) as u32 * 1_000_000,
288-
)
289-
.map_err(|e| {
290-
let err_msg = format!(
291-
"avro parse error.wrong timestamp millis value {}, err {:?}",
292-
millis, e
293-
);
294-
RwError::from(InternalError(err_msg))
295-
})?,
296-
),
297-
Value::TimestampMicros(micros) => ScalarImpl::NaiveDateTime(
298-
NaiveDateTimeWrapper::with_secs_nsecs(
299-
micros / 1_000_000,
300-
(micros % 1_000_000) as u32 * 1_000,
301-
)
302-
.map_err(|e| {
303-
let err_msg = format!(
304-
"avro parse error.wrong timestamp micros value {}, err {:?}",
305-
micros, e
306-
);
307-
RwError::from(InternalError(err_msg))
308-
})?,
309-
),
283+
Value::TimestampMicros(us) => ScalarImpl::Int64(us),
284+
Value::TimestampMillis(ms) => ScalarImpl::Int64(ms.checked_mul(1000).ok_or_else(|| {
285+
RwError::from(InternalError(format!(
286+
"avro parse millis overflow, value: {}",
287+
ms
288+
)))
289+
})?),
310290
Value::Duration(duration) => {
311291
let months = u32::from(duration.months()) as i32;
312292
let days = u32::from(duration.days()) as i32;
@@ -364,4 +344,16 @@ mod tests {
364344
let rust_decimal = avro_decimal_to_rust_decimal(avro_decimal, 28, 1).unwrap();
365345
assert_eq!(rust_decimal, rust_decimal::Decimal::from_f32(28.1).unwrap());
366346
}
347+
348+
#[test]
349+
fn test_avro_timestamp_micros() {
350+
let v1 = Value::TimestampMicros(1620000000000);
351+
let v2 = Value::TimestampMillis(1620000000);
352+
let value_schema1 = Schema::TimestampMicros;
353+
let value_schema2 = Schema::TimestampMillis;
354+
let datum1 = from_avro_value(v1, &value_schema1).unwrap();
355+
let datum2 = from_avro_value(v2, &value_schema2).unwrap();
356+
assert_eq!(datum1, Some(ScalarImpl::Int64(1620000000000)));
357+
assert_eq!(datum2, Some(ScalarImpl::Int64(1620000000000)));
358+
}
367359
}

0 commit comments

Comments
 (0)