diesel/query_source/aliasing/
alias.rs1use 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::{AppearsInFromClause, Column, Never, QuerySource, Table, TableNotEqual};
9use crate::result::QueryResult;
10
11use std::marker::PhantomData;
12
13#[derive(Debug, Clone, Copy, Default)]
14#[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 pub(crate) source: S,
24}
25
26impl<S: AliasSource> Alias<S> {
27 pub fn field<F>(&self, field: F) -> AliasedField<S, F>
29 where
30 F: Column<Table = S::Target>,
31 {
32 AliasedField {
33 _alias_source: PhantomData,
34 _field: field,
35 }
36 }
37 pub fn fields<Fields>(&self, fields: Fields) -> AliasedFields<S, Fields>
40 where
41 Fields: FieldAliasMapper<S>,
42 {
43 fields.map(self)
44 }
45}
46
47impl<S> Alias<S> {
48 #[doc(hidden)]
49 pub const fn new(source: S) -> Self {
51 Self { source }
52 }
53}
54
55impl<S> QueryId for Alias<S>
56where
57 Self: 'static,
58 S: AliasSource,
59 S::Target: QueryId,
60{
61 type QueryId = Self;
62 const HAS_STATIC_QUERY_ID: bool = <S::Target as QueryId>::HAS_STATIC_QUERY_ID;
63}
64
65impl<S> QuerySource for Alias<S>
66where
67 Self: 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{
74 type FromClause = Self;
75 type DefaultSelection =
76 <<S::Target as QuerySource>::DefaultSelection as FieldAliasMapper<S>>::Out;
77
78 fn from_clause(&self) -> Self::FromClause {
79 self.clone()
80 }
81
82 fn default_selection(&self) -> Self::DefaultSelection {
83 self.fields(self.source.target().default_selection())
84 }
85}
86
87impl<S, DB> QueryFragment<DB> for Alias<S>
88where
89 S: AliasSource,
90 DB: Backend,
91 Self: QueryFragment<DB, DB::AliasSyntax>,
92{
93 fn walk_ast<'b>(&'b self, pass: AstPass<'_, 'b, DB>) -> QueryResult<()> {
94 <Self as QueryFragment<DB, DB::AliasSyntax>>::walk_ast(self, pass)
95 }
96}
97
98impl<S, DB> QueryFragment<DB, sql_dialect::alias_syntax::AsAliasSyntax> for Alias<S>
99where
100 S: AliasSource,
101 DB: Backend,
102 S::Target: QueryFragment<DB>,
103{
104 fn walk_ast<'b>(&'b self, mut pass: AstPass<'_, 'b, DB>) -> QueryResult<()> {
105 self.source.target().walk_ast(pass.reborrow())?;
106 pass.push_sql(" AS ");
107 pass.push_identifier(S::NAME)?;
108 Ok(())
109 }
110}
111
112impl<S> AsQuery for Alias<S>
113where
114 S: AliasSource,
115 S::Target: AsQuery,
116 Self: QuerySource,
117 <Self as QuerySource>::DefaultSelection: ValidGrouping<()>,
118{
119 type SqlType = <<Self as QuerySource>::DefaultSelection as Expression>::SqlType;
120 type Query = SelectStatement<FromClause<Self>>;
121
122 fn as_query(self) -> Self::Query {
123 SelectStatement::simple(self)
124 }
125}
126
127pub trait AliasAppearsInFromClause<S, QS> {
136 type Count;
138}
139impl<S, QS> AppearsInFromClause<QS> for Alias<S>
140where
141 S: AliasSource,
142 S::Target: AliasAppearsInFromClause<S, QS>,
143{
144 type Count = <S::Target as AliasAppearsInFromClause<S, QS>>::Count;
145}
146
147pub trait AliasAliasAppearsInFromClause<T2, S1, S2> {
156 type Count;
158}
159impl<T1, S1, S2> AliasAppearsInFromClause<S1, Alias<S2>> for T1
160where
161 S2: AliasSource,
162 T1: AliasAliasAppearsInFromClause<S2::Target, S1, S2>,
163{
164 type Count = <T1 as AliasAliasAppearsInFromClause<S2::Target, S1, S2>>::Count;
165}
166
167pub trait AliasAliasAppearsInFromClauseSameTable<S2, T> {
180 type Count;
182}
183
184impl<T1, T2, S> AliasAppearsInFromClause<S, T2> for T1
187where
188 T1: TableNotEqual<T2> + Table,
189 T2: Table,
190 S: AliasSource<Target = T1>,
191{
192 type Count = Never;
193}
194
195impl<T1, T2, S1, S2> AliasAliasAppearsInFromClause<T1, S2, S1> for T2
198where
199 T1: TableNotEqual<T2> + Table,
200 T2: Table,
201 S1: AliasSource<Target = T1>,
202 S2: AliasSource<Target = T2>,
203{
204 type Count = Never;
205}
206
207#[allow(unreachable_pub)]
211pub trait GetAliasSourceFromAlias {
212 type Source;
213}
214
215impl<S> GetAliasSourceFromAlias for Alias<S> {
216 type Source = S;
217}