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

Issue:
Unable to sort columns used in a DISTINCT ON
Follow-up of a bug discovered here : https://github.com/diesel-rs/diesel/pull/3019#issuecomment-1013075368

## Setup

### Versions

- **Rust: 1.57**
- **Diesel: master (https://github.com/diesel-rs/diesel/commit/a213fe232a122f35a812b0ce0269708a1845a4c9)**
- **Database: Postgres 13.3**

### Feature Flags

- **diesel: postgres**

## Problem Description

We are unable to sort the columns used in `distinct_on`. For example, here  we are unable to sort `users::id` by descending order  :

```rust
use diesel::{ExpressionMethods, QueryDsl, table};

table! {
  users (id) {
    id -> Text,
    name -> Text,
  }
}

let _ = users::table
    .distinct_on(users::id)
    .select(users::id)
    .order_by((users::id.desc(), users::name));
```
```
13 |     .order_by((users::id.desc(), users::name));
|          ^^^^^^^^ the trait `query_dsl::order_dsl::ValidOrderingForDistinct<DistinctOnClause<columns::id>>` is not implemented for `diesel::query_builder::order_clause::OrderClause<(diesel::expression::operators::Desc<columns::id>, columns::name)>`
|
= help: the following implementations were found:
<diesel::query_builder::order_clause::OrderClause<(T,)> as query_dsl::order_dsl::ValidOrderingForDistinct<DistinctOnClause<T>>>
<diesel::query_builder::order_clause::OrderClause<(__D, T0)> as query_dsl::order_dsl::ValidOrderingForDistinct<DistinctOnClause<__D>>>
<diesel::query_builder::order_clause::OrderClause<(__D, T0, T1)> as query_dsl::order_dsl::ValidOrderingForDistinct<DistinctOnClause<__D>>>
<diesel::query_builder::order_clause::OrderClause<(__D, T0, T1, T2)> as query_dsl::order_dsl::ValidOrderingForDistinct<DistinctOnClause<__D>>>
and 14 others
= note: required because of the requirements on the impl of `OrderDsl<(diesel::expression::operators::Desc<columns::id>, columns::name)>` for `SelectStatement<FromClause<users::table>, diesel::query_builder::select_clause::SelectClause<columns::id>, DistinctOnClause<columns::id>>`
```
## 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
--> 
- [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



Discussion / hints:
+1 
@timonbimon Please do not comment to older issues if you have nothing to contribute. This only adds noise for all involved people.

Fix patch:
diff --git a/diesel/src/type_impls/tuples.rs b/diesel/src/type_impls/tuples.rs
index ade4495375e5..7b252bd7e914 100644
--- a/diesel/src/type_impls/tuples.rs
+++ b/diesel/src/type_impls/tuples.rs
@@ -367,6 +367,13 @@ macro_rules! tuple_impls {
             impl<__D, $($T,)*> crate::query_dsl::order_dsl::ValidOrderingForDistinct<crate::pg::DistinctOnClause<__D>>
                 for crate::query_builder::order_clause::OrderClause<(__D, $($T,)*)> {}
 
+            #[cfg(feature = "postgres")]
+            impl<__D, $($T,)*> crate::query_dsl::order_dsl::ValidOrderingForDistinct<crate::pg::DistinctOnClause<__D>>
+                for crate::query_builder::order_clause::OrderClause<(crate::helper_types::Desc<__D>, $($T,)*)> {}
+
+            #[cfg(feature = "postgres")]
+            impl<__D, $($T,)*> crate::query_dsl::order_dsl::ValidOrderingForDistinct<crate::pg::DistinctOnClause<__D>>
+                for crate::query_builder::order_clause::OrderClause<(crate::helper_types::Asc<__D>, $($T,)*)> {}
         )+
     }
 }


Test patch:
diff --git a/diesel_tests/tests/distinct.rs b/diesel_tests/tests/distinct.rs
index ccbc28c9cb2c..04cf585491f9 100644
--- a/diesel_tests/tests/distinct.rs
+++ b/diesel_tests/tests/distinct.rs
@@ -104,4 +104,36 @@ fn distinct_on_select_order_by_two_columns() {
     let data: Vec<_> = source.load(connection).unwrap();
 
     assert_eq!(expected_data, data);
+
+    let source = users
+        .select((name, hair_color))
+        .order((name.asc(), hair_color.desc()))
+        .distinct_on(name);
+    let data: Vec<_> = source.load(connection).unwrap();
+
+    assert_eq!(expected_data, data);
+
+    let source = users
+        .select((name, hair_color))
+        .order((name.desc(), hair_color.desc()))
+        .distinct_on(name);
+    let expected_data = vec![
+        NewUser::new("Tess", Some("champagne")),
+        NewUser::new("Sean", Some("black")),
+    ];
+    let data: Vec<_> = source.load(connection).unwrap();
+
+    assert_eq!(expected_data, data);
+
+    let source = users
+        .select((name, hair_color))
+        .order((name.desc(), hair_color))
+        .distinct_on(name);
+    let expected_data = vec![
+        NewUser::new("Tess", Some("bronze")),
+        NewUser::new("Sean", Some("aqua")),
+    ];
+    let data: Vec<_> = source.load(connection).unwrap();
+
+    assert_eq!(expected_data, data);
 }