Skip to content

Commit 927e81a

Browse files
Huliiiiiityt2y3
andcommitted
Format microsecond in prepare_constant (#929)
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 - [x] Fixed the issue where microseconds were truncated when formatting `Value::Constant` --------- Co-authored-by: Chris Tsang <[email protected]>
1 parent 72fb426 commit 927e81a

File tree

5 files changed

+73
-9
lines changed

5 files changed

+73
-9
lines changed

src/backend/query_builder.rs

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

src/value.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1999,7 +1999,7 @@ mod tests {
19991999

20002000
let query = Query::select().expr(timestamp).to_owned();
20012001

2002-
let formatted = "2020-01-01 02:02:02 +08:00";
2002+
let formatted = "2020-01-01 02:02:02.000000 +08:00";
20032003

20042004
assert_eq!(
20052005
query.to_string(MysqlQueryBuilder),

tests/mysql/query.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1125,7 +1125,7 @@ fn insert_4() {
11251125
.unwrap()
11261126
.into()])
11271127
.to_string(MysqlQueryBuilder),
1128-
"INSERT INTO `glyph` (`image`) VALUES ('1970-01-01 00:00:00')"
1128+
"INSERT INTO `glyph` (`image`) VALUES ('1970-01-01 00:00:00.000000')"
11291129
);
11301130
}
11311131

tests/postgres/query.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1164,7 +1164,7 @@ fn insert_4() {
11641164
.unwrap()
11651165
.into()])
11661166
.to_string(PostgresQueryBuilder),
1167-
"INSERT INTO \"glyph\" (\"image\") VALUES ('1970-01-01 00:00:00')"
1167+
"INSERT INTO \"glyph\" (\"image\") VALUES ('1970-01-01 00:00:00.000000')"
11681168
);
11691169
}
11701170

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)