Repository: diesel-rs/diesel (language: rust)

Issue:
Aggregate + non-aggregate expressions not allowed where they should be
<!--
If you want to report a bug, we added some points below which help us track down the problem faster.
-->

## Setup

### Versions

- **Rust: 1.66.0**
- **Diesel: 2.0.3**
- **Database: PostgreSQL**
- **Operating System: Linux**

### Feature Flags

- **diesel: ["uuid", "postgres", "r2d2", "numeric", "chrono", "serde_json"]**

## Problem Description

The following query gives some errors, mixing aggregate and non-aggregate expressions
```rust
diesel::table! {
    foo (uuid, date) {
        uuid -> Uuid,
        date -> Date,
    }
}

foo::table
        .select((foo::uuid, diesel::dsl::max(foo::date)))
        .group_by(foo::uuid)
```

### What are you trying to accomplish?

I'm trying to translate this valid SQL query to diesel dsl

```sql
CREATE TABLE foo (
    uuid uuid PRIMARY KEY NOT NULL,
    date timestamp DEFAULT now() NOT NULL
);

SELECT uuid, max(date) date FROM foo GROUP BY uuid;
```

### What is the expected output?

Being able to mix such expressions when it's valid sql

### What is the actual output?

```
error[E0277]: the trait bound `diesel::expression::is_aggregate::No: MixedAggregates<diesel::expression::is_aggregate::Yes>` is not satisfied
   --> src/graphql/entities/user.rs:392:10
    |
392 |         .select((foo::uuid_1, diesel::dsl::max(foo::date)))
    |          ^^^^^^ the trait `MixedAggregates<diesel::expression::is_aggregate::Yes>` is not implemented for `diesel::expression::is_aggregate::No`
    |
    = help: the following other types implement trait `MixedAggregates<Other>`:
              <diesel::expression::is_aggregate::No as MixedAggregates<diesel::expression::is_aggregate::Never>>
              <diesel::expression::is_aggregate::No as MixedAggregates<diesel::expression::is_aggregate::No>>
    = note: required for `(db::schema::foo::columns::uuid_1, diesel::expression::functions::aggregate_ordering::max::max<diesel::sql_types::Date, db::schema::foo::columns::date>)` to implement `ValidGrouping<()>`
    = note: required for `SelectStatement<FromClause<db::schema::foo::table>>` to implement `SelectDsl<(db::schema::foo::columns::uuid_1, diesel::expression::functions::aggregate_ordering::max::max<diesel::sql_types::Date, db::schema::foo::columns::date>)>`
```

### Are you seeing any additional errors?

No, many thanks for your hard work

### Steps to reproduce

<!--
Please include as much of your codebase as needed to reproduce the error.  If the relevant files are large, please consider linking to a public repository or a [Gist](https://gist.github.com/). This includes normally the following parts:

* The exact code where your hit the problem
* Relevant parts your schema, so any `table!` macro calls required for the
* Any other type definitions involved in the code, which produces your problem
-->

## Checklist

- [x] I have already looked over the [issue tracker](https://github.com/diesel-rs/diesel/issues)  and the [disussion forum](https://github.com/diesel-rs/diesel/discussions)  for similar possible closed issues.

If you are unsure if your issue is a duplicate of an existing issue please link the issue in question here

- https://github.com/diesel-rs/diesel/issues/1586

- [x] This issue can be reproduced on Rust's stable channel. (Your issue will be
  closed if this is not the case)
- [x] This issue can be reproduced without requiring a third party crate

<!--
Thank you for your submission!  You're helping make Diesel more robust 🎉

We'll try to respond as quickly as possible.
-->



Discussion / hints:
This is "expected" as we assume that the call to the `group_by` function appears before the `select` call. This assumption is made to have somewhat clearer error messages here (so that they point at least to the `.select()` call instead of only pointing at the query). So for reference the following query compiles:

```rust
foo::table
        .group_by(foo::uuid)
        .select((foo::uuid, diesel::dsl::max(foo::date)))
```

That written: I just checked the documentation and it does not mention this restriction at all. We should probably have that in the documentation of `.select` and `.group_by`. So that's at least a missing/bad documentation bug.
Thanks, it does indeed work better in this order
I can add this to the documentation if I have time
@weiznich I'll check and update docs

Fix patch:
diff --git a/diesel/src/query_dsl/mod.rs b/diesel/src/query_dsl/mod.rs
index 8be915e759fd..17d5546a5b75 100644
--- a/diesel/src/query_dsl/mod.rs
+++ b/diesel/src/query_dsl/mod.rs
@@ -205,6 +205,9 @@ pub trait QueryDsl: Sized {
     /// This is because you can only access columns from tables
     /// that appear in your query before that function call.
     ///
+    /// **Note:** When using `select` with `group_by`, the `group_by` call must appear
+    /// before the `select` call in the query chain.
+    ///
     /// [`.inner_join`]: QueryDsl::inner_join()
     /// [`.left_join`]: QueryDsl::left_join()
     /// [`.select`]: QueryDsl::select()
@@ -954,6 +957,9 @@ pub trait QueryDsl: Sized {
     /// **Note:** Queries having a `group by` clause require a custom select clause.
     /// Use [`QueryDsl::select()`] to specify one.
     ///
+    /// **Note:** When using `group_by` with `select`, the `group_by` call must appear
+    /// before the `select` call in the query chain.
+    ///
     /// If there was already a group by clause, it will be overridden.
     /// Grouping by multiple columns can be achieved by passing a tuple of those
     /// columns.


Test patch: