diesel/pg/expression/
array.rs

1use crate::expression::{
2    AppearsOnTable, AsExpressionList, Expression, SelectableExpression, ValidGrouping,
3};
4use crate::pg::Pg;
5use crate::query_builder::{AstPass, QueryFragment, QueryId};
6use crate::sql_types;
7use std::marker::PhantomData;
8
9/// An ARRAY[...] literal.
10#[derive(Debug, Clone, Copy, QueryId)]
11pub struct ArrayLiteral<T, ST> {
12    elements: T,
13    _marker: PhantomData<ST>,
14}
15
16/// Creates an `ARRAY[...]` expression.
17///
18/// The argument should be a tuple of expressions which can be represented by the
19/// same SQL type.
20///
21/// # Examples
22///
23/// ```rust
24/// # include!("../../doctest_setup.rs");
25/// #
26/// # fn main() {
27/// #     run_test().unwrap();
28/// # }
29/// #
30/// # fn run_test() -> QueryResult<()> {
31/// #     use schema::users::dsl::*;
32/// #     use diesel::dsl::array;
33/// #     use diesel::sql_types::Integer;
34/// #     let connection = &mut establish_connection();
35/// let ints = diesel::select(array::<Integer, _>((1, 2)))
36///     .get_result::<Vec<i32>>(connection)?;
37/// assert_eq!(vec![1, 2], ints);
38///
39/// let ids = users.select(array((id, id * 2)))
40///     .get_results::<Vec<i32>>(connection)?;
41/// let expected = vec![
42///     vec![1, 2],
43///     vec![2, 4],
44/// ];
45/// assert_eq!(expected, ids);
46/// #     Ok(())
47/// # }
48/// ```
49#[cfg(feature = "postgres_backend")]
50pub fn array<ST, T>(elements: T) -> ArrayLiteral<T::Expression, ST>
51where
52    T: AsExpressionList<ST>,
53{
54    ArrayLiteral {
55        elements: elements.as_expression_list(),
56        _marker: PhantomData,
57    }
58}
59
60impl<T, ST> Expression for ArrayLiteral<T, ST>
61where
62    ST: 'static,
63    T: Expression,
64{
65    type SqlType = sql_types::Array<ST>;
66}
67
68impl<T, ST> QueryFragment<Pg> for ArrayLiteral<T, ST>
69where
70    T: QueryFragment<Pg>,
71{
72    fn walk_ast<'b>(&'b self, mut out: AstPass<'_, 'b, Pg>) -> crate::result::QueryResult<()> {
73        out.push_sql("ARRAY[");
74        QueryFragment::walk_ast(&self.elements, out.reborrow())?;
75        out.push_sql("]");
76        Ok(())
77    }
78}
79
80impl<T, ST, QS> SelectableExpression<QS> for ArrayLiteral<T, ST>
81where
82    T: SelectableExpression<QS>,
83    ArrayLiteral<T, ST>: AppearsOnTable<QS>,
84{
85}
86
87impl<T, ST, QS> AppearsOnTable<QS> for ArrayLiteral<T, ST>
88where
89    T: AppearsOnTable<QS>,
90    ArrayLiteral<T, ST>: Expression,
91{
92}
93
94impl<T, ST, GB> ValidGrouping<GB> for ArrayLiteral<T, ST>
95where
96    T: ValidGrouping<GB>,
97{
98    type IsAggregate = T::IsAggregate;
99}