1use crate::dsl;
2use crate::expression::array_comparison::{AsInExpression, InExpression};
3use crate::expression::subselect::Subselect;
4use crate::expression::{
5 AppearsOnTable, AsExpression, Expression, SelectableExpression, TypedExpressionType,
6 ValidGrouping,
7};
8use crate::pg::Pg;
9use crate::query_builder::combination_clause::CombinationClause;
10use crate::query_builder::{
11 AstPass, BoxedSelectStatement, QueryFragment, QueryId, SelectQuery, SelectStatement,
12};
13use crate::sql_types::{self, SqlType};
14use std::marker::PhantomData;
15
16pub fn array<ST, T>(elements: T) -> dsl::array<ST, T>
50where
51 T: IntoArrayExpression<ST>,
52 ST: SqlType + TypedExpressionType,
53{
54 elements.into_array_expression()
55}
56
57#[allow(non_camel_case_types)]
59#[cfg(feature = "postgres_backend")]
60pub type array<ST, T> = <T as IntoArrayExpression<ST>>::ArrayExpression;
61
62#[diagnostic::on_unimplemented(
66 message = "cannot convert `{Self}` into an expression of type `Array<{ST}>`",
67 note = "`the trait bound `{Self}: IntoArrayExpression<{ST}>` is not satisfied. \
68 (`AsExpressionList` is a deprecated trait alias for `IntoArrayExpression`)"
69)]
70pub trait IntoArrayExpression<ST: SqlType + TypedExpressionType> {
71 type ArrayExpression: Expression<SqlType = sql_types::Array<ST>>;
73
74 fn into_array_expression(self) -> Self::ArrayExpression;
77}
78
79impl<ST, T> IntoArrayExpression<ST> for T
81where
82 T: AsExpression<sql_types::Array<ST>>,
83 ST: SqlType + TypedExpressionType + 'static,
84{
85 type ArrayExpression = <T as AsExpression<sql_types::Array<ST>>>::Expression;
86
87 fn into_array_expression(self) -> Self::ArrayExpression {
88 <T as AsExpression<sql_types::Array<ST>>>::as_expression(self)
89 }
90}
91
92macro_rules! tuple_impls {
98 ($(
99 $Tuple:tt {
100 $(($idx:tt) -> $T:ident, $ST:ident, $TT:ident,)+
101 }
102 )+) => {
103 $(
104 impl<$($T,)+ ST> IntoArrayExpression<ST> for ($($T,)+) where
105 $($T: AsExpression<ST>,)+
106 ST: SqlType + TypedExpressionType,
107 {
108 type ArrayExpression = ArrayLiteral<($($T::Expression,)+), ST>;
109
110 fn into_array_expression(self) -> Self::ArrayExpression {
111 ArrayLiteral {
112 elements: ($(self.$idx.as_expression(),)+),
113 _marker: PhantomData,
114 }
115 }
116 }
117 )+
118 }
119}
120
121impl<T, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16,
T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29, T30, T31,
ST> IntoArrayExpression<ST> for
(T, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16,
T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29, T30, T31)
where T: AsExpression<ST>, T1: AsExpression<ST>, T2: AsExpression<ST>,
T3: AsExpression<ST>, T4: AsExpression<ST>, T5: AsExpression<ST>,
T6: AsExpression<ST>, T7: AsExpression<ST>, T8: AsExpression<ST>,
T9: AsExpression<ST>, T10: AsExpression<ST>, T11: AsExpression<ST>,
T12: AsExpression<ST>, T13: AsExpression<ST>, T14: AsExpression<ST>,
T15: AsExpression<ST>, T16: AsExpression<ST>, T17: AsExpression<ST>,
T18: AsExpression<ST>, T19: AsExpression<ST>, T20: AsExpression<ST>,
T21: AsExpression<ST>, T22: AsExpression<ST>, T23: AsExpression<ST>,
T24: AsExpression<ST>, T25: AsExpression<ST>, T26: AsExpression<ST>,
T27: AsExpression<ST>, T28: AsExpression<ST>, T29: AsExpression<ST>,
T30: AsExpression<ST>, T31: AsExpression<ST>, ST: SqlType +
TypedExpressionType {
type ArrayExpression =
ArrayLiteral<(T::Expression, T1::Expression, T2::Expression,
T3::Expression, T4::Expression, T5::Expression, T6::Expression,
T7::Expression, T8::Expression, T9::Expression, T10::Expression,
T11::Expression, T12::Expression, T13::Expression, T14::Expression,
T15::Expression, T16::Expression, T17::Expression, T18::Expression,
T19::Expression, T20::Expression, T21::Expression, T22::Expression,
T23::Expression, T24::Expression, T25::Expression, T26::Expression,
T27::Expression, T28::Expression, T29::Expression, T30::Expression,
T31::Expression), ST>;
fn into_array_expression(self) -> Self::ArrayExpression {
ArrayLiteral {
elements: (self.0.as_expression(), self.1.as_expression(),
self.2.as_expression(), self.3.as_expression(),
self.4.as_expression(), self.5.as_expression(),
self.6.as_expression(), self.7.as_expression(),
self.8.as_expression(), self.9.as_expression(),
self.10.as_expression(), self.11.as_expression(),
self.12.as_expression(), self.13.as_expression(),
self.14.as_expression(), self.15.as_expression(),
self.16.as_expression(), self.17.as_expression(),
self.18.as_expression(), self.19.as_expression(),
self.20.as_expression(), self.21.as_expression(),
self.22.as_expression(), self.23.as_expression(),
self.24.as_expression(), self.25.as_expression(),
self.26.as_expression(), self.27.as_expression(),
self.28.as_expression(), self.29.as_expression(),
self.30.as_expression(), self.31.as_expression()),
_marker: PhantomData,
}
}
}diesel_derives::__diesel_for_each_tuple!(tuple_impls);
122
123)]
125pub struct ArrayLiteral<T, ST> {
126 elements: T,
127 _marker: PhantomData<ST>,
128}
129
130impl<T, ST> Expression for ArrayLiteral<T, ST>
131where
132 ST: 'static,
133 T: Expression,
134{
135 type SqlType = sql_types::Array<ST>;
136}
137
138impl<T, ST> QueryFragment<Pg> for ArrayLiteral<T, ST>
139where
140 T: QueryFragment<Pg>,
141{
142 fn walk_ast<'b>(&'b self, mut out: AstPass<'_, 'b, Pg>) -> crate::result::QueryResult<()> {
143 out.push_sql("ARRAY[");
144 QueryFragment::walk_ast(&self.elements, out.reborrow())?;
145 out.push_sql("]");
146 Ok(())
147 }
148}
149
150impl<T, ST, QS> SelectableExpression<QS> for ArrayLiteral<T, ST>
151where
152 T: SelectableExpression<QS>,
153 ArrayLiteral<T, ST>: AppearsOnTable<QS>,
154{
155}
156
157impl<T, ST, QS> AppearsOnTable<QS> for ArrayLiteral<T, ST>
158where
159 T: AppearsOnTable<QS>,
160 ArrayLiteral<T, ST>: Expression,
161{
162}
163
164impl<T, ST, GB> ValidGrouping<GB> for ArrayLiteral<T, ST>
165where
166 T: ValidGrouping<GB>,
167{
168 type IsAggregate = T::IsAggregate;
169}
170
171impl<T, ST> InExpression for ArrayLiteral<T, ST>
172where
173 Self: Expression<SqlType = sql_types::Array<ST>>,
174 ST: SqlType,
175{
176 type SqlType = ST;
177
178 fn is_empty(&self) -> bool {
179 false
180 }
181
182 fn is_array(&self) -> bool {
183 false
185 }
186}
187
188impl<T, ST> AsInExpression<ST> for ArrayLiteral<T, ST>
189where
190 Self: Expression<SqlType = sql_types::Array<ST>>,
191 ST: SqlType,
192{
193 type InExpression = Self;
194
195 fn as_in_expression(self) -> Self::InExpression {
196 self
197 }
198}
199
200impl<ST, F, S, D, W, O, LOf, G, H, LC> IntoArrayExpression<ST>
201 for SelectStatement<F, S, D, W, O, LOf, G, H, LC>
202where
203 ST: SqlType + TypedExpressionType,
204 ArraySubselect<Self, ST>: Expression<SqlType = sql_types::Array<ST>>,
205 Self: SelectQuery<SqlType = ST>,
206{
207 type ArrayExpression = ArraySubselect<Self, ST>;
208
209 fn into_array_expression(self) -> Self::ArrayExpression {
210 ArraySubselect::new(self)
211 }
212}
213
214impl<'a, ST, QS, DB, GB> IntoArrayExpression<ST> for BoxedSelectStatement<'a, ST, QS, DB, GB>
215where
216 ST: SqlType + TypedExpressionType,
217 ArraySubselect<BoxedSelectStatement<'a, ST, QS, DB, GB>, ST>:
218 Expression<SqlType = sql_types::Array<ST>>,
219{
220 type ArrayExpression = ArraySubselect<Self, ST>;
221
222 fn into_array_expression(self) -> Self::ArrayExpression {
223 ArraySubselect::new(self)
224 }
225}
226
227impl<ST, Combinator, Rule, Source, Rhs> IntoArrayExpression<ST>
228 for CombinationClause<Combinator, Rule, Source, Rhs>
229where
230 ST: SqlType + TypedExpressionType,
231 Self: SelectQuery<SqlType = ST>,
232 ArraySubselect<Self, ST>: Expression<SqlType = sql_types::Array<ST>>,
233{
234 type ArrayExpression = ArraySubselect<Self, ST>;
235
236 fn into_array_expression(self) -> Self::ArrayExpression {
237 ArraySubselect::new(self)
238 }
239}
240
241)]
243pub struct ArraySubselect<T, ST> {
244 subquery: Subselect<T, ST>,
245}
246
247impl<T, ST> ArraySubselect<T, ST> {
248 pub(crate) fn new(elements: T) -> Self {
249 Self {
250 subquery: Subselect::new(elements),
251 }
252 }
253}
254
255impl<T, ST> Expression for ArraySubselect<T, ST>
256where
257 ST: 'static,
258 Subselect<T, ST>: Expression<SqlType = ST>,
259{
260 type SqlType = sql_types::Array<ST>;
261}
262
263impl<T, ST> QueryFragment<Pg> for ArraySubselect<T, ST>
264where
265 Subselect<T, ST>: QueryFragment<Pg>,
266{
267 fn walk_ast<'b>(&'b self, mut out: AstPass<'_, 'b, Pg>) -> crate::result::QueryResult<()> {
268 out.push_sql("ARRAY(");
269 QueryFragment::walk_ast(&self.subquery, out.reborrow())?;
270 out.push_sql(")");
271 Ok(())
272 }
273}
274
275impl<T, ST, QS> SelectableExpression<QS> for ArraySubselect<T, ST>
276where
277 Subselect<T, ST>: SelectableExpression<QS>,
278 ArraySubselect<T, ST>: AppearsOnTable<QS>,
279{
280}
281
282impl<T, ST, QS> AppearsOnTable<QS> for ArraySubselect<T, ST>
283where
284 Subselect<T, ST>: AppearsOnTable<QS>,
285 ArraySubselect<T, ST>: Expression,
286{
287}
288
289impl<T, ST, GB> ValidGrouping<GB> for ArraySubselect<T, ST>
290where
291 Subselect<T, ST>: ValidGrouping<GB>,
292{
293 type IsAggregate = <Subselect<T, ST> as ValidGrouping<GB>>::IsAggregate;
294}
295
296impl<T, ST> InExpression for ArraySubselect<T, ST>
297where
298 Self: Expression<SqlType = sql_types::Array<ST>>,
299 ST: SqlType,
300{
301 type SqlType = ST;
302
303 fn is_empty(&self) -> bool {
304 false
305 }
306
307 fn is_array(&self) -> bool {
308 false
310 }
311}
312
313impl<T, ST> AsInExpression<ST> for ArraySubselect<T, ST>
314where
315 Self: Expression<SqlType = sql_types::Array<ST>>,
316 ST: SqlType,
317{
318 type InExpression = Self;
319
320 fn as_in_expression(self) -> Self::InExpression {
321 self
322 }
323}