Skip to content

Commit 3981c46

Browse files
authored
fix(query): to_date parse string with format should use UTC timezone (#17641)
1 parent 1393ad5 commit 3981c46

File tree

2 files changed

+36
-10
lines changed

2 files changed

+36
-10
lines changed

โ€Žsrc/query/functions/src/scalars/timestamp/src/datetime.rs

Lines changed: 17 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -300,8 +300,8 @@ fn register_string_to_timestamp(registry: &mut FunctionRegistry) {
300300
"to_timestamp",
301301
|_, _, _| FunctionDomain::MayThrow,
302302
vectorize_with_builder_2_arg::<StringType, StringType, NullableType<TimestampType>>(
303-
|timestamp, format, output, ctx| match string_to_format_timestamp(
304-
timestamp, format, ctx,
303+
|timestamp, format, output, ctx| match string_to_format_datetime(
304+
timestamp, format, ctx, true,
305305
) {
306306
Ok((ts, need_null)) => {
307307
if need_null {
@@ -322,8 +322,8 @@ fn register_string_to_timestamp(registry: &mut FunctionRegistry) {
322322
"try_to_timestamp",
323323
|_, _, _| FunctionDomain::MayThrow,
324324
vectorize_with_builder_2_arg::<StringType, StringType, NullableType<TimestampType>>(
325-
|timestamp, format, output, ctx| match string_to_format_timestamp(
326-
timestamp, format, ctx,
325+
|timestamp, format, output, ctx| match string_to_format_datetime(
326+
timestamp, format, ctx, true,
327327
) {
328328
Ok((ts, need_null)) => {
329329
if need_null {
@@ -347,7 +347,7 @@ fn register_string_to_timestamp(registry: &mut FunctionRegistry) {
347347
if format.is_empty() {
348348
output.push_null();
349349
} else {
350-
match string_to_format_timestamp(date, format, ctx) {
350+
match string_to_format_datetime(date, format, ctx, false) {
351351
Ok((res, false)) => {
352352
output.push((res / MICROS_PER_SEC / 24 / 3600) as _);
353353
}
@@ -372,7 +372,7 @@ fn register_string_to_timestamp(registry: &mut FunctionRegistry) {
372372
if format.is_empty() {
373373
output.push_null();
374374
} else {
375-
match string_to_format_timestamp(date, format, ctx) {
375+
match string_to_format_datetime(date, format, ctx, false) {
376376
Ok((res, false)) => {
377377
output.push((res / MICROS_PER_SEC / 24 / 3600) as _);
378378
}
@@ -386,10 +386,11 @@ fn register_string_to_timestamp(registry: &mut FunctionRegistry) {
386386
);
387387
}
388388

389-
fn string_to_format_timestamp(
389+
fn string_to_format_datetime(
390390
timestamp: &str,
391391
format: &str,
392392
ctx: &mut EvalContext,
393+
parse_timestamp: bool,
393394
) -> Result<(i64, bool), Box<ErrorCode>> {
394395
if format.is_empty() {
395396
return Ok((0, true));
@@ -424,9 +425,15 @@ fn string_to_format_timestamp(
424425
}
425426

426427
let z = if tm.offset().is_none() {
427-
ctx.func_ctx.tz.to_zoned(tm.to_datetime().map_err(|err| {
428-
ErrorCode::BadArguments(format!("{timestamp} to datetime error {err}"))
429-
})?)
428+
if parse_timestamp {
429+
ctx.func_ctx.tz.to_zoned(tm.to_datetime().map_err(|err| {
430+
ErrorCode::BadArguments(format!("{timestamp} to datetime error {err}"))
431+
})?)
432+
} else {
433+
TimeZone::UTC.to_zoned(tm.to_datetime().map_err(|err| {
434+
ErrorCode::BadArguments(format!("{timestamp} to datetime error {err}"))
435+
})?)
436+
}
430437
} else {
431438
tm.to_zoned()
432439
}

โ€Žtests/sqllogictests/suites/query/functions/02_0012_function_datetimes_tz.test

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1118,3 +1118,22 @@ select to_timestamp('1684275059752');
11181118

11191119
statement ok
11201120
unset enable_strict_datetime_parser;
1121+
1122+
statement ok
1123+
set timezone='Asia/Shanghai';
1124+
1125+
query T
1126+
select to_date('2024-03-01-1','%Y-%m-%d');
1127+
----
1128+
2024-03-01
1129+
1130+
statement ok
1131+
set timezone='America/Los_Angeles';
1132+
1133+
query T
1134+
select to_date('2024-03-01-1','%Y-%m-%d');
1135+
----
1136+
2024-03-01
1137+
1138+
statement ok
1139+
unset timezone;

0 commit comments

Comments
ย (0)