diff --git a/backend/windmill-worker/src/pg_executor.rs b/backend/windmill-worker/src/pg_executor.rs index 3fb96677fd..f679d6c003 100644 --- a/backend/windmill-worker/src/pg_executor.rs +++ b/backend/windmill-worker/src/pg_executor.rs @@ -561,6 +561,9 @@ pub fn pg_cell_to_json_value( Type::TIME => get_basic(row, column, column_i, |a: chrono::NaiveTime| { Ok(JSONValue::String(a.to_string())) })?, + Type::TIMETZ => get_basic(row, column, column_i, |a: TimeTZStr| { + Ok(JSONValue::String(a.0)) + })?, Type::TIMESTAMPTZ => get_basic(row, column, column_i, |a: chrono::DateTime| { Ok(JSONValue::String(a.to_string())) })?, @@ -633,6 +636,9 @@ pub fn pg_cell_to_json_value( Type::TIME_ARRAY => get_array(row, column, column_i, |a: chrono::NaiveTime| { Ok(JSONValue::String(a.to_string())) })?, + Type::TIMETZ_ARRAY => get_array(row, column, column_i, |a: TimeTZStr| { + Ok(JSONValue::String(a.0)) + })?, Type::TIMESTAMPTZ_ARRAY => get_array(row, column, column_i, |a: chrono::DateTime| { Ok(JSONValue::String(a.to_string())) })?, @@ -699,6 +705,28 @@ impl<'a> FromSql<'a> for IntervalStr { } } +struct TimeTZStr(String); +impl<'a> FromSql<'a> for TimeTZStr { + fn from_sql( + _: &Type, + mut raw: &'a [u8], + ) -> Result> { + let microsecond = raw.get_i64(); + let offset = raw.get_i32(); + let utc_sec = (microsecond / 1_000_000) + offset as i64; + let utc = chrono::NaiveTime::from_num_seconds_from_midnight_opt( + ((utc_sec + 3600 * 24) % (3600 * 24)) as u32, + ((microsecond % 1_000_000) * 1_000) as u32, + ) + .ok_or_else(|| anyhow::anyhow!("Invalid time value"))?; + Ok(TimeTZStr(format!("{:?} UTC", utc))) + } + + fn accepts(ty: &Type) -> bool { + matches!(ty, &Type::TIMETZ) + } +} + fn get_array<'a, T: FromSql<'a>>( row: &'a Row, column: &Column,