diesel/expression/
count.rs

1#[cfg(doc)]
2use super::functions::aggregate_expressions::{
3    AggregateExpressionMethods, WindowExpressionMethods,
4};
5use super::functions::declare_sql_function;
6use super::{Expression, ValidGrouping};
7use crate::backend::Backend;
8use crate::internal::sql_functions::{
9    FunctionFragment, IsWindowFunction, OverClause, WindowFunctionFragment,
10};
11use crate::query_builder::*;
12use crate::result::QueryResult;
13use crate::sql_types::{BigInt, DieselNumericOps, SingleValue, SqlType};
14
15#[doc(hidden)]
#[allow(non_camel_case_types, non_snake_case, unused_imports)]
pub(crate) mod count_utils {
    use diesel::{self, QueryResult};
    use diesel::expression::{
        AsExpression, Expression, SelectableExpression, AppearsOnTable,
        ValidGrouping,
    };
    use diesel::query_builder::{QueryFragment, AstPass};
    use diesel::sql_types::*;
    use diesel::internal::sql_functions::*;
    use super::*;
    pub struct count<T, expr> {
        pub(in super) expr: expr,
        pub(in super) T: ::std::marker::PhantomData<T>,
    }
    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, expr, __Rhs> ::std::ops::Add<__Rhs> for count<T, expr>
                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, expr, __Rhs> ::std::ops::Sub<__Rhs> for count<T, expr>
                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, expr, __Rhs> ::std::ops::Mul<__Rhs> for count<T, expr>
                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, expr, __Rhs> ::std::ops::Div<__Rhs> for count<T, expr>
                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())
                }
            }
        };
    #[automatically_derived]
    impl<T: ::core::fmt::Debug, expr: ::core::fmt::Debug> ::core::fmt::Debug
        for count<T, expr> {
        #[inline]
        fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
            ::core::fmt::Formatter::debug_struct_field2_finish(f, "count",
                "expr", &self.expr, "T", &&self.T)
        }
    }
    #[automatically_derived]
    impl<T: ::core::clone::Clone, expr: ::core::clone::Clone>
        ::core::clone::Clone for count<T, expr> {
        #[inline]
        fn clone(&self) -> count<T, expr> {
            count {
                expr: ::core::clone::Clone::clone(&self.expr),
                T: ::core::clone::Clone::clone(&self.T),
            }
        }
    }
    #[automatically_derived]
    impl<T: ::core::marker::Copy, expr: ::core::marker::Copy>
        ::core::marker::Copy for count<T, expr> {
    }
    const _: () =
        {
            use diesel;
            #[allow(non_camel_case_types)]
            impl<T: diesel::query_builder::QueryId,
                expr: diesel::query_builder::QueryId>
                diesel::query_builder::QueryId for count<T, expr> {
                type QueryId =
                    count<<T as diesel::query_builder::QueryId>::QueryId,
                    <expr as diesel::query_builder::QueryId>::QueryId>;
                const HAS_STATIC_QUERY_ID: bool =
                    <T as diesel::query_builder::QueryId>::HAS_STATIC_QUERY_ID
                            &&
                            <expr as
                                diesel::query_builder::QueryId>::HAS_STATIC_QUERY_ID &&
                        true;
                const IS_WINDOW_FUNCTION: bool =
                    <T as diesel::query_builder::QueryId>::IS_WINDOW_FUNCTION ||
                            <expr as diesel::query_builder::QueryId>::IS_WINDOW_FUNCTION
                        || false;
            }
        };
    #[doc = "The return type of [`count()`](super::fn_name)"]
    pub type HelperType<T, expr> =
        count<T, <expr as AsExpression<T>>::Expression>;
    impl<T: SqlType + SingleValue, expr> Expression for count<T, expr> where
        (expr): Expression {
        type SqlType = BigInt;
    }
    impl<T: SqlType + SingleValue, expr, __DieselInternal>
        SelectableExpression<__DieselInternal> for count<T, expr> where
        expr: SelectableExpression<__DieselInternal>,
        Self: AppearsOnTable<__DieselInternal> {}
    impl<T: SqlType + SingleValue, expr, __DieselInternal>
        AppearsOnTable<__DieselInternal> for count<T, expr> where
        expr: AppearsOnTable<__DieselInternal>, Self: Expression {}
    impl<T: SqlType + SingleValue, expr, __DieselInternal>
        FunctionFragment<__DieselInternal> for count<T, expr> where
        __DieselInternal: diesel::backend::Backend,
        expr: QueryFragment<__DieselInternal> {
        const FUNCTION_NAME: &'static str = "count";
        #[allow(unused_assignments)]
        fn walk_arguments<'__b>(&'__b self,
            mut out: AstPass<'_, '__b, __DieselInternal>) -> QueryResult<()> {
            let mut needs_comma = false;
            if !self.expr.is_noop(out.backend())? {
                if needs_comma { out.push_sql(", "); }
                self.expr.walk_ast(out.reborrow())?;
                needs_comma = true;
            }
            Ok(())
        }
    }
    impl<T: SqlType + SingleValue, expr, __DieselInternal>
        QueryFragment<__DieselInternal> for count<T, expr> where
        __DieselInternal: diesel::backend::Backend,
        expr: QueryFragment<__DieselInternal> {
        fn walk_ast<'__b>(&'__b self,
            mut out: AstPass<'_, '__b, __DieselInternal>) -> QueryResult<()> {
            out.push_sql(<Self as
                    FunctionFragment<__DieselInternal>>::FUNCTION_NAME);
            out.push_sql("(");
            self.walk_arguments(out.reborrow())?;
            out.push_sql(")");
            Ok(())
        }
    }
    impl<T: SqlType + SingleValue, expr, __P, __O, __F, __DieselInternal>
        WindowFunctionFragment<count<T, expr>, __DieselInternal> for
        OverClause<__P, __O, __F> where
        __DieselInternal: diesel::backend::Backend {}
    impl<T: SqlType + SingleValue, expr> IsWindowFunction for count<T, expr> {
        type ArgTypes = (expr,);
    }
    impl<T: SqlType + SingleValue, expr, __DieselInternal>
        ValidGrouping<__DieselInternal> for count<T, expr> {
        type IsAggregate = diesel::expression::is_aggregate::Yes;
    }
    impl<T: SqlType + SingleValue, expr> IsAggregateFunction for
        count<T, expr> {}
}#[declare_sql_function]
16extern "SQL" {
17    /// Creates a SQL `COUNT` expression
18    ///
19    /// As with most bare functions, this is not exported by default. You can import
20    /// it specifically as `diesel::dsl::count`, or glob import
21    /// `diesel::dsl::*`
22    ///
23    /// ## Window Function Usage
24    ///
25    /// This function can be used as window function. See [`WindowExpressionMethods`] for details
26    ///
27    /// ## Aggregate Function Expression
28    ///
29    /// This function can be used as aggregate expression. See [`AggregateExpressionMethods`] for details.
30    ///
31    /// # Examples
32    ///
33    /// ## Normal function usage
34    ///
35    /// ```rust
36    /// # include!("../doctest_setup.rs");
37    /// # use diesel::dsl::*;
38    /// #
39    /// # fn main() {
40    /// #     use schema::animals::dsl::*;
41    /// #     let connection = &mut establish_connection();
42    /// assert_eq!(Ok(1), animals.select(count(name)).first(connection));
43    /// # }
44    /// ```
45    ///
46    /// ## Window function
47    ///
48    /// ```rust
49    /// # include!("../doctest_setup.rs");
50    /// # use diesel::dsl::*;
51    /// #
52    /// # fn main() {
53    /// #     use schema::animals::dsl::*;
54    /// #     let connection = &mut establish_connection();
55    /// assert_eq!(
56    ///     Ok(1),
57    ///     animals
58    ///         .select(count(name).partition_by(id))
59    ///         .first(connection)
60    /// );
61    /// # }
62    /// ```
63    ///
64    /// ## Aggregate function expression
65    ///
66    /// ```rust
67    /// # include!("../doctest_setup.rs");
68    /// # use diesel::dsl::*;
69    /// #
70    /// # fn main() {
71    /// #     use schema::animals::dsl::*;
72    /// #     let connection = &mut establish_connection();
73    /// assert_eq!(
74    ///     Ok(1),
75    ///     animals
76    ///         .select(count(name).aggregate_distinct())
77    ///         .first(connection)
78    /// );
79    /// # }
80    /// ```
81    #[aggregate]
82    #[window]
83    fn count<T: SqlType + SingleValue>(expr: T) -> BigInt;
84}
85
86/// Creates a SQL `COUNT(*)` expression
87///
88/// For selecting the count of a query, and nothing else, you can just call
89/// [`count`](crate::query_dsl::QueryDsl::count())
90/// on the query instead.
91///
92/// As with most bare functions, this is not exported by default. You can import
93/// it specifically as `diesel::dsl::count_star`, or glob import
94/// `diesel::dsl::*`
95///
96/// # Examples
97///
98/// ```rust
99/// # include!("../doctest_setup.rs");
100/// # use diesel::dsl::*;
101/// #
102/// # fn main() {
103/// #     use schema::users::dsl::*;
104/// #     let connection = &mut establish_connection();
105/// assert_eq!(Ok(2), users.select(count_star()).first(connection));
106/// # }
107/// ```
108pub fn count_star() -> CountStar {
109    CountStar
110}
111
112#[derive(#[automatically_derived]
impl ::core::fmt::Debug for CountStar {
    #[inline]
    fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
        ::core::fmt::Formatter::write_str(f, "CountStar")
    }
}Debug, #[automatically_derived]
impl ::core::clone::Clone for CountStar {
    #[inline]
    fn clone(&self) -> CountStar { *self }
}Clone, #[automatically_derived]
impl ::core::marker::Copy for CountStar { }Copy, const _: () =
    {
        use diesel;
        #[allow(non_camel_case_types)]
        impl diesel::query_builder::QueryId for CountStar {
            type QueryId = CountStar<>;
            const HAS_STATIC_QUERY_ID: bool = true;
            const IS_WINDOW_FUNCTION: bool = 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<__Rhs> ::std::ops::Add<__Rhs> for CountStar 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<__Rhs> ::std::ops::Sub<__Rhs> for CountStar 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<__Rhs> ::std::ops::Mul<__Rhs> for CountStar 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<__Rhs> ::std::ops::Div<__Rhs> for CountStar 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, const _: () =
    {
        use diesel;
        impl<__GroupByClause>
            diesel::expression::ValidGrouping<__GroupByClause> for CountStar {
            type IsAggregate = diesel::expression::is_aggregate::Yes;
        }
    };ValidGrouping)]
113#[diesel(aggregate)]
114#[doc(hidden)]
115pub struct CountStar;
116
117impl Expression for CountStar {
118    type SqlType = BigInt;
119}
120
121impl<DB: Backend> FunctionFragment<DB> for CountStar {
122    const FUNCTION_NAME: &'static str = "COUNT";
123
124    fn walk_arguments<'b>(&'b self, mut out: AstPass<'_, 'b, DB>) -> QueryResult<()> {
125        out.push_sql("*");
126        Ok(())
127    }
128}
129
130impl<DB: Backend> QueryFragment<DB> for CountStar {
131    fn walk_ast<'b>(&'b self, mut out: AstPass<'_, 'b, DB>) -> QueryResult<()> {
132        out.push_sql("COUNT(*)");
133        Ok(())
134    }
135}
136
137impl<Partition, Order, Frame, DB: Backend> WindowFunctionFragment<CountStar, DB>
138    for OverClause<Partition, Order, Frame>
139{
140}
141
142impl IsWindowFunction for CountStar {
143    type ArgTypes = ();
144}
145
146impl<QS> crate::expression::SelectableExpression<QS> for CountStar where
    CountStar: crate::expression::AppearsOnTable<QS> {}
impl<QS> crate::expression::AppearsOnTable<QS> for CountStar where
    CountStar: crate::expression::Expression {}impl_selectable_expression!(CountStar);
147
148#[doc(hidden)]
149#[cfg(all(feature = "with-deprecated", not(feature = "without-deprecated")))]
150#[deprecated(note = "Use `AggregateExpressionMethods::aggregate_distinct` instead")]
151pub fn count_distinct<T, E>(expr: E) -> CountDistinct<T, E::Expression>
152where
153    T: SqlType + SingleValue,
154    E: crate::expression::AsExpression<T>,
155{
156    use crate::AggregateExpressionMethods;
157
158    count(expr).aggregate_distinct()
159}
160
161#[doc(hidden)]
162#[cfg(all(feature = "with-deprecated", not(feature = "without-deprecated")))]
163pub type CountDistinct<T, E> = crate::dsl::AggregateDistinct<self::count<T, E>>;