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