Skip to content

feat(query): function about convert_timezone #16177 #16181

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 64 commits into from
Nov 5, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
64 commits
Select commit Hold shift + click to select a range
a1ed5c5
Feature: function about convert_timezone #16177
florann Aug 4, 2024
e5816af
Correction trait type
florann Aug 4, 2024
8112be0
Formatting the function
florann Aug 4, 2024
b61543f
Solving compiling issue
florann Aug 4, 2024
3fe6c57
Correcting file format
florann Aug 4, 2024
dea89c7
adding tests
florann Aug 4, 2024
4d5b0c9
Correction unti test
florann Aug 4, 2024
1aff0e8
Correction unit tests 2
florann Aug 4, 2024
c376200
Correction unit tests 3
florann Aug 4, 2024
af370a6
Correction unit tests 4
florann Aug 4, 2024
1074c0a
Correction unit tests 5
florann Aug 4, 2024
5fc9299
Correction unit tests 6
florann Aug 4, 2024
856eef4
Correction unit tests 6
florann Aug 4, 2024
0f7d834
Implementation of convert_timezone
florann Aug 5, 2024
71803ab
Correction registry and error handling
florann Aug 5, 2024
33f170b
Correction eval function
florann Aug 5, 2024
9947d8f
Correction eval function 2
florann Aug 5, 2024
5df3e12
Correction eval function 3
florann Aug 5, 2024
56d9f60
Correction eval function 4
florann Aug 5, 2024
b279233
Correction eval function 5
florann Aug 5, 2024
ae5b74d
Correction eval function 6
florann Aug 5, 2024
0ec240e
Correction eval function 7
florann Aug 5, 2024
707c445
Correction eval function 8
florann Aug 5, 2024
2f9b60b
Correction eval function 9
florann Aug 5, 2024
e1d7898
Correction eval function 11
florann Aug 5, 2024
aa9d108
Correction eval function 12
florann Aug 5, 2024
b74ad41
Correction eval function 13 + add of the 3 arguments function version
florann Aug 6, 2024
8f61741
Code formatting
florann Aug 6, 2024
c4d493c
Correction third parameter convert_timezone()
florann Aug 6, 2024
3edf227
Correction type
florann Aug 6, 2024
9b82482
Correction 1
florann Aug 6, 2024
aeac109
Correction 2
florann Aug 6, 2024
58bb68c
Adding unit test
florann Aug 6, 2024
220c56d
Adding unit test 2
florann Aug 6, 2024
46121cb
Correciton unit test 4
florann Aug 6, 2024
875fc24
Correciton unit test 5
florann Aug 6, 2024
b1a55f2
Correciton unit test 6
florann Aug 6, 2024
467f139
Correciton unit test 7
florann Aug 6, 2024
b17ba0e
Correction unit test 8
florann Aug 6, 2024
73dc4a6
Correction checked expr
florann Aug 7, 2024
27bc461
Correction convert_timezone
florann Aug 7, 2024
ee4ee70
Correction convert_timezone 2
florann Aug 7, 2024
5d7fef4
Correction convert_timezone 3
florann Aug 7, 2024
231c89c
Correction convert_timezone 4
florann Aug 7, 2024
26c808f
Correction convert_timezone 5
florann Aug 7, 2024
e8a9ee9
Correction convert_timezone 6
florann Aug 7, 2024
cff049b
Correction convert_timezone 7
florann Aug 7, 2024
aadb453
Correction convert_timezone 8
florann Aug 7, 2024
05de10e
Correction convert_timezone 9
florann Aug 8, 2024
ab38264
Correction convert_timezone 10
florann Aug 8, 2024
bfe224c
Correction convert_timezone 11
florann Aug 8, 2024
5ce929f
Correction convert_timezone 12
florann Aug 8, 2024
66f61ad
Correction convert_timezone 12
florann Aug 8, 2024
e50bb78
Correction convert_timezone 13
florann Aug 8, 2024
e45aba2
Unit test
florann Aug 9, 2024
e34f6c1
Unit test 2
florann Aug 9, 2024
fd69ab3
Unit test 3
florann Aug 9, 2024
4eaa110
Unit test 4
florann Aug 9, 2024
0e38b10
Unit test 5
florann Aug 9, 2024
86495ea
Unit test 6
florann Aug 9, 2024
12fb5fa
Unit test 7
florann Aug 9, 2024
1cee2cf
feat: convert_timezone(target_timezone, ts)
TCeason Nov 1, 2024
658141d
add some check
TCeason Nov 1, 2024
769e9f5
if error output push default
TCeason Nov 1, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
56 changes: 56 additions & 0 deletions src/query/functions/src/scalars/datetime.rs
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,9 @@ pub fn register(registry: &mut FunctionRegistry) {

// [date | timestamp] +/- number
register_timestamp_add_sub(registry);

// convert_timezone( target_timezone, 'timestamp')
register_convert_timezone(registry);
}

/// Check if timestamp is within range, and return the timestamp in micros.
Expand All @@ -134,6 +137,59 @@ fn int64_domain_to_timestamp_domain<T: AsPrimitive<i64>>(
})
}

fn register_convert_timezone(registry: &mut FunctionRegistry) {
// 2 arguments function [target_timezone, src_timestamp]
registry.register_passthrough_nullable_2_arg::<StringType, TimestampType, TimestampType, _, _>(
"convert_timezone",
|_, _, _| FunctionDomain::MayThrow,
vectorize_with_builder_2_arg::<StringType, TimestampType, TimestampType>(
|target_tz, src_timestamp, output, ctx| {
if let Some(validity) = &ctx.validity {
if !validity.get_bit(output.len()) {
output.push(0);
return;
}
}
// Convert source timestamp from source timezone to target timezone
let p_src_timestamp = src_timestamp.to_timestamp(ctx.func_ctx.tz.tz);
let src_dst_from_utc = p_src_timestamp.offset().fix().local_minus_utc();
let t_tz: Tz = match target_tz.parse() {
Ok(tz) => tz,
Err(e) => {
ctx.set_error(
output.len(),
format!("cannot parse target `timezone`. {}", e),
);
output.push(0);
return;
}
};

let result_timestamp = p_src_timestamp.with_timezone(&t_tz).timestamp_micros();
let target_dst_from_utc = p_src_timestamp
.with_timezone(&t_tz)
.offset()
.fix()
.local_minus_utc();
let offset_as_micros_sec = (target_dst_from_utc - src_dst_from_utc) as i64;
match offset_as_micros_sec.checked_mul(MICROS_PER_SEC) {
Some(offset) => match result_timestamp.checked_add(offset) {
Some(res) => output.push(res),
None => {
ctx.set_error(output.len(), "calc final time error".to_string());
output.push(0);
}
},
None => {
ctx.set_error(output.len(), "calc time offset error".to_string());
output.push(0);
}
}
},
),
);
}

fn register_string_to_timestamp(registry: &mut FunctionRegistry) {
registry.register_aliases("to_date", &["str_to_date", "date"]);
registry.register_aliases("to_year", &["str_to_year", "year"]);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1224,6 +1224,8 @@ Functions overloads:
26 contains(Array(Boolean), Boolean) :: Boolean
27 contains(Array(Boolean) NULL, Boolean NULL) :: Boolean NULL
28 contains(Array(T0) NULL, T0) :: Boolean
0 convert_timezone(String, Timestamp) :: Timestamp
1 convert_timezone(String NULL, Timestamp NULL) :: Timestamp NULL
0 cos(Float64) :: Float64
1 cos(Float64 NULL) :: Float64 NULL
0 cosine_distance(Array(Float32), Array(Float32)) :: Float32
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -658,7 +658,6 @@ select to_datetime('1', '%s')
statement error 1006
select to_timestamp('200,2000', '%s,%Y');


statement ok
set timezone='UTC';

Expand Down Expand Up @@ -769,3 +768,59 @@ query T
SELECT substr(DATE_ADD(month, 1, now())::String, 1,4)=substr(now()::String, 1,4);
----
1


statement ok
set timezone='Asia/Shanghai';

query T
SELECT convert_timezone('America/Los_Angeles', '2024-11-01 11:36:10')
----
2024-10-31 20:36:10.000000

statement ok
set timezone='UTC';

statement ok
create or replace table t(a string null, c timestamp null);

statement ok
insert into t values('America/Los_Angeles','1970-01-01 00:00:00'), ('America/Los_Angeles','2024-10-31 22:21:15'), (null, '1970-01-01 00:00:00'), ('Asia/Shanghai', '1970-01-01 00:00:00'), ('Asia/Shanghai', '2024-10-31 22:21:15'),('Asia/Shanghai', null), (null, null);

# UTC to America/Los_Angeles, 20240-03-10 ~ 2024-11-03 is UTC-7(dst), other is UTC-8
query T
select a, c, CONVERT_TIMEZONE(a, c) from t order by a,c;
----
America/Los_Angeles 1970-01-01 00:00:00.000000 1969-12-31 16:00:00.000000
America/Los_Angeles 2024-10-31 22:21:15.000000 2024-10-31 15:21:15.000000
Asia/Shanghai 1970-01-01 00:00:00.000000 1970-01-01 08:00:00.000000
Asia/Shanghai 2024-10-31 22:21:15.000000 2024-11-01 06:21:15.000000
Asia/Shanghai NULL NULL
NULL 1970-01-01 00:00:00.000000 NULL
NULL NULL NULL

statement ok
set timezone='Asia/Shanghai';


statement error 1006
select convert_timezone('Asia/Shanghai', '1947-04-15 00:00:00');

statement ok
set enable_dst_hour_fix=1;

# 1947-04-15 00:00:00 is not exists in Asia/Shanghai. Such timings cannot be guaranteed to meet completely
# consider use date_add/sub calc the offset.
query T
select convert_timezone('UTC', '1947-04-15 00:00:00');
----
1947-04-14 15:00:00.000000

statement ok
unset enable_dst_hour_fix;

statement ok
drop table if exists t;

statement ok
unset timezone;
Loading