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