@@ -246,7 +246,7 @@ struct ICUStrptime : public ICUDateFunc {
246
246
TailPatch (name, db, types);
247
247
}
248
248
249
- static bool CastFromVarchar (Vector &source, Vector &result, idx_t count, CastParameters ¶meters) {
249
+ static bool VarcharToTimestampTZ (Vector &source, Vector &result, idx_t count, CastParameters ¶meters) {
250
250
auto &cast_data = parameters.cast_data ->Cast <CastData>();
251
251
auto &info = cast_data.info ->Cast <BindData>();
252
252
CalendarPtr cal (info.calendar ->clone ());
@@ -260,7 +260,7 @@ struct ICUStrptime : public ICUDateFunc {
260
260
bool has_offset = false ;
261
261
if (!Timestamp::TryConvertTimestampTZ (str, len, result, has_offset, tz)) {
262
262
auto msg = Timestamp::ConversionError (string (str, len));
263
- HandleCastError::AssignError (msg, parameters. error_message );
263
+ HandleCastError::AssignError (msg, parameters);
264
264
mask.SetInvalid (idx);
265
265
} else if (!has_offset) {
266
266
// Convert parts to a TZ (default or parsed) if no offset was provided
@@ -280,22 +280,64 @@ struct ICUStrptime : public ICUDateFunc {
280
280
return true ;
281
281
}
282
282
283
+ static bool VarcharToTimeTZ (Vector &source, Vector &result, idx_t count, CastParameters ¶meters) {
284
+ auto &cast_data = parameters.cast_data ->Cast <CastData>();
285
+ auto &info = cast_data.info ->Cast <BindData>();
286
+ CalendarPtr cal (info.calendar ->clone ());
287
+
288
+ UnaryExecutor::ExecuteWithNulls<string_t , dtime_tz_t >(
289
+ source, result, count, [&](string_t input, ValidityMask &mask, idx_t idx) {
290
+ dtime_tz_t result;
291
+ const auto str = input.GetData ();
292
+ const auto len = input.GetSize ();
293
+ bool has_offset = false ;
294
+ idx_t pos = 0 ;
295
+ if (!Time::TryConvertTimeTZ (str, len, pos, result, has_offset, false )) {
296
+ auto msg = Time::ConversionError (string (str, len));
297
+ HandleCastError::AssignError (msg, parameters);
298
+ mask.SetInvalid (idx);
299
+ } else if (!has_offset) {
300
+ // Convert parts to a TZ (default or parsed) if no offset was provided
301
+ auto calendar = cal.get ();
302
+
303
+ // Extract the offset from the calendar
304
+ auto offset = ExtractField (calendar, UCAL_ZONE_OFFSET);
305
+ offset += ExtractField (calendar, UCAL_DST_OFFSET);
306
+ offset /= Interval::MSECS_PER_SEC;
307
+
308
+ // Apply it to the offset +00 time we parsed.
309
+ result = dtime_tz_t (result.time (), offset);
310
+ }
311
+
312
+ return result;
313
+ });
314
+ return true ;
315
+ }
316
+
283
317
static BoundCastInfo BindCastFromVarchar (BindCastInput &input, const LogicalType &source,
284
318
const LogicalType &target) {
285
319
if (!input.context ) {
286
- throw InternalException (" Missing context for VARCHAR to TIMESTAMPTZ cast." );
320
+ throw InternalException (" Missing context for VARCHAR to TIME/ TIMESTAMPTZ cast." );
287
321
}
288
322
289
323
auto cast_data = make_uniq<CastData>(make_uniq<BindData>(*input.context ));
290
324
291
- return BoundCastInfo (CastFromVarchar, std::move (cast_data));
325
+ switch (target.id ()) {
326
+ case LogicalTypeId::TIMESTAMP_TZ:
327
+ return BoundCastInfo (VarcharToTimestampTZ, std::move (cast_data));
328
+ case LogicalTypeId::TIME_TZ:
329
+ return BoundCastInfo (VarcharToTimeTZ, std::move (cast_data));
330
+ default :
331
+ throw InternalException (" Unsupported type for VARCHAR to TIME/TIMESTAMPTZ cast." );
332
+ }
292
333
}
293
334
294
335
static void AddCasts (DatabaseInstance &db) {
295
336
auto &config = DBConfig::GetConfig (db);
296
337
auto &casts = config.GetCastFunctions ();
297
338
298
339
casts.RegisterCastFunction (LogicalType::VARCHAR, LogicalType::TIMESTAMP_TZ, BindCastFromVarchar);
340
+ casts.RegisterCastFunction (LogicalType::VARCHAR, LogicalType::TIME_TZ, BindCastFromVarchar);
299
341
}
300
342
};
301
343
0 commit comments