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        let order = OrderClause(expr);
298        SelectStatement::new(
299            self.select,
300            self.from,
301            self.distinct,
302            self.where_clause,
303            order,
304            self.limit_offset,
305            self.group_by,
306            self.having,
307            self.locking,
308        )
309    }
310}
311
312// With GROUP BY: only validate that the ORDER BY expression is valid for the group
313// (grouped column or aggregate). SELECT validity is enforced by the Query impl at
314// execution time, so checking it here would reject valid queries where order_by()
315// is called before select() with a non-trivial GROUP BY.
316impl<ST, F, S, D, W, O, LOf, GB, H, LC, Expr> OrderDsl<Expr>
317    for SelectStatement<FromClause<F>, S, D, W, O, LOf, GroupByClause<GB>, H, LC>
318where
319    F: QuerySource,
320    Expr: AppearsOnTable<F>,
321    Self: SelectQuery<SqlType = ST>,
322    SelectStatement<FromClause<F>, S, D, W, OrderClause<Expr>, LOf, GroupByClause<GB>, H, LC>:
323        SelectQuery<SqlType = ST>,
324    OrderClause<Expr>: ValidOrderingForDistinct<D>,
325    Expr: ValidGrouping<GB>,
326{
327    type Output =
328        SelectStatement<FromClause<F>, S, D, W, OrderClause<Expr>, LOf, GroupByClause<GB>, H, LC>;
329
330    fn order(self, expr: Expr) -> Self::Output {
331        let order = OrderClause(expr);
332        SelectStatement::new(
333            self.select,
334            self.from,
335            self.distinct,
336            self.where_clause,
337            order,
338            self.limit_offset,
339            self.group_by,
340            self.having,
341            self.locking,
342        )
343    }
344}
345
346// Without GROUP BY: validate that SELECT and the new ORDER BY term have matching
347// aggregate nature.
348impl<F, S, D, W, O, LOf, H, LC, Expr> ThenOrderDsl<Expr>
349    for SelectStatement<FromClause<F>, S, D, W, OrderClause<O>, LOf, NoGroupByClause, H, LC>
350where
351    F: QuerySource,
352    Expr: AppearsOnTable<F>,
353    S: SelectClauseExpression<FromClause<F>>,
354    Expr: ValidGrouping<()>,
355    S::Selection: ValidGrouping<()>,
356    <S::Selection as ValidGrouping<()>>::IsAggregate:
357        MixedAggregates<<Expr as ValidGrouping<()>>::IsAggregate>,
358    OrderClause<(O, Expr)>: ValidOrderingForDistinct<D>,
359{
360    type Output = SelectStatement<
361        FromClause<F>,
362        S,
363        D,
364        W,
365        OrderClause<(O, Expr)>,
366        LOf,
367        NoGroupByClause,
368        H,
369        LC,
370    >;
371
372    fn then_order_by(self, expr: Expr) -> Self::Output {
373        SelectStatement::new(
374            self.select,
375            self.from,
376            self.distinct,
377            self.where_clause,
378            OrderClause((self.order.0, expr)),
379            self.limit_offset,
380            self.group_by,
381            self.having,
382            self.locking,
383        )
384    }
385}
386
387// With GROUP BY: Validate the whole order expression against the given group by expression
388impl<ST, F, S, D, W, O, LOf, GB, H, LC, Expr> ThenOrderDsl<Expr>
389    for SelectStatement<FromClause<F>, S, D, W, OrderClause<O>, LOf, GroupByClause<GB>, H, LC>
390where
391    F: QuerySource,
392    Expr: AppearsOnTable<F>,
393    Self: SelectQuery<SqlType = ST>,
394    SelectStatement<FromClause<F>, S, D, W, OrderClause<(O, Expr)>, LOf, GroupByClause<GB>, H, LC>:
395        SelectQuery<SqlType = ST>,
396    (O, Expr): ValidGrouping<GB>,
397    OrderClause<(O, Expr)>: ValidOrderingForDistinct<D>,
398{
399    type Output = SelectStatement<
400        FromClause<F>,
401        S,
402        D,
403        W,
404        OrderClause<(O, Expr)>,
405        LOf,
406        GroupByClause<GB>,
407        H,
408        LC,
409    >;
410
411    fn then_order_by(self, expr: Expr) -> Self::Output {
412        SelectStatement::new(
413            self.select,
414            self.from,
415            self.distinct,
416            self.where_clause,
417            OrderClause((self.order.0, expr)),
418            self.limit_offset,
419            self.group_by,
420            self.having,
421            self.locking,
422        )
423    }
424}
425
426impl<F, S, D, W, LOf, G, LC, Expr> ThenOrderDsl<Expr>
427    for SelectStatement<F, S, D, W, NoOrderClause, LOf, G, LC>
428where
429    Expr: Expression,
430    Self: OrderDsl<Expr>,
431{
432    type Output = crate::dsl::Order<Self, Expr>;
433
434    fn then_order_by(self, expr: Expr) -> Self::Output {
435        self.order_by(expr)
436    }
437}
438
439#[doc(hidden)]
440type Limit = AsExprOf<i64, BigInt>;
441
442impl<ST, F, S, D, W, O, L, Of, G, H, LC> LimitDsl
443    for SelectStatement<F, S, D, W, O, LimitOffsetClause<L, Of>, G, H, LC>
444where
445    Self: SelectQuery<SqlType = ST>,
446    SelectStatement<F, S, D, W, O, LimitOffsetClause<LimitClause<Limit>, Of>, G, H, LC>:
447        SelectQuery<SqlType = ST>,
448{
449    type Output =
450        SelectStatement<F, S, D, W, O, LimitOffsetClause<LimitClause<Limit>, Of>, G, H, LC>;
451
452    fn limit(self, limit: i64) -> Self::Output {
453        let limit_clause = LimitClause(limit.into_sql::<BigInt>());
454        SelectStatement::new(
455            self.select,
456            self.from,
457            self.distinct,
458            self.where_clause,
459            self.order,
460            LimitOffsetClause {
461                limit_clause,
462                offset_clause: self.limit_offset.offset_clause,
463            },
464            self.group_by,
465            self.having,
466            self.locking,
467        )
468    }
469}
470
471#[doc(hidden)]
472type Offset = Limit;
473
474impl<ST, F, S, D, W, O, L, Of, G, H, LC> OffsetDsl
475    for SelectStatement<F, S, D, W, O, LimitOffsetClause<L, Of>, G, H, LC>
476where
477    Self: SelectQuery<SqlType = ST>,
478    SelectStatement<F, S, D, W, O, LimitOffsetClause<L, OffsetClause<Offset>>, G, H, LC>:
479        SelectQuery<SqlType = ST>,
480{
481    type Output =
482        SelectStatement<F, S, D, W, O, LimitOffsetClause<L, OffsetClause<Offset>>, G, H, LC>;
483
484    fn offset(self, offset: i64) -> Self::Output {
485        let offset_clause = OffsetClause(offset.into_sql::<BigInt>());
486        SelectStatement::new(
487            self.select,
488            self.from,
489            self.distinct,
490            self.where_clause,
491            self.order,
492            LimitOffsetClause {
493                limit_clause: self.limit_offset.limit_clause,
494                offset_clause,
495            },
496            self.group_by,
497            self.having,
498            self.locking,
499        )
500    }
501}
502
503impl<F, S, D, W, O, LOf, G, H, Expr> GroupByDsl<Expr> for SelectStatement<F, S, D, W, O, LOf, G, H>
504where
505    SelectStatement<F, S, D, W, O, LOf, GroupByClause<Expr>, H>: SelectQuery,
506    Expr: Expression + AppearsOnTable<F>,
507{
508    type Output = SelectStatement<F, S, D, W, O, LOf, GroupByClause<Expr>, H>;
509
510    fn group_by(self, expr: Expr) -> Self::Output {
511        let group_by = GroupByClause(expr);
512        SelectStatement::new(
513            self.select,
514            self.from,
515            self.distinct,
516            self.where_clause,
517            self.order,
518            self.limit_offset,
519            group_by,
520            self.having,
521            self.locking,
522        )
523    }
524}
525
526impl<F, S, W, O, LOf, Lock> LockingDsl<Lock>
527    for SelectStatement<F, S, NoDistinctClause, W, O, LOf>
528{
529    type Output = SelectStatement<
530        F,
531        S,
532        NoDistinctClause,
533        W,
534        O,
535        LOf,
536        NoGroupByClause,
537        NoHavingClause,
538        LockingClause<Lock, NoModifier>,
539    >;
540
541    fn with_lock(self, lock: Lock) -> Self::Output {
542        SelectStatement::new(
543            self.select,
544            self.from,
545            self.distinct,
546            self.where_clause,
547            self.order,
548            self.limit_offset,
549            self.group_by,
550            self.having,
551            LockingClause::new(lock, NoModifier),
552        )
553    }
554}
555
556impl<F, S, D, W, O, LOf, G, H, LC, LM, Modifier> ModifyLockDsl<Modifier>
557    for SelectStatement<F, S, D, W, O, LOf, G, H, LockingClause<LC, LM>>
558{
559    type Output = SelectStatement<F, S, D, W, O, LOf, G, H, LockingClause<LC, Modifier>>;
560
561    fn modify_lock(self, modifier: Modifier) -> Self::Output {
562        SelectStatement::new(
563            self.select,
564            self.from,
565            self.distinct,
566            self.where_clause,
567            self.order,
568            self.limit_offset,
569            self.group_by,
570            self.having,
571            LockingClause::new(self.locking.lock_mode, modifier),
572        )
573    }
574}
575
576impl<'a, F, S, D, W, O, LOf, G, H, DB> BoxedDsl<'a, DB>
577    for SelectStatement<FromClause<F>, S, D, W, O, LOf, G, H>
578where
579    Self: AsQuery,
580    DB: Backend,
581    F: QuerySource,
582    S: SelectClauseExpression<FromClause<F>> + QueryFragment<DB> + Send + 'a,
583    S::Selection: ValidGrouping<G::Expressions>,
584    D: QueryFragment<DB> + Send + 'a,
585    W: Into<BoxedWhereClause<'a, DB>>,
586    O: Into<Option<Box<dyn QueryFragment<DB> + Send + 'a>>>,
587    LOf: IntoBoxedClause<'a, DB, BoxedClause = BoxedLimitOffsetClause<'a, DB>>,
588    G: ValidGroupByClause + QueryFragment<DB> + Send + 'a,
589    H: QueryFragment<DB> + Send + 'a,
590{
591    type Output =
592        BoxedSelectStatement<'a, S::SelectClauseSqlType, FromClause<F>, DB, G::Expressions>;
593
594    fn internal_into_boxed(self) -> Self::Output {
595        BoxedSelectStatement::new(
596            self.select,
597            self.from,
598            Box::new(self.distinct),
599            self.where_clause.into(),
600            self.order.into(),
601            self.limit_offset.into_boxed(),
602            self.group_by,
603            Box::new(self.having),
604        )
605    }
606}
607
608impl<'a, F, S, D, W, O, LOf, G, H, DB> BoxedCloneDsl<'a, DB>
609    for SelectStatement<FromClause<F>, S, D, W, O, LOf, G, H>
610where
611    Self: AsQuery,
612    DB: Backend,
613    F: QuerySource,
614    S: SelectClauseExpression<FromClause<F>> + QueryFragment<DB> + Send + Sync + 'a,
615    S::Selection: ValidGrouping<G::Expressions>,
616    D: QueryFragment<DB> + Send + Sync + 'a,
617    W: Into<BoxedCloneWhereClause<'a, DB>>,
618    O: Into<Option<Arc<dyn QueryFragment<DB> + Send + Sync + 'a>>>,
619    LOf: IntoBoxedCloneClause<'a, DB, BoxedCloneClause = BoxedCloneLimitOffsetClause<'a, DB>>,
620    G: ValidGroupByClause + QueryFragment<DB> + Send + Sync + 'a,
621    H: QueryFragment<DB> + Send + Sync + 'a,
622{
623    type Output =
624        BoxedCloneSelectStatement<'a, S::SelectClauseSqlType, FromClause<F>, DB, G::Expressions>;
625
626    fn internal_into_boxed_clone(self) -> Self::Output {
627        BoxedCloneSelectStatement::new(
628            self.select,
629            self.from,
630            Arc::new(self.distinct),
631            self.where_clause.into(),
632            self.order.into(),
633            self.limit_offset.into_boxed_clone(),
634            self.group_by,
635            Arc::new(self.having),
636        )
637    }
638}
639
640impl<'a, S, D, W, O, LOf, G, H, DB> BoxedDsl<'a, DB>
641    for SelectStatement<NoFromClause, S, D, W, O, LOf, G, H>
642where
643    Self: AsQuery,
644    DB: Backend,
645    S: SelectClauseExpression<NoFromClause> + QueryFragment<DB> + Send + 'a,
646    S::Selection: ValidGrouping<G::Expressions>,
647    D: QueryFragment<DB> + Send + 'a,
648    W: Into<BoxedWhereClause<'a, DB>>,
649    O: Into<Option<Box<dyn QueryFragment<DB> + Send + 'a>>>,
650    LOf: IntoBoxedClause<'a, DB, BoxedClause = BoxedLimitOffsetClause<'a, DB>>,
651    G: ValidGroupByClause + QueryFragment<DB> + Send + 'a,
652    H: QueryFragment<DB> + Send + 'a,
653{
654    type Output =
655        BoxedSelectStatement<'a, S::SelectClauseSqlType, NoFromClause, DB, G::Expressions>;
656
657    fn internal_into_boxed(self) -> Self::Output {
658        BoxedSelectStatement::new_no_from_clause(
659            self.select,
660            self.from,
661            Box::new(self.distinct),
662            self.where_clause.into(),
663            self.order.into(),
664            self.limit_offset.into_boxed(),
665            self.group_by,
666            Box::new(self.having),
667        )
668    }
669}
670
671impl<'a, S, D, W, O, LOf, G, H, DB> BoxedCloneDsl<'a, DB>
672    for SelectStatement<NoFromClause, S, D, W, O, LOf, G, H>
673where
674    Self: AsQuery,
675    DB: Backend,
676    S: SelectClauseExpression<NoFromClause> + QueryFragment<DB> + Send + Sync + 'a,
677    S::Selection: ValidGrouping<G::Expressions>,
678    D: QueryFragment<DB> + Send + Sync + 'a,
679    W: Into<BoxedCloneWhereClause<'a, DB>>,
680    O: Into<Option<Arc<dyn QueryFragment<DB> + Send + Sync + 'a>>>,
681    LOf: IntoBoxedCloneClause<'a, DB, BoxedCloneClause = BoxedCloneLimitOffsetClause<'a, DB>>,
682    G: ValidGroupByClause + QueryFragment<DB> + Send + Sync + 'a,
683    H: QueryFragment<DB> + Send + Sync + 'a,
684{
685    type Output =
686        BoxedCloneSelectStatement<'a, S::SelectClauseSqlType, NoFromClause, DB, G::Expressions>;
687
688    fn internal_into_boxed_clone(self) -> Self::Output {
689        BoxedCloneSelectStatement::new_no_from_clause(
690            self.select,
691            self.from,
692            Arc::new(self.distinct),
693            self.where_clause.into(),
694            self.order.into(),
695            self.limit_offset.into_boxed_clone(),
696            self.group_by,
697            Arc::new(self.having),
698        )
699    }
700}
701
702impl<F, S, D, W, O, LOf, G, H, LC> HasTable
703    for SelectStatement<FromClause<F>, S, D, W, O, LOf, G, H, LC>
704where
705    F: HasTable + QuerySource,
706{
707    type Table = F::Table;
708
709    fn table() -> Self::Table {
710        F::table()
711    }
712}
713
714impl<F, W> IntoUpdateTarget
715    for SelectStatement<FromClause<F>, DefaultSelectClause<FromClause<F>>, NoDistinctClause, W>
716where
717    F: QuerySource,
718    Self: HasTable,
719    W: ValidWhereClause<F>,
720{
721    type WhereClause = W;
722
723    fn into_update_target(self) -> UpdateTarget<Self::Table, Self::WhereClause> {
724        UpdateTarget {
725            table: Self::table(),
726            where_clause: self.where_clause,
727        }
728    }
729}
730
731// FIXME: Should we disable joining when `.group_by` has been called? Are there
732// any other query methods where a join no longer has the same semantics as
733// joining on just the table?
734impl<F, S, D, W, O, LOf, G, H, LC, Rhs> JoinTo<Rhs>
735    for SelectStatement<FromClause<F>, S, D, W, O, LOf, G, H, LC>
736where
737    F: JoinTo<Rhs> + QuerySource,
738{
739    type FromClause = <F as JoinTo<Rhs>>::FromClause;
740    type OnClause = F::OnClause;
741
742    fn join_target(rhs: Rhs) -> (Self::FromClause, Self::OnClause) {
743        F::join_target(rhs)
744    }
745}
746
747impl<F, S, D, W, O, LOf, G, H, LC> QueryDsl for SelectStatement<F, S, D, W, O, LOf, G, H, LC> {}
748
749impl<F, S, D, W, O, LOf, G, H, LC> RunQueryDslSupport
750    for SelectStatement<F, S, D, W, O, LOf, G, H, LC>
751{
752}
753
754impl<F, S, D, W, O, LOf, G, H, LC, Tab> Insertable<Tab>
755    for SelectStatement<F, S, D, W, O, LOf, G, H, LC>
756where
757    Tab: Table,
758    Self: Query,
759    <Tab::AllColumns as ValidGrouping<()>>::IsAggregate:
760        MixedAggregates<is_aggregate::No, Output = is_aggregate::No>,
761{
762    type Values = InsertFromSelect<Self, Tab::AllColumns>;
763
764    fn values(self) -> Self::Values {
765        InsertFromSelect::new(self)
766    }
767}
768
769impl<F, S, D, W, O, LOf, G, H, LC, Tab> Insertable<Tab>
770    for &SelectStatement<F, S, D, W, O, LOf, G, H, LC>
771where
772    Tab: Table,
773    Self: Query,
774    <Tab::AllColumns as ValidGrouping<()>>::IsAggregate:
775        MixedAggregates<is_aggregate::No, Output = is_aggregate::No>,
776{
777    type Values = InsertFromSelect<Self, Tab::AllColumns>;
778
779    fn values(self) -> Self::Values {
780        InsertFromSelect::new(self)
781    }
782}
783
784impl<F, S, D, W, O, LOf, G, H> SelectNullableDsl
785    for SelectStatement<F, SelectClause<S>, D, W, O, LOf, G, H>
786{
787    type Output = SelectStatement<F, SelectClause<Nullable<S>>, D, W, O, LOf, G, H>;
788
789    fn nullable(self) -> Self::Output {
790        SelectStatement::new(
791            SelectClause(Nullable::new(self.select.0)),
792            self.from,
793            self.distinct,
794            self.where_clause,
795            self.order,
796            self.limit_offset,
797            self.group_by,
798            self.having,
799            self.locking,
800        )
801    }
802}
803
804impl<F, D, W, O, LOf, G, H> SelectNullableDsl
805    for SelectStatement<F, DefaultSelectClause<F>, D, W, O, LOf, G, H>
806where
807    F: AsQuerySource,
808{
809    type Output = SelectStatement<
810        F,
811        SelectClause<Nullable<<F::QuerySource as QuerySource>::DefaultSelection>>,
812        D,
813        W,
814        O,
815        LOf,
816        G,
817        H,
818    >;
819
820    fn nullable(self) -> Self::Output {
821        SelectStatement::new(
822            SelectClause(Nullable::new(
823                self.from.as_query_source().default_selection(),
824            )),
825            self.from,
826            self.distinct,
827            self.where_clause,
828            self.order,
829            self.limit_offset,
830            self.group_by,
831            self.having,
832            self.locking,
833        )
834    }
835}
836
837impl<F, S, D, W, O, LOf, G, H, Predicate> HavingDsl<Predicate>
838    for SelectStatement<FromClause<F>, S, D, W, O, LOf, GroupByClause<G>, H>
839where
840    F: QuerySource,
841    Predicate: AppearsOnTable<F>,
842    Predicate: Expression,
843    Predicate::SqlType: BoolOrNullableBool,
844{
845    type Output =
846        SelectStatement<FromClause<F>, S, D, W, O, LOf, GroupByClause<G>, HavingClause<Predicate>>;
847
848    fn having(self, predicate: Predicate) -> Self::Output {
849        SelectStatement::new(
850            self.select,
851            self.from,
852            self.distinct,
853            self.where_clause,
854            self.order,
855            self.limit_offset,
856            self.group_by,
857            HavingClause(predicate),
858            self.locking,
859        )
860    }
861}
862
863impl<F, S, D, W, O, LOf, G, H, LC> CombineDsl for SelectStatement<F, S, D, W, O, LOf, G, H, LC>
864where
865    Self: Query,
866{
867    type Query = Self;
868
869    fn union<Rhs>(self, rhs: Rhs) -> crate::dsl::Union<Self, Rhs>
870    where
871        Rhs: AsQuery<SqlType = <Self::Query as Query>::SqlType>,
872    {
873        CombinationClause::new(Union, Distinct, self, rhs.as_query())
874    }
875
876    fn union_all<Rhs>(self, rhs: Rhs) -> crate::dsl::UnionAll<Self, Rhs>
877    where
878        Rhs: AsQuery<SqlType = <Self::Query as Query>::SqlType>,
879    {
880        CombinationClause::new(Union, All, self, rhs.as_query())
881    }
882
883    fn intersect<Rhs>(self, rhs: Rhs) -> crate::dsl::Intersect<Self, Rhs>
884    where
885        Rhs: AsQuery<SqlType = <Self::Query as Query>::SqlType>,
886    {
887        CombinationClause::new(Intersect, Distinct, self, rhs.as_query())
888    }
889
890    fn intersect_all<Rhs>(self, rhs: Rhs) -> crate::dsl::IntersectAll<Self, Rhs>
891    where
892        Rhs: AsQuery<SqlType = <Self::Query as Query>::SqlType>,
893    {
894        CombinationClause::new(Intersect, All, self, rhs.as_query())
895    }
896
897    fn except<Rhs>(self, rhs: Rhs) -> crate::dsl::Except<Self, Rhs>
898    where
899        Rhs: AsQuery<SqlType = <Self::Query as Query>::SqlType>,
900    {
901        CombinationClause::new(Except, Distinct, self, rhs.as_query())
902    }
903
904    fn except_all<Rhs>(self, rhs: Rhs) -> crate::dsl::ExceptAll<Self, Rhs>
905    where
906        Rhs: AsQuery<SqlType = <Self::Query as Query>::SqlType>,
907    {
908        CombinationClause::new(Except, All, self, rhs.as_query())
909    }
910}