From caee3b2495da99a0e6c3f4ab41b6a19622800200 Mon Sep 17 00:00:00 2001 From: Quentin Date: Sun, 1 Dec 2024 19:10:10 +0100 Subject: [PATCH] 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