Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

implement array_fill #4203

Merged
merged 3 commits into from
Aug 28, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
80 changes: 80 additions & 0 deletions diesel/src/pg/expression/functions.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1096,3 +1096,83 @@ define_sql_function! {
/// ```
fn array_length<Arr: ArrayOrNullableArray + SingleValue>(array: Arr, dimension: Integer) -> Nullable<Integer>;
}

#[cfg(feature = "postgres_backend")]
define_sql_function! {
/// Returns an array initialized with supplied value and dimensions,
/// optionally with lower bounds other than 1. This function omits the optional
/// lower bound argument. See [array_fill_with_lower_bound] for that.
///
/// # Example
///
/// ```rust
/// # include!("../../doctest_setup.rs");
/// #
/// # fn main(){
/// # run_test().unwrap();
/// # }
/// # fn run_test()->QueryResult<()>{
/// # use diesel::dsl::array_fill;
/// # use diesel::sql_types::{Nullable,Array,Integer,Text};
/// # let connection = &mut establish_connection();
///
/// let array = diesel::select(array_fill::<Integer,_,_>(2,vec![2]))
/// .get_result::<Vec<i32>>(connection)?;
/// assert_eq!(vec![2,2],array);
///
/// let array = diesel::select(array_fill::<Text,_,_>(String::from("abc"),vec![3]))
/// .get_result::<Vec<String>>(connection)?;
/// assert_eq!(vec!["abc","abc","abc"],array);
///
/// let array = diesel::select(array_fill::<Nullable<Integer>,_,_>(Some(4),vec![3]))
/// .get_result::<Vec<Option<i32>>>(connection)?;
/// assert_eq!(vec![Some(4),Some(4),Some(4)],array);
///
/// let array = diesel::select(array_fill::<Nullable<Integer>,_,_>(None::<i32>,vec![3]))
/// .get_result::<Vec<Option<i32>>>(connection)?;
/// assert_eq!(vec![None::<i32>,None::<i32>,None::<i32>],array);
/// # Ok(())
/// # }
///
fn array_fill<E:SingleValue>(value: E, dim: Array<Integer>) -> Array<E>;
}

#[cfg(feature = "postgres_backend")]
define_sql_function! {
/// Returns an array initialized with supplied value and dimensions,
/// with lower bounds other than 1
///
/// # Example
///
/// ```rust
/// # include!("../../doctest_setup.rs");
/// #
/// # fn main(){
/// # run_test().unwrap();
/// # }
/// # fn run_test()->QueryResult<()>{
/// # use diesel::dsl::array_fill_with_lower_bound;
/// # use diesel::sql_types::{Nullable,Array,Integer,Text};
/// # let connection = &mut establish_connection();
///
/// let array = diesel::select(array_fill_with_lower_bound::<Integer,_,_,_>(2,vec![2],vec![2]))
/// .get_result::<Vec<i32>>(connection)?;
/// assert_eq!(vec![2,2],array);
///
/// let array = diesel::select(array_fill_with_lower_bound::<Text,_,_,_>(String::from("abc"),vec![3],vec![3]))
/// .get_result::<Vec<String>>(connection)?;
/// assert_eq!(vec!["abc","abc","abc"],array);
///
/// let array = diesel::select(array_fill_with_lower_bound::<Nullable<Integer>,_,_,_>(Some(4),vec![3],vec![3]))
/// .get_result::<Vec<Option<i32>>>(connection)?;
/// assert_eq!(vec![Some(4),Some(4),Some(4)],array);
///
/// let array = diesel::select(array_fill_with_lower_bound::<Nullable<Integer>,_,_,_>(None::<i32>,vec![3],vec![3]))
/// .get_result::<Vec<Option<i32>>>(connection)?;
/// assert_eq!(vec![None::<i32>,None::<i32>,None::<i32>],array);
/// # Ok(())
/// # }
///
#[sql_name = "array_fill"]
fn array_fill_with_lower_bound<E:SingleValue>(value: E, dim: Array<Integer>, lower_bound: Array<Integer>) -> Array<E>;
}
11 changes: 11 additions & 0 deletions diesel/src/pg/expression/helper_types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -418,3 +418,14 @@ pub type array_cat<A, B> = super::functions::array_cat<SqlTypeOf<A>, A, B>;
#[allow(non_camel_case_types)]
#[cfg(feature = "postgres_backend")]
pub type array_length<A, D> = super::functions::array_length<SqlTypeOf<A>, A, D>;

/// Return type of [`array_fill(value,array)`](super::functions::array_fill())
#[allow(non_camel_case_types)]
#[cfg(feature = "postgres_backend")]
pub type array_fill<E, A> = super::functions::array_fill<SqlTypeOf<E>, E, A>;

/// Return type of [`array_fill_with_lower_bound(value,array,array)`](super::functions::array_fill_with_lower_bound())
#[allow(non_camel_case_types)]
#[cfg(feature = "postgres_backend")]
pub type array_fill_with_lower_bound<E, A1, A2> =
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not sure why i have to write generics here for arguments that have concrete types, but this works. An explanation would be appreciated!

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

define_sql_function! generates a function signature as follows for the array_fill function:

fn array_fill<E: SingleValue, value: T1, dim: T2>(value: T1, dim: T2) -> _
where T1: AsExpression<E>, 
            T2: AsExpression<Array<Integer>>

The additional AsExpression bounds enable diesel to accept a typed SQL expression (like for example a column) or a rust side value (for example 5) as argument in this position.

super::functions::array_fill_with_lower_bound<SqlTypeOf<E>, E, A1, A2>;
2 changes: 2 additions & 0 deletions diesel_derives/tests/auto_type.rs
Original file line number Diff line number Diff line change
Expand Up @@ -424,6 +424,8 @@ fn postgres_functions() -> _ {
trim_array(pg_extras::array, pg_extras::id),
array_cat(pg_extras::array, pg_extras::array),
array_length(pg_extras::array, 1_i32),
array_fill(pg_extras::id, pg_extras::array),
array_fill_with_lower_bound(pg_extras::id, pg_extras::array, pg_extras::array),
)
}

Expand Down
Loading