@@ -111,7 +111,7 @@ pub fn register(registry: &mut FunctionRegistry) {
111
111
// [date | timestamp] +/- number
112
112
register_timestamp_add_sub ( registry) ;
113
113
114
- // convert_timezone( target_timezone, date, src_timezone )
114
+ // convert_timezone( target_timezone, 'timestamp' )
115
115
register_convert_timezone ( registry) ;
116
116
}
117
117
@@ -144,6 +144,12 @@ fn register_convert_timezone(registry: &mut FunctionRegistry) {
144
144
|_, _, _| FunctionDomain :: MayThrow ,
145
145
vectorize_with_builder_2_arg :: < StringType , TimestampType , TimestampType > (
146
146
|target_tz, src_timestamp, output, ctx| {
147
+ if let Some ( validity) = & ctx. validity {
148
+ if !validity. get_bit ( output. len ( ) ) {
149
+ output. push ( 0 ) ;
150
+ return ;
151
+ }
152
+ }
147
153
// Convert source timestamp from source timezone to target timezone
148
154
let p_src_timestamp = src_timestamp. to_timestamp ( ctx. func_ctx . tz . tz ) ;
149
155
let src_dst_from_utc = p_src_timestamp. offset ( ) . fix ( ) . local_minus_utc ( ) ;
@@ -163,10 +169,14 @@ fn register_convert_timezone(registry: &mut FunctionRegistry) {
163
169
. offset ( )
164
170
. fix ( )
165
171
. local_minus_utc ( ) ;
166
- let offset_as_micros_sec =
167
- ( target_dst_from_utc - src_dst_from_utc) as i64 * MICROS_PER_SEC ;
168
- let res = result_timestamp. checked_add ( offset_as_micros_sec) . unwrap ( ) ;
169
- output. push ( res)
172
+ let offset_as_micros_sec = ( target_dst_from_utc - src_dst_from_utc) as i64 ;
173
+ match offset_as_micros_sec. checked_mul ( MICROS_PER_SEC ) {
174
+ Some ( offset) => match result_timestamp. checked_add ( offset) {
175
+ Some ( res) => output. push ( res) ,
176
+ None => ctx. set_error ( output. len ( ) , "calc final time error" . to_string ( ) ) ,
177
+ } ,
178
+ None => ctx. set_error ( output. len ( ) , "calc time offset error" . to_string ( ) ) ,
179
+ }
170
180
} ,
171
181
) ,
172
182
) ;
0 commit comments