Skip to main content

diesel/query_builder/select_statement/
dsl_impls.rs

1use super::BoxedCloneSelectStatement;
2use super::BoxedSelectStatement;
3use crate::associations::HasTable;
4use crate::backend::Backend;
5use crate::dsl::AsExprOf;
6use crate::expression::nullable::Nullable;
7use crate::expression::*;
8use crate::insertable::Insertable;
9use crate::query_builder::NoFromClause;
10use crate::query_builder::combination_clause::*;
11use crate::query_builder::distinct_clause::*;
12use crate::query_builder::from_clause::AsQuerySource;
13use crate::query_builder::from_clause::FromClause;
14use crate::query_builder::group_by_clause::*;
15use crate::query_builder::insert_statement::InsertFromSelect;
16use crate::query_builder::limit_clause::*;
17use crate::query_builder::limit_offset_clause::{
18    BoxedCloneLimitOffsetClause, BoxedLimitOffsetClause, LimitOffsetClause,
19};
20use crate::query_builder::locking_clause::*;
21use crate::query_builder::offset_clause::*;
22use crate::query_builder::order_clause::*;
23use crate::query_builder::select_clause::*;
24use crate::query_builder::update_statement::target::*;
25use crate::query_builder::where_clause::*;
26use crate::query_builder::{
27    AsQuery, IntoBoxedClause, IntoBoxedCloneClause, Query, QueryFragment, SelectQuery,
28    SelectStatement,
29};
30use crate::query_dsl::group_by_dsl::ValidDistinctForGroupBy;
31use crate::query_dsl::methods::*;
32use crate::query_dsl::order_dsl::ValidOrderingForDistinct;
33use crate::query_dsl::*;
34use crate::query_source::QuerySource;
35use crate::query_source::joins::{Join, JoinOn, JoinTo};
36use crate::sql_types::{BigInt, BoolOrNullableBool};
37use alloc::boxed::Box;
38use alloc::sync::Arc;
39
40impl<F, D, W, O, LOf, G, H, LC, Rhs, Kind, On> InternalJoinDsl<Rhs, Kind, On>
41    for SelectStatement<FromClause<F>, DefaultSelectClause<FromClause<F>>, D, W, O, LOf, G, H, LC>
42where
43    F: QuerySource,
44    Rhs: QuerySource,
45    JoinOn<Join<F, Rhs, Kind>, On>: QuerySource,
46    SelectStatement<
47        FromClause<JoinOn<Join<F, Rhs, Kind>, On>>,
48        DefaultSelectClause<FromClause<JoinOn<Join<F, Rhs, Kind>, On>>>,
49        D,
50        W,
51        O,
52        LOf,
53        G,
54        H,
55        LC,
56    >: AsQuery,
57{
58    type Output = SelectStatement<
59        FromClause<JoinOn<Join<F, Rhs, Kind>, On>>,
60        DefaultSelectClause<FromClause<JoinOn<Join<F, Rhs, Kind>, On>>>,
61        D,
62        W,
63        O,
64        LOf,
65        G,
66        H,
67        LC,
68    >;
69
70    fn join(self, rhs: Rhs, kind: Kind, on: On) -> Self::Output {
71        let from = FromClause::new(Join::new(self.from.source, rhs, kind).on(on));
72        SelectStatement::new(
73            DefaultSelectClause::new(&from),
74            from,
75            self.distinct,
76            self.where_clause,
77            self.order,
78            self.limit_offset,
79            self.group_by,
80            self.having,
81            self.locking,
82        )
83    }
84}
85
86impl<F, S, D, W, O, LOf, G, H, LC, Rhs, Kind, On> InternalJoinDsl<Rhs, Kind, On>
87    for SelectStatement<FromClause<F>, SelectClause<S>, D, W, O, LOf, G, H, LC>
88where
89    F: QuerySource,
90    Rhs: QuerySource,
91    JoinOn<Join<F, Rhs, Kind>, On>: QuerySource,
92    SelectStatement<
93        FromClause<JoinOn<Join<F, Rhs, Kind>, On>>,
94        SelectClause<S>,
95        D,
96        W,
97        O,
98        LOf,
99        G,
100        H,
101        LC,
102    >: AsQuery,
103{
104    type Output = SelectStatement<
105        FromClause<JoinOn<Join<F, Rhs, Kind>, On>>,
106        SelectClause<S>,
107        D,
108        W,
109        O,
110        LOf,
111        G,
112        H,
113        LC,
114    >;
115
116    fn join(self, rhs: Rhs, kind: Kind, on: On) -> Self::Output {
117        SelectStatement::new(
118            self.select,
119            FromClause::new(Join::new(self.from.source, rhs, kind).on(on)),
120            self.distinct,
121            self.where_clause,
122            self.order,
123            self.limit_offset,
124            self.group_by,
125            self.having,
126            self.locking,
127        )
128    }
129}
130
131impl<F, S, D, W, O, LOf, G, H, LC, Selection> SelectDsl<Selection>
132    for SelectStatement<FromClause<F>, S, D, W, O, LOf, G, H, LC>
133where
134    G: ValidGroupByClause,
135    F: QuerySource,
136    Selection: SelectableExpression<F> + ValidGrouping<G::Expressions>,
137    SelectStatement<FromClause<F>, SelectClause<Selection>, D, W, O, LOf, G, H, LC>: SelectQuery,
138    D: ValidDistinctForGroupBy<Selection, G::Expressions>,
139    O: ValidGrouping<G::Expressions>,
140    <Selection as ValidGrouping<G::Expressions>>::IsAggregate:
141        MixedAggregates<<O as ValidGrouping<G::Expressions>>::IsAggregate>,
142{
143    type Output = SelectStatement<FromClause<F>, SelectClause<Selection>, D, W, O, LOf, G, H, LC>;
144
145    fn select(self, selection: Selection) -> Self::Output {
146        SelectStatement::new(
147            SelectClause(selection),
148            self.from,
149            self.distinct,
150            self.where_clause,
151            self.order,
152            self.limit_offset,
153            self.group_by,
154            self.having,
155            self.locking,
156        )
157    }
158}
159
160impl<S, D, W, O, LOf, G, H, LC, Selection> SelectDsl<Selection>
161    for SelectStatement<NoFromClause, S, D, W, O, LOf, G, H, LC>
162where
163    G: ValidGroupByClause,
164    Selection: SelectableExpression<NoFromClause> + ValidGrouping<G::Expressions>,
165    SelectStatement<NoFromClause, SelectClause<Selection>, D, W, O, LOf, G, H, LC>: SelectQuery,
166    D: ValidDistinctForGroupBy<Selection, G::Expressions>,
167{
168    type Output = SelectStatement<NoFromClause, SelectClause<Selection>, D, W, O, LOf, G, H, LC>;
169
170    fn select(self, selection: Selection) -> Self::Output {
171        SelectStatement::new(
172            SelectClause(selection),
173            self.from,
174            self.distinct,
175            self.where_clause,
176            self.order,
177            self.limit_offset,
178            self.group_by,
179            self.having,
180            self.locking,
181        )
182    }
183}
184
185impl<ST, F, S, D, W, O, LOf, G, H> DistinctDsl for SelectStatement<F, S, D, W, O, LOf, G, H>
186where
187    Self: SelectQuery<SqlType = ST>,
188    SelectStatement<F, S, DistinctClause, W, O, LOf, G, H>: SelectQuery<SqlType = ST>,
189{
190    type Output = SelectStatement<F, S, DistinctClause, W, O, LOf, G, H>;
191
192    fn distinct(self) -> Self::Output {
193        SelectStatement::new(
194            self.select,
195            self.from,
196            DistinctClause,
197            self.where_clause,
198            self.order,
199            self.limit_offset,
200            self.group_by,
201            self.having,
202            self.locking,
203        )
204    }
205}
206
207impl<F, S, D, W, O, LOf, G, H, LC, Predicate> FilterDsl<Predicate>
208    for SelectStatement<F, S, D, W, O, LOf, G, H, LC>
209where
210    Predicate: Expression + NonAggregate,
211    Predicate::SqlType: BoolOrNullableBool,
212    W: WhereAnd<Predicate>,
213{
214    type Output = SelectStatement<F, S, D, W::Output, O, LOf, G, H, LC>;
215
216    fn filter(self, predicate: Predicate) -> Self::Output {
217        SelectStatement::new(
218            self.select,
219            self.from,
220            self.distinct,
221            self.where_clause.and(predicate),
222            self.order,
223            self.limit_offset,
224            self.group_by,
225            self.having,
226            self.locking,
227        )
228    }
229}
230
231impl<F, S, D, W, O, LOf, G, H, LC, Predicate> OrFilterDsl<Predicate>
232    for SelectStatement<F, S, D, W, O, LOf, G, H, LC>
233where
234    Predicate: Expression + NonAggregate,
235    Predicate::SqlType: BoolOrNullableBool,
236    W: WhereOr<Predicate>,
237{
238    type Output = SelectStatement<F, S, D, W::Output, O, LOf, G, H, LC>;
239
240    fn or_filter(self, predicate: Predicate) -> Self::Output {
241        SelectStatement::new(
242            self.select,
243            self.from,
244            self.distinct,
245            self.where_clause.or(predicate),
246            self.order,
247            self.limit_offset,
248            self.group_by,
249            self.having,
250            self.locking,
251        )
252    }
253}
254
255use crate::dsl::Filter;
256use crate::expression_methods::EqAll;
257use crate::query_builder::having_clause::{HavingClause, NoHavingClause};
258use crate::query_source::Table;
259
260impl<F, S, D, W, O, LOf, G, H, LC, PK> FindDsl<PK>
261    for SelectStatement<FromClause<F>, S, D, W, O, LOf, G, H, LC>
262where
263    F: Table,
264    F::PrimaryKey: EqAll<PK>,
265    Self: FilterDsl<<F::PrimaryKey as EqAll<PK>>::Output>,
266{
267    type Output = Filter<Self, <F::PrimaryKey as EqAll<PK>>::Output>;
268
269    fn find(self, id: PK) -> Self::Output {
270        let primary_key = self.from.source.primary_key();
271        FilterDsl::filter(self, primary_key.eq_all(id))
272    }
273}
274
275// no impls for `NoFromClause` here because order is not really supported there yet
276
277// Without GROUP BY: validate that SELECT and ORDER BY have matching aggregate nature.
278impl<ST, F, S, D, W, O, LOf, H, LC, Expr> OrderDsl<Expr>
279    for SelectStatement<FromClause<F>, S, D, W, O, LOf, NoGroupByClause, H, LC>
280where
281    F: QuerySource,
282    Expr: AppearsOnTable<F>,
283    Self: SelectQuery<SqlType = ST>,
284    SelectStatement<FromClause<F>, S, D, W, OrderClause<Expr>, LOf, NoGroupByClause, H, LC>:
285        SelectQuery<SqlType = ST>,
286    OrderClause<Expr>: ValidOrderingForDistinct<D>,
287    S: SelectClauseExpression<FromClause<F>>,
288    Expr: ValidGrouping<()>,
289    S::Selection: ValidGrouping<()>,
290    <S::Selection as ValidGrouping<()>>::IsAggregate:
291        MixedAggregates<<Expr as ValidGrouping<()>>::IsAggregate>,
292{
293    type Output =
294        SelectStatement<FromClause<F>, S, D, W, OrderClause<Expr>, LOf, NoGroupByClause, H, LC>;
295
296    fn order(self, expr: Expr) -> Self::Output {
297        self.map_order(|_| OrderClause(expr))
298    }
299}
300
301// With GROUP BY: only validate that the ORDER BY expression is valid for the group
302// (grouped column or aggregate). SELECT validity is enforced by the Query impl at
303// execution time, so checking it here would reject valid queries where order_by()
304// is called before select() with a non-trivial GROUP BY.
305impl<ST, F, S, D, W, O, LOf, GB, H, LC, Expr> OrderDsl<Expr>
306    for SelectStatement<FromClause<F>, S, D, W, O, LOf, GroupByClause<GB>, H, LC>
307where
308    F: QuerySource,
309    Expr: AppearsOnTable<F>,
310    Self: SelectQuery<SqlType = ST>,
311    SelectStatement<FromClause<F>, S, D, W, OrderClause<Expr>, LOf, GroupByClause<GB>, H, LC>:
312        SelectQuery<SqlType = ST>,
313    OrderClause<Expr>: ValidOrderingForDistinct<D>,
314    Expr: ValidGrouping<GB>,
315{
316    type Output =
317        SelectStatement<FromClause<F>, S, D, W, OrderClause<Expr>, LOf, GroupByClause<GB>, H, LC>;
318
319    fn order(self, expr: Expr) -> Self::Output {
320        self.map_order(|_| OrderClause(expr))
321    }
322}
323
324// Without GROUP BY: validate that SELECT and the new ORDER BY term have matching
325// aggregate nature.
326impl<F, S, D, W, O, LOf, H, LC, Expr> ThenOrderDsl<Expr>
327    for SelectStatement<FromClause<F>, S, D, W, OrderClause<O>, LOf, NoGroupByClause, H, LC>
328where
329    F: QuerySource,
330    Expr: AppearsOnTable<F>,
331    S: SelectClauseExpression<FromClause<F>>,
332    Expr: ValidGrouping<()>,
333    S::Selection: ValidGrouping<()>,
334    <S::Selection as ValidGrouping<()>>::IsAggregate:
335        MixedAggregates<<Expr as ValidGrouping<()>>::IsAggregate>,
336    OrderClause<(O, Expr)>: ValidOrderingForDistinct<D>,
337{
338    type Output = SelectStatement<
339        FromClause<F>,
340        S,
341        D,
342        W,
343        OrderClause<(O, Expr)>,
344        LOf,
345        NoGroupByClause,
346        H,
347        LC,
348    >;
349
350    fn then_order_by(self, expr: Expr) -> Self::Output {
351        self.map_order(|order| OrderClause((order.0, expr)))
352    }
353}
354
355// With GROUP BY: Validate the whole order expression against the given group by expression
356impl<ST, F, S, D, W, O, LOf, GB, H, LC, Expr> ThenOrderDsl<Expr>
357    for SelectStatement<FromClause<F>, S, D, W, OrderClause<O>, LOf, GroupByClause<GB>, H, LC>
358where
359    F: QuerySource,
360    Expr: AppearsOnTable<F>,
361    Self: SelectQuery<SqlType = ST>,
362    SelectStatement<FromClause<F>, S, D, W, OrderClause<(O, Expr)>, LOf, GroupByClause<GB>, H, LC>:
363        SelectQuery<SqlType = ST>,
364    (O, Expr): ValidGrouping<GB>,
365    OrderClause<(O, Expr)>: ValidOrderingForDistinct<D>,
366{
367    type Output = SelectStatement<
368        FromClause<F>,
369        S,
370        D,
371        W,
372        OrderClause<(O, Expr)>,
373        LOf,
374        GroupByClause<GB>,
375        H,
376        LC,
377    >;
378
379    fn then_order_by(self, expr: Expr) -> Self::Output {
380        self.map_order(|order| OrderClause((order.0, expr)))
381    }
382}
383
384impl<F, S, D, W, LOf, G, LC, Expr> ThenOrderDsl<Expr>
385    for SelectStatement<F, S, D, W, NoOrderClause, LOf, G, LC>
386where
387    Expr: Expression,
388    Self: OrderDsl<Expr>,
389{
390    type Output = crate::dsl::Order<Self, Expr>;
391
392    fn then_order_by(self, expr: Expr) -> Self::Output {
393        self.order_by(expr)
394    }
395}
396
397#[doc(hidden)]
398type Limit = AsExprOf<i64, BigInt>;
399
400impl<ST, F, S, D, W, O, L, Of, G, H, LC> LimitDsl
401    for SelectStatement<F, S, D, W, O, LimitOffsetClause<L, Of>, G, H, LC>
402where
403    Self: SelectQuery<SqlType = ST>,
404    SelectStatement<F, S, D, W, O, LimitOffsetClause<LimitClause<Limit>, Of>, G, H, LC>:
405        SelectQuery<SqlType = ST>,
406{
407    type Output =
408        SelectStatement<F, S, D, W, O, LimitOffsetClause<LimitClause<Limit>, Of>, G, H, LC>;
409
410    fn limit(self, limit: i64) -> Self::Output {
411        let limit_clause = LimitClause(limit.into_sql::<BigInt>());
412        SelectStatement::new(
413            self.select,
414            self.from,
415            self.distinct,
416            self.where_clause,
417            self.order,
418            LimitOffsetClause {
419                limit_clause,
420                offset_clause: self.limit_offset.offset_clause,
421            },
422            self.group_by,
423            self.having,
424            self.locking,
425        )
426    }
427}
428
429#[doc(hidden)]
430type Offset = Limit;
431
432impl<ST, F, S, D, W, O, L, Of, G, H, LC> OffsetDsl
433    for SelectStatement<F, S, D, W, O, LimitOffsetClause<L, Of>, G, H, LC>
434where
435    Self: SelectQuery<SqlType = ST>,
436    SelectStatement<F, S, D, W, O, LimitOffsetClause<L, OffsetClause<Offset>>, G, H, LC>:
437        SelectQuery<SqlType = ST>,
438{
439    type Output =
440        SelectStatement<F, S, D, W, O, LimitOffsetClause<L, OffsetClause<Offset>>, G, H, LC>;
441
442    fn offset(self, offset: i64) -> Self::Output {
443        let offset_clause = OffsetClause(offset.into_sql::<BigInt>());
444        SelectStatement::new(
445            self.select,
446            self.from,
447            self.distinct,
448            self.where_clause,
449            self.order,
450            LimitOffsetClause {
451                limit_clause: self.limit_offset.limit_clause,
452                offset_clause,
453            },
454            self.group_by,
455            self.having,
456            self.locking,
457        )
458    }
459}
460
461impl<F, S, D, W, O, LOf, G, H, Expr> GroupByDsl<Expr> for SelectStatement<F, S, D, W, O, LOf, G, H>
462where
463    SelectStatement<F, S, D, W, O, LOf, GroupByClause<Expr>, H>: SelectQuery,
464    Expr: Expression + AppearsOnTable<F>,
465{
466    type Output = SelectStatement<F, S, D, W, O, LOf, GroupByClause<Expr>, H>;
467
468    fn group_by(self, expr: Expr) -> Self::Output {
469        let group_by = GroupByClause(expr);
470        SelectStatement::new(
471            self.select,
472            self.from,
473            self.distinct,
474            self.where_clause,
475            self.order,
476            self.limit_offset,
477            group_by,
478            self.having,
479            self.locking,
480        )
481    }
482}
483
484impl<F, S, W, O, LOf, Lock> LockingDsl<Lock>
485    for SelectStatement<F, S, NoDistinctClause, W, O, LOf>
486{
487    type Output = SelectStatement<
488        F,
489        S,
490        NoDistinctClause,
491        W,
492        O,
493        LOf,
494        NoGroupByClause,
495        NoHavingClause,
496        LockingClause<Lock, NoModifier>,
497    >;
498
499    fn with_lock(self, lock: Lock) -> Self::Output {
500        SelectStatement::new(
501            self.select,
502            self.from,
503            self.distinct,
504            self.where_clause,
505            self.order,
506            self.limit_offset,
507            self.group_by,
508            self.having,
509            LockingClause::new(lock, NoModifier),
510        )
511    }
512}
513
514impl<F, S, D, W, O, LOf, G, H, LC, LM, Modifier> ModifyLockDsl<Modifier>
515    for SelectStatement<F, S, D, W, O, LOf, G, H, LockingClause<LC, LM>>
516{
517    type Output = SelectStatement<F, S, D, W, O, LOf, G, H, LockingClause<LC, Modifier>>;
518
519    fn modify_lock(self, modifier: Modifier) -> Self::Output {
520        SelectStatement::new(
521            self.select,
522            self.from,
523            self.distinct,
524            self.where_clause,
525            self.order,
526            self.limit_offset,
527            self.group_by,
528            self.having,
529            LockingClause::new(self.locking.lock_mode, modifier),
530        )
531    }
532}
533
534impl<'a, F, S, D, W, O, LOf, G, H, DB> BoxedDsl<'a, DB>
535    for SelectStatement<FromClause<F>, S, D, W, O, LOf, G, H>
536where
537    Self: AsQuery,
538    DB: Backend,
539    F: QuerySource,
540    S: SelectClauseExpression<FromClause<F>> + QueryFragment<DB> + Send + 'a,
541    S::Selection: ValidGrouping<G::Expressions>,
542    D: QueryFragment<DB> + Send + 'a,
543    W: Into<BoxedWhereClause<'a, DB>>,
544    O: Into<Option<Box<dyn QueryFragment<DB> + Send + 'a>>>,
545    LOf: IntoBoxedClause<'a, DB, BoxedClause = BoxedLimitOffsetClause<'a, DB>>,
546    G: ValidGroupByClause + QueryFragment<DB> + Send + 'a,
547    H: QueryFragment<DB> + Send + 'a,
548{
549    type Output =
550        BoxedSelectStatement<'a, S::SelectClauseSqlType, FromClause<F>, DB, G::Expressions>;
551
552    fn internal_into_boxed(self) -> Self::Output {
553        BoxedSelectStatement::new(
554            self.select,
555            self.from,
556            Box::new(self.distinct),
557            self.where_clause.into(),
558            self.order.into(),
559            self.limit_offset.into_boxed(),
560            self.group_by,
561            Box::new(self.having),
562        )
563    }
564}
565
566impl<'a, F, S, D, W, O, LOf, G, H, DB> BoxedCloneDsl<'a, DB>
567    for SelectStatement<FromClause<F>, S, D, W, O, LOf, G, H>
568where
569    Self: AsQuery,
570    DB: Backend,
571    F: QuerySource,
572    S: SelectClauseExpression<FromClause<F>> + QueryFragment<DB> + Send + Sync + 'a,
573    S::Selection: ValidGrouping<G::Expressions>,
574    D: QueryFragment<DB> + Send + Sync + 'a,
575    W: Into<BoxedCloneWhereClause<'a, DB>>,
576    O: Into<Option<Arc<dyn QueryFragment<DB> + Send + Sync + 'a>>>,
577    LOf: IntoBoxedCloneClause<'a, DB, BoxedCloneClause = BoxedCloneLimitOffsetClause<'a, DB>>,
578    G: ValidGroupByClause + QueryFragment<DB> + Send + Sync + 'a,
579    H: QueryFragment<DB> + Send + Sync + 'a,
580{
581    type Output =
582        BoxedCloneSelectStatement<'a, S::SelectClauseSqlType, FromClause<F>, DB, G::Expressions>;
583
584    fn internal_into_boxed_clone(self) -> Self::Output {
585        BoxedCloneSelectStatement::new(
586            self.select,
587            self.from,
588            Arc::new(self.distinct),
589            self.where_clause.into(),
590            self.order.into(),
591            self.limit_offset.into_boxed_clone(),
592            self.group_by,
593            Arc::new(self.having),
594        )
595    }
596}
597
598impl<'a, S, D, W, O, LOf, G, H, DB> BoxedDsl<'a, DB>
599    for SelectStatement<NoFromClause, S, D, W, O, LOf, G, H>
600where
601    Self: AsQuery,
602    DB: Backend,
603    S: SelectClauseExpression<NoFromClause> + QueryFragment<DB> + Send + 'a,
604    S::Selection: ValidGrouping<G::Expressions>,
605    D: QueryFragment<DB> + Send + 'a,
606    W: Into<BoxedWhereClause<'a, DB>>,
607    O: Into<Option<Box<dyn QueryFragment<DB> + Send + 'a>>>,
608    LOf: IntoBoxedClause<'a, DB, BoxedClause = BoxedLimitOffsetClause<'a, DB>>,
609    G: ValidGroupByClause + QueryFragment<DB> + Send + 'a,
610    H: QueryFragment<DB> + Send + 'a,
611{
612    type Output =
613        BoxedSelectStatement<'a, S::SelectClauseSqlType, NoFromClause, DB, G::Expressions>;
614
615    fn internal_into_boxed(self) -> Self::Output {
616        BoxedSelectStatement::new_no_from_clause(
617            self.select,
618            self.from,
619            Box::new(self.distinct),
620            self.where_clause.into(),
621            self.order.into(),
622            self.limit_offset.into_boxed(),
623            self.group_by,
624            Box::new(self.having),
625        )
626    }
627}
628
629impl<'a, S, D, W, O, LOf, G, H, DB> BoxedCloneDsl<'a, DB>
630    for SelectStatement<NoFromClause, S, D, W, O, LOf, G, H>
631where
632    Self: AsQuery,
633    DB: Backend,
634    S: SelectClauseExpression<NoFromClause> + QueryFragment<DB> + Send + Sync + 'a,
635    S::Selection: ValidGrouping<G::Expressions>,
636    D: QueryFragment<DB> + Send + Sync + 'a,
637    W: Into<BoxedCloneWhereClause<'a, DB>>,
638    O: Into<Option<Arc<dyn QueryFragment<DB> + Send + Sync + 'a>>>,
639    LOf: IntoBoxedCloneClause<'a, DB, BoxedCloneClause = BoxedCloneLimitOffsetClause<'a, DB>>,
640    G: ValidGroupByClause + QueryFragment<DB> + Send + Sync + 'a,
641    H: QueryFragment<DB> + Send + Sync + 'a,
642{
643    type Output =
644        BoxedCloneSelectStatement<'a, S::SelectClauseSqlType, NoFromClause, DB, G::Expressions>;
645
646    fn internal_into_boxed_clone(self) -> Self::Output {
647        BoxedCloneSelectStatement::new_no_from_clause(
648            self.select,
649            self.from,
650            Arc::new(self.distinct),
651            self.where_clause.into(),
652            self.order.into(),
653            self.limit_offset.into_boxed_clone(),
654            self.group_by,
655            Arc::new(self.having),
656        )
657    }
658}
659
660impl<F, S, D, W, O, LOf, G, H, LC> HasTable
661    for SelectStatement<FromClause<F>, S, D, W, O, LOf, G, H, LC>
662where
663    F: HasTable + QuerySource,
664{
665    type Table = F::Table;
666
667    fn table() -> Self::Table {
668        F::table()
669    }
670}
671
672impl<F, W> IntoUpdateTarget
673    for SelectStatement<FromClause<F>, DefaultSelectClause<FromClause<F>>, NoDistinctClause, W>
674where
675    F: QuerySource,
676    Self: HasTable,
677    W: ValidWhereClause<F>,
678{
679    type WhereClause = W;
680
681    fn into_update_target(self) -> UpdateTarget<Self::Table, Self::WhereClause> {
682        UpdateTarget {
683            table: Self::table(),
684            where_clause: self.where_clause,
685        }
686    }
687}
688
689// FIXME: Should we disable joining when `.group_by` has been called? Are there
690// any other query methods where a join no longer has the same semantics as
691// joining on just the table?
692impl<F, S, D, W, O, LOf, G, H, LC, Rhs> JoinTo<Rhs>
693    for SelectStatement<FromClause<F>, S, D, W, O, LOf, G, H, LC>
694where
695    F: JoinTo<Rhs> + QuerySource,
696{
697    type FromClause = <F as JoinTo<Rhs>>::FromClause;
698    type OnClause = F::OnClause;
699
700    fn join_target(rhs: Rhs) -> (Self::FromClause, Self::OnClause) {
701        F::join_target(rhs)
702    }
703}
704
705impl<F, S, D, W, O, LOf, G, H, LC> QueryDsl for SelectStatement<F, S, D, W, O, LOf, G, H, LC> {}
706
707impl<F, S, D, W, O, LOf, G, H, LC> RunQueryDslSupport
708    for SelectStatement<F, S, D, W, O, LOf, G, H, LC>
709{
710}
711
712impl<F, S, D, W, O, LOf, G, H, LC, Tab> Insertable<Tab>
713    for SelectStatement<F, S, D, W, O, LOf, G, H, LC>
714where
715    Tab: Table,
716    Self: Query,
717    <Tab::AllColumns as ValidGrouping<()>>::IsAggregate:
718        MixedAggregates<is_aggregate::No, Output = is_aggregate::No>,
719{
720    type Values = InsertFromSelect<Self, Tab::AllColumns>;
721
722    fn values(self) -> Self::Values {
723        InsertFromSelect::new(self)
724    }
725}
726
727impl<F, S, D, W, O, LOf, G, H, LC, Tab> Insertable<Tab>
728    for &SelectStatement<F, S, D, W, O, LOf, G, H, LC>
729where
730    Tab: Table,
731    Self: Query,
732    <Tab::AllColumns as ValidGrouping<()>>::IsAggregate:
733        MixedAggregates<is_aggregate::No, Output = is_aggregate::No>,
734{
735    type Values = InsertFromSelect<Self, Tab::AllColumns>;
736
737    fn values(self) -> Self::Values {
738        InsertFromSelect::new(self)
739    }
740}
741
742impl<F, S, D, W, O, LOf, G, H> SelectNullableDsl
743    for SelectStatement<F, SelectClause<S>, D, W, O, LOf, G, H>
744{
745    type Output = SelectStatement<F, SelectClause<Nullable<S>>, D, W, O, LOf, G, H>;
746
747    fn nullable(self) -> Self::Output {
748        SelectStatement::new(
749            SelectClause(Nullable::new(self.select.0)),
750            self.from,
751            self.distinct,
752            self.where_clause,
753            self.order,
754            self.limit_offset,
755            self.group_by,
756            self.having,
757            self.locking,
758        )
759    }
760}
761
762impl<F, D, W, O, LOf, G, H> SelectNullableDsl
763    for SelectStatement<F, DefaultSelectClause<F>, D, W, O, LOf, G, H>
764where
765    F: AsQuerySource,
766{
767    type Output = SelectStatement<
768        F,
769        SelectClause<Nullable<<F::QuerySource as QuerySource>::DefaultSelection>>,
770        D,
771        W,
772        O,
773        LOf,
774        G,
775        H,
776    >;
777
778    fn nullable(self) -> Self::Output {
779        SelectStatement::new(
780            SelectClause(Nullable::new(
781                self.from.as_query_source().default_selection(),
782            )),
783            self.from,
784            self.distinct,
785            self.where_clause,
786            self.order,
787            self.limit_offset,
788            self.group_by,
789            self.having,
790            self.locking,
791        )
792    }
793}
794
795impl<F, S, D, W, O, LOf, G, H, Predicate> HavingDsl<Predicate>
796    for SelectStatement<FromClause<F>, S, D, W, O, LOf, GroupByClause<G>, H>
797where
798    F: QuerySource,
799    Predicate: AppearsOnTable<F>,
800    Predicate: Expression,
801    Predicate::SqlType: BoolOrNullableBool,
802{
803    type Output =
804        SelectStatement<FromClause<F>, S, D, W, O, LOf, GroupByClause<G>, HavingClause<Predicate>>;
805
806    fn having(self, predicate: Predicate) -> Self::Output {
807        SelectStatement::new(
808            self.select,
809            self.from,
810            self.distinct,
811            self.where_clause,
812            self.order,
813            self.limit_offset,
814            self.group_by,
815            HavingClause(predicate),
816            self.locking,
817        )
818    }
819}
820
821impl<F, S, D, W, O, LOf, G, H, LC> CombineDsl for SelectStatement<F, S, D, W, O, LOf, G, H, LC>
822where
823    Self: Query,
824{
825    type Query = Self;
826
827    fn union<Rhs>(self, rhs: Rhs) -> crate::dsl::Union<Self, Rhs>
828    where
829        Rhs: AsQuery<SqlType = <Self::Query as Query>::SqlType>,
830    {
831        CombinationClause::new(Union, Distinct, self, rhs.as_query())
832    }
833
834    fn union_all<Rhs>(self, rhs: Rhs) -> crate::dsl::UnionAll<Self, Rhs>
835    where
836        Rhs: AsQuery<SqlType = <Self::Query as Query>::SqlType>,
837    {
838        CombinationClause::new(Union, All, self, rhs.as_query())
839    }
840
841    fn intersect<Rhs>(self, rhs: Rhs) -> crate::dsl::Intersect<Self, Rhs>
842    where
843        Rhs: AsQuery<SqlType = <Self::Query as Query>::SqlType>,
844    {
845        CombinationClause::new(Intersect, Distinct, self, rhs.as_query())
846    }
847
848    fn intersect_all<Rhs>(self, rhs: Rhs) -> crate::dsl::IntersectAll<Self, Rhs>
849    where
850        Rhs: AsQuery<SqlType = <Self::Query as Query>::SqlType>,
851    {
852        CombinationClause::new(Intersect, All, self, rhs.as_query())
853    }
854
855    fn except<Rhs>(self, rhs: Rhs) -> crate::dsl::Except<Self, Rhs>
856    where
857        Rhs: AsQuery<SqlType = <Self::Query as Query>::SqlType>,
858    {
859        CombinationClause::new(Except, Distinct, self, rhs.as_query())
860    }
861
862    fn except_all<Rhs>(self, rhs: Rhs) -> crate::dsl::ExceptAll<Self, Rhs>
863    where
864        Rhs: AsQuery<SqlType = <Self::Query as Query>::SqlType>,
865    {
866        CombinationClause::new(Except, All, self, rhs.as_query())
867    }
868}