diesel/expression/
coerce.rs

1use crate::expression::*;
2use crate::query_builder::*;
3use crate::result::QueryResult;
4use crate::sql_types::DieselNumericOps;
5use std::marker::PhantomData;
6
7#[derive(#[automatically_derived]
impl<T: ::core::fmt::Debug, ST: ::core::fmt::Debug> ::core::fmt::Debug for
    Coerce<T, ST> {
    #[inline]
    fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
        ::core::fmt::Formatter::debug_struct_field2_finish(f, "Coerce",
            "expr", &self.expr, "_marker", &&self._marker)
    }
}Debug, #[automatically_derived]
impl<T: ::core::marker::Copy, ST: ::core::marker::Copy> ::core::marker::Copy
    for Coerce<T, ST> {
}Copy, #[automatically_derived]
impl<T: ::core::clone::Clone, ST: ::core::clone::Clone> ::core::clone::Clone
    for Coerce<T, ST> {
    #[inline]
    fn clone(&self) -> Coerce<T, ST> {
        Coerce {
            expr: ::core::clone::Clone::clone(&self.expr),
            _marker: ::core::clone::Clone::clone(&self._marker),
        }
    }
}Clone, const _: () =
    {
        use diesel;
        #[allow(non_camel_case_types)]
        impl<T: diesel::query_builder::QueryId,
            ST: diesel::query_builder::QueryId> diesel::query_builder::QueryId
            for Coerce<T, ST> {
            type QueryId =
                Coerce<<T as diesel::query_builder::QueryId>::QueryId,
                <ST as diesel::query_builder::QueryId>::QueryId>;
            const HAS_STATIC_QUERY_ID: bool =
                <T as diesel::query_builder::QueryId>::HAS_STATIC_QUERY_ID &&
                        <ST as diesel::query_builder::QueryId>::HAS_STATIC_QUERY_ID
                    && true;
            const IS_WINDOW_FUNCTION: bool =
                <T as diesel::query_builder::QueryId>::IS_WINDOW_FUNCTION ||
                        <ST as diesel::query_builder::QueryId>::IS_WINDOW_FUNCTION
                    || false;
        }
    };QueryId, 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<T, ST, __Rhs> ::std::ops::Add<__Rhs> for Coerce<T, ST> 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<T, ST, __Rhs> ::std::ops::Sub<__Rhs> for Coerce<T, ST> 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<T, ST, __Rhs> ::std::ops::Mul<__Rhs> for Coerce<T, ST> 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<T, ST, __Rhs> ::std::ops::Div<__Rhs> for Coerce<T, ST> 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)]
8#[doc(hidden)]
9/// Coerces an expression to be another type. No checks are performed to ensure
10/// that the new type is valid in all positions that the previous type was.
11/// This does not perform an actual cast, it just lies to our type system.
12///
13/// This is used for a few expressions where we know that the types are actually
14/// always interchangeable. (Examples of this include `Timestamp` vs
15/// `Timestamptz`, `VarChar` vs `Text`, and `Json` vs `Jsonb`).
16///
17/// This struct should not be considered a general solution to equivalent types.
18/// It is a short term workaround for expressions which are known to be commonly
19/// used.
20pub struct Coerce<T, ST> {
21    expr: T,
22    _marker: PhantomData<ST>,
23}
24
25impl<T, ST> Coerce<T, ST> {
26    pub fn new(expr: T) -> Self {
27        Coerce {
28            expr: expr,
29            _marker: PhantomData,
30        }
31    }
32}
33
34impl<T, ST> Expression for Coerce<T, ST>
35where
36    T: Expression,
37    ST: SqlType + TypedExpressionType,
38{
39    type SqlType = ST;
40}
41
42impl<T, ST, QS> SelectableExpression<QS> for Coerce<T, ST>
43where
44    T: SelectableExpression<QS>,
45    Self: Expression,
46{
47}
48
49impl<T, ST, QS> AppearsOnTable<QS> for Coerce<T, ST>
50where
51    T: AppearsOnTable<QS>,
52    Self: Expression,
53{
54}
55
56impl<T, ST, DB> QueryFragment<DB> for Coerce<T, ST>
57where
58    T: QueryFragment<DB>,
59    DB: Backend,
60{
61    fn walk_ast<'b>(&'b self, pass: AstPass<'_, 'b, DB>) -> QueryResult<()> {
62        self.expr.walk_ast(pass)
63    }
64}
65
66impl<T, ST, GB> ValidGrouping<GB> for Coerce<T, ST>
67where
68    T: ValidGrouping<GB>,
69{
70    type IsAggregate = T::IsAggregate;
71}