Skip to main content

diesel/query_source/aliasing/
aliased_field.rs

1use diesel_derives::DieselNumericOps;
2
3use super::{Alias, AliasSource};
4
5use crate::backend::Backend;
6use crate::dsl;
7use crate::expression::subselect::{SubselectFieldGrouping, SubselectGroupBy};
8use crate::expression::{
9    AppearsOnTable, AsExpression, Expression, SelectableExpression, ValidGrouping, is_aggregate,
10};
11use crate::expression_methods::{EqAll, ExpressionMethods};
12use crate::query_builder::{AstPass, FromClause, QueryFragment, QueryId, SelectStatement};
13use crate::query_source::{AppearsInFromClause, Once, QueryRelationField, QuerySource};
14use crate::result::QueryResult;
15use crate::sql_types;
16
17use core::marker::PhantomData;
18
19#[derive(#[automatically_derived]
impl<S: ::core::fmt::Debug, F: ::core::fmt::Debug> ::core::fmt::Debug for
    AliasedField<S, F> {
    #[inline]
    fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
        ::core::fmt::Formatter::debug_struct_field2_finish(f, "AliasedField",
            "_alias_source", &self._alias_source, "_field", &&self._field)
    }
}Debug, #[automatically_derived]
impl<S: ::core::clone::Clone, F: ::core::clone::Clone> ::core::clone::Clone
    for AliasedField<S, F> {
    #[inline]
    fn clone(&self) -> Self {
        Self {
            _alias_source: ::core::clone::Clone::clone(&self._alias_source),
            _field: ::core::clone::Clone::clone(&self._field),
        }
    }
}Clone, #[automatically_derived]
impl<S: ::core::marker::Copy, F: ::core::marker::Copy> ::core::marker::Copy
    for AliasedField<S, F> {
}Copy, const _: () =
    {
        use diesel;
        use diesel::internal::derives::numeric_ops as ops;
        use diesel::expression::{Expression, AsExpression};
        use diesel::sql_types::ops::{Add, Sub, Mul, Div};
        use diesel::sql_types::{SqlType, SingleValue};
        impl<S, F, __Rhs> ::core::ops::Add<__Rhs> for AliasedField<S, F> where
            Self: Expression, Self: Expression,
            <Self as Expression>::SqlType: Add,
            <<Self as Expression>::SqlType as Add>::Rhs: SqlType +
            SingleValue,
            __Rhs: AsExpression<<<Self as Expression>::SqlType as Add>::Rhs> {
            type Output = ops::Add<Self, __Rhs::Expression>;
            fn add(self, rhs: __Rhs) -> Self::Output {
                ops::Add::new(self, rhs.as_expression())
            }
        }
        impl<S, F, __Rhs> ::core::ops::Sub<__Rhs> for AliasedField<S, F> where
            Self: Expression, Self: Expression,
            <Self as Expression>::SqlType: Sub,
            <<Self as Expression>::SqlType as Sub>::Rhs: SqlType +
            SingleValue,
            __Rhs: AsExpression<<<Self as Expression>::SqlType as Sub>::Rhs> {
            type Output = ops::Sub<Self, __Rhs::Expression>;
            fn sub(self, rhs: __Rhs) -> Self::Output {
                ops::Sub::new(self, rhs.as_expression())
            }
        }
        impl<S, F, __Rhs> ::core::ops::Mul<__Rhs> for AliasedField<S, F> where
            Self: Expression, Self: Expression,
            <Self as Expression>::SqlType: Mul,
            <<Self as Expression>::SqlType as Mul>::Rhs: SqlType +
            SingleValue,
            __Rhs: AsExpression<<<Self as Expression>::SqlType as Mul>::Rhs> {
            type Output = ops::Mul<Self, __Rhs::Expression>;
            fn mul(self, rhs: __Rhs) -> Self::Output {
                ops::Mul::new(self, rhs.as_expression())
            }
        }
        impl<S, F, __Rhs> ::core::ops::Div<__Rhs> for AliasedField<S, F> where
            Self: Expression, Self: Expression,
            <Self as Expression>::SqlType: Div,
            <<Self as Expression>::SqlType as Div>::Rhs: SqlType +
            SingleValue,
            __Rhs: AsExpression<<<Self as Expression>::SqlType as Div>::Rhs> {
            type Output = ops::Div<Self, __Rhs::Expression>;
            fn div(self, rhs: __Rhs) -> Self::Output {
                ops::Div::new(self, rhs.as_expression())
            }
        }
    };DieselNumericOps)]
20/// Represents an aliased field (column) within diesel's query builder
21///
22/// See [`alias!`](crate::alias) for more details.
23pub struct AliasedField<S, F> {
24    pub(super) _alias_source: PhantomData<S>,
25    pub(super) _field: F,
26}
27
28impl<S, C> QueryId for AliasedField<S, C>
29where
30    S: AliasSource + 'static,
31    S::Target: 'static,
32    C: QueryRelationField<QueryRelation = S::Target> + 'static + QueryId,
33{
34    type QueryId = Self;
35    const HAS_STATIC_QUERY_ID: bool = <C as QueryId>::HAS_STATIC_QUERY_ID;
36}
37
38impl<QS, S, C> AppearsOnTable<QS> for AliasedField<S, C>
39where
40    S: AliasSource,
41    QS: AppearsInFromClause<Alias<S>, Count = Once>,
42    C: QueryRelationField<QueryRelation = S::Target>,
43{
44}
45
46impl<S, C, DB> QueryFragment<DB> for AliasedField<S, C>
47where
48    S: AliasSource,
49    DB: Backend,
50    C: QueryRelationField<QueryRelation = S::Target>,
51{
52    fn walk_ast<'b>(&'b self, mut pass: AstPass<'_, 'b, DB>) -> QueryResult<()> {
53        pass.push_identifier(S::NAME)?;
54        pass.push_sql(".");
55        pass.push_identifier(C::NAME)?;
56        Ok(())
57    }
58}
59
60impl<S, C> Expression for AliasedField<S, C>
61where
62    S: AliasSource,
63    C: QueryRelationField<QueryRelation = S::Target> + Expression,
64{
65    type SqlType = C::SqlType;
66}
67
68impl<S, C> SelectableExpression<Alias<S>> for AliasedField<S, C>
69where
70    S: AliasSource,
71    C: QueryRelationField<QueryRelation = S::Target>,
72    Self: AppearsOnTable<Alias<S>>,
73{
74}
75
76impl<S, C> ValidGrouping<()> for AliasedField<S, C>
77where
78    S: AliasSource,
79    C: QueryRelationField<QueryRelation = S::Target>,
80{
81    type IsAggregate = is_aggregate::No;
82}
83
84impl<S, C1, C2> ValidGrouping<AliasedField<S, C1>> for AliasedField<S, C2>
85where
86    S: AliasSource,
87    C1: QueryRelationField<QueryRelation = S::Target>,
88    C2: QueryRelationField<QueryRelation = S::Target>,
89    C2: ValidGrouping<C1, IsAggregate = is_aggregate::Yes>,
90{
91    type IsAggregate = is_aggregate::Yes;
92}
93
94impl<S, C, GB, From> ValidGrouping<SubselectGroupBy<GB, From>> for AliasedField<S, C>
95where
96    S: AliasSource,
97    C: QueryRelationField<QueryRelation = S::Target>,
98    From: AppearsInFromClause<Alias<S>>,
99    From::Count: SubselectFieldGrouping<Self, GB>,
100{
101    type IsAggregate = <From::Count as SubselectFieldGrouping<Self, GB>>::IsAggregate;
102}
103
104// FIXME: Remove this when overlapping marker traits are stable
105impl<From, S, C> SelectableExpression<SelectStatement<FromClause<From>>> for AliasedField<S, C>
106where
107    Self: SelectableExpression<From> + AppearsOnTable<SelectStatement<FromClause<From>>>,
108    From: QuerySource,
109{
110}
111
112impl<S, C, T> EqAll<T> for AliasedField<S, C>
113where
114    S: AliasSource,
115    C: QueryRelationField<QueryRelation = S::Target>,
116    Self: ExpressionMethods,
117    <Self as Expression>::SqlType: sql_types::SqlType,
118    T: AsExpression<<Self as Expression>::SqlType>,
119    dsl::Eq<Self, T>: Expression<SqlType = sql_types::Bool>,
120{
121    type Output = dsl::Eq<Self, T>;
122
123    fn eq_all(self, rhs: T) -> Self::Output {
124        self.eq(rhs)
125    }
126}