From 60379bb4e928862e04641a3cc2d73e1e8965a83c Mon Sep 17 00:00:00 2001 From: Guilherme Stabach Salustiano Date: Thu, 22 Aug 2024 13:46:23 -0300 Subject: [PATCH 01/10] use .. on lower example --- diesel/src/pg/expression/functions.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/diesel/src/pg/expression/functions.rs b/diesel/src/pg/expression/functions.rs index 34161c7d490d..9bfe3c858194 100644 --- a/diesel/src/pg/expression/functions.rs +++ b/diesel/src/pg/expression/functions.rs @@ -95,7 +95,7 @@ define_sql_function! { /// let int = diesel::select(lower::>, _>(None::>)).get_result::>(connection)?; /// assert_eq!(None, int); /// - /// let int = diesel::select(lower::, _>(vec![(Bound::Included(5), Bound::Included(7))])).get_result::>(connection)?; + /// let int = diesel::select(lower::, _>(vec![5..7])).get_result::>(connection)?; /// assert_eq!(Some(5), int); /// # Ok(()) /// # } From f7a12b109450979a3f54d9f939e1612a81953326 Mon Sep 17 00:00:00 2001 From: Guilherme Stabach Salustiano Date: Thu, 22 Aug 2024 13:56:59 -0300 Subject: [PATCH 02/10] upper --- diesel/src/pg/expression/functions.rs | 37 +++++++++++---------------- 1 file changed, 15 insertions(+), 22 deletions(-) diff --git a/diesel/src/pg/expression/functions.rs b/diesel/src/pg/expression/functions.rs index 9bfe3c858194..274b1ea2b10c 100644 --- a/diesel/src/pg/expression/functions.rs +++ b/diesel/src/pg/expression/functions.rs @@ -114,39 +114,32 @@ define_sql_function! { /// ```rust /// # include!("../../doctest_setup.rs"); /// # - /// # table! { - /// # posts { - /// # id -> Integer, - /// # versions -> Range, - /// # } - /// # } - /// # /// # fn main() { /// # run_test().unwrap(); /// # } /// # /// # fn run_test() -> QueryResult<()> { - /// # use self::posts::dsl::*; + /// # use diesel::pg::sql_types::{Range, Multirange}; + /// # use diesel::dsl::upper; /// # use std::collections::Bound; - /// # let conn = &mut establish_connection(); - /// # diesel::sql_query("DROP TABLE IF EXISTS posts").execute(conn).unwrap(); - /// # diesel::sql_query("CREATE TABLE posts (id SERIAL PRIMARY KEY, versions INT4RANGE NOT NULL)").execute(conn).unwrap(); - /// # - /// use diesel::dsl::upper; - /// diesel::insert_into(posts) - /// .values(&[ - /// versions.eq((Bound::Included(5), Bound::Excluded(7))), - /// versions.eq((Bound::Included(5), Bound::Unbounded)) - /// ]).execute(conn)?; + /// # use diesel::sql_types::{Nullable, Integer, Array}; + /// # let connection = &mut establish_connection(); + /// let int = diesel::select(upper::, _>(1..2)).get_result::>(connection)?; + /// assert_eq!(Some(2), int); + /// + /// let int = diesel::select(upper::, _>(1..)).get_result::>(connection)?; + /// assert_eq!(None, int); + /// + /// let int = diesel::select(upper::>, _>(None::>)).get_result::>(connection)?; + /// assert_eq!(None, int); /// - /// let cool_posts = posts.select(upper(versions)) - /// .load::>(conn)?; - /// assert_eq!(vec![Some(7), None], cool_posts); + /// let int = diesel::select(upper::, _>(vec![5..7])).get_result::>(connection)?; + /// assert_eq!(Some(7), int); /// # Ok(()) /// # } /// ``` #[cfg(feature = "postgres_backend")] - fn upper(range: T) -> Nullable<::Inner>; + fn upper(range: R) -> Nullable; } define_sql_function! { From 2fcc9484e5aef24ec6d8e3c59fef18c202c491c4 Mon Sep 17 00:00:00 2001 From: Guilherme Stabach Salustiano Date: Thu, 22 Aug 2024 14:25:45 -0300 Subject: [PATCH 03/10] isempty (with null fix) --- diesel/src/pg/expression/functions.rs | 37 +++++++++++---------------- 1 file changed, 15 insertions(+), 22 deletions(-) diff --git a/diesel/src/pg/expression/functions.rs b/diesel/src/pg/expression/functions.rs index 274b1ea2b10c..62024a06b481 100644 --- a/diesel/src/pg/expression/functions.rs +++ b/diesel/src/pg/expression/functions.rs @@ -150,39 +150,32 @@ define_sql_function! { /// ```rust /// # include!("../../doctest_setup.rs"); /// # - /// # table! { - /// # posts { - /// # id -> Integer, - /// # versions -> Range, - /// # } - /// # } - /// # /// # fn main() { /// # run_test().unwrap(); /// # } /// # /// # fn run_test() -> QueryResult<()> { - /// # use self::posts::dsl::*; + /// # use diesel::pg::sql_types::{Range, Multirange}; + /// # use diesel::dsl::isempty; /// # use std::collections::Bound; - /// # let conn = &mut establish_connection(); - /// # diesel::sql_query("DROP TABLE IF EXISTS posts").execute(conn).unwrap(); - /// # diesel::sql_query("CREATE TABLE posts (id SERIAL PRIMARY KEY, versions INT4RANGE NOT NULL)").execute(conn).unwrap(); - /// # - /// use diesel::dsl::isempty; - /// diesel::insert_into(posts) - /// .values(&[ - /// versions.eq((Bound::Included(5), Bound::Excluded(7))), - /// versions.eq((Bound::Excluded(7), Bound::Excluded(7))), - /// ]).execute(conn)?; + /// # use diesel::sql_types::{Nullable, Integer, Array}; + /// # let connection = &mut establish_connection(); + /// let int = diesel::select(isempty::, _>(1..5)).get_result::>(connection)?; + /// assert_eq!(Some(false), int); /// - /// let cool_posts = posts.select(isempty(versions)) - /// .load::(conn)?; - /// assert_eq!(vec![false, true], cool_posts); + /// let int = diesel::select(isempty::, _>(1..1)).get_result::>(connection)?; + /// assert_eq!(Some(true), int); + /// + /// let int = diesel::select(isempty::>, _>(None::>)).get_result::>(connection)?; + /// assert_eq!(None, int); + /// + /// let int = diesel::select(isempty::, _>(vec![5..7])).get_result::>(connection)?; + /// assert_eq!(Some(false), int); /// # Ok(()) /// # } /// ``` #[cfg(feature = "postgres_backend")] - fn isempty(range: T) -> Bool; + fn isempty(range: R) -> Nullable; } define_sql_function! { From 538b789711408d7bb0a56618bc1ac46b6291df70 Mon Sep 17 00:00:00 2001 From: Guilherme Stabach Salustiano Date: Thu, 22 Aug 2024 14:33:20 -0300 Subject: [PATCH 04/10] lower_inc (with null fix) --- diesel/src/pg/expression/functions.rs | 37 +++++++++++---------------- 1 file changed, 15 insertions(+), 22 deletions(-) diff --git a/diesel/src/pg/expression/functions.rs b/diesel/src/pg/expression/functions.rs index 62024a06b481..792fa6ab56cc 100644 --- a/diesel/src/pg/expression/functions.rs +++ b/diesel/src/pg/expression/functions.rs @@ -186,39 +186,32 @@ define_sql_function! { /// ```rust /// # include!("../../doctest_setup.rs"); /// # - /// # table! { - /// # posts { - /// # id -> Integer, - /// # versions -> Range, - /// # } - /// # } - /// # /// # fn main() { /// # run_test().unwrap(); /// # } /// # /// # fn run_test() -> QueryResult<()> { - /// # use self::posts::dsl::*; + /// # use diesel::pg::sql_types::{Range, Multirange}; + /// # use diesel::dsl::lower_inc; /// # use std::collections::Bound; - /// # let conn = &mut establish_connection(); - /// # diesel::sql_query("DROP TABLE IF EXISTS posts").execute(conn).unwrap(); - /// # diesel::sql_query("CREATE TABLE posts (id SERIAL PRIMARY KEY, versions INT4RANGE NOT NULL)").execute(conn).unwrap(); - /// # - /// use diesel::dsl::lower_inc; - /// diesel::insert_into(posts) - /// .values(&[ - /// versions.eq((Bound::Included(5), Bound::Excluded(7))), - /// versions.eq((Bound::Excluded(7), Bound::Excluded(7))), - /// ]).execute(conn)?; + /// # use diesel::sql_types::{Nullable, Integer, Array}; + /// # let connection = &mut establish_connection(); + /// let int = diesel::select(lower_inc::, _>(1..5)).get_result::>(connection)?; + /// assert_eq!(Some(true), int); /// - /// let cool_posts = posts.select(lower_inc(versions)) - /// .load::(conn)?; - /// assert_eq!(vec![true, false], cool_posts); + /// let int = diesel::select(lower_inc::, _>(..5)).get_result::>(connection)?; + /// assert_eq!(Some(false), int); + /// + /// let int = diesel::select(lower_inc::>, _>(None::>)).get_result::>(connection)?; + /// assert_eq!(None, int); + /// + /// let int = diesel::select(lower_inc::, _>(vec![5..7])).get_result::>(connection)?; + /// assert_eq!(Some(true), int); /// # Ok(()) /// # } /// ``` #[cfg(feature = "postgres_backend")] - fn lower_inc(range: T) -> Bool; + fn lower_inc(range: R) -> Nullable; } define_sql_function! { From f5006f359dee2c185ec1fc39f989ebbac33fcbff Mon Sep 17 00:00:00 2001 From: Guilherme Stabach Salustiano Date: Thu, 22 Aug 2024 15:08:44 -0300 Subject: [PATCH 05/10] upper_inc (with null fix) --- diesel/src/pg/expression/functions.rs | 33 ++++++++++----------------- 1 file changed, 12 insertions(+), 21 deletions(-) diff --git a/diesel/src/pg/expression/functions.rs b/diesel/src/pg/expression/functions.rs index 792fa6ab56cc..962631ced588 100644 --- a/diesel/src/pg/expression/functions.rs +++ b/diesel/src/pg/expression/functions.rs @@ -222,38 +222,29 @@ define_sql_function! { /// ```rust /// # include!("../../doctest_setup.rs"); /// # - /// # table! { - /// # posts { - /// # id -> Integer, - /// # versions -> Range, - /// # } - /// # } - /// # /// # fn main() { /// # run_test().unwrap(); /// # } /// # /// # fn run_test() -> QueryResult<()> { - /// # use self::posts::dsl::*; + /// # use diesel::pg::sql_types::{Range, Multirange}; + /// # use diesel::dsl::upper_inc; /// # use std::collections::Bound; - /// # let conn = &mut establish_connection(); - /// # diesel::sql_query("DROP TABLE IF EXISTS posts").execute(conn).unwrap(); - /// # diesel::sql_query("CREATE TABLE posts (id SERIAL PRIMARY KEY, versions INT4RANGE NOT NULL)").execute(conn).unwrap(); - /// # - /// use diesel::dsl::upper_inc; - /// diesel::insert_into(posts) - /// .values(&[ - /// versions.eq((Bound::Included(5), Bound::Excluded(7))), - /// ]).execute(conn)?; + /// # use diesel::sql_types::{Nullable, Integer, Array}; + /// # let connection = &mut establish_connection(); + /// let int = diesel::select(upper_inc::, _>(1..5)).get_result::>(connection)?; + /// assert_eq!(Some(false), int); /// - /// let cool_posts = posts.select(upper_inc(versions)) - /// .load::(conn)?; - /// assert_eq!(vec![false], cool_posts); + /// let int = diesel::select(upper_inc::>, _>(None::>)).get_result::>(connection)?; + /// assert_eq!(None, int); + /// + /// let int = diesel::select(upper_inc::, _>(vec![5..7])).get_result::>(connection)?; + /// assert_eq!(Some(false), int); /// # Ok(()) /// # } /// ``` #[cfg(feature = "postgres_backend")] - fn upper_inc(range: T) -> Bool; + fn upper_inc(range: R) -> Nullable; } define_sql_function! { From e2f1bab9f06c665b539504a4642223a32a2c9672 Mon Sep 17 00:00:00 2001 From: Guilherme Stabach Salustiano Date: Thu, 22 Aug 2024 16:15:06 -0300 Subject: [PATCH 06/10] lower_inf (with null fix) --- diesel/src/pg/expression/functions.rs | 37 +++++++++++---------------- 1 file changed, 15 insertions(+), 22 deletions(-) diff --git a/diesel/src/pg/expression/functions.rs b/diesel/src/pg/expression/functions.rs index 962631ced588..a3086e9b3ab2 100644 --- a/diesel/src/pg/expression/functions.rs +++ b/diesel/src/pg/expression/functions.rs @@ -255,39 +255,32 @@ define_sql_function! { /// ```rust /// # include!("../../doctest_setup.rs"); /// # - /// # table! { - /// # posts { - /// # id -> Integer, - /// # versions -> Range, - /// # } - /// # } - /// # /// # fn main() { /// # run_test().unwrap(); /// # } /// # /// # fn run_test() -> QueryResult<()> { - /// # use self::posts::dsl::*; + /// # use diesel::pg::sql_types::{Range, Multirange}; + /// # use diesel::dsl::lower_inf; /// # use std::collections::Bound; - /// # let conn = &mut establish_connection(); - /// # diesel::sql_query("DROP TABLE IF EXISTS posts").execute(conn).unwrap(); - /// # diesel::sql_query("CREATE TABLE posts (id SERIAL PRIMARY KEY, versions INT4RANGE NOT NULL)").execute(conn).unwrap(); - /// # - /// use diesel::dsl::lower_inf; - /// diesel::insert_into(posts) - /// .values(&[ - /// versions.eq((Bound::Included(5), Bound::Excluded(7))), - /// versions.eq((Bound::Unbounded, Bound::Excluded(7))), - /// ]).execute(conn)?; + /// # use diesel::sql_types::{Nullable, Integer, Array}; + /// # let connection = &mut establish_connection(); + /// let int = diesel::select(lower_inf::, _>(1..5)).get_result::>(connection)?; + /// assert_eq!(Some(false), int); /// - /// let cool_posts = posts.select(lower_inf(versions)) - /// .load::(conn)?; - /// assert_eq!(vec![false, true], cool_posts); + /// let int = diesel::select(lower_inf::, _>(..5)).get_result::>(connection)?; + /// assert_eq!(Some(true), int); + /// + /// let int = diesel::select(lower_inf::>, _>(None::>)).get_result::>(connection)?; + /// assert_eq!(None, int); + /// + /// let int = diesel::select(lower_inf::, _>(vec![5..7])).get_result::>(connection)?; + /// assert_eq!(Some(false), int); /// # Ok(()) /// # } /// ``` #[cfg(feature = "postgres_backend")] - fn lower_inf(range: T) -> Bool; + fn lower_inf(range: R) -> Nullable; } define_sql_function! { From ba1aa634c8318c7e769d7945c967fd1effd5e90c Mon Sep 17 00:00:00 2001 From: Guilherme Stabach Salustiano Date: Thu, 22 Aug 2024 16:18:10 -0300 Subject: [PATCH 07/10] upper_inf (with null fix) --- diesel/src/pg/expression/functions.rs | 37 +++++++++++---------------- 1 file changed, 15 insertions(+), 22 deletions(-) diff --git a/diesel/src/pg/expression/functions.rs b/diesel/src/pg/expression/functions.rs index a3086e9b3ab2..599f945dd925 100644 --- a/diesel/src/pg/expression/functions.rs +++ b/diesel/src/pg/expression/functions.rs @@ -291,39 +291,32 @@ define_sql_function! { /// ```rust /// # include!("../../doctest_setup.rs"); /// # - /// # table! { - /// # posts { - /// # id -> Integer, - /// # versions -> Range, - /// # } - /// # } - /// # /// # fn main() { /// # run_test().unwrap(); /// # } /// # /// # fn run_test() -> QueryResult<()> { - /// # use self::posts::dsl::*; + /// # use diesel::pg::sql_types::{Range, Multirange}; + /// # use diesel::dsl::upper_inf; /// # use std::collections::Bound; - /// # let conn = &mut establish_connection(); - /// # diesel::sql_query("DROP TABLE IF EXISTS posts").execute(conn).unwrap(); - /// # diesel::sql_query("CREATE TABLE posts (id SERIAL PRIMARY KEY, versions INT4RANGE NOT NULL)").execute(conn).unwrap(); - /// # - /// use diesel::dsl::upper_inf; - /// diesel::insert_into(posts) - /// .values(&[ - /// versions.eq((Bound::Included(5), Bound::Excluded(7))), - /// versions.eq((Bound::Included(5),Bound::Unbounded)), - /// ]).execute(conn)?; + /// # use diesel::sql_types::{Nullable, Integer, Array}; + /// # let connection = &mut establish_connection(); + /// let int = diesel::select(upper_inf::, _>(1..5)).get_result::>(connection)?; + /// assert_eq!(Some(false), int); /// - /// let cool_posts = posts.select(upper_inf(versions)) - /// .load::(conn)?; - /// assert_eq!(vec![false, true], cool_posts); + /// let int = diesel::select(upper_inf::, _>(1..)).get_result::>(connection)?; + /// assert_eq!(Some(true), int); + /// + /// let int = diesel::select(upper_inf::>, _>(None::>)).get_result::>(connection)?; + /// assert_eq!(None, int); + /// + /// let int = diesel::select(upper_inf::, _>(vec![5..7])).get_result::>(connection)?; + /// assert_eq!(Some(false), int); /// # Ok(()) /// # } /// ``` #[cfg(feature = "postgres_backend")] - fn upper_inf(range: T) -> Bool; + fn upper_inf(range: R) -> Nullable; } define_sql_function! { From 0badc3b82338773a85cca38c3396a8c35f3c7cb8 Mon Sep 17 00:00:00 2001 From: Guilherme Stabach Salustiano Date: Thu, 22 Aug 2024 17:29:57 -0300 Subject: [PATCH 08/10] range_merge --- .../src/pg/expression/expression_methods.rs | 12 ++++-- diesel/src/pg/expression/functions.rs | 40 ++++++++----------- 2 files changed, 25 insertions(+), 27 deletions(-) diff --git a/diesel/src/pg/expression/expression_methods.rs b/diesel/src/pg/expression/expression_methods.rs index 67e8f73cb447..b176e7302b9d 100644 --- a/diesel/src/pg/expression/expression_methods.rs +++ b/diesel/src/pg/expression/expression_methods.rs @@ -3485,10 +3485,16 @@ pub(in crate::pg) mod private { message = "`{Self}` is neither `diesel::sql_types::Range<_>` nor `diesel::sql_types::Nullable>`", note = "try to provide an expression that produces one of the expected sql types" )] - pub trait RangeOrNullableRange {} + pub trait RangeOrNullableRange { + type Inner: SingleValue; + } - impl RangeOrNullableRange for Range {} - impl RangeOrNullableRange for Nullable> {} + impl RangeOrNullableRange for Range { + type Inner = ST; + } + impl RangeOrNullableRange for Nullable> { + type Inner = ST; + } /// Marker trait used to implement `PgRangeExpressionMethods` on the appropriate /// types. Once coherence takes associated types into account, we can remove diff --git a/diesel/src/pg/expression/functions.rs b/diesel/src/pg/expression/functions.rs index 599f945dd925..237f5bed59af 100644 --- a/diesel/src/pg/expression/functions.rs +++ b/diesel/src/pg/expression/functions.rs @@ -1,7 +1,7 @@ //! PostgreSQL specific functions use super::expression_methods::InetOrCidr; -use super::expression_methods::RangeHelper; +use super::expression_methods::RangeOrNullableRange; use crate::expression::functions::define_sql_function; use crate::pg::expression::expression_methods::ArrayOrNullableArray; use crate::pg::expression::expression_methods::MultirangeOrRangeMaybeNullable; @@ -327,40 +327,32 @@ define_sql_function! { /// ```rust /// # include!("../../doctest_setup.rs"); /// # - /// # table! { - /// # posts { - /// # id -> Integer, - /// # first_versions -> Range, - /// # second_versions -> Range, - /// # } - /// # } - /// # /// # fn main() { /// # run_test().unwrap(); /// # } /// # /// # fn run_test() -> QueryResult<()> { - /// # use self::posts::dsl::*; + /// # use diesel::pg::sql_types::{Range, Multirange}; + /// # use diesel::dsl::range_merge; /// # use std::collections::Bound; - /// # let conn = &mut establish_connection(); - /// # diesel::sql_query("DROP TABLE IF EXISTS posts").execute(conn).unwrap(); - /// # diesel::sql_query("CREATE TABLE posts (id SERIAL PRIMARY KEY, first_versions INT4RANGE NOT NULL, second_versions INT4RANGE NOT NULL)").execute(conn).unwrap(); - /// # - /// use diesel::dsl::range_merge; - /// diesel::insert_into(posts) - /// .values(( - /// first_versions.eq((Bound::Included(5), Bound::Excluded(7))), - /// second_versions.eq((Bound::Included(6),Bound::Unbounded)), - /// )).execute(conn)?; + /// # use diesel::sql_types::{Nullable, Integer, Array}; + /// # let connection = &mut establish_connection(); + /// let int = diesel::select(range_merge::, Range<_>, _, _>(5..11, 10..)).get_result::, Bound)>>(connection)?; + /// assert_eq!(Some((Bound::Included(5), Bound::Unbounded)), int); /// - /// let cool_posts = posts.select(range_merge(first_versions, second_versions)) - /// .load::<(Bound, Bound)>(conn)?; - /// assert_eq!(vec![(Bound::Included(5), Bound::Unbounded)], cool_posts); + /// let int = diesel::select(range_merge::, Range<_>, _, _>(1..3, 7..10)).get_result::, Bound)>>(connection)?; + /// assert_eq!(Some((Bound::Included(1), Bound::Excluded(10))), int); + /// + /// let int = diesel::select(range_merge::>, Nullable>, _, _>(None::>, 7..10)).get_result::, Bound)>>(connection)?; + /// assert_eq!(None, int); + /// + /// let int = diesel::select(range_merge::>, Nullable>, _, _>(1..3, None::>)).get_result::, Bound)>>(connection)?; + /// assert_eq!(None, int); /// # Ok(()) /// # } /// ``` #[cfg(feature = "postgres_backend")] - fn range_merge>(lhs: T1, rhs: T2) -> Range; + fn range_merge + SingleValue>(lhs: R1, rhs: R2) -> Nullable>; } define_sql_function! { From aed46db1ee4e849807c34105eb44b0da89df1359 Mon Sep 17 00:00:00 2001 From: Guilherme Stabach Salustiano Date: Thu, 22 Aug 2024 17:57:15 -0300 Subject: [PATCH 09/10] multirange_merge --- .../src/pg/expression/expression_methods.rs | 25 ++++++++++++-- diesel/src/pg/expression/functions.rs | 34 ++++++++++++++++++- 2 files changed, 56 insertions(+), 3 deletions(-) diff --git a/diesel/src/pg/expression/expression_methods.rs b/diesel/src/pg/expression/expression_methods.rs index b176e7302b9d..43ca9d0a243d 100644 --- a/diesel/src/pg/expression/expression_methods.rs +++ b/diesel/src/pg/expression/expression_methods.rs @@ -2,8 +2,8 @@ pub(in crate::pg) use self::private::{ ArrayOrNullableArray, InetOrCidr, JsonIndex, JsonOrNullableJsonOrJsonbOrNullableJsonb, - JsonRemoveIndex, JsonbOrNullableJsonb, MultirangeOrRangeMaybeNullable, RangeHelper, - RangeOrNullableRange, TextOrNullableText, + JsonRemoveIndex, JsonbOrNullableJsonb, MultirangeOrNullableMultirange, + MultirangeOrRangeMaybeNullable, RangeHelper, RangeOrNullableRange, TextOrNullableText, }; use super::date_and_time::{AtTimeZone, DateTimeLike}; use super::operators::*; @@ -3496,6 +3496,27 @@ pub(in crate::pg) mod private { type Inner = ST; } + /// Marker trait used to implement `PgRangeExpressionMethods` on the appropriate + /// types. Once coherence takes associated types into account, we can remove + /// this trait. + #[diagnostic::on_unimplemented( + message = "`{Self}` is neither `diesel::sql_types::Range<_>` nor `diesel::sql_types::Nullable>`", + note = "try to provide an expression that produces one of the expected sql types" + )] + pub trait MultirangeOrNullableMultirange { + type Inner: SingleValue; + type Range: SingleValue; + } + + impl MultirangeOrNullableMultirange for Multirange { + type Inner = ST; + type Range = Range; + } + impl MultirangeOrNullableMultirange for Nullable> { + type Inner = ST; + type Range = Nullable>; + } + /// Marker trait used to implement `PgRangeExpressionMethods` on the appropriate /// types. Once coherence takes associated types into account, we can remove /// this trait. diff --git a/diesel/src/pg/expression/functions.rs b/diesel/src/pg/expression/functions.rs index 237f5bed59af..a13b318d0ef0 100644 --- a/diesel/src/pg/expression/functions.rs +++ b/diesel/src/pg/expression/functions.rs @@ -1,10 +1,11 @@ //! PostgreSQL specific functions use super::expression_methods::InetOrCidr; -use super::expression_methods::RangeOrNullableRange; use crate::expression::functions::define_sql_function; use crate::pg::expression::expression_methods::ArrayOrNullableArray; +use crate::pg::expression::expression_methods::MultirangeOrNullableMultirange; use crate::pg::expression::expression_methods::MultirangeOrRangeMaybeNullable; +use crate::pg::expression::expression_methods::RangeOrNullableRange; use crate::sql_types::*; define_sql_function! { @@ -355,6 +356,37 @@ define_sql_function! { fn range_merge + SingleValue>(lhs: R1, rhs: R2) -> Nullable>; } +define_sql_function! { + /// Returns the smallest range which includes all ranges in the multirange + /// + /// # Example + /// + /// ```rust + /// # include!("../../doctest_setup.rs"); + /// # + /// # fn main() { + /// # run_test().unwrap(); + /// # } + /// # + /// # fn run_test() -> QueryResult<()> { + /// # use diesel::pg::sql_types::{Range, Multirange}; + /// # use diesel::dsl::multirange_merge; + /// # use std::collections::Bound; + /// # use diesel::sql_types::{Nullable, Integer, Array}; + /// # let connection = &mut establish_connection(); + /// let int = diesel::select(multirange_merge::, _>(vec![1..3, 7..10])).get_result::<(Bound, Bound)>(connection)?; + /// assert_eq!((Bound::Included(1), Bound::Excluded(10)), int); + /// + /// let int = diesel::select(multirange_merge::>, _>(None::>>)).get_result::, Bound)>>(connection)?; + /// assert_eq!(None, int); + /// # Ok(()) + /// # } + /// ``` + #[cfg(feature = "postgres_backend")] + #[sql_name = "range_merge"] + fn multirange_merge(multirange: R) -> R::Range; +} + define_sql_function! { /// Returns range of integer /// From 36a76a25e07718def9ddd85addb9414c09b07cce Mon Sep 17 00:00:00 2001 From: Guilherme Stabach Salustiano Date: Fri, 23 Aug 2024 10:37:28 -0300 Subject: [PATCH 10/10] add multirange autotype --- diesel/src/pg/expression/helper_types.rs | 5 +++++ diesel_derives/tests/auto_type.rs | 2 ++ 2 files changed, 7 insertions(+) diff --git a/diesel/src/pg/expression/helper_types.rs b/diesel/src/pg/expression/helper_types.rs index 0a582ba1ebfc..8a010be841d6 100644 --- a/diesel/src/pg/expression/helper_types.rs +++ b/diesel/src/pg/expression/helper_types.rs @@ -348,6 +348,11 @@ pub type upper_inf = super::functions::upper_inf, R>; #[cfg(feature = "postgres_backend")] pub type range_merge = super::functions::range_merge, SqlTypeOf, R1, R2>; +/// Return type of [`multirange_merge(multirange)`](super::functions::multirange_merge()) +#[allow(non_camel_case_types)] +#[cfg(feature = "postgres_backend")] +pub type multirange_merge = super::functions::multirange_merge, R>; + /// Return type of [`array_append(array, element)`](super::functions::array_append()) #[allow(non_camel_case_types)] #[cfg(feature = "postgres_backend")] diff --git a/diesel_derives/tests/auto_type.rs b/diesel_derives/tests/auto_type.rs index c556e2f10b32..2f924474e5ad 100644 --- a/diesel_derives/tests/auto_type.rs +++ b/diesel_derives/tests/auto_type.rs @@ -49,6 +49,7 @@ table! { blob -> Binary, timestamp -> Timestamp, range -> Range, + multirange -> Multirange, timestamptz -> Timestamptz, } } @@ -400,6 +401,7 @@ fn postgres_functions() -> _ { lower_inf(pg_extras::range), upper_inf(pg_extras::range), range_merge(pg_extras::range, pg_extras::range), + multirange_merge(pg_extras::multirange), int4range(users::id.nullable(), users::id.nullable(), bound), int8range(users::bigint.nullable(), users::bigint.nullable(), bound), numrange(users::numeric.nullable(), users::numeric.nullable(), bound),