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::query_builder::*;
9use crate::result::QueryResult;
10use crate::sql_types::{BigInt, DieselNumericOps, SingleValue, SqlType};
11
12#[declare_sql_function]
13extern "SQL" {
14    /// Creates a SQL `COUNT` expression
15    ///
16    /// As with most bare functions, this is not exported by default. You can import
17    /// it specifically as `diesel::dsl::count`, or glob import
18    /// `diesel::dsl::*`
19    ///
20    /// ## Window Function Usage
21    ///
22    /// This function can be used as window function. See [`WindowExpressionMethods`] for details
23    ///
24    /// ## Aggregate Function Expression
25    ///
26    /// This function can be used as aggregate expression. See [`AggregateExpressionMethods`] for details.
27    ///
28    /// # Examples
29    ///
30    /// ## Normal function usage
31    ///
32    /// ```rust
33    /// # include!("../doctest_setup.rs");
34    /// # use diesel::dsl::*;
35    /// #
36    /// # fn main() {
37    /// #     use schema::animals::dsl::*;
38    /// #     let connection = &mut establish_connection();
39    /// assert_eq!(Ok(1), animals.select(count(name)).first(connection));
40    /// # }
41    /// ```
42    ///
43    /// ## Window function
44    ///
45    /// ```rust
46    /// # include!("../doctest_setup.rs");
47    /// # use diesel::dsl::*;
48    /// #
49    /// # fn main() {
50    /// #     use schema::animals::dsl::*;
51    /// #     let connection = &mut establish_connection();
52    /// assert_eq!(
53    ///     Ok(1),
54    ///     animals
55    ///         .select(count(name).partition_by(id))
56    ///         .first(connection)
57    /// );
58    /// # }
59    /// ```
60    ///
61    /// ## Aggregate function expression
62    ///
63    /// ```rust
64    /// # include!("../doctest_setup.rs");
65    /// # use diesel::dsl::*;
66    /// #
67    /// # fn main() {
68    /// #     use schema::animals::dsl::*;
69    /// #     let connection = &mut establish_connection();
70    /// assert_eq!(
71    ///     Ok(1),
72    ///     animals
73    ///         .select(count(name).aggregate_distinct())
74    ///         .first(connection)
75    /// );
76    /// # }
77    /// ```
78    #[aggregate]
79    #[window]
80    fn count<T: SqlType + SingleValue>(expr: T) -> BigInt;
81}
82
83/// Creates a SQL `COUNT(*)` expression
84///
85/// For selecting the count of a query, and nothing else, you can just call
86/// [`count`](crate::query_dsl::QueryDsl::count())
87/// on the query instead.
88///
89/// As with most bare functions, this is not exported by default. You can import
90/// it specifically as `diesel::dsl::count_star`, or glob import
91/// `diesel::dsl::*`
92///
93/// # Examples
94///
95/// ```rust
96/// # include!("../doctest_setup.rs");
97/// # use diesel::dsl::*;
98/// #
99/// # fn main() {
100/// #     use schema::users::dsl::*;
101/// #     let connection = &mut establish_connection();
102/// assert_eq!(Ok(2), users.select(count_star()).first(connection));
103/// # }
104/// ```
105pub fn count_star() -> CountStar {
106    CountStar
107}
108
109#[derive(Debug, Clone, Copy, QueryId, DieselNumericOps, ValidGrouping)]
110#[diesel(aggregate)]
111#[doc(hidden)]
112pub struct CountStar;
113
114impl Expression for CountStar {
115    type SqlType = BigInt;
116}
117
118impl<DB: Backend> QueryFragment<DB> for CountStar {
119    fn walk_ast<'b>(&'b self, mut out: AstPass<'_, 'b, DB>) -> QueryResult<()> {
120        out.push_sql("COUNT(*)");
121        Ok(())
122    }
123}
124
125impl_selectable_expression!(CountStar);
126
127#[doc(hidden)]
128#[cfg(all(feature = "with-deprecated", not(feature = "without-deprecated")))]
129#[deprecated(note = "Use `AggregateExpressionMethods::aggregate_distinct` instead")]
130pub fn count_distinct<T, E>(expr: E) -> CountDistinct<T, E::Expression>
131where
132    T: SqlType + SingleValue,
133    E: crate::expression::AsExpression<T>,
134{
135    use crate::AggregateExpressionMethods;
136
137    count(expr).aggregate_distinct()
138}
139
140#[doc(hidden)]
141#[cfg(all(feature = "with-deprecated", not(feature = "without-deprecated")))]
142pub type CountDistinct<T, E> = crate::dsl::AggregateDistinct<self::count<T, E>>;