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