fix: improve MySQL datetime parser timezone handling (WIN-1155) (#5645)

* fix mysql datetime parser for non tz dates

* static regexes
This commit is contained in:
Diego Imbert
2025-04-21 14:46:28 +02:00
committed by GitHub
parent 80658a4b21
commit 5bca8f60e9
+24 -10
View File
@@ -6,8 +6,10 @@ use itertools::Itertools;
use mysql_async::{
consts::ColumnType, prelude::*, FromValueError, OptsBuilder, Params, Row, SslOpts,
};
use once_cell::sync::Lazy;
use serde::{Deserialize, Serialize};
use serde_json::{json, value::RawValue, Value};
use std::str::FromStr;
use tokio::sync::Mutex;
use windmill_common::{
error::{to_anyhow, Error},
@@ -303,26 +305,38 @@ pub async fn do_mysql(
return Ok(raw_result);
}
// 2023-12-01T16:18:00.000Z
static DATE_REGEX_TZ: Lazy<regex::Regex> = Lazy::new(|| {
regex::Regex::new(r"(\d{4})-(\d{2})-(\d{2})T(\d{2}):(\d{2}):(\d{2})\.(\d+)Z").unwrap()
});
// 2025-04-21 10:08:00
static DATE_REGEX: Lazy<regex::Regex> =
Lazy::new(|| regex::Regex::new(r"(\d{4})-(\d{2})-(\d{2}) (\d{2}):(\d{2}):(\d{2})").unwrap());
fn string_date_to_mysql_date(s: &str) -> mysql_async::Value {
// 2023-12-01T16:18:00.000Z
let re = regex::Regex::new(r"(\d{4})-(\d{2})-(\d{2})T(\d{2}):(\d{2}):(\d{2})\.(\d+)Z").unwrap();
let caps = re.captures(s);
let caps = DATE_REGEX_TZ.captures(s).or_else(|| DATE_REGEX.captures(s));
if let Some(caps) = caps {
mysql_async::Value::Date(
caps.get(1).unwrap().as_str().parse().unwrap_or_default(),
caps.get(2).unwrap().as_str().parse().unwrap_or_default(),
caps.get(3).unwrap().as_str().parse().unwrap_or_default(),
caps.get(4).unwrap().as_str().parse().unwrap_or_default(),
caps.get(5).unwrap().as_str().parse().unwrap_or_default(),
caps.get(6).unwrap().as_str().parse().unwrap_or_default(),
caps.get(7).unwrap().as_str().parse().unwrap_or_default(),
get_capture_by_index(&caps, 1),
get_capture_by_index(&caps, 2),
get_capture_by_index(&caps, 3),
get_capture_by_index(&caps, 4),
get_capture_by_index(&caps, 5),
get_capture_by_index(&caps, 6),
get_capture_by_index(&caps, 7),
)
} else {
mysql_async::Value::Date(0, 0, 0, 0, 0, 0, 0)
}
}
fn get_capture_by_index<T: FromStr + Default>(caps: &regex::Captures, n: usize) -> T {
caps.get(n)
.and_then(|s| s.as_str().parse::<T>().ok())
.unwrap_or_default()
}
fn convert_row_to_value(row: Row) -> serde_json::Value {
let mut map = serde_json::Map::new();