1pub(crate) mod boxed;
15pub(crate) mod boxed_clone;
16mod dsl_impls;
17pub use self::boxed::BoxedSelectStatement;#[diesel_derives::__diesel_public_if(
18 feature = "i-implement-a-third-party-backend-and-opt-into-breaking-changes"
19)]
20pub(crate) use self::boxed::BoxedSelectStatement;
21pub use self::boxed_clone::BoxedCloneSelectStatement;#[diesel_derives::__diesel_public_if(
22 feature = "i-implement-a-third-party-backend-and-opt-into-breaking-changes"
23)]
24pub(crate) use self::boxed_clone::BoxedCloneSelectStatement;
25
26use super::NoFromClause;
27use super::distinct_clause::NoDistinctClause;
28use super::from_clause::AsQuerySource;
29use super::from_clause::FromClause;
30use super::group_by_clause::*;
31use super::limit_clause::NoLimitClause;
32use super::locking_clause::NoLockingClause;
33use super::offset_clause::NoOffsetClause;
34use super::order_clause::NoOrderClause;
35use super::select_clause::*;
36use super::where_clause::*;
37use super::{AstPass, Query, QueryFragment};
38use crate::backend::{Backend, sql_dialect};
39use crate::expression::subselect::ValidSubselect;
40use crate::expression::*;
41use crate::query_builder::having_clause::NoHavingClause;
42use crate::query_builder::limit_offset_clause::LimitOffsetClause;
43use crate::query_builder::{QueryId, SelectQuery};
44use crate::query_dsl::order_dsl::ValidOrderingForDistinct;
45use crate::query_source::joins::{AppendSelection, Inner, Join};
46use crate::query_source::*;
47use crate::result::QueryResult;
48
49#[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(
54 feature = "i-implement-a-third-party-backend-and-opt-into-breaking-changes",
55 public_fields(
56 select,
57 from,
58 distinct,
59 where_clause,
60 order,
61 limit_offset,
62 group_by,
63 having,
64 locking
65 )
66)]
67#[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)]
68#[must_use = "Queries are only executed when calling `load`, `get_result` or similar."]
69pub struct SelectStatement<
70 From,
71 Select = DefaultSelectClause<From>,
72 Distinct = NoDistinctClause,
73 Where = NoWhereClause,
74 Order = NoOrderClause,
75 LimitOffset = LimitOffsetClause<NoLimitClause, NoOffsetClause>,
76 GroupBy = NoGroupByClause,
77 Having = NoHavingClause,
78 Locking = NoLockingClause,
79> {
80 pub(crate) select: Select,
82 pub(crate) from: From,
84 pub(crate) distinct: Distinct,
86 pub(crate) where_clause: Where,
88 pub(crate) order: Order,
90 pub(crate) limit_offset: LimitOffset,
92 pub(crate) group_by: GroupBy,
94 pub(crate) having: Having,
96 pub(crate) locking: Locking,
98}
99
100pub trait SelectStatementAccessor {
104 type Select;
106 type From;
108 type Distinct;
110 type Where;
112 type Order;
114 type LimitOffset;
116 type GroupBy;
118 type Having;
120 type Locking;
122
123 fn select_clause(&self) -> &Self::Select;
125 #[allow(clippy::wrong_self_convention)] fn from_clause(&self) -> &Self::From;
128 fn distinct_clause(&self) -> &Self::Distinct;
130 fn where_clause(&self) -> &Self::Where;
132 fn order_clause(&self) -> &Self::Order;
134 fn limit_offset_clause(&self) -> &Self::LimitOffset;
136 fn group_by_clause(&self) -> &Self::GroupBy;
138 fn having_clause(&self) -> &Self::Having;
140 fn locking_clause(&self) -> &Self::Locking;
142}
143
144impl<F, S, D, W, O, LOf, G, H, LC> SelectStatementAccessor
145 for SelectStatement<F, S, D, W, O, LOf, G, H, LC>
146{
147 type Select = S;
148 type From = F;
149 type Distinct = D;
150 type Where = W;
151 type Order = O;
152 type LimitOffset = LOf;
153 type GroupBy = G;
154 type Having = H;
155 type Locking = LC;
156
157 fn select_clause(&self) -> &Self::Select {
158 &self.select
159 }
160
161 fn from_clause(&self) -> &Self::From {
162 &self.from
163 }
164
165 fn distinct_clause(&self) -> &Self::Distinct {
166 &self.distinct
167 }
168
169 fn where_clause(&self) -> &Self::Where {
170 &self.where_clause
171 }
172
173 fn order_clause(&self) -> &Self::Order {
174 &self.order
175 }
176
177 fn limit_offset_clause(&self) -> &Self::LimitOffset {
178 &self.limit_offset
179 }
180
181 fn group_by_clause(&self) -> &Self::GroupBy {
182 &self.group_by
183 }
184
185 fn having_clause(&self) -> &Self::Having {
186 &self.having
187 }
188
189 fn locking_clause(&self) -> &Self::Locking {
190 &self.locking
191 }
192}
193
194impl<F, S, D, W, O, LOf, G, H, LC> SelectStatement<F, S, D, W, O, LOf, G, H, LC> {
195 #[allow(clippy::too_many_arguments)]
196 pub(crate) fn new(
197 select: S,
198 from: F,
199 distinct: D,
200 where_clause: W,
201 order: O,
202 limit_offset: LOf,
203 group_by: G,
204 having: H,
205 locking: LC,
206 ) -> Self {
207 SelectStatement {
208 select,
209 from,
210 distinct,
211 where_clause,
212 order,
213 limit_offset,
214 group_by,
215 having,
216 locking,
217 }
218 }
219}
220
221impl<F: QuerySource> SelectStatement<FromClause<F>> {
222 #[doc(hidden)]
224 pub fn simple(from: F) -> Self {
225 let from = FromClause::new(from);
226 SelectStatement::new(
227 DefaultSelectClause::new(&from),
228 from,
229 NoDistinctClause,
230 NoWhereClause,
231 NoOrderClause,
232 LimitOffsetClause {
233 limit_clause: NoLimitClause,
234 offset_clause: NoOffsetClause,
235 },
236 NoGroupByClause,
237 NoHavingClause,
238 NoLockingClause,
239 )
240 }
241}
242
243impl<F, S, D, W, O, LOf, G, H, LC> Query for SelectStatement<F, S, D, W, O, LOf, G, H, LC>
244where
245 G: ValidGroupByClause,
246 S: SelectClauseExpression<F>,
247 S::Selection: ValidGrouping<G::Expressions>,
248 W: ValidWhereClause<F>,
249{
250 type SqlType = S::SelectClauseSqlType;
251}
252
253impl<F, S, D, W, O, LOf, G, H, LC> SelectQuery for SelectStatement<F, S, D, W, O, LOf, G, H, LC>
254where
255 S: SelectClauseExpression<F>,
256 O: ValidOrderingForDistinct<D>,
257{
258 type SqlType = S::SelectClauseSqlType;
259}
260
261impl<F, S, D, W, O, LOf, G, H, LC, DB> QueryFragment<DB>
262 for SelectStatement<F, S, D, W, O, LOf, G, H, LC>
263where
264 DB: Backend,
265 Self: QueryFragment<DB, DB::SelectStatementSyntax>,
266{
267 fn walk_ast<'b>(&'b self, pass: AstPass<'_, 'b, DB>) -> QueryResult<()> {
268 <Self as QueryFragment<DB, DB::SelectStatementSyntax>>::walk_ast(self, pass)
269 }
270}
271
272impl<F, S, D, W, O, LOf, G, H, LC, DB>
273 QueryFragment<DB, sql_dialect::select_statement_syntax::AnsiSqlSelectStatement>
274 for SelectStatement<F, S, D, W, O, LOf, G, H, LC>
275where
276 DB: Backend<
277 SelectStatementSyntax = sql_dialect::select_statement_syntax::AnsiSqlSelectStatement,
278 >,
279 S: QueryFragment<DB>,
280 F: QueryFragment<DB>,
281 D: QueryFragment<DB>,
282 W: QueryFragment<DB>,
283 O: QueryFragment<DB>,
284 LOf: QueryFragment<DB>,
285 G: QueryFragment<DB>,
286 H: QueryFragment<DB>,
287 LC: QueryFragment<DB>,
288{
289 fn walk_ast<'b>(&'b self, mut out: AstPass<'_, 'b, DB>) -> QueryResult<()> {
290 out.push_sql("SELECT ");
291 self.distinct.walk_ast(out.reborrow())?;
292 self.select.walk_ast(out.reborrow())?;
293 self.from.walk_ast(out.reborrow())?;
294 self.where_clause.walk_ast(out.reborrow())?;
295 self.group_by.walk_ast(out.reborrow())?;
296 self.having.walk_ast(out.reborrow())?;
297 self.order.walk_ast(out.reborrow())?;
298 self.limit_offset.walk_ast(out.reborrow())?;
299 self.locking.walk_ast(out.reborrow())?;
300 Ok(())
301 }
302}
303
304impl<S, F, D, W, O, LOf, G, H, LC, QS> ValidSubselect<QS>
305 for SelectStatement<FromClause<F>, S, D, W, O, LOf, G, H, LC>
306where
307 Self: SelectQuery,
308 F: QuerySource,
309 QS: QuerySource,
310 Join<F, QS, Inner>: QuerySource,
311 W: ValidWhereClause<FromClause<Join<F, QS, Inner>>>,
312{
313}
314
315impl<S, D, W, O, LOf, G, H, LC> ValidSubselect<NoFromClause>
316 for SelectStatement<NoFromClause, S, D, W, O, LOf, G, H, LC>
317where
318 Self: SelectQuery,
319 W: ValidWhereClause<NoFromClause>,
320{
321}
322
323impl<S, F, D, W, O, LOf, G, H, LC> ValidSubselect<NoFromClause>
324 for SelectStatement<FromClause<F>, S, D, W, O, LOf, G, H, LC>
325where
326 Self: SelectQuery,
327 F: QuerySource,
328 W: ValidWhereClause<FromClause<F>>,
329{
330}
331
332impl<S, D, W, O, LOf, G, H, LC, QS> ValidSubselect<QS>
333 for SelectStatement<NoFromClause, S, D, W, O, LOf, G, H, LC>
334where
335 Self: SelectQuery,
336 QS: QuerySource,
337 W: ValidWhereClause<NoFromClause>,
338{
339}
340
341impl<From, T> AppearsInFromClause<T> for SelectStatement<From>
344where
345 From: AsQuerySource,
346 From::QuerySource: AppearsInFromClause<T> + QuerySource,
347{
348 type Count = <From::QuerySource as AppearsInFromClause<T>>::Count;
349}
350
351impl<From> QuerySource for SelectStatement<From>
352where
353 From: AsQuerySource,
354 <From::QuerySource as QuerySource>::DefaultSelection: SelectableExpression<Self>,
355{
356 type FromClause = <From::QuerySource as QuerySource>::FromClause;
357 type DefaultSelection = <From::QuerySource as QuerySource>::DefaultSelection;
358
359 fn from_clause(&self) -> <From::QuerySource as QuerySource>::FromClause {
360 self.from.as_query_source().from_clause()
361 }
362
363 fn default_selection(&self) -> Self::DefaultSelection {
364 self.from.as_query_source().default_selection()
365 }
366}
367
368impl<From, Selection> AppendSelection<Selection> for SelectStatement<From>
369where
370 From: AsQuerySource,
371 From::QuerySource: AppendSelection<Selection>,
372{
373 type Output = <From::QuerySource as AppendSelection<Selection>>::Output;
374
375 fn append_selection(&self, selection: Selection) -> Self::Output {
376 self.from.as_query_source().append_selection(selection)
377 }
378}