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