diesel/expression/
count.rs1use std::marker::PhantomData;
2
3use super::functions::define_sql_function;
4use super::{is_aggregate, AsExpression};
5use super::{Expression, ValidGrouping};
6use crate::backend::Backend;
7use crate::query_builder::*;
8use crate::result::QueryResult;
9use crate::sql_types::{BigInt, DieselNumericOps, SingleValue, SqlType};
10use crate::{AppearsOnTable, SelectableExpression};
11
12define_sql_function! {
13    #[aggregate]
32    fn count<T: SqlType + SingleValue>(expr: T) -> BigInt;
33}
34
35pub fn count_star() -> CountStar {
58    CountStar
59}
60
61#[derive(Debug, Clone, Copy, QueryId, DieselNumericOps, ValidGrouping)]
62#[diesel(aggregate)]
63#[doc(hidden)]
64pub struct CountStar;
65
66impl Expression for CountStar {
67    type SqlType = BigInt;
68}
69
70impl<DB: Backend> QueryFragment<DB> for CountStar {
71    fn walk_ast<'b>(&'b self, mut out: AstPass<'_, 'b, DB>) -> QueryResult<()> {
72        out.push_sql("COUNT(*)");
73        Ok(())
74    }
75}
76
77impl_selectable_expression!(CountStar);
78
79pub fn count_distinct<T, E>(expr: E) -> CountDistinct<T, E::Expression>
100where
101    T: SqlType + SingleValue,
102    E: AsExpression<T>,
103{
104    CountDistinct {
105        expr: expr.as_expression(),
106        _marker: PhantomData,
107    }
108}
109
110#[derive(Debug, Clone, Copy, QueryId, DieselNumericOps)]
111#[doc(hidden)]
112pub struct CountDistinct<T, E> {
113    expr: E,
114    _marker: PhantomData<T>,
115}
116
117impl<T, E> Expression for CountDistinct<T, E>
118where
119    T: SqlType + SingleValue,
120    E: Expression,
121{
122    type SqlType = BigInt;
123}
124
125impl<T, E, GB> ValidGrouping<GB> for CountDistinct<T, E>
126where
127    T: SqlType + SingleValue,
128{
129    type IsAggregate = is_aggregate::Yes;
130}
131
132impl<T, E, QS> SelectableExpression<QS> for CountDistinct<T, E>
133where
134    Self: AppearsOnTable<QS>,
135    E: SelectableExpression<QS>,
136{
137}
138
139impl<T, E, QS> AppearsOnTable<QS> for CountDistinct<T, E>
140where
141    Self: Expression,
142    E: AppearsOnTable<QS>,
143{
144}
145
146impl<T, E, DB> QueryFragment<DB> for CountDistinct<T, E>
147where
148    T: SqlType + SingleValue,
149    DB: Backend,
150    E: QueryFragment<DB>,
151{
152    fn walk_ast<'b>(&'b self, mut out: AstPass<'_, 'b, DB>) -> QueryResult<()> {
153        out.push_sql("COUNT(DISTINCT ");
154        self.expr.walk_ast(out.reborrow())?;
155        out.push_sql(")");
156        Ok(())
157    }
158}