Skip to content

Commit 05ff5c0

Browse files
Huliiiiiityt2y3
andauthored
Format microsecond in prepare_constant (#929)
## PR Info Fixed the issue where milliseconds were truncated when formatting `Value::Constant` - [Postgres](https://www.postgresql.org/docs/current/datatype-datetime.html#DATATYPE-DATETIME-INPUT-TIMES) Support microseconds - [Mysql](https://dev.mysql.com/doc/refman/8.4/en/fractional-seconds.html) Support microseconds - [Sqlite](https://sqlite.org/lang_datefunc.html) Support milliseconds, ignore extra digits <!-- mention the related issue --> - Closes #808 ## Bug Fixes - [x] Fixed the issue where microseconds were truncated when formatting `Value::Constant` --------- Co-authored-by: Chris Tsang <[email protected]>
1 parent aefb97b commit 05ff5c0

File tree

5 files changed

+76
-8
lines changed

5 files changed

+76
-8
lines changed

CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -138,6 +138,10 @@ impl Iden for Glyph {
138138
If you had custom implementations in your own code, some may no longer compile
139139
and may need to be deleted.
140140

141+
### Bug Fixes
142+
143+
* Fixed the issue where milliseconds were truncated when formatting `Value::Constant`
144+
141145
### Upgrades
142146

143147
* Upgraded to Rust Edition 2024 https://github.com/SeaQL/sea-query/pull/885

src/backend/query_builder.rs

Lines changed: 69 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1120,22 +1120,22 @@ pub trait QueryBuilder:
11201120
#[cfg(feature = "with-chrono")]
11211121
Value::ChronoDate(Some(v)) => write!(s, "'{}'", v.format("%Y-%m-%d")).unwrap(),
11221122
#[cfg(feature = "with-chrono")]
1123-
Value::ChronoTime(Some(v)) => write!(s, "'{}'", v.format("%H:%M:%S")).unwrap(),
1123+
Value::ChronoTime(Some(v)) => write!(s, "'{}'", v.format("%H:%M:%S%.6f")).unwrap(),
11241124
#[cfg(feature = "with-chrono")]
11251125
Value::ChronoDateTime(Some(v)) => {
1126-
write!(s, "'{}'", v.format("%Y-%m-%d %H:%M:%S")).unwrap()
1126+
write!(s, "'{}'", v.format("%Y-%m-%d %H:%M:%S%.6f")).unwrap()
11271127
}
11281128
#[cfg(feature = "with-chrono")]
11291129
Value::ChronoDateTimeUtc(Some(v)) => {
1130-
write!(s, "'{}'", v.format("%Y-%m-%d %H:%M:%S %:z")).unwrap()
1130+
write!(s, "'{}'", v.format("%Y-%m-%d %H:%M:%S%.6f %:z")).unwrap()
11311131
}
11321132
#[cfg(feature = "with-chrono")]
11331133
Value::ChronoDateTimeLocal(Some(v)) => {
1134-
write!(s, "'{}'", v.format("%Y-%m-%d %H:%M:%S %:z")).unwrap()
1134+
write!(s, "'{}'", v.format("%Y-%m-%d %H:%M:%S%.6f %:z")).unwrap()
11351135
}
11361136
#[cfg(feature = "with-chrono")]
11371137
Value::ChronoDateTimeWithTimeZone(Some(v)) => {
1138-
write!(s, "'{}'", v.format("%Y-%m-%d %H:%M:%S %:z")).unwrap()
1138+
write!(s, "'{}'", v.format("%Y-%m-%d %H:%M:%S%.6f %:z")).unwrap()
11391139
}
11401140
#[cfg(feature = "with-time")]
11411141
Value::TimeDate(Some(v)) => {
@@ -1703,3 +1703,67 @@ pub(crate) fn common_well_known_left_associative(op: &BinOper) -> bool {
17031703
BinOper::And | BinOper::Or | BinOper::Add | BinOper::Sub | BinOper::Mul | BinOper::Mod
17041704
)
17051705
}
1706+
1707+
#[cfg(test)]
1708+
mod tests {
1709+
#[cfg(feature = "with-chrono")]
1710+
use chrono::{DateTime, FixedOffset, NaiveDate, NaiveDateTime, NaiveTime, Utc};
1711+
1712+
use crate::{MysqlQueryBuilder, PostgresQueryBuilder, QueryBuilder, SqliteQueryBuilder};
1713+
1714+
/// [Postgresql reference](https://www.postgresql.org/docs/current/datatype-datetime.html#DATATYPE-DATETIME-INPUT-TIMES)
1715+
///
1716+
/// [Mysql reference](https://dev.mysql.com/doc/refman/8.4/en/fractional-seconds.html)
1717+
///
1718+
/// [Sqlite reference](https://sqlite.org/lang_datefunc.html)
1719+
#[test]
1720+
#[cfg(feature = "with-chrono")]
1721+
fn format_time_constant() {
1722+
let time = NaiveTime::from_hms_micro_opt(1, 2, 3, 123456)
1723+
.unwrap()
1724+
.into();
1725+
1726+
let mut string = String::new();
1727+
macro_rules! compare {
1728+
($a:ident, $b:literal) => {
1729+
PostgresQueryBuilder.prepare_constant(&$a, &mut string);
1730+
assert_eq!(string, $b);
1731+
1732+
string.clear();
1733+
1734+
MysqlQueryBuilder.prepare_constant(&$a, &mut string);
1735+
assert_eq!(string, $b);
1736+
1737+
string.clear();
1738+
1739+
SqliteQueryBuilder.prepare_constant(&$a, &mut string);
1740+
assert_eq!(string, $b);
1741+
1742+
string.clear();
1743+
};
1744+
}
1745+
1746+
compare!(time, "'01:02:03.123456'");
1747+
1748+
let d = NaiveDate::from_ymd_opt(2015, 6, 3).unwrap();
1749+
let t = NaiveTime::from_hms_micro_opt(12, 34, 56, 123456).unwrap();
1750+
1751+
let dt = NaiveDateTime::new(d, t);
1752+
1753+
let date_time = dt.into();
1754+
1755+
compare!(date_time, "'2015-06-03 12:34:56.123456'");
1756+
1757+
let date_time_utc = DateTime::<Utc>::from_naive_utc_and_offset(dt, Utc).into();
1758+
1759+
compare!(date_time_utc, "'2015-06-03 12:34:56.123456 +00:00'");
1760+
1761+
let date_time_tz = DateTime::<FixedOffset>::from_naive_utc_and_offset(
1762+
dt,
1763+
FixedOffset::east_opt(8 * 3600).unwrap(),
1764+
)
1765+
.into();
1766+
1767+
compare!(date_time_tz, "'2015-06-03 20:34:56.123456 +08:00'");
1768+
}
1769+
}

tests/mysql/query.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1099,7 +1099,7 @@ fn insert_4() {
10991099
.unwrap()
11001100
.into()])
11011101
.to_string(MysqlQueryBuilder),
1102-
"INSERT INTO `glyph` (`image`) VALUES ('1970-01-01 00:00:00')"
1102+
"INSERT INTO `glyph` (`image`) VALUES ('1970-01-01 00:00:00.000000')"
11031103
);
11041104
}
11051105

tests/postgres/query.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1273,7 +1273,7 @@ fn insert_4() {
12731273
.unwrap()
12741274
.into()])
12751275
.to_string(PostgresQueryBuilder),
1276-
"INSERT INTO \"glyph\" (\"image\") VALUES ('1970-01-01 00:00:00')"
1276+
"INSERT INTO \"glyph\" (\"image\") VALUES ('1970-01-01 00:00:00.000000')"
12771277
);
12781278
}
12791279

tests/sqlite/query.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1098,7 +1098,7 @@ fn insert_4() {
10981098
.unwrap()
10991099
.into()])
11001100
.to_string(SqliteQueryBuilder),
1101-
r#"INSERT INTO "glyph" ("image") VALUES ('1970-01-01 00:00:00')"#
1101+
r#"INSERT INTO "glyph" ("image") VALUES ('1970-01-01 00:00:00.000000')"#
11021102
);
11031103
}
11041104

0 commit comments

Comments
 (0)