diesel/query_source/aliasing/
alias.rs

1use super::field_alias_mapper::FieldAliasMapper;
2use super::{AliasSource, AliasedField};
3
4use crate::backend::{sql_dialect, Backend};
5use crate::expression::{Expression, SelectableExpression, ValidGrouping};
6use crate::helper_types::AliasedFields;
7use crate::query_builder::{AsQuery, AstPass, FromClause, QueryFragment, QueryId, SelectStatement};
8use crate::query_source::{
9    AppearsInFromClause, Never, QueryRelation, QueryRelationField, QuerySource, TableNotEqual,
10};
11use crate::result::QueryResult;
12
13use std::marker::PhantomData;
14
15#[derive(#[automatically_derived]
impl<S: ::core::fmt::Debug> ::core::fmt::Debug for Alias<S> {
    #[inline]
    fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
        ::core::fmt::Formatter::debug_struct_field1_finish(f, "Alias",
            "source", &&self.source)
    }
}Debug, #[automatically_derived]
impl<S: ::core::clone::Clone> ::core::clone::Clone for Alias<S> {
    #[inline]
    fn clone(&self) -> Alias<S> {
        Alias { source: ::core::clone::Clone::clone(&self.source) }
    }
}Clone, #[automatically_derived]
impl<S: ::core::marker::Copy> ::core::marker::Copy for Alias<S> { }Copy, #[automatically_derived]
impl<S: ::core::default::Default> ::core::default::Default for Alias<S> {
    #[inline]
    fn default() -> Alias<S> {
        Alias { source: ::core::default::Default::default() }
    }
}Default)]
16/// Represents an alias within diesel's query builder
17///
18/// See [`alias!`](crate::alias) for more details.
19#[doc = " Represents an alias within diesel\'s query builder"]
#[doc = ""]
#[doc = " See [`alias!`](crate::alias) for more details."]
#[non_exhaustive]
pub struct Alias<S> {
    #[doc = " The inner alias definition"]
    pub source: S,
}#[diesel_derives::__diesel_public_if(
20    feature = "i-implement-a-third-party-backend-and-opt-into-breaking-changes",
21    public_fields(source)
22)]
23pub struct Alias<S> {
24    /// The inner alias definition
25    pub(crate) source: S,
26}
27
28impl<S: AliasSource> Alias<S> {
29    /// Maps a single field of the source table in this alias
30    pub fn field<F>(&self, field: F) -> AliasedField<S, F>
31    where
32        F: QueryRelationField<QueryRelation = S::Target>,
33    {
34        AliasedField {
35            _alias_source: PhantomData,
36            _field: field,
37        }
38    }
39    /// Maps multiple fields of the source table in this alias
40    /// (takes in tuples and some expressions)
41    pub fn fields<Fields>(&self, fields: Fields) -> AliasedFields<S, Fields>
42    where
43        Fields: FieldAliasMapper<S>,
44    {
45        fields.map(self)
46    }
47}
48
49impl<S> Alias<S> {
50    #[doc(hidden)]
51    /// May be used to create an alias. Used by the [`alias!`](crate::alias) macro.
52    pub const fn new(source: S) -> Self {
53        Self { source }
54    }
55}
56
57impl<S> QueryId for Alias<S>
58where
59    Self: 'static,
60    S: AliasSource,
61    S::Target: QueryId,
62{
63    type QueryId = Self;
64    const HAS_STATIC_QUERY_ID: bool = <S::Target as QueryId>::HAS_STATIC_QUERY_ID;
65}
66
67impl<S> QuerySource for Alias<S>
68where
69    Self: Clone,
70    S: AliasSource,
71    S::Target: QuerySource,
72    <S::Target as QuerySource>::DefaultSelection: FieldAliasMapper<S>,
73    <<S::Target as QuerySource>::DefaultSelection as FieldAliasMapper<S>>::Out:
74        SelectableExpression<Self>,
75{
76    type FromClause = Self;
77    type DefaultSelection =
78        <<S::Target as QuerySource>::DefaultSelection as FieldAliasMapper<S>>::Out;
79
80    fn from_clause(&self) -> Self::FromClause {
81        self.clone()
82    }
83
84    fn default_selection(&self) -> Self::DefaultSelection {
85        self.fields(self.source.target().default_selection())
86    }
87}
88
89impl<S, DB> QueryFragment<DB> for Alias<S>
90where
91    S: AliasSource,
92    DB: Backend,
93    Self: QueryFragment<DB, DB::AliasSyntax>,
94{
95    fn walk_ast<'b>(&'b self, pass: AstPass<'_, 'b, DB>) -> QueryResult<()> {
96        <Self as QueryFragment<DB, DB::AliasSyntax>>::walk_ast(self, pass)
97    }
98}
99
100impl<S, DB> QueryFragment<DB, sql_dialect::alias_syntax::AsAliasSyntax> for Alias<S>
101where
102    S: AliasSource,
103    DB: Backend,
104    S::Target: QueryFragment<DB>,
105{
106    fn walk_ast<'b>(&'b self, mut pass: AstPass<'_, 'b, DB>) -> QueryResult<()> {
107        self.source.target().walk_ast(pass.reborrow())?;
108        pass.push_sql(" AS ");
109        pass.push_identifier(S::NAME)?;
110        Ok(())
111    }
112}
113
114impl<S> AsQuery for Alias<S>
115where
116    S: AliasSource,
117    S::Target: AsQuery,
118    Self: QuerySource,
119    <Self as QuerySource>::DefaultSelection: ValidGrouping<()>,
120{
121    type SqlType = <<Self as QuerySource>::DefaultSelection as Expression>::SqlType;
122    type Query = SelectStatement<FromClause<Self>>;
123
124    fn as_query(self) -> Self::Query {
125        SelectStatement::simple(self)
126    }
127}
128
129/// This trait is used to allow external crates to implement
130/// `AppearsInFromClause<QS> for Alias<S>`
131///
132/// at the table level without running in conflicting impl issues
133///
134/// Implementing this at the table level (in the crate that defines the tables)
135/// does not result in conflicting impl issues because the table is the struct
136/// we're implementing on.
137pub trait AliasAppearsInFromClause<S, QS> {
138    /// Will be passed on to the `impl AppearsInFromClause<QS>`
139    type Count;
140}
141impl<S, QS> AppearsInFromClause<QS> for Alias<S>
142where
143    S: AliasSource,
144    S::Target: AliasAppearsInFromClause<S, QS>,
145{
146    type Count = <S::Target as AliasAppearsInFromClause<S, QS>>::Count;
147}
148
149/// This trait is used to allow external crates to implement
150/// `AppearsInFromClause<Alias<S2>> for Alias<S1>`
151///
152/// at the table level without running in conflicting impl issues
153///
154/// Implementing this at the table level (in the crate that defines the tables)
155/// does not result in conflicting impl issues because the tables are specified as both first
156/// argument of the trait and struct we're implementing on.
157pub trait AliasAliasAppearsInFromClause<T2, S1, S2> {
158    /// Will be passed on to the `impl AppearsInFromClause<QS>`
159    type Count;
160}
161impl<T1, S1, S2> AliasAppearsInFromClause<S1, Alias<S2>> for T1
162where
163    S2: AliasSource,
164    T1: AliasAliasAppearsInFromClause<S2::Target, S1, S2>,
165{
166    type Count = <T1 as AliasAliasAppearsInFromClause<S2::Target, S1, S2>>::Count;
167}
168
169/// This trait is used to allow external crates to implement
170/// `AppearsInFromClause<Alias<S2>> for Alias<S1>`
171///
172/// at the alias level without running in conflicting impl issues
173///
174/// Implementing this at the alias level (in the crate that defines the aliases)
175/// does not result in conflicting impl issues because the aliases are specified as both first
176/// argument of the trait and struct we're implementing on.
177///
178/// The corresponding implementation of `AliasAliasAppearsInFromClause` for implementors of this
179/// trait is done at the table level, to avoid conflict with the implementation for distinct tables
180/// below.
181pub trait AliasAliasAppearsInFromClauseSameTable<S2, T> {
182    /// Will be passed on to the `impl AppearsInFromClause<QS>`
183    type Count;
184}
185
186// impl<S: AliasSource<Table=T1>> AppearsInFromClause<T2> for Alias<S>
187// where T1 != T2
188impl<T1, T2, S> AliasAppearsInFromClause<S, T2> for T1
189where
190    T1: TableNotEqual<T2> + QueryRelation,
191    T2: QueryRelation,
192    S: AliasSource<Target = T1>,
193{
194    type Count = Never;
195}
196
197// impl<S1, S2> AppearsInFromClause<Alias<S1>> for Alias<S2>
198// where S1: AliasSource, S2: AliasSource, S1::Table != S2::Table
199impl<T1, T2, S1, S2> AliasAliasAppearsInFromClause<T1, S2, S1> for T2
200where
201    T1: TableNotEqual<T2> + QueryRelation,
202    T2: QueryRelation,
203    S1: AliasSource<Target = T1>,
204    S2: AliasSource<Target = T2>,
205{
206    type Count = Never;
207}
208
209/// To be able to define `helper_types::Fields` with the usual conventions
210///
211/// This type is intentionally not publicly exported
212#[allow(unreachable_pub)]
213pub trait GetAliasSourceFromAlias {
214    type Source;
215}
216
217impl<S> GetAliasSourceFromAlias for Alias<S> {
218    type Source = S;
219}