1pub(crate) mod boxed;
15mod dsl_impls;
16pub use self::boxed::BoxedSelectStatement;#[diesel_derives::__diesel_public_if(
17 feature = "i-implement-a-third-party-backend-and-opt-into-breaking-changes"
18)]
19pub(crate) use self::boxed::BoxedSelectStatement;
20
21use super::distinct_clause::NoDistinctClause;
22use super::from_clause::AsQuerySource;
23use super::from_clause::FromClause;
24use super::group_by_clause::*;
25use super::limit_clause::NoLimitClause;
26use super::locking_clause::NoLockingClause;
27use super::offset_clause::NoOffsetClause;
28use super::order_clause::NoOrderClause;
29use super::select_clause::*;
30use super::where_clause::*;
31use super::NoFromClause;
32use super::{AstPass, Query, QueryFragment};
33use crate::backend::{sql_dialect, Backend};
34use crate::expression::subselect::ValidSubselect;
35use crate::expression::*;
36use crate::query_builder::having_clause::NoHavingClause;
37use crate::query_builder::limit_offset_clause::LimitOffsetClause;
38use crate::query_builder::{QueryId, SelectQuery};
39use crate::query_dsl::order_dsl::ValidOrderingForDistinct;
40use crate::query_source::joins::{AppendSelection, Inner, Join};
41use crate::query_source::*;
42use crate::result::QueryResult;
43
44#[doc = " This type represents a select query"]
#[doc = ""]
#[doc = " Using this type directly is only meaningful for custom backends"]
#[doc = " that need to provide a custom [`QueryFragment`] implementation"]
#[must_use =
"Queries are only executed when calling `load`, `get_result` or similar."]
#[non_exhaustive]
pub struct SelectStatement<From, Select = DefaultSelectClause<From>, Distinct
= NoDistinctClause, Where = NoWhereClause, Order = NoOrderClause,
LimitOffset = LimitOffsetClause<NoLimitClause, NoOffsetClause>, GroupBy =
NoGroupByClause, Having = NoHavingClause, Locking = NoLockingClause> {
#[doc = " The select clause of the query"]
pub select: Select,
#[doc = " The from clause of the query"]
pub from: From,
#[doc = " The distinct clause of the query"]
pub distinct: Distinct,
#[doc = " The where clause of the query"]
pub where_clause: Where,
#[doc = " The order clause of the query"]
pub order: Order,
#[doc = " The combined limit/offset clause of the query"]
pub limit_offset: LimitOffset,
#[doc = " The group by clause of the query"]
pub group_by: GroupBy,
#[doc = " The having clause of the query"]
pub having: Having,
#[doc = " The locking clause of the query"]
pub locking: Locking,
}#[diesel_derives::__diesel_public_if(
49 feature = "i-implement-a-third-party-backend-and-opt-into-breaking-changes",
50 public_fields(
51 select,
52 from,
53 distinct,
54 where_clause,
55 order,
56 limit_offset,
57 group_by,
58 having,
59 locking
60 )
61)]
62#[derive(#[automatically_derived]
impl<From: ::core::fmt::Debug, Select: ::core::fmt::Debug,
Distinct: ::core::fmt::Debug, Where: ::core::fmt::Debug,
Order: ::core::fmt::Debug, LimitOffset: ::core::fmt::Debug,
GroupBy: ::core::fmt::Debug, Having: ::core::fmt::Debug,
Locking: ::core::fmt::Debug> ::core::fmt::Debug for
SelectStatement<From, Select, Distinct, Where, Order, LimitOffset,
GroupBy, Having, Locking> {
#[inline]
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
let names: &'static _ =
&["select", "from", "distinct", "where_clause", "order",
"limit_offset", "group_by", "having", "locking"];
let values: &[&dyn ::core::fmt::Debug] =
&[&self.select, &self.from, &self.distinct, &self.where_clause,
&self.order, &self.limit_offset, &self.group_by,
&self.having, &&self.locking];
::core::fmt::Formatter::debug_struct_fields_finish(f,
"SelectStatement", names, values)
}
}Debug, #[automatically_derived]
impl<From: ::core::clone::Clone, Select: ::core::clone::Clone,
Distinct: ::core::clone::Clone, Where: ::core::clone::Clone,
Order: ::core::clone::Clone, LimitOffset: ::core::clone::Clone,
GroupBy: ::core::clone::Clone, Having: ::core::clone::Clone,
Locking: ::core::clone::Clone> ::core::clone::Clone for
SelectStatement<From, Select, Distinct, Where, Order, LimitOffset,
GroupBy, Having, Locking> {
#[inline]
fn clone(&self)
->
SelectStatement<From, Select, Distinct, Where, Order, LimitOffset,
GroupBy, Having, Locking> {
SelectStatement {
select: ::core::clone::Clone::clone(&self.select),
from: ::core::clone::Clone::clone(&self.from),
distinct: ::core::clone::Clone::clone(&self.distinct),
where_clause: ::core::clone::Clone::clone(&self.where_clause),
order: ::core::clone::Clone::clone(&self.order),
limit_offset: ::core::clone::Clone::clone(&self.limit_offset),
group_by: ::core::clone::Clone::clone(&self.group_by),
having: ::core::clone::Clone::clone(&self.having),
locking: ::core::clone::Clone::clone(&self.locking),
}
}
}Clone, #[automatically_derived]
impl<From: ::core::marker::Copy, Select: ::core::marker::Copy,
Distinct: ::core::marker::Copy, Where: ::core::marker::Copy,
Order: ::core::marker::Copy, LimitOffset: ::core::marker::Copy,
GroupBy: ::core::marker::Copy, Having: ::core::marker::Copy,
Locking: ::core::marker::Copy> ::core::marker::Copy for
SelectStatement<From, Select, Distinct, Where, Order, LimitOffset,
GroupBy, Having, Locking> {
}Copy, const _: () =
{
use diesel;
#[allow(non_camel_case_types)]
impl<From: diesel::query_builder::QueryId,
Select: diesel::query_builder::QueryId,
Distinct: diesel::query_builder::QueryId,
Where: diesel::query_builder::QueryId,
Order: diesel::query_builder::QueryId,
LimitOffset: diesel::query_builder::QueryId,
GroupBy: diesel::query_builder::QueryId,
Having: diesel::query_builder::QueryId,
Locking: diesel::query_builder::QueryId>
diesel::query_builder::QueryId for
SelectStatement<From, Select, Distinct, Where, Order, LimitOffset,
GroupBy, Having, Locking> {
type QueryId =
SelectStatement<<From as
diesel::query_builder::QueryId>::QueryId,
<Select as diesel::query_builder::QueryId>::QueryId,
<Distinct as diesel::query_builder::QueryId>::QueryId,
<Where as diesel::query_builder::QueryId>::QueryId,
<Order as diesel::query_builder::QueryId>::QueryId,
<LimitOffset as diesel::query_builder::QueryId>::QueryId,
<GroupBy as diesel::query_builder::QueryId>::QueryId,
<Having as diesel::query_builder::QueryId>::QueryId,
<Locking as diesel::query_builder::QueryId>::QueryId>;
const HAS_STATIC_QUERY_ID: bool =
<From as diesel::query_builder::QueryId>::HAS_STATIC_QUERY_ID
&&
<Select as
diesel::query_builder::QueryId>::HAS_STATIC_QUERY_ID &&
<Distinct as
diesel::query_builder::QueryId>::HAS_STATIC_QUERY_ID &&
<Where as
diesel::query_builder::QueryId>::HAS_STATIC_QUERY_ID &&
<Order as
diesel::query_builder::QueryId>::HAS_STATIC_QUERY_ID &&
<LimitOffset as
diesel::query_builder::QueryId>::HAS_STATIC_QUERY_ID &&
<GroupBy as
diesel::query_builder::QueryId>::HAS_STATIC_QUERY_ID &&
<Having as
diesel::query_builder::QueryId>::HAS_STATIC_QUERY_ID &&
<Locking as
diesel::query_builder::QueryId>::HAS_STATIC_QUERY_ID &&
true;
const IS_WINDOW_FUNCTION: bool =
<From as diesel::query_builder::QueryId>::IS_WINDOW_FUNCTION
||
<Select as
diesel::query_builder::QueryId>::IS_WINDOW_FUNCTION ||
<Distinct as
diesel::query_builder::QueryId>::IS_WINDOW_FUNCTION ||
<Where as
diesel::query_builder::QueryId>::IS_WINDOW_FUNCTION ||
<Order as
diesel::query_builder::QueryId>::IS_WINDOW_FUNCTION ||
<LimitOffset as
diesel::query_builder::QueryId>::IS_WINDOW_FUNCTION ||
<GroupBy as
diesel::query_builder::QueryId>::IS_WINDOW_FUNCTION ||
<Having as
diesel::query_builder::QueryId>::IS_WINDOW_FUNCTION ||
<Locking as
diesel::query_builder::QueryId>::IS_WINDOW_FUNCTION ||
false;
}
};QueryId)]
63#[must_use = "Queries are only executed when calling `load`, `get_result` or similar."]
64pub struct SelectStatement<
65 From,
66 Select = DefaultSelectClause<From>,
67 Distinct = NoDistinctClause,
68 Where = NoWhereClause,
69 Order = NoOrderClause,
70 LimitOffset = LimitOffsetClause<NoLimitClause, NoOffsetClause>,
71 GroupBy = NoGroupByClause,
72 Having = NoHavingClause,
73 Locking = NoLockingClause,
74> {
75 pub(crate) select: Select,
77 pub(crate) from: From,
79 pub(crate) distinct: Distinct,
81 pub(crate) where_clause: Where,
83 pub(crate) order: Order,
85 pub(crate) limit_offset: LimitOffset,
87 pub(crate) group_by: GroupBy,
89 pub(crate) having: Having,
91 pub(crate) locking: Locking,
93}
94
95pub trait SelectStatementAccessor {
99 type Select;
101 type From;
103 type Distinct;
105 type Where;
107 type Order;
109 type LimitOffset;
111 type GroupBy;
113 type Having;
115 type Locking;
117
118 fn select_clause(&self) -> &Self::Select;
120 #[allow(clippy::wrong_self_convention)] fn from_clause(&self) -> &Self::From;
123 fn distinct_clause(&self) -> &Self::Distinct;
125 fn where_clause(&self) -> &Self::Where;
127 fn order_clause(&self) -> &Self::Order;
129 fn limit_offset_clause(&self) -> &Self::LimitOffset;
131 fn group_by_clause(&self) -> &Self::GroupBy;
133 fn having_clause(&self) -> &Self::Having;
135 fn locking_clause(&self) -> &Self::Locking;
137}
138
139impl<F, S, D, W, O, LOf, G, H, LC> SelectStatementAccessor
140 for SelectStatement<F, S, D, W, O, LOf, G, H, LC>
141{
142 type Select = S;
143 type From = F;
144 type Distinct = D;
145 type Where = W;
146 type Order = O;
147 type LimitOffset = LOf;
148 type GroupBy = G;
149 type Having = H;
150 type Locking = LC;
151
152 fn select_clause(&self) -> &Self::Select {
153 &self.select
154 }
155
156 fn from_clause(&self) -> &Self::From {
157 &self.from
158 }
159
160 fn distinct_clause(&self) -> &Self::Distinct {
161 &self.distinct
162 }
163
164 fn where_clause(&self) -> &Self::Where {
165 &self.where_clause
166 }
167
168 fn order_clause(&self) -> &Self::Order {
169 &self.order
170 }
171
172 fn limit_offset_clause(&self) -> &Self::LimitOffset {
173 &self.limit_offset
174 }
175
176 fn group_by_clause(&self) -> &Self::GroupBy {
177 &self.group_by
178 }
179
180 fn having_clause(&self) -> &Self::Having {
181 &self.having
182 }
183
184 fn locking_clause(&self) -> &Self::Locking {
185 &self.locking
186 }
187}
188
189impl<F, S, D, W, O, LOf, G, H, LC> SelectStatement<F, S, D, W, O, LOf, G, H, LC> {
190 #[allow(clippy::too_many_arguments)]
191 pub(crate) fn new(
192 select: S,
193 from: F,
194 distinct: D,
195 where_clause: W,
196 order: O,
197 limit_offset: LOf,
198 group_by: G,
199 having: H,
200 locking: LC,
201 ) -> Self {
202 SelectStatement {
203 select,
204 from,
205 distinct,
206 where_clause,
207 order,
208 limit_offset,
209 group_by,
210 having,
211 locking,
212 }
213 }
214}
215
216impl<F: QuerySource> SelectStatement<FromClause<F>> {
217 #[doc(hidden)]
219 pub fn simple(from: F) -> Self {
220 let from = FromClause::new(from);
221 SelectStatement::new(
222 DefaultSelectClause::new(&from),
223 from,
224 NoDistinctClause,
225 NoWhereClause,
226 NoOrderClause,
227 LimitOffsetClause {
228 limit_clause: NoLimitClause,
229 offset_clause: NoOffsetClause,
230 },
231 NoGroupByClause,
232 NoHavingClause,
233 NoLockingClause,
234 )
235 }
236}
237
238impl<F, S, D, W, O, LOf, G, H, LC> Query for SelectStatement<F, S, D, W, O, LOf, G, H, LC>
239where
240 G: ValidGroupByClause,
241 S: SelectClauseExpression<F>,
242 S::Selection: ValidGrouping<G::Expressions>,
243 W: ValidWhereClause<F>,
244{
245 type SqlType = S::SelectClauseSqlType;
246}
247
248impl<F, S, D, W, O, LOf, G, H, LC> SelectQuery for SelectStatement<F, S, D, W, O, LOf, G, H, LC>
249where
250 S: SelectClauseExpression<F>,
251 O: ValidOrderingForDistinct<D>,
252{
253 type SqlType = S::SelectClauseSqlType;
254}
255
256impl<F, S, D, W, O, LOf, G, H, LC, DB> QueryFragment<DB>
257 for SelectStatement<F, S, D, W, O, LOf, G, H, LC>
258where
259 DB: Backend,
260 Self: QueryFragment<DB, DB::SelectStatementSyntax>,
261{
262 fn walk_ast<'b>(&'b self, pass: AstPass<'_, 'b, DB>) -> QueryResult<()> {
263 <Self as QueryFragment<DB, DB::SelectStatementSyntax>>::walk_ast(self, pass)
264 }
265}
266
267impl<F, S, D, W, O, LOf, G, H, LC, DB>
268 QueryFragment<DB, sql_dialect::select_statement_syntax::AnsiSqlSelectStatement>
269 for SelectStatement<F, S, D, W, O, LOf, G, H, LC>
270where
271 DB: Backend<
272 SelectStatementSyntax = sql_dialect::select_statement_syntax::AnsiSqlSelectStatement,
273 >,
274 S: QueryFragment<DB>,
275 F: QueryFragment<DB>,
276 D: QueryFragment<DB>,
277 W: QueryFragment<DB>,
278 O: QueryFragment<DB>,
279 LOf: QueryFragment<DB>,
280 G: QueryFragment<DB>,
281 H: QueryFragment<DB>,
282 LC: QueryFragment<DB>,
283{
284 fn walk_ast<'b>(&'b self, mut out: AstPass<'_, 'b, DB>) -> QueryResult<()> {
285 out.push_sql("SELECT ");
286 self.distinct.walk_ast(out.reborrow())?;
287 self.select.walk_ast(out.reborrow())?;
288 self.from.walk_ast(out.reborrow())?;
289 self.where_clause.walk_ast(out.reborrow())?;
290 self.group_by.walk_ast(out.reborrow())?;
291 self.having.walk_ast(out.reborrow())?;
292 self.order.walk_ast(out.reborrow())?;
293 self.limit_offset.walk_ast(out.reborrow())?;
294 self.locking.walk_ast(out.reborrow())?;
295 Ok(())
296 }
297}
298
299impl<S, F, D, W, O, LOf, G, H, LC, QS> ValidSubselect<QS>
300 for SelectStatement<FromClause<F>, S, D, W, O, LOf, G, H, LC>
301where
302 Self: SelectQuery,
303 F: QuerySource,
304 QS: QuerySource,
305 Join<F, QS, Inner>: QuerySource,
306 W: ValidWhereClause<FromClause<Join<F, QS, Inner>>>,
307{
308}
309
310impl<S, D, W, O, LOf, G, H, LC> ValidSubselect<NoFromClause>
311 for SelectStatement<NoFromClause, S, D, W, O, LOf, G, H, LC>
312where
313 Self: SelectQuery,
314 W: ValidWhereClause<NoFromClause>,
315{
316}
317
318impl<S, F, D, W, O, LOf, G, H, LC> ValidSubselect<NoFromClause>
319 for SelectStatement<FromClause<F>, S, D, W, O, LOf, G, H, LC>
320where
321 Self: SelectQuery,
322 F: QuerySource,
323 W: ValidWhereClause<FromClause<F>>,
324{
325}
326
327impl<S, D, W, O, LOf, G, H, LC, QS> ValidSubselect<QS>
328 for SelectStatement<NoFromClause, S, D, W, O, LOf, G, H, LC>
329where
330 Self: SelectQuery,
331 QS: QuerySource,
332 W: ValidWhereClause<NoFromClause>,
333{
334}
335
336impl<From, T> AppearsInFromClause<T> for SelectStatement<From>
339where
340 From: AsQuerySource,
341 From::QuerySource: AppearsInFromClause<T> + QuerySource,
342{
343 type Count = <From::QuerySource as AppearsInFromClause<T>>::Count;
344}
345
346impl<From> QuerySource for SelectStatement<From>
347where
348 From: AsQuerySource,
349 <From::QuerySource as QuerySource>::DefaultSelection: SelectableExpression<Self>,
350{
351 type FromClause = <From::QuerySource as QuerySource>::FromClause;
352 type DefaultSelection = <From::QuerySource as QuerySource>::DefaultSelection;
353
354 fn from_clause(&self) -> <From::QuerySource as QuerySource>::FromClause {
355 self.from.as_query_source().from_clause()
356 }
357
358 fn default_selection(&self) -> Self::DefaultSelection {
359 self.from.as_query_source().default_selection()
360 }
361}
362
363impl<From, Selection> AppendSelection<Selection> for SelectStatement<From>
364where
365 From: AsQuerySource,
366 From::QuerySource: AppendSelection<Selection>,
367{
368 type Output = <From::QuerySource as AppendSelection<Selection>>::Output;
369
370 fn append_selection(&self, selection: Selection) -> Self::Output {
371 self.from.as_query_source().append_selection(selection)
372 }
373}