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