diesel/query_source/aliasing/
joins.rs

1//! Implements all the traits related to being able to join from/to aliases
2
3use super::field_alias_mapper::FieldAliasMapper;
4use super::{Alias, AliasSource, AliasedField};
5
6use crate::expression::{AppearsOnTable, SelectableExpression};
7use crate::query_builder::AsQuery;
8use crate::query_dsl::InternalJoinDsl;
9use crate::query_source::joins::{
10    AppendSelection, Inner, Join, JoinOn, JoinTo, LeftOuter, OnClauseWrapper, ToInnerJoin,
11};
12use crate::query_source::{
13    AppearsInFromClause, FromClause, Never, Pick, QuerySource, SelectStatement, Table,
14};
15
16#[diagnostic::do_not_recommend]
17impl<T, S> JoinTo<T> for Alias<S>
18where
19    T: Table,
20    S: AliasSource + Default,
21    S::Target: JoinTo<T>,
22    <S::Target as JoinTo<T>>::OnClause: FieldAliasMapper<S>,
23{
24    type FromClause = <S::Target as JoinTo<T>>::FromClause;
25    type OnClause = <<S::Target as JoinTo<T>>::OnClause as FieldAliasMapper<S>>::Out;
26
27    fn join_target(rhs: T) -> (Self::FromClause, Self::OnClause) {
28        let (from_clause, on_clause) = <S::Target as JoinTo<T>>::join_target(rhs);
29        (from_clause, Self::default().fields(on_clause))
30    }
31}
32
33impl<S2, S> JoinTo<Alias<S2>> for Alias<S>
34where
35    S2: AliasSource,
36    S: AliasSource + Default,
37    S::Target: JoinTo<Alias<S2>>,
38    <S::Target as JoinTo<Alias<S2>>>::OnClause: FieldAliasMapper<S>,
39{
40    type FromClause = <S::Target as JoinTo<Alias<S2>>>::FromClause;
41    type OnClause = <<S::Target as JoinTo<Alias<S2>>>::OnClause as FieldAliasMapper<S>>::Out;
42
43    fn join_target(rhs: Alias<S2>) -> (Self::FromClause, Self::OnClause) {
44        let (from_clause, on_clause) = <S::Target as JoinTo<Alias<S2>>>::join_target(rhs);
45        (from_clause, Self::default().fields(on_clause))
46    }
47}
48
49impl<S, Rhs, On> JoinTo<OnClauseWrapper<Rhs, On>> for Alias<S> {
50    type FromClause = Rhs;
51    type OnClause = On;
52
53    fn join_target(rhs: OnClauseWrapper<Rhs, On>) -> (Self::FromClause, Self::OnClause) {
54        (rhs.source, rhs.on)
55    }
56}
57
58impl<S, F, Select, D, W, O, L, Of, G>
59    JoinTo<SelectStatement<FromClause<F>, Select, D, W, O, L, Of, G>> for Alias<S>
60where
61    F: QuerySource,
62    S: AliasSource + Default,
63    SelectStatement<FromClause<F>, Select, D, W, O, L, Of, G>: JoinTo<Alias<S>>,
64{
65    type FromClause = SelectStatement<FromClause<F>, Select, D, W, O, L, Of, G>;
66    type OnClause =
67        <SelectStatement<FromClause<F>, Select, D, W, O, L, Of, G> as JoinTo<Alias<S>>>::OnClause;
68
69    fn join_target(
70        rhs: SelectStatement<FromClause<F>, Select, D, W, O, L, Of, G>,
71    ) -> (Self::FromClause, Self::OnClause) {
72        let (_, on_clause) =
73            diesel::internal::table_macro::SelectStatement::join_target(Self::default());
74        (rhs, on_clause)
75    }
76}
77
78impl<S: AliasSource> ToInnerJoin for Alias<S> {
79    type InnerJoin = Self;
80}
81
82impl<S, Rhs, Kind, On> InternalJoinDsl<Rhs, Kind, On> for Alias<S>
83where
84    Self: AsQuery,
85    <Self as AsQuery>::Query: InternalJoinDsl<Rhs, Kind, On>,
86{
87    type Output = <<Self as AsQuery>::Query as InternalJoinDsl<Rhs, Kind, On>>::Output;
88
89    fn join(self, rhs: Rhs, kind: Kind, on: On) -> Self::Output {
90        self.as_query().join(rhs, kind, on)
91    }
92}
93
94impl<Left, Right, S, C> SelectableExpression<Join<Left, Right, LeftOuter>> for AliasedField<S, C>
95where
96    Self: AppearsOnTable<Join<Left, Right, LeftOuter>>,
97    Self: SelectableExpression<Left>,
98    Left: QuerySource,
99    Right: AppearsInFromClause<Alias<S>, Count = Never> + QuerySource,
100{
101}
102
103impl<Left, Right, S, C> SelectableExpression<Join<Left, Right, Inner>> for AliasedField<S, C>
104where
105    Self: AppearsOnTable<Join<Left, Right, Inner>>,
106    Left: AppearsInFromClause<Alias<S>> + QuerySource,
107    Right: AppearsInFromClause<Alias<S>> + QuerySource,
108    (Left::Count, Right::Count): Pick<Left, Right>,
109    Self: SelectableExpression<<(Left::Count, Right::Count) as Pick<Left, Right>>::Selection>,
110{
111}
112
113// FIXME: Remove this when overlapping marker traits are stable
114impl<Join, On, S, C> SelectableExpression<JoinOn<Join, On>> for AliasedField<S, C> where
115    Self: SelectableExpression<Join> + AppearsOnTable<JoinOn<Join, On>>
116{
117}
118
119impl<S, Selection> AppendSelection<Selection> for Alias<S>
120where
121    Self: QuerySource,
122{
123    type Output = (<Self as QuerySource>::DefaultSelection, Selection);
124
125    fn append_selection(&self, selection: Selection) -> Self::Output {
126        (self.default_selection(), selection)
127    }
128}