Skip to content

Commit

Permalink
Fix the having clause tests + add a test for normal select queries
Browse files Browse the repository at this point in the history
  • Loading branch information
weiznich authored and obsoleszenz committed Apr 18, 2024
1 parent 0799a44 commit 6a9bfdf
Show file tree
Hide file tree
Showing 4 changed files with 48 additions and 13 deletions.
3 changes: 2 additions & 1 deletion diesel/src/query_builder/select_statement/boxed.rs
Original file line number Diff line number Diff line change
Expand Up @@ -507,8 +507,9 @@ where
}

impl<'a, ST, QS, DB, GB, Predicate> HavingDsl<Predicate>
for BoxedSelectStatement<'a, ST, QS, DB, GB>
for BoxedSelectStatement<'a, ST, FromClause<QS>, DB, GB>
where
QS: QuerySource,
DB: Backend,
GB: Expression,
HavingClause<Predicate>: QueryFragment<DB> + Send + 'a,
Expand Down
3 changes: 2 additions & 1 deletion diesel/src/query_builder/select_statement/dsl_impls.rs
Original file line number Diff line number Diff line change
Expand Up @@ -669,7 +669,8 @@ where
Predicate: Expression,
Predicate::SqlType: BoolOrNullableBool,
{
type Output = SelectStatement<FromClause<F>, S, D, W, O, LOf, GroupByClause<G>, HavingClause<Predicate>>;
type Output =
SelectStatement<FromClause<F>, S, D, W, O, LOf, GroupByClause<G>, HavingClause<Predicate>>;

fn having(self, predicate: Predicate) -> Self::Output {
SelectStatement::new(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ error[E0277]: the trait bound `SelectStatement<FromClause<users::table>, diesel:
26 | users::table.select(users::name).having(users::id.gt(1)).load(&mut conn);
| ^^^^^^ the trait `HavingDsl<_>` is not implemented for `SelectStatement<FromClause<users::table>, diesel::query_builder::select_clause::SelectClause<users::columns::name>>`
|
= help: the trait `HavingDsl<Predicate>` is implemented for `SelectStatement<F, S, D, W, O, LOf, diesel::query_builder::group_by_clause::GroupByClause<G>, H>`
= help: the trait `HavingDsl<Predicate>` is implemented for `SelectStatement<FromClause<F>, S, D, W, O, LOf, diesel::query_builder::group_by_clause::GroupByClause<G>, H>`

error[E0277]: the trait bound `(): diesel::Expression` is not satisfied
--> tests/fail/having_cant_be_used_without_group_by.rs:28:31
Expand All @@ -24,32 +24,32 @@ error[E0277]: the trait bound `(): diesel::Expression` is not satisfied
and $N others
= note: required for `BoxedSelectStatement<'_, (diesel::sql_types::Integer, diesel::sql_types::Text), FromClause<users::table>, _>` to implement `HavingDsl<_>`

error[E0271]: type mismatch resolving `<FromClause<table> as AppearsInFromClause<table>>::Count == Once`
error[E0271]: type mismatch resolving `<table as AppearsInFromClause<table>>::Count == Once`
--> tests/fail/having_cant_be_used_without_group_by.rs:30:58
|
30 | users::table.select(users::name).group_by(users::id).having(posts::id.eq(42)).load(&mut conn);
| ^^^^^^ expected struct `Never`, found struct `Once`
|
note: required for `posts::columns::id` to implement `AppearsOnTable<FromClause<users::table>>`
note: required for `posts::columns::id` to implement `AppearsOnTable<users::table>`
--> tests/fail/having_cant_be_used_without_group_by.rs:14:9
|
14 | id -> Integer,
| ^^
= note: 2 redundant requirements hidden
= note: required for `Grouped<Eq<id, Bound<Integer, i32>>>` to implement `AppearsOnTable<FromClause<users::table>>`
= note: required for `Grouped<Eq<id, Bound<Integer, i32>>>` to implement `AppearsOnTable<users::table>`
= note: required for `SelectStatement<FromClause<table>, SelectClause<name>, NoDistinctClause, NoWhereClause, ..., ..., ...>` to implement `HavingDsl<diesel::expression::grouped::Grouped<diesel::expression::operators::Eq<posts::columns::id, diesel::expression::bound::Bound<diesel::sql_types::Integer, i32>>>>`

error[E0271]: type mismatch resolving `<FromClause<table> as AppearsInFromClause<table>>::Count == Once`
error[E0271]: type mismatch resolving `<table as AppearsInFromClause<table>>::Count == Once`
--> tests/fail/having_cant_be_used_without_group_by.rs:32:71
|
32 | users::table.select(users::name).group_by(users::id).into_boxed().having(posts::id.eq(42)).load(&mut conn);
| ^^^^^^ expected struct `Never`, found struct `Once`
|
note: required for `posts::columns::id` to implement `AppearsOnTable<FromClause<users::table>>`
note: required for `posts::columns::id` to implement `AppearsOnTable<users::table>`
--> tests/fail/having_cant_be_used_without_group_by.rs:14:9
|
14 | id -> Integer,
| ^^
= note: 2 redundant requirements hidden
= note: required for `Grouped<Eq<id, Bound<Integer, i32>>>` to implement `AppearsOnTable<FromClause<users::table>>`
= note: required for `Grouped<Eq<id, Bound<Integer, i32>>>` to implement `AppearsOnTable<users::table>`
= note: required for `BoxedSelectStatement<'_, diesel::sql_types::Text, FromClause<users::table>, _, users::columns::id>` to implement `HavingDsl<diesel::expression::grouped::Grouped<diesel::expression::operators::Eq<posts::columns::id, diesel::expression::bound::Bound<diesel::sql_types::Integer, i32>>>>`
41 changes: 37 additions & 4 deletions diesel_tests/tests/boxed_queries.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
use super::schema::*;
use diesel::expression::is_aggregate;
use diesel::*;

#[test]
Expand Down Expand Up @@ -184,10 +185,42 @@ fn can_box_query_with_boxable_expression() {
fn can_box_query_having_with_boxable_expression() {
let connection = &mut connection_with_sean_and_tess_in_users_table();

use diesel::expression::ValidGrouping;
let expr: Box<dyn BoxableExpression<users::table, <users::id as ValidGrouping<(users::id)>>::IsAggregate, SqlType = _>> =
Box::new(count(users::id).eq(2)) as _;
let expr: Box<
dyn BoxableExpression<
users::table,
crate::schema::TestBackend,
users::id,
is_aggregate::Yes,
SqlType = _,
>,
> = Box::new(count(users::id).eq(1)) as _;

use diesel::dsl::count;
let data: Vec<i64> = users::table.select(count(users::id)).group_by(users::id).into_boxed().having(expr).load(connection).expect("db error");

let data = users::table
.select(count(users::id))
.group_by(users::id)
.having(expr)
.load::<i64>(connection)
.expect("db error");
assert_eq!(data, [1, 1]);

let expr: Box<
dyn BoxableExpression<
users::table,
crate::schema::TestBackend,
users::id,
is_aggregate::Yes,
SqlType = _,
>,
> = Box::new(count(users::id).eq(1)) as _;

let data = users::table
.select(count(users::id))
.group_by(users::id)
.into_boxed()
.having(expr)
.load::<i64>(connection)
.expect("db error");
assert_eq!(data, [1, 1]);
}

0 comments on commit 6a9bfdf

Please sign in to comment.