From ff8f58a8613417a818cf09efda32374276d1c82c Mon Sep 17 00:00:00 2001 From: Chris Tsang Date: Wed, 27 Nov 2024 10:03:22 +0000 Subject: [PATCH 01/17] Add example for SET NULL --- src/query/update.rs | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/src/query/update.rs b/src/query/update.rs index b267e813f..a514127b6 100644 --- a/src/query/update.rs +++ b/src/query/update.rs @@ -132,6 +132,24 @@ impl UpdateStatement { /// query.to_string(SqliteQueryBuilder), /// r#"UPDATE "glyph" SET "aspect" = 60 * 24 * 24, "image" = '24B0E11951B03B07F8300FD003983F03F0780060'"# /// ); + /// + /// let query = Query::update() + /// .table(Glyph::Table) + /// .value(Glyph::Aspect, Expr::value(Value::Int(None))) + /// .to_owned(); + /// + /// assert_eq!( + /// query.to_string(MysqlQueryBuilder), + /// r#"UPDATE `glyph` SET `aspect` = NULL"# + /// ); + /// assert_eq!( + /// query.to_string(PostgresQueryBuilder), + /// r#"UPDATE "glyph" SET "aspect" = NULL"# + /// ); + /// assert_eq!( + /// query.to_string(SqliteQueryBuilder), + /// r#"UPDATE "glyph" SET "aspect" = NULL"# + /// ); /// ``` pub fn value(&mut self, col: C, value: T) -> &mut Self where From ea1d9faf71bd78ee03056d99d55641bf36388fd4 Mon Sep 17 00:00:00 2001 From: Hamir Mahal Date: Thu, 28 Nov 2024 01:53:13 -0800 Subject: [PATCH 02/17] refactor: remove unnecessary string hashes (#815) * refactor: remove unnecessary string hashes * fix: formatting in `src/types.rs` * refactor: restore `#` for consistent formatting in specific spots * refactor: restore stylistic changes in `table.rs` --- src/token.rs | 10 +-- src/types.rs | 9 +-- tests/mysql/query.rs | 180 +++++++++++++++++++++--------------------- tests/mysql/table.rs | 4 +- tests/sqlite/query.rs | 2 +- 5 files changed, 101 insertions(+), 104 deletions(-) diff --git a/src/token.rs b/src/token.rs index 44ddf62b1..1d0ee9714 100644 --- a/src/token.rs +++ b/src/token.rs @@ -454,7 +454,7 @@ mod tests { #[test] fn test_9() { - let string = r#"[ab] "#; + let string = r"[ab] "; let tokenizer = Tokenizer::new(string); let tokens: Vec = tokenizer.iter().collect(); assert_eq!( @@ -491,7 +491,7 @@ mod tests { #[test] fn test_11() { - let string = r#" `a``b` "#; + let string = r" `a``b` "; let tokenizer = Tokenizer::new(string); let tokens: Vec = tokenizer.iter().collect(); assert_eq!( @@ -510,7 +510,7 @@ mod tests { #[test] fn test_12() { - let string = r#" 'a''b' "#; + let string = r" 'a''b' "; let tokenizer = Tokenizer::new(string); let tokens: Vec = tokenizer.iter().collect(); assert_eq!( @@ -529,7 +529,7 @@ mod tests { #[test] fn test_13() { - let string = r#"(?)"#; + let string = r"(?)"; let tokenizer = Tokenizer::new(string); let tokens: Vec = tokenizer.iter().collect(); assert_eq!( @@ -548,7 +548,7 @@ mod tests { #[test] fn test_14() { - let string = r#"($1 = $2)"#; + let string = r"($1 = $2)"; let tokenizer = Tokenizer::new(string); let tokens: Vec = tokenizer.iter().collect(); assert_eq!( diff --git a/src/types.rs b/src/types.rs index 0b2b834df..43d9a1dec 100644 --- a/src/types.rs +++ b/src/types.rs @@ -623,10 +623,7 @@ mod tests { .to_owned(); #[cfg(feature = "backend-mysql")] - assert_eq!( - query.to_string(MysqlQueryBuilder), - r#"SELECT `hello-World_`"# - ); + assert_eq!(query.to_string(MysqlQueryBuilder), r"SELECT `hello-World_`"); #[cfg(feature = "backend-postgres")] assert_eq!( query.to_string(PostgresQueryBuilder), @@ -644,7 +641,7 @@ mod tests { let query = Query::select().column(Alias::new("hel`lo")).to_owned(); #[cfg(feature = "backend-mysql")] - assert_eq!(query.to_string(MysqlQueryBuilder), r#"SELECT `hel``lo`"#); + assert_eq!(query.to_string(MysqlQueryBuilder), r"SELECT `hel``lo`"); #[cfg(feature = "backend-sqlite")] assert_eq!(query.to_string(SqliteQueryBuilder), r#"SELECT "hel`lo""#); @@ -659,7 +656,7 @@ mod tests { let query = Query::select().column(Alias::new("hel``lo")).to_owned(); #[cfg(feature = "backend-mysql")] - assert_eq!(query.to_string(MysqlQueryBuilder), r#"SELECT `hel````lo`"#); + assert_eq!(query.to_string(MysqlQueryBuilder), r"SELECT `hel````lo`"); #[cfg(feature = "backend-sqlite")] assert_eq!(query.to_string(SqliteQueryBuilder), r#"SELECT "hel``lo""#); diff --git a/tests/mysql/query.rs b/tests/mysql/query.rs index c0bb2e7dc..3e5344a50 100644 --- a/tests/mysql/query.rs +++ b/tests/mysql/query.rs @@ -518,7 +518,7 @@ fn select_35() { assert_eq!( statement, - r#"SELECT `id` FROM `glyph` WHERE `aspect` IS NULL"# + r"SELECT `id` FROM `glyph` WHERE `aspect` IS NULL" ); assert_eq!(values.0, vec![]); } @@ -533,7 +533,7 @@ fn select_36() { assert_eq!( statement, - r#"SELECT `id` FROM `glyph` WHERE `aspect` IS NULL"# + r"SELECT `id` FROM `glyph` WHERE `aspect` IS NULL" ); assert_eq!(values.0, vec![]); } @@ -546,7 +546,7 @@ fn select_37() { .cond_where(Cond::any().add(Cond::all()).add(Cond::any())) .build(MysqlQueryBuilder); - assert_eq!(statement, r#"SELECT `id` FROM `glyph` WHERE TRUE OR FALSE"#); + assert_eq!(statement, r"SELECT `id` FROM `glyph` WHERE TRUE OR FALSE"); assert_eq!(values.0, vec![]); } @@ -565,7 +565,7 @@ fn select_37a() { assert_eq!( statement, - r#"SELECT `id` FROM `glyph` WHERE NOT ((NOT TRUE) AND (NOT FALSE))"# + r"SELECT `id` FROM `glyph` WHERE NOT ((NOT TRUE) AND (NOT FALSE))" ); assert_eq!(values.0, vec![]); } @@ -584,7 +584,7 @@ fn select_38() { assert_eq!( statement, - r#"SELECT `id` FROM `glyph` WHERE `aspect` IS NULL OR `aspect` IS NOT NULL"# + r"SELECT `id` FROM `glyph` WHERE `aspect` IS NULL OR `aspect` IS NOT NULL" ); assert_eq!(values.0, vec![]); } @@ -603,7 +603,7 @@ fn select_39() { assert_eq!( statement, - r#"SELECT `id` FROM `glyph` WHERE `aspect` IS NULL AND `aspect` IS NOT NULL"# + r"SELECT `id` FROM `glyph` WHERE `aspect` IS NULL AND `aspect` IS NOT NULL" ); assert_eq!(values.0, vec![]); } @@ -624,7 +624,7 @@ fn select_40() { assert_eq!( statement, - r#"SELECT `id` FROM `glyph` WHERE `aspect` IS NULL OR (`aspect` IS NOT NULL AND `aspect` < 8)"# + r"SELECT `id` FROM `glyph` WHERE `aspect` IS NULL OR (`aspect` IS NOT NULL AND `aspect` < 8)" ); } @@ -656,7 +656,7 @@ fn select_42() { assert_eq!( statement, - r#"SELECT `id` FROM `glyph` WHERE `aspect` < 8 AND `aspect` IS NOT NULL"# + r"SELECT `id` FROM `glyph` WHERE `aspect` < 8 AND `aspect` IS NOT NULL" ); } @@ -685,7 +685,7 @@ fn select_44() { assert_eq!( statement, - r#"SELECT `id` FROM `glyph` WHERE NOT `aspect` < 8"# + r"SELECT `id` FROM `glyph` WHERE NOT `aspect` < 8" ); } @@ -704,7 +704,7 @@ fn select_45() { assert_eq!( statement, - r#"SELECT `id` FROM `glyph` WHERE NOT (`aspect` < 8 OR `aspect` IS NOT NULL)"# + r"SELECT `id` FROM `glyph` WHERE NOT (`aspect` < 8 OR `aspect` IS NOT NULL)" ); } @@ -722,7 +722,7 @@ fn select_46() { assert_eq!( statement, - r#"SELECT `id` FROM `glyph` WHERE NOT `aspect` < 8"# + r"SELECT `id` FROM `glyph` WHERE NOT `aspect` < 8" ); } @@ -741,7 +741,7 @@ fn select_47() { assert_eq!( statement, - r#"SELECT `id` FROM `glyph` WHERE NOT (`aspect` < 8 AND `aspect` IS NOT NULL)"# + r"SELECT `id` FROM `glyph` WHERE NOT (`aspect` < 8 AND `aspect` IS NOT NULL)" ); } @@ -760,7 +760,7 @@ fn select_48() { assert_eq!( statement, - r#"SELECT `id` FROM `glyph` WHERE (`aspect`, 100) < (8, 100)"# + r"SELECT `id` FROM `glyph` WHERE (`aspect`, 100) < (8, 100)" ); } @@ -782,7 +782,7 @@ fn select_48a() { assert_eq!( statement, - r#"SELECT `id` FROM `glyph` WHERE (`aspect`, '100') IN ((8, '100'))"# + r"SELECT `id` FROM `glyph` WHERE (`aspect`, '100') IN ((8, '100'))" ); } @@ -793,7 +793,7 @@ fn select_49() { .from(Char::Table) .to_string(MysqlQueryBuilder); - assert_eq!(statement, r#"SELECT * FROM `character`"#); + assert_eq!(statement, r"SELECT * FROM `character`"); } #[test] @@ -810,7 +810,7 @@ fn select_50() { assert_eq!( statement, - r#"SELECT `character`.*, `font`.`name` FROM `character` INNER JOIN `font` ON `character`.`font_id` = `font`.`id`"# + r"SELECT `character`.*, `font`.`name` FROM `character` INNER JOIN `font` ON `character`.`font_id` = `font`.`id`" ) } @@ -829,13 +829,13 @@ fn select_51() { ) .to_string(MysqlQueryBuilder), [ - r#"SELECT `aspect`"#, - r#"FROM `glyph`"#, - r#"WHERE IFNULL(`aspect`, 0) > 2"#, - r#"ORDER BY `image` IS NULL DESC,"#, - r#"`image` DESC,"#, - r#"`glyph`.`aspect` IS NULL ASC,"#, - r#"`glyph`.`aspect` ASC"#, + r"SELECT `aspect`", + r"FROM `glyph`", + r"WHERE IFNULL(`aspect`, 0) > 2", + r"ORDER BY `image` IS NULL DESC,", + r"`image` DESC,", + r"`glyph`.`aspect` IS NULL ASC,", + r"`glyph`.`aspect` ASC", ] .join(" ") ); @@ -854,13 +854,13 @@ fn select_52() { ]) .to_string(MysqlQueryBuilder), [ - r#"SELECT `aspect`"#, - r#"FROM `glyph`"#, - r#"WHERE IFNULL(`aspect`, 0) > 2"#, - r#"ORDER BY `id` IS NULL DESC,"#, - r#"`id` ASC,"#, - r#"`aspect` IS NULL ASC,"#, - r#"`aspect` DESC"#, + r"SELECT `aspect`", + r"FROM `glyph`", + r"WHERE IFNULL(`aspect`, 0) > 2", + r"ORDER BY `id` IS NULL DESC,", + r"`id` ASC,", + r"`aspect` IS NULL ASC,", + r"`aspect` DESC", ] .join(" ") ); @@ -883,13 +883,13 @@ fn select_53() { ]) .to_string(MysqlQueryBuilder), [ - r#"SELECT `aspect`"#, - r#"FROM `glyph`"#, - r#"WHERE IFNULL(`aspect`, 0) > 2"#, - r#"ORDER BY `glyph`.`id` IS NULL DESC,"#, - r#"`glyph`.`id` ASC,"#, - r#"`glyph`.`aspect` IS NULL ASC,"#, - r#"`glyph`.`aspect` DESC"#, + r"SELECT `aspect`", + r"FROM `glyph`", + r"WHERE IFNULL(`aspect`, 0) > 2", + r"ORDER BY `glyph`.`id` IS NULL DESC,", + r"`glyph`.`id` ASC,", + r"`glyph`.`aspect` IS NULL ASC,", + r"`glyph`.`aspect` DESC", ] .join(" ") ); @@ -906,7 +906,7 @@ fn select_54() { assert_eq!( statement, - r#"SELECT * FROM `character`, `font` WHERE `font`.`id` = `character`.`font_id`"# + r"SELECT * FROM `character`, `font` WHERE `font`.`id` = `character`.`font_id`" ); } @@ -924,16 +924,16 @@ fn select_55() { .order_by((Glyph::Table, Glyph::Aspect), Order::Asc) .to_string(MysqlQueryBuilder), [ - r#"SELECT `aspect`"#, - r#"FROM `glyph`"#, - r#"WHERE IFNULL(`aspect`, 0) > 2"#, - r#"ORDER BY CASE"#, - r#"WHEN `id`=4 THEN 0"#, - r#"WHEN `id`=5 THEN 1"#, - r#"WHEN `id`=1 THEN 2"#, - r#"WHEN `id`=3 THEN 3"#, - r#"ELSE 4 END,"#, - r#"`glyph`.`aspect` ASC"#, + r"SELECT `aspect`", + r"FROM `glyph`", + r"WHERE IFNULL(`aspect`, 0) > 2", + r"ORDER BY CASE", + r"WHEN `id`=4 THEN 0", + r"WHEN `id`=5 THEN 1", + r"WHEN `id`=1 THEN 2", + r"WHEN `id`=3 THEN 3", + r"ELSE 4 END,", + r"`glyph`.`aspect` ASC", ] .join(" ") ); @@ -953,15 +953,15 @@ fn select_56() { ) .to_string(MysqlQueryBuilder), [ - r#"SELECT `aspect`"#, - r#"FROM `glyph`"#, - r#"WHERE IFNULL(`aspect`, 0) > 2"#, - r#"ORDER BY `glyph`.`aspect` ASC,"#, - r#"CASE WHEN `id`=4 THEN 0"#, - r#"WHEN `id`=5 THEN 1"#, - r#"WHEN `id`=1 THEN 2"#, - r#"WHEN `id`=3 THEN 3"#, - r#"ELSE 4 END"#, + r"SELECT `aspect`", + r"FROM `glyph`", + r"WHERE IFNULL(`aspect`, 0) > 2", + r"ORDER BY `glyph`.`aspect` ASC,", + r"CASE WHEN `id`=4 THEN 0", + r"WHEN `id`=5 THEN 1", + r"WHEN `id`=1 THEN 2", + r"WHEN `id`=3 THEN 3", + r"ELSE 4 END", ] .join(" ") ); @@ -982,7 +982,7 @@ fn select_57() { assert_eq!( query.to_string(MysqlQueryBuilder), - r#"SELECT (CASE WHEN (`glyph`.`aspect` > 0) THEN 'positive' WHEN (`glyph`.`aspect` < 0) THEN 'negative' ELSE 'zero' END) AS `polarity` FROM `glyph`"# + r"SELECT (CASE WHEN (`glyph`.`aspect` > 0) THEN 'positive' WHEN (`glyph`.`aspect` < 0) THEN 'negative' ELSE 'zero' END) AS `polarity` FROM `glyph`" ); } @@ -1049,13 +1049,13 @@ fn select_61() { .offset(100) .to_string(MysqlQueryBuilder), [ - r#"SELECT `character`, `size_w`, `size_h`"#, - r#"FROM `character`"#, - r#"IGNORE INDEX FOR JOIN (`IDX_123456`)"#, - r#"USE INDEX FOR GROUP BY (`IDX_789ABC`)"#, - r#"FORCE INDEX FOR ORDER BY (`IDX_DEFGHI`)"#, - r#"LIMIT 10"#, - r#"OFFSET 100"#, + r"SELECT `character`, `size_w`, `size_h`", + r"FROM `character`", + r"IGNORE INDEX FOR JOIN (`IDX_123456`)", + r"USE INDEX FOR GROUP BY (`IDX_789ABC`)", + r"FORCE INDEX FOR ORDER BY (`IDX_DEFGHI`)", + r"LIMIT 10", + r"OFFSET 100", ] .join(" ") ); @@ -1203,7 +1203,7 @@ fn insert_from_select() { .unwrap() .to_owned() .to_string(MysqlQueryBuilder), - r#"INSERT INTO `glyph` (`aspect`, `image`) SELECT `aspect`, `image` FROM `glyph` WHERE `image` LIKE '%'"# + r"INSERT INTO `glyph` (`aspect`, `image`) SELECT `aspect`, `image` FROM `glyph` WHERE `image` LIKE '%'" ); } @@ -1225,9 +1225,9 @@ fn insert_on_conflict_0() { ) .to_string(MysqlQueryBuilder), [ - r#"INSERT INTO `glyph` (`aspect`, `image`)"#, - r#"VALUES ('04108048005887010020060000204E0180400400', 3.1415)"#, - r#"ON DUPLICATE KEY UPDATE `aspect` = VALUES(`aspect`), `image` = VALUES(`image`)"#, + r"INSERT INTO `glyph` (`aspect`, `image`)", + r"VALUES ('04108048005887010020060000204E0180400400', 3.1415)", + r"ON DUPLICATE KEY UPDATE `aspect` = VALUES(`aspect`), `image` = VALUES(`image`)", ] .join(" ") ); @@ -1251,9 +1251,9 @@ fn insert_on_conflict_1() { ) .to_string(MysqlQueryBuilder), [ - r#"INSERT INTO `glyph` (`aspect`, `image`)"#, - r#"VALUES ('04108048005887010020060000204E0180400400', 3.1415)"#, - r#"ON DUPLICATE KEY UPDATE `aspect` = VALUES(`aspect`)"#, + r"INSERT INTO `glyph` (`aspect`, `image`)", + r"VALUES ('04108048005887010020060000204E0180400400', 3.1415)", + r"ON DUPLICATE KEY UPDATE `aspect` = VALUES(`aspect`)", ] .join(" ") ); @@ -1277,9 +1277,9 @@ fn insert_on_conflict_2() { ) .to_string(MysqlQueryBuilder), [ - r#"INSERT INTO `glyph` (`aspect`, `image`)"#, - r#"VALUES ('04108048005887010020060000204E0180400400', 3.1415)"#, - r#"ON DUPLICATE KEY UPDATE `aspect` = VALUES(`aspect`), `image` = VALUES(`image`)"#, + r"INSERT INTO `glyph` (`aspect`, `image`)", + r"VALUES ('04108048005887010020060000204E0180400400', 3.1415)", + r"ON DUPLICATE KEY UPDATE `aspect` = VALUES(`aspect`), `image` = VALUES(`image`)", ] .join(" ") ); @@ -1306,9 +1306,9 @@ fn insert_on_conflict_3() { ) .to_string(MysqlQueryBuilder), [ - r#"INSERT INTO `glyph` (`aspect`, `image`)"#, - r#"VALUES ('04108048005887010020060000204E0180400400', 3.1415)"#, - r#"ON DUPLICATE KEY UPDATE `aspect` = '04108048005887010020060000204E0180400400', `image` = 3.1415"#, + r"INSERT INTO `glyph` (`aspect`, `image`)", + r"VALUES ('04108048005887010020060000204E0180400400', 3.1415)", + r"ON DUPLICATE KEY UPDATE `aspect` = '04108048005887010020060000204E0180400400', `image` = 3.1415", ] .join(" ") ); @@ -1332,9 +1332,9 @@ fn insert_on_conflict_4() { ) .to_string(MysqlQueryBuilder), [ - r#"INSERT INTO `glyph` (`aspect`, `image`)"#, - r#"VALUES ('04108048005887010020060000204E0180400400', 3.1415)"#, - r#"ON DUPLICATE KEY UPDATE `image` = 1 + 2"#, + r"INSERT INTO `glyph` (`aspect`, `image`)", + r"VALUES ('04108048005887010020060000204E0180400400', 3.1415)", + r"ON DUPLICATE KEY UPDATE `image` = 1 + 2", ] .join(" ") ); @@ -1359,9 +1359,9 @@ fn insert_on_conflict_5() { ) .to_string(MysqlQueryBuilder), [ - r#"INSERT INTO `glyph` (`aspect`, `image`)"#, - r#"VALUES ('04108048005887010020060000204E0180400400', 3.1415)"#, - r#"ON DUPLICATE KEY UPDATE `aspect` = '04108048005887010020060000204E0180400400', `image` = VALUES(`image`)"#, + r"INSERT INTO `glyph` (`aspect`, `image`)", + r"VALUES ('04108048005887010020060000204E0180400400', 3.1415)", + r"ON DUPLICATE KEY UPDATE `aspect` = '04108048005887010020060000204E0180400400', `image` = VALUES(`image`)", ] .join(" ") ); @@ -1386,9 +1386,9 @@ fn insert_on_conflict_6() { ) .to_string(MysqlQueryBuilder), [ - r#"INSERT INTO `glyph` (`aspect`, `image`)"#, - r#"VALUES ('04108048005887010020060000204E0180400400', 3.1415)"#, - r#"ON DUPLICATE KEY UPDATE `aspect` = VALUES(`aspect`), `image` = 1 + 2"#, + r"INSERT INTO `glyph` (`aspect`, `image`)", + r"VALUES ('04108048005887010020060000204E0180400400', 3.1415)", + r"ON DUPLICATE KEY UPDATE `aspect` = VALUES(`aspect`), `image` = 1 + 2", ] .join(" ") ); @@ -1409,9 +1409,9 @@ fn insert_on_conflict_do_nothing_on() { ) .to_string(MysqlQueryBuilder), [ - r#"INSERT INTO `glyph` (`aspect`, `image`)"#, - r#"VALUES ('abcd', 3.1415)"#, - r#"ON DUPLICATE KEY UPDATE `id` = `id`"#, + r"INSERT INTO `glyph` (`aspect`, `image`)", + r"VALUES ('abcd', 3.1415)", + r"ON DUPLICATE KEY UPDATE `id` = `id`", ] .join(" ") ); diff --git a/tests/mysql/table.rs b/tests/mysql/table.rs index 0d3a7d091..5f71f4e72 100644 --- a/tests/mysql/table.rs +++ b/tests/mysql/table.rs @@ -359,7 +359,7 @@ fn create_with_check_constraint() { .check(Expr::col(Glyph::Id).lt(20)) .check(Expr::col(Glyph::Id).ne(15)) .to_string(MysqlQueryBuilder), - r#"CREATE TABLE `glyph` ( `id` int NOT NULL CHECK (`id` > 10), CHECK (`id` < 20), CHECK (`id` <> 15) )"#, + r"CREATE TABLE `glyph` ( `id` int NOT NULL CHECK (`id` > 10), CHECK (`id` < 20), CHECK (`id` <> 15) )", ); } @@ -376,6 +376,6 @@ fn alter_with_check_constraint() { .check(Expr::col(Glyph::Aspect).gt(100)) ) .to_string(MysqlQueryBuilder), - r#"ALTER TABLE `glyph` ADD COLUMN `aspect` int NOT NULL DEFAULT 101 CHECK (`aspect` > 100)"#, + r"ALTER TABLE `glyph` ADD COLUMN `aspect` int NOT NULL DEFAULT 101 CHECK (`aspect` > 100)", ); } diff --git a/tests/sqlite/query.rs b/tests/sqlite/query.rs index 9a9c8fcf5..57f0a774c 100644 --- a/tests/sqlite/query.rs +++ b/tests/sqlite/query.rs @@ -434,7 +434,7 @@ fn select_31() { Query::select() .expr((1..10_i32).fold(Expr::value(0), |expr, i| { expr.add(i) })) .to_string(SqliteQueryBuilder), - r#"SELECT 0 + 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9"# + r"SELECT 0 + 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9" ); } From e9c167f27fcb4afd78cf00b71ab7bb731828c141 Mon Sep 17 00:00:00 2001 From: Chris Tsang Date: Thu, 28 Nov 2024 09:59:45 +0000 Subject: [PATCH 03/17] Update CHANGELOG.md --- CHANGELOG.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 6b843e018..1c7b931ab 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,12 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](http://keepachangelog.com/) and this project adheres to [Semantic Versioning](http://semver.org/). +## Pending + +### House keeping + +* Remove unnecessary string hashes https://github.com/SeaQL/sea-query/pull/815 + ## 0.32.0 - 2024-10-17 ### Releases From e980885bbc6a32dedfd3d58ea204c846de2e4eff Mon Sep 17 00:00:00 2001 From: Billy Chan Date: Thu, 28 Nov 2024 19:12:41 +0800 Subject: [PATCH 04/17] clippy --- src/backend/query_builder.rs | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/src/backend/query_builder.rs b/src/backend/query_builder.rs index 7bf29b552..f2465fe35 100644 --- a/src/backend/query_builder.rs +++ b/src/backend/query_builder.rs @@ -471,12 +471,9 @@ pub trait QueryBuilder: None => {} }; - match &select_expr.alias { - Some(alias) => { - write!(sql, " AS ").unwrap(); - alias.prepare(sql.as_writer(), self.quote()); - } - None => {} + if let Some(alias) = &select_expr.alias { + write!(sql, " AS ").unwrap(); + alias.prepare(sql.as_writer(), self.quote()); }; } From 73be1f76e7ae7639e1723d8452ff785316cd2d9d Mon Sep 17 00:00:00 2001 From: Chris Tsang Date: Sun, 1 Dec 2024 17:12:26 +0000 Subject: [PATCH 05/17] Add `Value::as_null` --- src/value.rs | 101 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 101 insertions(+) diff --git a/src/value.rs b/src/value.rs index 7d6236a25..40e293b2b 100644 --- a/src/value.rs +++ b/src/value.rs @@ -290,6 +290,107 @@ impl Value { { T::expect(self, msg) } + + /// Get the null variant of self + /// + /// ``` + /// use sea_query::Value; + /// + /// let v = Value::Int(Some(2)); + /// let n = v.as_null(); + /// + /// assert_eq!(n, Value::Int(None)); + /// ``` + pub fn as_null(&self) -> Self { + match self { + Self::Bool(_) => Self::Bool(None), + Self::TinyInt(_) => Self::TinyInt(None), + Self::SmallInt(_) => Self::SmallInt(None), + Self::Int(_) => Self::Int(None), + Self::BigInt(_) => Self::BigInt(None), + Self::TinyUnsigned(_) => Self::TinyUnsigned(None), + Self::SmallUnsigned(_) => Self::SmallUnsigned(None), + Self::Unsigned(_) => Self::Unsigned(None), + Self::BigUnsigned(_) => Self::BigUnsigned(None), + Self::Float(_) => Self::Float(None), + Self::Double(_) => Self::Double(None), + Self::String(_) => Self::String(None), + Self::Char(_) => Self::Char(None), + Self::Bytes(_) => Self::Bytes(None), + + #[cfg(feature = "with-json")] + #[cfg_attr(docsrs, doc(cfg(feature = "with-json")))] + Self::Json(_) => Self::Json(None), + + #[cfg(feature = "with-chrono")] + #[cfg_attr(docsrs, doc(cfg(feature = "with-chrono")))] + Self::ChronoDate(_) => Self::ChronoDate(None), + + #[cfg(feature = "with-chrono")] + #[cfg_attr(docsrs, doc(cfg(feature = "with-chrono")))] + Self::ChronoTime(_) => Self::ChronoTime(None), + + #[cfg(feature = "with-chrono")] + #[cfg_attr(docsrs, doc(cfg(feature = "with-chrono")))] + Self::ChronoDateTime(_) => Self::ChronoDateTime(None), + + #[cfg(feature = "with-chrono")] + #[cfg_attr(docsrs, doc(cfg(feature = "with-chrono")))] + Self::ChronoDateTimeUtc(_) => Self::ChronoDateTimeUtc(None), + + #[cfg(feature = "with-chrono")] + #[cfg_attr(docsrs, doc(cfg(feature = "with-chrono")))] + Self::ChronoDateTimeLocal(_) => Self::ChronoDateTimeLocal(None), + + #[cfg(feature = "with-chrono")] + #[cfg_attr(docsrs, doc(cfg(feature = "with-chrono")))] + Self::ChronoDateTimeWithTimeZone(_) => Self::ChronoDateTimeWithTimeZone(None), + + #[cfg(feature = "with-time")] + #[cfg_attr(docsrs, doc(cfg(feature = "with-time")))] + Self::TimeDate(_) => Self::TimeDate(None), + + #[cfg(feature = "with-time")] + #[cfg_attr(docsrs, doc(cfg(feature = "with-time")))] + Self::TimeTime(_) => Self::TimeTime(None), + + #[cfg(feature = "with-time")] + #[cfg_attr(docsrs, doc(cfg(feature = "with-time")))] + Self::TimeDateTime(_) => Self::TimeDateTime(None), + + #[cfg(feature = "with-time")] + #[cfg_attr(docsrs, doc(cfg(feature = "with-time")))] + Self::TimeDateTimeWithTimeZone(_) => Self::TimeDateTimeWithTimeZone(None), + + #[cfg(feature = "with-uuid")] + #[cfg_attr(docsrs, doc(cfg(feature = "with-uuid")))] + Self::Uuid(_) => Self::Uuid(None), + + #[cfg(feature = "with-rust_decimal")] + #[cfg_attr(docsrs, doc(cfg(feature = "with-rust_decimal")))] + Self::Decimal(_) => Self::Decimal(None), + + #[cfg(feature = "with-bigdecimal")] + #[cfg_attr(docsrs, doc(cfg(feature = "with-bigdecimal")))] + Self::BigDecimal(_) => Self::BigDecimal(None), + + #[cfg(feature = "postgres-array")] + #[cfg_attr(docsrs, doc(cfg(feature = "postgres-array")))] + Self::Array(ArrayType, _) => Self::Array(None), + + #[cfg(feature = "postgres-vector")] + #[cfg_attr(docsrs, doc(cfg(feature = "postgres-vector")))] + Self::Vector(_) => Self::Vector(None), + + #[cfg(feature = "with-ipnetwork")] + #[cfg_attr(docsrs, doc(cfg(feature = "with-ipnetwork")))] + Self::IpNetwork(_) => Self::IpNetwork(None), + + #[cfg(feature = "with-mac_address")] + #[cfg_attr(docsrs, doc(cfg(feature = "with-mac_address")))] + Self::MacAddress(_) => Self::MacAddress(None), + } + } } macro_rules! type_to_value { From 2d08a3e4a14aed6369cb55ec526fd5f164b6f15c Mon Sep 17 00:00:00 2001 From: Chris Tsang Date: Sun, 1 Dec 2024 17:28:39 +0000 Subject: [PATCH 06/17] Fixup --- src/value.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/value.rs b/src/value.rs index 40e293b2b..b1ef14229 100644 --- a/src/value.rs +++ b/src/value.rs @@ -376,7 +376,7 @@ impl Value { #[cfg(feature = "postgres-array")] #[cfg_attr(docsrs, doc(cfg(feature = "postgres-array")))] - Self::Array(ArrayType, _) => Self::Array(None), + Self::Array(ty, _) => Self::Array(ty.clone(), None), #[cfg(feature = "postgres-vector")] #[cfg_attr(docsrs, doc(cfg(feature = "postgres-vector")))] From 3715b2e0ae1d8ba84af90df04b0d6404b812c26f Mon Sep 17 00:00:00 2001 From: Chris Tsang Date: Sun, 1 Dec 2024 17:41:06 +0000 Subject: [PATCH 07/17] Changelog --- CHANGELOG.md | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 1c7b931ab..ed63cc553 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,7 +5,17 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](http://keepachangelog.com/) and this project adheres to [Semantic Versioning](http://semver.org/). -## Pending +## 0.32.1 - 2024-12-01 + +### Enhancements + +* Added `Value::as_null` +```rust +let v = Value::Int(Some(2)); +let n = v.as_null(); + +assert_eq!(n, Value::Int(None)); +``` ### House keeping From 81117a75b6376844b8ea3571ae500a56eaf14786 Mon Sep 17 00:00:00 2001 From: Billy Chan Date: Mon, 2 Dec 2024 01:45:46 +0800 Subject: [PATCH 08/17] Added `ValueType::enum_type_name()` to signify enum types (#836) --- src/value.rs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/value.rs b/src/value.rs index b1ef14229..7a7ac3001 100644 --- a/src/value.rs +++ b/src/value.rs @@ -237,6 +237,10 @@ pub trait ValueType: Sized { fn array_type() -> ArrayType; fn column_type() -> ColumnType; + + fn enum_type_name() -> Option<&'static str> { + None + } } #[derive(Debug)] From 67713263e4ddc4efc3629bce2425af6a50c481db Mon Sep 17 00:00:00 2001 From: Andrew Baxter Date: Mon, 2 Dec 2024 02:46:26 +0900 Subject: [PATCH 09/17] Fix #830, remove restriction on recursive CTE (#835) * Fix #830, remove incorrect restriction on recursive CTE I tested this with sqlite and the queries execute successfully. It's possible that there are other incorrect behaviors that can be pre-emptively caught, perhaps those could be added in a new PR later. * Add test --------- Co-authored-by: Andrew Baxter <> --- src/backend/query_builder.rs | 9 -------- tests/sqlite/query.rs | 44 ++++++++++++++++++++++++++++++++++++ 2 files changed, 44 insertions(+), 9 deletions(-) diff --git a/src/backend/query_builder.rs b/src/backend/query_builder.rs index f2465fe35..8d80a7d11 100644 --- a/src/backend/query_builder.rs +++ b/src/backend/query_builder.rs @@ -774,15 +774,6 @@ pub trait QueryBuilder: "Cannot build a with query that has no common table expression!" ); - if with_clause.recursive { - assert_eq!( - with_clause.cte_expressions.len(), - 1, - "Cannot build a recursive query with more than one common table! \ - A recursive with query must have a single cte inside it that has a union query of \ - two queries!" - ); - } for cte in &with_clause.cte_expressions { if !cte_first { write!(sql, ", ").unwrap(); diff --git a/tests/sqlite/query.rs b/tests/sqlite/query.rs index 57f0a774c..e248144b8 100644 --- a/tests/sqlite/query.rs +++ b/tests/sqlite/query.rs @@ -1792,3 +1792,47 @@ fn sub_query_with_fn() { r#"SELECT ARRAY((SELECT * FROM "character"))"# ); } + +#[test] +fn recursive_with_multiple_ctes() { + let sub_select1 = Query::select() + .column(Asterisk) + .from(Char::Table) + .to_owned(); + let sub_select1_name = SeaRc::new(Alias::new("sub1")); + let mut sub_select1_cte = CommonTableExpression::new(); + sub_select1_cte.table_name(sub_select1_name.clone()); + sub_select1_cte.column(SeaRc::new(Alias::new("a"))); + sub_select1_cte.query(sub_select1); + let sub_select2 = Query::select() + .column(Asterisk) + .from(Char::Table) + .to_owned(); + let sub_select2_name = SeaRc::new(Alias::new("sub2")); + let mut sub_select2_cte = CommonTableExpression::new(); + sub_select2_cte.table_name(sub_select2_name.clone()); + sub_select2_cte.column(SeaRc::new(Alias::new("b"))); + sub_select2_cte.query(sub_select2); + + let mut with = WithClause::new(); + with.recursive(true) + .cte(sub_select1_cte) + .cte(sub_select2_cte); + + let mut main_sel2 = Query::select(); + main_sel2 + .expr(Expr::col(Asterisk)) + .from(TableRef::Table(sub_select2_name)); + let mut main_sel1 = Query::select(); + main_sel1 + .expr(Expr::col(Asterisk)) + .from(TableRef::Table(sub_select1_name)) + .union(UnionType::All, main_sel2); + + let query = with.query(main_sel1); + + assert_eq!( + query.to_string(SqliteQueryBuilder), + r#"WITH RECURSIVE "sub1" ("a") AS (SELECT * FROM "character") , "sub2" ("b") AS (SELECT * FROM "character") SELECT * FROM "sub1" UNION ALL SELECT * FROM "sub2""# + ); +} From f914cc300aa89b67503d35390e63ef29caf04a4e Mon Sep 17 00:00:00 2001 From: xxchan Date: Mon, 2 Dec 2024 01:59:35 +0800 Subject: [PATCH 10/17] feat: add bitwise and/or operators (#841) Signed-off-by: xxchan --- src/backend/query_builder.rs | 2 ++ src/expr.rs | 66 ++++++++++++++++++++++++++++++++++++ src/types.rs | 2 ++ 3 files changed, 70 insertions(+) diff --git a/src/backend/query_builder.rs b/src/backend/query_builder.rs index 8d80a7d11..e6ee78119 100644 --- a/src/backend/query_builder.rs +++ b/src/backend/query_builder.rs @@ -589,6 +589,8 @@ pub trait QueryBuilder: BinOper::As => "AS", BinOper::Escape => "ESCAPE", BinOper::Custom(raw) => raw, + BinOper::BitAnd => "&", + BinOper::BitOr => "|", #[allow(unreachable_patterns)] _ => unimplemented!(), } diff --git a/src/expr.rs b/src/expr.rs index 06cf08ed8..70c3c7a73 100644 --- a/src/expr.rs +++ b/src/expr.rs @@ -1299,6 +1299,72 @@ pub trait ExprTrait: Sized { /// ); /// ``` fn unary(self, o: UnOper) -> SimpleExpr; + + /// Express a bitwise AND operation. + /// + /// # Examples + /// + /// ``` + /// use sea_query::{tests_cfg::*, *}; + /// + /// let query = Query::select() + /// .columns([Char::Character, Char::SizeW, Char::SizeH]) + /// .from(Char::Table) + /// .and_where(1.bit_and(1).eq(1)) + /// .to_owned(); + /// + /// assert_eq!( + /// query.to_string(MysqlQueryBuilder), + /// r#"SELECT `character`, `size_w`, `size_h` FROM `character` WHERE (1 & 1) = 1"# + /// ); + /// assert_eq!( + /// query.to_string(PostgresQueryBuilder), + /// r#"SELECT "character", "size_w", "size_h" FROM "character" WHERE (1 & 1) = 1"# + /// ); + /// assert_eq!( + /// query.to_string(SqliteQueryBuilder), + /// r#"SELECT "character", "size_w", "size_h" FROM "character" WHERE (1 & 1) = 1"# + /// ); + /// ``` + fn bit_and(self, right: R) -> SimpleExpr + where + R: Into, + { + ExprTrait::binary(self, BinOper::BitAnd, right) + } + + /// Express a bitwise OR operation. + /// + /// # Examples + /// + /// ``` + /// use sea_query::{tests_cfg::*, *}; + /// + /// let query = Query::select() + /// .columns([Char::Character, Char::SizeW, Char::SizeH]) + /// .from(Char::Table) + /// .and_where(1.bit_or(1).eq(1)) + /// .to_owned(); + /// + /// assert_eq!( + /// query.to_string(MysqlQueryBuilder), + /// r#"SELECT `character`, `size_w`, `size_h` FROM `character` WHERE (1 | 1) = 1"# + /// ); + /// assert_eq!( + /// query.to_string(PostgresQueryBuilder), + /// r#"SELECT "character", "size_w", "size_h" FROM "character" WHERE (1 | 1) = 1"# + /// ); + /// assert_eq!( + /// query.to_string(SqliteQueryBuilder), + /// r#"SELECT "character", "size_w", "size_h" FROM "character" WHERE (1 | 1) = 1"# + /// ); + /// ``` + fn bit_or(self, right: R) -> SimpleExpr + where + R: Into, + { + ExprTrait::binary(self, BinOper::BitOr, right) + } } /// This generic implementation covers all expression types, diff --git a/src/types.rs b/src/types.rs index 43d9a1dec..5ef4d1122 100644 --- a/src/types.rs +++ b/src/types.rs @@ -181,6 +181,8 @@ pub enum BinOper { Mul, Div, Mod, + BitAnd, + BitOr, LShift, RShift, As, From caee3b2495da99a0e6c3f4ab41b6a19622800200 Mon Sep 17 00:00:00 2001 From: Quentin Date: Sun, 1 Dec 2024 19:10:10 +0100 Subject: [PATCH 11/17] feat(function): Add support for GREATEST / LEAST function (#844) Signed-off-by: MATILLAT Quentin --- src/backend/query_builder.rs | 14 +++++++ src/backend/sqlite/query.rs | 8 ++++ src/func.rs | 72 ++++++++++++++++++++++++++++++++++++ 3 files changed, 94 insertions(+) diff --git a/src/backend/query_builder.rs b/src/backend/query_builder.rs index e6ee78119..41cac8626 100644 --- a/src/backend/query_builder.rs +++ b/src/backend/query_builder.rs @@ -666,6 +666,8 @@ pub trait QueryBuilder: Function::Coalesce => "COALESCE", Function::Count => "COUNT", Function::IfNull => self.if_null_function(), + Function::Greatest => self.greatest_function(), + Function::Least => self.least_function(), Function::CharLength => self.char_length_function(), Function::Cast => "CAST", Function::Lower => "LOWER", @@ -1459,6 +1461,18 @@ pub trait QueryBuilder: "IFNULL" } + #[doc(hidden)] + /// The name of the function that represents the "greatest" function. + fn greatest_function(&self) -> &str { + "GREATEST" + } + + #[doc(hidden)] + /// The name of the function that represents the "least" function. + fn least_function(&self) -> &str { + "LEAST" + } + #[doc(hidden)] /// The name of the function that returns the char length. fn char_length_function(&self) -> &str { diff --git a/src/backend/sqlite/query.rs b/src/backend/sqlite/query.rs index ece86a79b..0a062294d 100644 --- a/src/backend/sqlite/query.rs +++ b/src/backend/sqlite/query.rs @@ -76,6 +76,14 @@ impl QueryBuilder for SqliteQueryBuilder { sql.push_param(value.clone(), self as _); } + fn greatest_function(&self) -> &str { + "MAX" + } + + fn least_function(&self) -> &str { + "MIN" + } + fn char_length_function(&self) -> &str { "LENGTH" } diff --git a/src/func.rs b/src/func.rs index 957a3028f..7c8126464 100644 --- a/src/func.rs +++ b/src/func.rs @@ -15,6 +15,8 @@ pub enum Function { Abs, Count, IfNull, + Greatest, + Least, CharLength, Cast, Custom(DynIden), @@ -392,6 +394,76 @@ impl Func { FunctionCall::new(Function::CharLength).arg(expr) } + /// Call `GREATEST` function. + /// + /// # Examples + /// + /// ``` + /// use sea_query::{tests_cfg::*, *}; + /// + /// let query = Query::select() + /// .expr(Func::greatest([ + /// Expr::col(Char::SizeW).into(), + /// Expr::col(Char::SizeH).into(), + /// ])) + /// .from(Char::Table) + /// .to_owned(); + /// + /// assert_eq!( + /// query.to_string(MysqlQueryBuilder), + /// r#"SELECT GREATEST(`size_w`, `size_h`) FROM `character`"# + /// ); + /// assert_eq!( + /// query.to_string(PostgresQueryBuilder), + /// r#"SELECT GREATEST("size_w", "size_h") FROM "character""# + /// ); + /// assert_eq!( + /// query.to_string(SqliteQueryBuilder), + /// r#"SELECT MAX("size_w", "size_h") FROM "character""# + /// ); + /// ``` + pub fn greatest(args: I) -> FunctionCall + where + I: IntoIterator, + { + FunctionCall::new(Function::Greatest).args(args) + } + + /// Call `LEAST` function. + /// + /// # Examples + /// + /// ``` + /// use sea_query::{tests_cfg::*, *}; + /// + /// let query = Query::select() + /// .expr(Func::least([ + /// Expr::col(Char::SizeW).into(), + /// Expr::col(Char::SizeH).into(), + /// ])) + /// .from(Char::Table) + /// .to_owned(); + /// + /// assert_eq!( + /// query.to_string(MysqlQueryBuilder), + /// r#"SELECT LEAST(`size_w`, `size_h`) FROM `character`"# + /// ); + /// assert_eq!( + /// query.to_string(PostgresQueryBuilder), + /// r#"SELECT LEAST("size_w", "size_h") FROM "character""# + /// ); + /// assert_eq!( + /// query.to_string(SqliteQueryBuilder), + /// r#"SELECT MIN("size_w", "size_h") FROM "character""# + /// ); + /// ``` + pub fn least(args: I) -> FunctionCall + where + I: IntoIterator, + { + FunctionCall::new(Function::Least).args(args) + } + /// Call `IF NULL` function. /// /// # Examples From 8b9a5b79133f8077e2258a81295770233d1d2794 Mon Sep 17 00:00:00 2001 From: Chris Tsang Date: Sun, 1 Dec 2024 19:19:57 +0000 Subject: [PATCH 12/17] Changelog --- CHANGELOG.md | 19 ++++++++++++++++++- src/expr.rs | 9 +++++++++ 2 files changed, 27 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index ed63cc553..7fe817052 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,7 +7,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/). ## 0.32.1 - 2024-12-01 -### Enhancements +### New Features * Added `Value::as_null` ```rust @@ -16,6 +16,23 @@ let n = v.as_null(); assert_eq!(n, Value::Int(None)); ``` +* Added bitwise and/or operators (`bit_and`, `bit_or`) https://github.com/SeaQL/sea-query/pull/841 +```rust +let query = Query::select() + .expr(1.bit_and(2).eq(3)) + .to_owned(); + +assert_eq!( + query.to_string(PostgresQueryBuilder), + r#"SELECT (1 & 2) = 3"# +); +``` + +### Enhancements + +* Added `GREATEST` & `LEAST` function https://github.com/SeaQL/sea-query/pull/844 +* Added `ValueType::enum_type_name()` https://github.com/SeaQL/sea-query/pull/836 +* Removed "one common table" restriction on recursive CTE https://github.com/SeaQL/sea-query/pull/835 ### House keeping diff --git a/src/expr.rs b/src/expr.rs index 70c3c7a73..d78339718 100644 --- a/src/expr.rs +++ b/src/expr.rs @@ -1308,6 +1308,15 @@ pub trait ExprTrait: Sized { /// use sea_query::{tests_cfg::*, *}; /// /// let query = Query::select() + /// .expr(1.bit_and(2).eq(3)) + /// .to_owned(); + /// + /// assert_eq!( + /// query.to_string(PostgresQueryBuilder), + /// r#"SELECT (1 & 2) = 3"# + /// ); + /// + /// let query = Query::select() /// .columns([Char::Character, Char::SizeW, Char::SizeH]) /// .from(Char::Table) /// .and_where(1.bit_and(1).eq(1)) From 3882a01fdc9327cbfb9bc45bbeecee304b158a2a Mon Sep 17 00:00:00 2001 From: Chris Tsang Date: Sun, 1 Dec 2024 19:19:57 +0000 Subject: [PATCH 13/17] Changelog --- Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Cargo.toml b/Cargo.toml index 698cc4799..b5f076cb7 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -3,7 +3,7 @@ members = [".", "sea-query-derive"] [package] name = "sea-query" -version = "0.32.0" +version = "0.32.1" authors = [ "Chris Tsang ", "Billy Chan ", From 207cffd07392174fd4b8b4bc26a7a220e23541b0 Mon Sep 17 00:00:00 2001 From: Chris Tsang Date: Sun, 1 Dec 2024 19:25:00 +0000 Subject: [PATCH 14/17] Revert "Changelog" This reverts commit 3882a01fdc9327cbfb9bc45bbeecee304b158a2a. --- Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Cargo.toml b/Cargo.toml index b5f076cb7..698cc4799 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -3,7 +3,7 @@ members = [".", "sea-query-derive"] [package] name = "sea-query" -version = "0.32.1" +version = "0.32.0" authors = [ "Chris Tsang ", "Billy Chan ", From c5724eba9463f56ba19ebcb04edfb7e8c4e61fc7 Mon Sep 17 00:00:00 2001 From: Chris Tsang Date: Sun, 1 Dec 2024 19:25:10 +0000 Subject: [PATCH 15/17] 0.32.1 --- Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Cargo.toml b/Cargo.toml index 698cc4799..b5f076cb7 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -3,7 +3,7 @@ members = [".", "sea-query-derive"] [package] name = "sea-query" -version = "0.32.0" +version = "0.32.1" authors = [ "Chris Tsang ", "Billy Chan ", From 446e0e22f5b789ef8f794ac8cd66007b6a812839 Mon Sep 17 00:00:00 2001 From: Chris Tsang Date: Sun, 1 Dec 2024 19:33:58 +0000 Subject: [PATCH 16/17] fmt --- src/expr.rs | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/expr.rs b/src/expr.rs index d78339718..b6894c944 100644 --- a/src/expr.rs +++ b/src/expr.rs @@ -1307,9 +1307,7 @@ pub trait ExprTrait: Sized { /// ``` /// use sea_query::{tests_cfg::*, *}; /// - /// let query = Query::select() - /// .expr(1.bit_and(2).eq(3)) - /// .to_owned(); + /// let query = Query::select().expr(1.bit_and(2).eq(3)).to_owned(); /// /// assert_eq!( /// query.to_string(PostgresQueryBuilder), From 605ec4450332f28f1201f23f5a9a111e61081b32 Mon Sep 17 00:00:00 2001 From: Chris Tsang Date: Fri, 6 Dec 2024 00:17:11 +0000 Subject: [PATCH 17/17] Tweaks --- src/value.rs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/value.rs b/src/value.rs index 7a7ac3001..1499a3311 100644 --- a/src/value.rs +++ b/src/value.rs @@ -304,6 +304,9 @@ impl Value { /// let n = v.as_null(); /// /// assert_eq!(n, Value::Int(None)); + /// + /// // one liner: + /// assert_eq!(Into::::into(2.2).as_null(), Value::Double(None)); /// ``` pub fn as_null(&self) -> Self { match self {