1use super::field_alias_mapper::FieldAliasMapper;
2use super::{AliasSource, AliasedField};
34use crate::backend::{Backend, sql_dialect};
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::{
9AppearsInFromClause, Never, QueryRelation, QueryRelationField, QuerySource, TableNotEqual,
10};
11use crate::result::QueryResult;
1213use core::marker::PhantomData;
1415#[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
25pub(crate) source: S,
26}
2728impl<S: AliasSource> Alias<S> {
29/// Maps a single field of the source table in this alias
30pub fn field<F>(&self, field: F) -> AliasedField<S, F>
31where
32F: QueryRelationField<QueryRelation = S::Target>,
33 {
34AliasedField {
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)
41pub fn fields<Fields>(&self, fields: Fields) -> AliasedFields<S, Fields>
42where
43Fields: FieldAliasMapper<S>,
44 {
45fields.map(self)
46 }
47}
4849impl<S> Alias<S> {
50#[doc(hidden)]
51/// May be used to create an alias. Used by the [`alias!`](crate::alias) macro.
52pub const fn new(source: S) -> Self {
53Self { source }
54 }
55}
5657impl<S> QueryIdfor Alias<S>
58where
59Self: 'static,
60 S: AliasSource,
61 S::Target: QueryId,
62{
63type QueryId = Self;
64const HAS_STATIC_QUERY_ID: bool = <S::Target as QueryId>::HAS_STATIC_QUERY_ID;
65}
6667impl<S> QuerySourcefor Alias<S>
68where
69Self: Clone,
70 S: AliasSource,
71 S::Target: QuerySource,
72 <S::Target as QuerySource>::DefaultSelection: FieldAliasMapper<S>,
73 <<S::Target as QuerySource>::DefaultSelectionas FieldAliasMapper<S>>::Out:
74SelectableExpression<Self>,
75{
76type FromClause = Self;
77type DefaultSelection =
78 <<S::Target as QuerySource>::DefaultSelectionas FieldAliasMapper<S>>::Out;
7980fn from_clause(&self) -> Self::FromClause {
81self.clone()
82 }
8384fn default_selection(&self) -> Self::DefaultSelection {
85self.fields(self.source.target().default_selection())
86 }
87}
8889impl<S, DB> QueryFragment<DB> for Alias<S>
90where
91S: AliasSource,
92 DB: Backend,
93Self: QueryFragment<DB, DB::AliasSyntax>,
94{
95fn walk_ast<'b>(&'b self, pass: AstPass<'_, 'b, DB>) -> QueryResult<()> {
96 <Self as QueryFragment<DB, DB::AliasSyntax>>::walk_ast(self, pass)
97 }
98}
99100impl<S, DB> QueryFragment<DB, sql_dialect::alias_syntax::AsAliasSyntax> for Alias<S>
101where
102S: AliasSource,
103 DB: Backend,
104 S::Target: QueryFragment<DB>,
105{
106fn walk_ast<'b>(&'b self, mut pass: AstPass<'_, 'b, DB>) -> QueryResult<()> {
107self.source.target().walk_ast(pass.reborrow())?;
108pass.push_sql(" AS ");
109 pass.push_identifier(S::NAME)?;
110Ok(())
111 }
112}
113114impl<S> AsQueryfor Alias<S>
115where
116S: AliasSource,
117 S::Target: AsQuery,
118Self: QuerySource,
119 <Self as QuerySource>::DefaultSelection: ValidGrouping<()>,
120{
121type SqlType = <<Self as QuerySource>::DefaultSelectionas Expression>::SqlType;
122type Query = SelectStatement<FromClause<Self>>;
123124fn as_query(self) -> Self::Query {
125SelectStatement::simple(self)
126 }
127}
128129/// 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>`
139type Count;
140}
141impl<S, QS> AppearsInFromClause<QS> for Alias<S>
142where
143S: AliasSource,
144 S::Target: AliasAppearsInFromClause<S, QS>,
145{
146type Count = <S::Target as AliasAppearsInFromClause<S, QS>>::Count;
147}
148149/// 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>`
159type Count;
160}
161impl<T1, S1, S2> AliasAppearsInFromClause<S1, Alias<S2>> for T1
162where
163S2: AliasSource,
164 T1: AliasAliasAppearsInFromClause<S2::Target, S1, S2>,
165{
166type Count = <T1 as AliasAliasAppearsInFromClause<S2::Target, S1, S2>>::Count;
167}
168169/// 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>`
183type Count;
184}
185186// impl<S: AliasSource<Table=T1>> AppearsInFromClause<T2> for Alias<S>
187// where T1 != T2
188impl<T1, T2, S> AliasAppearsInFromClause<S, T2> for T1
189where
190T1: TableNotEqual<T2> + QueryRelation,
191 T2: QueryRelation,
192 S: AliasSource<Target = T1>,
193{
194type Count = Never;
195}
196197// 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
201T1: TableNotEqual<T2> + QueryRelation,
202 T2: QueryRelation,
203 S1: AliasSource<Target = T1>,
204 S2: AliasSource<Target = T2>,
205{
206type Count = Never;
207}
208209/// 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 {
214type Source;
215}
216217impl<S> GetAliasSourceFromAliasfor Alias<S> {
218type Source = S;
219}