Skip to main content

diesel/query_builder/select_statement/
dsl_impls.rs

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