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

Issue:
Regression in distinct_on: cannot use .nullable() on column
<!--
If you want to report a bug, we added some points below which help us track down the problem faster.
-->

## Setup

### Versions

- **Rust:** rustc 1.71.1
- **Diesel:** 2.1.1
- **Database:** Postgres
- **Operating System** Linux

## Problem Description

Code using `fn distinct_on` works in Diesel `v2.0.1` but not in `v2.1.1`.

Minimal reproducible example: https://gist.github.com/Ploppz/f8235d83f287bb7926655cd91dfba8fa
`Cargo.toml`: `diesel = { version = "=2.0.1", features = ["postgres", "r2d2"] }`

It compiles in `v2.0.1` but in `v2.1.1` there is the compiler error:
```
error[E0277]: the trait bound `NullableExpression<measurement::columns::id>: Column` is not satisfied
  --> src/main.rs:74:10
   |
74 |         .distinct_on(m::id.nullable())
   |          ^^^^^^^^^^^ the trait `Column` is not implemented for `NullableExpression<measurement::columns::id>`
   |
```

So I tried to remove the `nullable()` so the two lines become:
```rust
        .order_by((m::id, wj::submit_date.nullable().desc()))
        .distinct_on(m::id)
```
But then I get the error:
```
error[E0271]: type mismatch resolving `<Only<table> as AppearsInFromClause<table>>::Count == Never`
  --> src/main.rs:74:10
   |
74 |         .distinct_on(m::id)
   |          ^^^^^^^^^^^ expected `Once`, found `Never`
   |
```
Which makes sense I guess, because the `measurement` table is left-joined so `m::id` is not always present.

## Checklist

- [X] I have already looked over the [issue tracker](https://github.com/diesel-rs/diesel/issues) and the [discussion 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

Regression in distinct_on: cannot use .nullable() on column
<!--
If you want to report a bug, we added some points below which help us track down the problem faster.
-->

## Setup

### Versions

- **Rust:** rustc 1.71.1
- **Diesel:** 2.1.1
- **Database:** Postgres
- **Operating System** Linux

## Problem Description

Code using `fn distinct_on` works in Diesel `v2.0.1` but not in `v2.1.1`.

Minimal reproducible example: https://gist.github.com/Ploppz/f8235d83f287bb7926655cd91dfba8fa
`Cargo.toml`: `diesel = { version = "=2.0.1", features = ["postgres", "r2d2"] }`

It compiles in `v2.0.1` but in `v2.1.1` there is the compiler error:
```
error[E0277]: the trait bound `NullableExpression<measurement::columns::id>: Column` is not satisfied
  --> src/main.rs:74:10
   |
74 |         .distinct_on(m::id.nullable())
   |          ^^^^^^^^^^^ the trait `Column` is not implemented for `NullableExpression<measurement::columns::id>`
   |
```

So I tried to remove the `nullable()` so the two lines become:
```rust
        .order_by((m::id, wj::submit_date.nullable().desc()))
        .distinct_on(m::id)
```
But then I get the error:
```
error[E0271]: type mismatch resolving `<Only<table> as AppearsInFromClause<table>>::Count == Never`
  --> src/main.rs:74:10
   |
74 |         .distinct_on(m::id)
   |          ^^^^^^^^^^^ expected `Once`, found `Never`
   |
```
Which makes sense I guess, because the `measurement` table is left-joined so `m::id` is not always present.

## Checklist

- [X] I have already looked over the [issue tracker](https://github.com/diesel-rs/diesel/issues) and the [discussion 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:

Fix patch:
diff --git a/diesel/src/pg/query_builder/distinct_on.rs b/diesel/src/pg/query_builder/distinct_on.rs
index 63652575d972..50e7875f7212 100644
--- a/diesel/src/pg/query_builder/distinct_on.rs
+++ b/diesel/src/pg/query_builder/distinct_on.rs
@@ -37,31 +37,84 @@ where
 }
 
 macro_rules! valid_ordering {
-    // Special-case: rule out the all ident case:
+    // Special-case: for single tuple elements
+    // generate plain impls as well:
+    (
+        @optional_untuple:
+        [generics: $($T: ident)*]
+        [distinct: $D:ident]
+        [order: $O: ty,]
+    ) => {
+        // nothing if both a single tuple elements
+    };
+    (
+        @optional_untuple:
+        [generics: $($T: ident)*]
+        [distinct: $D:ident]
+        [order: $($O: ty,)*]
+    ) => {
+        impl<$($T,)*> ValidOrderingForDistinct<DistinctOnClause<$D>>
+            for OrderClause<($($O,)*)>
+        {}
+    };
+    (
+        @optional_untuple:
+        [generics: $($T: ident)*]
+        [distinct: $($D:ident)*]
+        [order: $O: ty,]
+    ) => {
+        impl<$($T,)*> ValidOrderingForDistinct<DistinctOnClause<($($D,)*)>>
+            for OrderClause<$O>
+        {}
+    };
+    (
+        @optional_untuple:
+        [generics: $($T: ident)*]
+        [distinct: $($D:ident)*]
+        [order: $($O: ty,)*]
+    ) => {};
+    // Special-case: rule out the all ident case if the
+    // corresponding flag is set
+    // We want to have these impls if
+    // the tuple sizes do **not** match
+    // therefore we set the flag below
     (@impl_one:
+     [allow_plain = false]
      $generics:tt
+     $distinct:tt
+     $other:tt
      [$($T_:ident, )*]
     ) => {
         /* skip this one */
     };
     (@impl_one:
+     [allow_plain = $allow_plain: expr]
      [generics: $($T:ident)*]
+     [distinct: $($D:ident)*]
+     [other: $($O:ident)*]
      [$($Ty:ty, )*]
     ) => {
-        impl<$($T,)*> ValidOrderingForDistinct<DistinctOnClause<($($T, )*)>>
-            for OrderClause<($($Ty, )*)>
+        impl<$($T,)*> ValidOrderingForDistinct<DistinctOnClause<($($D, )*)>>
+            for OrderClause<($($Ty, )* $($O,)*)>
         {}
+        valid_ordering!(@optional_untuple: [generics: $($T)*] [distinct: $($D)*] [order: $($Ty,)* $($O,)*]);
     };
     (
         @perm:
+        $allow_plain:tt
         $generics:tt
+        $distinct:tt
+        $other:tt
         [acc: $([$($acc:tt)*])*]
         $T:ident
         $($rest:tt)*
     ) => {
         valid_ordering! {
             @perm:
+            $allow_plain
             $generics
+            $distinct
+            $other
                 [acc:
                  $(
                      [$($acc)* crate::expression::operators::Asc<$T>, ]
@@ -74,47 +127,95 @@ macro_rules! valid_ordering {
     };
     (
         @perm:
+        $allow_plain:tt
         $generics:tt
+        $distinct:tt
+        $other:tt
         [acc: $($Tys:tt)*]
         /* nothing left */
     ) => (
         $(
             valid_ordering! {@impl_one:
+                $allow_plain
                 $generics
+                $distinct
+                $other
                 $Tys
             }
         )*
     );
-    (@skip: ($ST1: ident, $($ST:ident,)*), $T1:ident, ) => {};
-    (@skip: ($ST1: ident, $($ST:ident,)*), $T1:ident, $($T:ident,)+) => {
-        valid_ordering!(($($ST,)*), ($ST1,), $($T,)*);
+    (@skip_distinct_rev: [generics: $($G: ident)*] [other: $($O: ident)*] [acc: $($T: ident)*]) => {
+        valid_ordering!(@perm:
+                        [allow_plain = true]
+                        [generics: $($G)*]
+                        [distinct: $($T)*]
+                        [other: $($O)* ]
+                        [acc: []]
+                        $($T)*
+        );
     };
-    (($ST1: ident,), ($($OT:ident,)*), $T1:ident,) => {
-        impl<$T1, $ST1, $($OT,)*> ValidOrderingForDistinct<DistinctOnClause<($ST1, $($OT,)*)>> for OrderClause<$T1>
-        where $T1: crate::pg::OrderDecorator<Column = $ST1>,
-        {}
-        impl<$T1, $ST1, $($OT,)*> ValidOrderingForDistinct<DistinctOnClause<($ST1, $($OT,)*)>> for OrderClause<($T1,)>
-        where $T1: crate::pg::OrderDecorator<Column = $ST1>,
-        {}
-        impl<$T1, $ST1, $($OT,)*> ValidOrderingForDistinct<DistinctOnClause<($T1,)>> for OrderClause<($ST1, $($OT,)*)>
-        where $ST1: crate::pg::OrderDecorator<Column = $T1>,
-        {}
-
-        impl<$T1, $ST1, $($OT,)*> ValidOrderingForDistinct<DistinctOnClause<$T1>> for OrderClause<($ST1, $($OT,)*)>
-        where $ST1: crate::pg::OrderDecorator<Column = $T1>,
-              $T1: crate::Column,
-        {}
+    (@skip_distinct_rev: [generics: $($G: ident)*] [other: $($O: ident)*] [acc: $($I: ident)*] $T: ident $($Ts: ident)*) => {
+        valid_ordering!(
+            @skip_distinct_rev:
+            [generics: $($G)*]
+            [other: $($O)*]
+            [acc: $T $($I)*]
+            $($Ts)*
+        );
     };
-    (($ST1: ident, $($ST:ident,)*), ($($OT: ident,)*), $T1:ident, $($T:ident,)+) => {
-        impl<$T1, $($T,)* $ST1, $($ST,)* $($OT,)*> ValidOrderingForDistinct<DistinctOnClause<($ST1, $($ST,)* $($OT,)*)>> for OrderClause<($T1, $($T,)*)>
-        where $T1: crate::pg::OrderDecorator<Column = $ST1>,
-              $($T: crate::pg::OrderDecorator<Column = $ST>,)*
-        {}
-        impl<$T1, $($T,)* $ST1, $($ST,)* $($OT,)*> ValidOrderingForDistinct<DistinctOnClause<($T1, $($T,)*)>> for OrderClause<($ST1, $($ST,)* $($OT,)*)>
-        where $ST1: crate::pg::OrderDecorator<Column = $T1>,
-              $($ST: crate::pg::OrderDecorator<Column = $T>,)*
-        {}
-        valid_ordering!(($($ST,)*), ($($OT,)* $ST1,), $($T,)*);
+    (@skip_distinct:
+     [generics: $($G: ident)*]
+     [acc: $($O: ident)*]
+     $T: ident
+    ) => {};
+    (@skip_distinct:
+     [generics: $($G: ident)*]
+     [acc: $($O: ident)*]
+     $T:ident $($Ts: ident)*
+    ) => {
+        valid_ordering!(@skip_distinct_rev:
+            [generics: $($G)*]
+            [other: $($O)* $T]
+            [acc: ]
+            $($Ts)*
+        );
+        valid_ordering!(@skip_distinct: [generics: $($G)*] [acc: $($O)* $T] $($Ts)*);
+    };
+    (@skip_order_rev: [generics: $($G: ident)*] [acc: $($T: ident)*]) => {
+        valid_ordering!(@perm:
+            [allow_plain = true]
+            [generics: $($G)*]
+            [distinct: $($G)*]
+            [other: ]
+            [acc: []]
+            $($T)*
+        );
+    };
+    (@skip_order_rev: [generics: $($G: ident)*] [acc: $($I: ident)*] $T: ident $($Ts: ident)*) => {
+        valid_ordering!(
+            @skip_order_rev:
+            [generics: $($G)*]
+            [acc: $T $($I)*]
+            $($Ts)*
+        );
+    };
+    (@skip_order:
+     [generics: $($G: ident)*]
+     $T: ident
+    ) => {};
+    (@skip_order:
+     [generics: $($G: ident)*]
+     $T: ident $($Ts: ident)*
+    ) => {
+        valid_ordering!(@skip_order_rev: [generics: $($G)*] [acc: ] $($Ts)*);
+        valid_ordering!(@skip_order: [generics: $($G)*] $($Ts)*);
+    };
+    (@reverse_list: [generics: $($G: ident)*] [acc: $($I: ident)*]) => {
+        valid_ordering!(@skip_order: [generics: $($G)*] $($I)*);
+        valid_ordering!(@skip_distinct: [generics: $($G)*] [acc: ] $($I)*);
+    };
+    (@reverse_list: [generics: $($G: ident)*] [acc: $($I: ident)*] $T: ident $($Ts: ident)*) => {
+        valid_ordering!(@reverse_list: [generics: $($G)*] [acc: $T $($I)*] $($Ts)*);
     };
     ($(
         $Tuple:tt {
@@ -122,8 +223,15 @@ macro_rules! valid_ordering {
         }
     )+) => {
         $(
-            valid_ordering!(@skip: ($($ST,)*), $($T,)*);
-            valid_ordering!(@perm: [generics: $($T)*] [acc: []] $($T)*);
+            valid_ordering!(@perm:
+                [allow_plain = false]
+                [generics: $($T)*]
+                [distinct: $($T)*]
+                [other: ]
+                [acc: []]
+                $($T)*
+            );
+            valid_ordering!(@reverse_list: [generics: $($T)*] [acc: ] $($T)*);
         )*
     }
 }
@@ -132,7 +240,7 @@ macro_rules! valid_ordering {
 // If we would generate these impls up to max_table_column_count tuple elements that
 // would be a really large number for 128 tuple elements (~64k trait impls)
 // It's fine to increase this number at some point in the future gradually
-diesel_derives::__diesel_for_each_tuple!(valid_ordering, 5);
+diesel_derives::__diesel_for_each_tuple!(valid_ordering, 3);
 
 /// A decorator trait for `OrderClause`
 /// It helps to have bounds on either Col, Asc<Col> and Desc<Col>.


Test patch:
diff --git a/diesel_compile_tests/tests/fail/distinct_on_requires_matching_order_clause.stderr b/diesel_compile_tests/tests/fail/distinct_on_requires_matching_order_clause.stderr
index 1ad308ba0257..70ec21134f4e 100644
--- a/diesel_compile_tests/tests/fail/distinct_on_requires_matching_order_clause.stderr
+++ b/diesel_compile_tests/tests/fail/distinct_on_requires_matching_order_clause.stderr
@@ -7,14 +7,14 @@ error[E0277]: the trait bound `diesel::query_builder::order_clause::OrderClause<
     |                                              required by a bound introduced by this call
     |
     = help: the following other types implement trait `query_dsl::order_dsl::ValidOrderingForDistinct<D>`:
-              <diesel::query_builder::order_clause::OrderClause<(ST1, ST0)> as query_dsl::order_dsl::ValidOrderingForDistinct<DistinctOnClause<(T1,)>>>
-              <diesel::query_builder::order_clause::OrderClause<(ST1, ST0)> as query_dsl::order_dsl::ValidOrderingForDistinct<DistinctOnClause<T1>>>
-              <diesel::query_builder::order_clause::OrderClause<(ST1, ST2, ST0)> as query_dsl::order_dsl::ValidOrderingForDistinct<DistinctOnClause<(T1, T2)>>>
-              <diesel::query_builder::order_clause::OrderClause<(ST1, ST2, ST3, ST0)> as query_dsl::order_dsl::ValidOrderingForDistinct<DistinctOnClause<(T1, T2, T3)>>>
-              <diesel::query_builder::order_clause::OrderClause<(ST1, ST2, ST3, ST4, ST0)> as query_dsl::order_dsl::ValidOrderingForDistinct<DistinctOnClause<(T1, T2, T3, T4)>>>
-              <diesel::query_builder::order_clause::OrderClause<(ST2, ST0, ST1)> as query_dsl::order_dsl::ValidOrderingForDistinct<DistinctOnClause<(T2,)>>>
-              <diesel::query_builder::order_clause::OrderClause<(ST2, ST0, ST1)> as query_dsl::order_dsl::ValidOrderingForDistinct<DistinctOnClause<T2>>>
-              <diesel::query_builder::order_clause::OrderClause<(ST2, ST3, ST0, ST1)> as query_dsl::order_dsl::ValidOrderingForDistinct<DistinctOnClause<(T2, T3)>>>
+              <diesel::query_builder::order_clause::OrderClause<(T,)> as query_dsl::order_dsl::ValidOrderingForDistinct<DistinctOnClause<T>>>
+              <diesel::query_builder::order_clause::OrderClause<(T0, T1)> as query_dsl::order_dsl::ValidOrderingForDistinct<DistinctOnClause<(T0, T1, T2)>>>
+              <diesel::query_builder::order_clause::OrderClause<(T0, T1)> as query_dsl::order_dsl::ValidOrderingForDistinct<DistinctOnClause<(T0,)>>>
+              <diesel::query_builder::order_clause::OrderClause<(T0, T1)> as query_dsl::order_dsl::ValidOrderingForDistinct<DistinctOnClause<T0>>>
+              <diesel::query_builder::order_clause::OrderClause<(T0, T1, T2)> as query_dsl::order_dsl::ValidOrderingForDistinct<DistinctOnClause<(T0, T1)>>>
+              <diesel::query_builder::order_clause::OrderClause<(T0, T1, diesel::expression::operators::Asc<T2>)> as query_dsl::order_dsl::ValidOrderingForDistinct<DistinctOnClause<(T0, T1, T2)>>>
+              <diesel::query_builder::order_clause::OrderClause<(T0, T1, diesel::expression::operators::Desc<T2>)> as query_dsl::order_dsl::ValidOrderingForDistinct<DistinctOnClause<(T0, T1, T2)>>>
+              <diesel::query_builder::order_clause::OrderClause<(T0, T2, T1)> as query_dsl::order_dsl::ValidOrderingForDistinct<DistinctOnClause<(T0,)>>>
             and $N others
     = note: required for `SelectStatement<FromClause<table>, DefaultSelectClause<FromClause<table>>, NoDistinctClause, ..., ...>` to implement `DistinctOnDsl<columns::name>`
 note: required by a bound in `diesel::QueryDsl::distinct_on`
@@ -23,23 +23,55 @@ note: required by a bound in `diesel::QueryDsl::distinct_on`
     |         Self: methods::DistinctOnDsl<Expr>,
     |               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `QueryDsl::distinct_on`
 
-error[E0271]: type mismatch resolving `<id as OrderDecorator>::Column == name`
-   --> tests/fail/distinct_on_requires_matching_order_clause.rs:117:61
+error[E0277]: the trait bound `diesel::query_builder::order_clause::OrderClause<(columns::id, columns::name)>: query_dsl::order_dsl::ValidOrderingForDistinct<DistinctOnClause<columns::name>>` is not satisfied
+   --> tests/fail/distinct_on_requires_matching_order_clause.rs:117:73
     |
 117 |     let _ = users::table.order_by((users::id, users::name)).distinct_on(users::name);
-    |                                                             ^^^^^^^^^^^ expected struct `id`, found struct `name`
+    |                                                             ----------- ^^^^^^^^^^^ the trait `query_dsl::order_dsl::ValidOrderingForDistinct<DistinctOnClause<columns::name>>` is not implemented for `diesel::query_builder::order_clause::OrderClause<(columns::id, columns::name)>`
+    |                                                             |
+    |                                                             required by a bound introduced by this call
     |
-    = note: required for `diesel::query_builder::order_clause::OrderClause<(columns::id, columns::name)>` to implement `query_dsl::order_dsl::ValidOrderingForDistinct<DistinctOnClause<columns::name>>`
+    = help: the following other types implement trait `query_dsl::order_dsl::ValidOrderingForDistinct<D>`:
+              <diesel::query_builder::order_clause::OrderClause<(T,)> as query_dsl::order_dsl::ValidOrderingForDistinct<DistinctOnClause<T>>>
+              <diesel::query_builder::order_clause::OrderClause<(T0, T1)> as query_dsl::order_dsl::ValidOrderingForDistinct<DistinctOnClause<(T0, T1, T2)>>>
+              <diesel::query_builder::order_clause::OrderClause<(T0, T1)> as query_dsl::order_dsl::ValidOrderingForDistinct<DistinctOnClause<(T0,)>>>
+              <diesel::query_builder::order_clause::OrderClause<(T0, T1)> as query_dsl::order_dsl::ValidOrderingForDistinct<DistinctOnClause<T0>>>
+              <diesel::query_builder::order_clause::OrderClause<(T0, T1, T2)> as query_dsl::order_dsl::ValidOrderingForDistinct<DistinctOnClause<(T0, T1)>>>
+              <diesel::query_builder::order_clause::OrderClause<(T0, T1, diesel::expression::operators::Asc<T2>)> as query_dsl::order_dsl::ValidOrderingForDistinct<DistinctOnClause<(T0, T1, T2)>>>
+              <diesel::query_builder::order_clause::OrderClause<(T0, T1, diesel::expression::operators::Desc<T2>)> as query_dsl::order_dsl::ValidOrderingForDistinct<DistinctOnClause<(T0, T1, T2)>>>
+              <diesel::query_builder::order_clause::OrderClause<(T0, T2, T1)> as query_dsl::order_dsl::ValidOrderingForDistinct<DistinctOnClause<(T0,)>>>
+            and $N others
     = note: required for `SelectStatement<FromClause<table>, DefaultSelectClause<FromClause<table>>, NoDistinctClause, ..., ...>` to implement `DistinctOnDsl<columns::name>`
+note: required by a bound in `diesel::QueryDsl::distinct_on`
+   --> $DIESEL/src/query_dsl/mod.rs
+    |
+    |         Self: methods::DistinctOnDsl<Expr>,
+    |               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `QueryDsl::distinct_on`
 
-error[E0271]: type mismatch resolving `<id as OrderDecorator>::Column == name`
-   --> tests/fail/distinct_on_requires_matching_order_clause.rs:123:10
+error[E0277]: the trait bound `diesel::query_builder::order_clause::OrderClause<(columns::id, columns::name)>: query_dsl::order_dsl::ValidOrderingForDistinct<DistinctOnClause<columns::name>>` is not satisfied
+   --> tests/fail/distinct_on_requires_matching_order_clause.rs:123:22
     |
 123 |         .distinct_on(users::name);
-    |          ^^^^^^^^^^^ expected struct `id`, found struct `name`
+    |          ----------- ^^^^^^^^^^^ the trait `query_dsl::order_dsl::ValidOrderingForDistinct<DistinctOnClause<columns::name>>` is not implemented for `diesel::query_builder::order_clause::OrderClause<(columns::id, columns::name)>`
+    |          |
+    |          required by a bound introduced by this call
     |
-    = note: required for `diesel::query_builder::order_clause::OrderClause<(columns::id, columns::name)>` to implement `query_dsl::order_dsl::ValidOrderingForDistinct<DistinctOnClause<columns::name>>`
+    = help: the following other types implement trait `query_dsl::order_dsl::ValidOrderingForDistinct<D>`:
+              <diesel::query_builder::order_clause::OrderClause<(T,)> as query_dsl::order_dsl::ValidOrderingForDistinct<DistinctOnClause<T>>>
+              <diesel::query_builder::order_clause::OrderClause<(T0, T1)> as query_dsl::order_dsl::ValidOrderingForDistinct<DistinctOnClause<(T0, T1, T2)>>>
+              <diesel::query_builder::order_clause::OrderClause<(T0, T1)> as query_dsl::order_dsl::ValidOrderingForDistinct<DistinctOnClause<(T0,)>>>
+              <diesel::query_builder::order_clause::OrderClause<(T0, T1)> as query_dsl::order_dsl::ValidOrderingForDistinct<DistinctOnClause<T0>>>
+              <diesel::query_builder::order_clause::OrderClause<(T0, T1, T2)> as query_dsl::order_dsl::ValidOrderingForDistinct<DistinctOnClause<(T0, T1)>>>
+              <diesel::query_builder::order_clause::OrderClause<(T0, T1, diesel::expression::operators::Asc<T2>)> as query_dsl::order_dsl::ValidOrderingForDistinct<DistinctOnClause<(T0, T1, T2)>>>
+              <diesel::query_builder::order_clause::OrderClause<(T0, T1, diesel::expression::operators::Desc<T2>)> as query_dsl::order_dsl::ValidOrderingForDistinct<DistinctOnClause<(T0, T1, T2)>>>
+              <diesel::query_builder::order_clause::OrderClause<(T0, T2, T1)> as query_dsl::order_dsl::ValidOrderingForDistinct<DistinctOnClause<(T0,)>>>
+            and $N others
     = note: required for `SelectStatement<FromClause<table>, DefaultSelectClause<FromClause<table>>, NoDistinctClause, ..., ...>` to implement `DistinctOnDsl<columns::name>`
+note: required by a bound in `diesel::QueryDsl::distinct_on`
+   --> $DIESEL/src/query_dsl/mod.rs
+    |
+    |         Self: methods::DistinctOnDsl<Expr>,
+    |               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `QueryDsl::distinct_on`
 
 error[E0277]: the trait bound `diesel::query_builder::order_clause::OrderClause<columns::id>: query_dsl::order_dsl::ValidOrderingForDistinct<DistinctOnClause<columns::name>>` is not satisfied
    --> tests/fail/distinct_on_requires_matching_order_clause.rs:127:60
@@ -50,14 +82,14 @@ error[E0277]: the trait bound `diesel::query_builder::order_clause::OrderClause<
     |                                                   required by a bound introduced by this call
     |
     = help: the following other types implement trait `query_dsl::order_dsl::ValidOrderingForDistinct<D>`:
-              <diesel::query_builder::order_clause::OrderClause<(ST1, ST0)> as query_dsl::order_dsl::ValidOrderingForDistinct<DistinctOnClause<(T1,)>>>
-              <diesel::query_builder::order_clause::OrderClause<(ST1, ST0)> as query_dsl::order_dsl::ValidOrderingForDistinct<DistinctOnClause<T1>>>
-              <diesel::query_builder::order_clause::OrderClause<(ST1, ST2, ST0)> as query_dsl::order_dsl::ValidOrderingForDistinct<DistinctOnClause<(T1, T2)>>>
-              <diesel::query_builder::order_clause::OrderClause<(ST1, ST2, ST3, ST0)> as query_dsl::order_dsl::ValidOrderingForDistinct<DistinctOnClause<(T1, T2, T3)>>>
-              <diesel::query_builder::order_clause::OrderClause<(ST1, ST2, ST3, ST4, ST0)> as query_dsl::order_dsl::ValidOrderingForDistinct<DistinctOnClause<(T1, T2, T3, T4)>>>
-              <diesel::query_builder::order_clause::OrderClause<(ST2, ST0, ST1)> as query_dsl::order_dsl::ValidOrderingForDistinct<DistinctOnClause<(T2,)>>>
-              <diesel::query_builder::order_clause::OrderClause<(ST2, ST0, ST1)> as query_dsl::order_dsl::ValidOrderingForDistinct<DistinctOnClause<T2>>>
-              <diesel::query_builder::order_clause::OrderClause<(ST2, ST3, ST0, ST1)> as query_dsl::order_dsl::ValidOrderingForDistinct<DistinctOnClause<(T2, T3)>>>
+              <diesel::query_builder::order_clause::OrderClause<(T,)> as query_dsl::order_dsl::ValidOrderingForDistinct<DistinctOnClause<T>>>
+              <diesel::query_builder::order_clause::OrderClause<(T0, T1)> as query_dsl::order_dsl::ValidOrderingForDistinct<DistinctOnClause<(T0, T1, T2)>>>
+              <diesel::query_builder::order_clause::OrderClause<(T0, T1)> as query_dsl::order_dsl::ValidOrderingForDistinct<DistinctOnClause<(T0,)>>>
+              <diesel::query_builder::order_clause::OrderClause<(T0, T1)> as query_dsl::order_dsl::ValidOrderingForDistinct<DistinctOnClause<T0>>>
+              <diesel::query_builder::order_clause::OrderClause<(T0, T1, T2)> as query_dsl::order_dsl::ValidOrderingForDistinct<DistinctOnClause<(T0, T1)>>>
+              <diesel::query_builder::order_clause::OrderClause<(T0, T1, diesel::expression::operators::Asc<T2>)> as query_dsl::order_dsl::ValidOrderingForDistinct<DistinctOnClause<(T0, T1, T2)>>>
+              <diesel::query_builder::order_clause::OrderClause<(T0, T1, diesel::expression::operators::Desc<T2>)> as query_dsl::order_dsl::ValidOrderingForDistinct<DistinctOnClause<(T0, T1, T2)>>>
+              <diesel::query_builder::order_clause::OrderClause<(T0, T2, T1)> as query_dsl::order_dsl::ValidOrderingForDistinct<DistinctOnClause<(T0,)>>>
             and $N others
     = note: required for `SelectStatement<FromClause<table>, DefaultSelectClause<FromClause<table>>, DistinctOnClause<name>>` to implement `OrderDsl<columns::id>`
 note: required by a bound in `order_by`
@@ -75,14 +107,14 @@ error[E0277]: the trait bound `diesel::query_builder::order_clause::OrderClause<
     |                                              required by a bound introduced by this call
     |
     = help: the following other types implement trait `query_dsl::order_dsl::ValidOrderingForDistinct<D>`:
-              <diesel::query_builder::order_clause::OrderClause<(ST1, ST0)> as query_dsl::order_dsl::ValidOrderingForDistinct<DistinctOnClause<(T1,)>>>
-              <diesel::query_builder::order_clause::OrderClause<(ST1, ST0)> as query_dsl::order_dsl::ValidOrderingForDistinct<DistinctOnClause<T1>>>
-              <diesel::query_builder::order_clause::OrderClause<(ST1, ST2, ST0)> as query_dsl::order_dsl::ValidOrderingForDistinct<DistinctOnClause<(T1, T2)>>>
-              <diesel::query_builder::order_clause::OrderClause<(ST1, ST2, ST3, ST0)> as query_dsl::order_dsl::ValidOrderingForDistinct<DistinctOnClause<(T1, T2, T3)>>>
-              <diesel::query_builder::order_clause::OrderClause<(ST1, ST2, ST3, ST4, ST0)> as query_dsl::order_dsl::ValidOrderingForDistinct<DistinctOnClause<(T1, T2, T3, T4)>>>
-              <diesel::query_builder::order_clause::OrderClause<(ST2, ST0, ST1)> as query_dsl::order_dsl::ValidOrderingForDistinct<DistinctOnClause<(T2,)>>>
-              <diesel::query_builder::order_clause::OrderClause<(ST2, ST0, ST1)> as query_dsl::order_dsl::ValidOrderingForDistinct<DistinctOnClause<T2>>>
-              <diesel::query_builder::order_clause::OrderClause<(ST2, ST3, ST0, ST1)> as query_dsl::order_dsl::ValidOrderingForDistinct<DistinctOnClause<(T2, T3)>>>
+              <diesel::query_builder::order_clause::OrderClause<(T,)> as query_dsl::order_dsl::ValidOrderingForDistinct<DistinctOnClause<T>>>
+              <diesel::query_builder::order_clause::OrderClause<(T0, T1)> as query_dsl::order_dsl::ValidOrderingForDistinct<DistinctOnClause<(T0, T1, T2)>>>
+              <diesel::query_builder::order_clause::OrderClause<(T0, T1)> as query_dsl::order_dsl::ValidOrderingForDistinct<DistinctOnClause<(T0,)>>>
+              <diesel::query_builder::order_clause::OrderClause<(T0, T1)> as query_dsl::order_dsl::ValidOrderingForDistinct<DistinctOnClause<T0>>>
+              <diesel::query_builder::order_clause::OrderClause<(T0, T1, T2)> as query_dsl::order_dsl::ValidOrderingForDistinct<DistinctOnClause<(T0, T1)>>>
+              <diesel::query_builder::order_clause::OrderClause<(T0, T1, diesel::expression::operators::Asc<T2>)> as query_dsl::order_dsl::ValidOrderingForDistinct<DistinctOnClause<(T0, T1, T2)>>>
+              <diesel::query_builder::order_clause::OrderClause<(T0, T1, diesel::expression::operators::Desc<T2>)> as query_dsl::order_dsl::ValidOrderingForDistinct<DistinctOnClause<(T0, T1, T2)>>>
+              <diesel::query_builder::order_clause::OrderClause<(T0, T2, T1)> as query_dsl::order_dsl::ValidOrderingForDistinct<DistinctOnClause<(T0,)>>>
             and $N others
     = note: required for `SelectStatement<FromClause<table>, DefaultSelectClause<FromClause<table>>, NoDistinctClause, ..., ...>` to implement `DistinctOnDsl<columns::name>`
 note: required by a bound in `diesel::QueryDsl::distinct_on`
@@ -91,14 +123,30 @@ note: required by a bound in `diesel::QueryDsl::distinct_on`
     |         Self: methods::DistinctOnDsl<Expr>,
     |               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `QueryDsl::distinct_on`
 
-error[E0271]: type mismatch resolving `<id as OrderDecorator>::Column == name`
-   --> tests/fail/distinct_on_requires_matching_order_clause.rs:136:10
+error[E0277]: the trait bound `diesel::query_builder::order_clause::OrderClause<(columns::id, columns::name)>: query_dsl::order_dsl::ValidOrderingForDistinct<DistinctOnClause<columns::name>>` is not satisfied
+   --> tests/fail/distinct_on_requires_matching_order_clause.rs:136:22
     |
 136 |         .distinct_on(users::name)
-    |          ^^^^^^^^^^^ expected struct `id`, found struct `name`
+    |          ----------- ^^^^^^^^^^^ the trait `query_dsl::order_dsl::ValidOrderingForDistinct<DistinctOnClause<columns::name>>` is not implemented for `diesel::query_builder::order_clause::OrderClause<(columns::id, columns::name)>`
+    |          |
+    |          required by a bound introduced by this call
     |
-    = note: required for `diesel::query_builder::order_clause::OrderClause<(columns::id, columns::name)>` to implement `query_dsl::order_dsl::ValidOrderingForDistinct<DistinctOnClause<columns::name>>`
+    = help: the following other types implement trait `query_dsl::order_dsl::ValidOrderingForDistinct<D>`:
+              <diesel::query_builder::order_clause::OrderClause<(T,)> as query_dsl::order_dsl::ValidOrderingForDistinct<DistinctOnClause<T>>>
+              <diesel::query_builder::order_clause::OrderClause<(T0, T1)> as query_dsl::order_dsl::ValidOrderingForDistinct<DistinctOnClause<(T0, T1, T2)>>>
+              <diesel::query_builder::order_clause::OrderClause<(T0, T1)> as query_dsl::order_dsl::ValidOrderingForDistinct<DistinctOnClause<(T0,)>>>
+              <diesel::query_builder::order_clause::OrderClause<(T0, T1)> as query_dsl::order_dsl::ValidOrderingForDistinct<DistinctOnClause<T0>>>
+              <diesel::query_builder::order_clause::OrderClause<(T0, T1, T2)> as query_dsl::order_dsl::ValidOrderingForDistinct<DistinctOnClause<(T0, T1)>>>
+              <diesel::query_builder::order_clause::OrderClause<(T0, T1, diesel::expression::operators::Asc<T2>)> as query_dsl::order_dsl::ValidOrderingForDistinct<DistinctOnClause<(T0, T1, T2)>>>
+              <diesel::query_builder::order_clause::OrderClause<(T0, T1, diesel::expression::operators::Desc<T2>)> as query_dsl::order_dsl::ValidOrderingForDistinct<DistinctOnClause<(T0, T1, T2)>>>
+              <diesel::query_builder::order_clause::OrderClause<(T0, T2, T1)> as query_dsl::order_dsl::ValidOrderingForDistinct<DistinctOnClause<(T0,)>>>
+            and $N others
     = note: required for `SelectStatement<FromClause<table>, DefaultSelectClause<FromClause<table>>, NoDistinctClause, ..., ...>` to implement `DistinctOnDsl<columns::name>`
+note: required by a bound in `diesel::QueryDsl::distinct_on`
+   --> $DIESEL/src/query_dsl/mod.rs
+    |
+    |         Self: methods::DistinctOnDsl<Expr>,
+    |               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `QueryDsl::distinct_on`
 
 error[E0277]: the trait bound `diesel::query_builder::order_clause::OrderClause<(columns::id, columns::name)>: query_dsl::order_dsl::ValidOrderingForDistinct<DistinctOnClause<(columns::name, columns::id)>>` is not satisfied
    --> tests/fail/distinct_on_requires_matching_order_clause.rs:143:22
@@ -109,14 +157,14 @@ error[E0277]: the trait bound `diesel::query_builder::order_clause::OrderClause<
     |          required by a bound introduced by this call
     |
     = help: the following other types implement trait `query_dsl::order_dsl::ValidOrderingForDistinct<D>`:
-              <diesel::query_builder::order_clause::OrderClause<(ST1, ST0)> as query_dsl::order_dsl::ValidOrderingForDistinct<DistinctOnClause<(T1,)>>>
-              <diesel::query_builder::order_clause::OrderClause<(ST1, ST0)> as query_dsl::order_dsl::ValidOrderingForDistinct<DistinctOnClause<T1>>>
-              <diesel::query_builder::order_clause::OrderClause<(ST1, ST2, ST0)> as query_dsl::order_dsl::ValidOrderingForDistinct<DistinctOnClause<(T1, T2)>>>
-              <diesel::query_builder::order_clause::OrderClause<(ST1, ST2, ST3, ST0)> as query_dsl::order_dsl::ValidOrderingForDistinct<DistinctOnClause<(T1, T2, T3)>>>
-              <diesel::query_builder::order_clause::OrderClause<(ST1, ST2, ST3, ST4, ST0)> as query_dsl::order_dsl::ValidOrderingForDistinct<DistinctOnClause<(T1, T2, T3, T4)>>>
-              <diesel::query_builder::order_clause::OrderClause<(ST2, ST0, ST1)> as query_dsl::order_dsl::ValidOrderingForDistinct<DistinctOnClause<(T2,)>>>
-              <diesel::query_builder::order_clause::OrderClause<(ST2, ST0, ST1)> as query_dsl::order_dsl::ValidOrderingForDistinct<DistinctOnClause<T2>>>
-              <diesel::query_builder::order_clause::OrderClause<(ST2, ST3, ST0, ST1)> as query_dsl::order_dsl::ValidOrderingForDistinct<DistinctOnClause<(T2, T3)>>>
+              <diesel::query_builder::order_clause::OrderClause<(T,)> as query_dsl::order_dsl::ValidOrderingForDistinct<DistinctOnClause<T>>>
+              <diesel::query_builder::order_clause::OrderClause<(T0, T1)> as query_dsl::order_dsl::ValidOrderingForDistinct<DistinctOnClause<(T0, T1, T2)>>>
+              <diesel::query_builder::order_clause::OrderClause<(T0, T1)> as query_dsl::order_dsl::ValidOrderingForDistinct<DistinctOnClause<(T0,)>>>
+              <diesel::query_builder::order_clause::OrderClause<(T0, T1)> as query_dsl::order_dsl::ValidOrderingForDistinct<DistinctOnClause<T0>>>
+              <diesel::query_builder::order_clause::OrderClause<(T0, T1, T2)> as query_dsl::order_dsl::ValidOrderingForDistinct<DistinctOnClause<(T0, T1)>>>
+              <diesel::query_builder::order_clause::OrderClause<(T0, T1, diesel::expression::operators::Asc<T2>)> as query_dsl::order_dsl::ValidOrderingForDistinct<DistinctOnClause<(T0, T1, T2)>>>
+              <diesel::query_builder::order_clause::OrderClause<(T0, T1, diesel::expression::operators::Desc<T2>)> as query_dsl::order_dsl::ValidOrderingForDistinct<DistinctOnClause<(T0, T1, T2)>>>
+              <diesel::query_builder::order_clause::OrderClause<(T0, T2, T1)> as query_dsl::order_dsl::ValidOrderingForDistinct<DistinctOnClause<(T0,)>>>
             and $N others
     = note: required for `SelectStatement<FromClause<table>, DefaultSelectClause<FromClause<table>>, NoDistinctClause, ..., ...>` to implement `DistinctOnDsl<(columns::name, columns::id)>`
 note: required by a bound in `diesel::QueryDsl::distinct_on`
@@ -125,23 +173,55 @@ note: required by a bound in `diesel::QueryDsl::distinct_on`
     |         Self: methods::DistinctOnDsl<Expr>,
     |               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `QueryDsl::distinct_on`
 
-error[E0271]: type mismatch resolving `<id as OrderDecorator>::Column == name`
-   --> tests/fail/distinct_on_requires_matching_order_clause.rs:150:10
+error[E0277]: the trait bound `diesel::query_builder::order_clause::OrderClause<columns::id>: query_dsl::order_dsl::ValidOrderingForDistinct<DistinctOnClause<(columns::name, columns::id)>>` is not satisfied
+   --> tests/fail/distinct_on_requires_matching_order_clause.rs:150:22
     |
 150 |         .distinct_on((users::name, users::id))
-    |          ^^^^^^^^^^^ expected struct `id`, found struct `name`
+    |          ----------- ^^^^^^^^^^^^^^^^^^^^^^^^ the trait `query_dsl::order_dsl::ValidOrderingForDistinct<DistinctOnClause<(columns::name, columns::id)>>` is not implemented for `diesel::query_builder::order_clause::OrderClause<columns::id>`
+    |          |
+    |          required by a bound introduced by this call
     |
-    = note: required for `diesel::query_builder::order_clause::OrderClause<columns::id>` to implement `query_dsl::order_dsl::ValidOrderingForDistinct<DistinctOnClause<(columns::name, columns::id)>>`
+    = help: the following other types implement trait `query_dsl::order_dsl::ValidOrderingForDistinct<D>`:
+              <diesel::query_builder::order_clause::OrderClause<(T,)> as query_dsl::order_dsl::ValidOrderingForDistinct<DistinctOnClause<T>>>
+              <diesel::query_builder::order_clause::OrderClause<(T0, T1)> as query_dsl::order_dsl::ValidOrderingForDistinct<DistinctOnClause<(T0, T1, T2)>>>
+              <diesel::query_builder::order_clause::OrderClause<(T0, T1)> as query_dsl::order_dsl::ValidOrderingForDistinct<DistinctOnClause<(T0,)>>>
+              <diesel::query_builder::order_clause::OrderClause<(T0, T1)> as query_dsl::order_dsl::ValidOrderingForDistinct<DistinctOnClause<T0>>>
+              <diesel::query_builder::order_clause::OrderClause<(T0, T1, T2)> as query_dsl::order_dsl::ValidOrderingForDistinct<DistinctOnClause<(T0, T1)>>>
+              <diesel::query_builder::order_clause::OrderClause<(T0, T1, diesel::expression::operators::Asc<T2>)> as query_dsl::order_dsl::ValidOrderingForDistinct<DistinctOnClause<(T0, T1, T2)>>>
+              <diesel::query_builder::order_clause::OrderClause<(T0, T1, diesel::expression::operators::Desc<T2>)> as query_dsl::order_dsl::ValidOrderingForDistinct<DistinctOnClause<(T0, T1, T2)>>>
+              <diesel::query_builder::order_clause::OrderClause<(T0, T2, T1)> as query_dsl::order_dsl::ValidOrderingForDistinct<DistinctOnClause<(T0,)>>>
+            and $N others
     = note: required for `SelectStatement<FromClause<table>, DefaultSelectClause<FromClause<table>>, NoDistinctClause, ..., ...>` to implement `DistinctOnDsl<(columns::name, columns::id)>`
+note: required by a bound in `diesel::QueryDsl::distinct_on`
+   --> $DIESEL/src/query_dsl/mod.rs
+    |
+    |         Self: methods::DistinctOnDsl<Expr>,
+    |               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `QueryDsl::distinct_on`
 
-error[E0271]: type mismatch resolving `<id as OrderDecorator>::Column == name`
-   --> tests/fail/distinct_on_requires_matching_order_clause.rs:157:10
+error[E0277]: the trait bound `diesel::query_builder::order_clause::OrderClause<(columns::id, columns::name)>: query_dsl::order_dsl::ValidOrderingForDistinct<DistinctOnClause<columns::name>>` is not satisfied
+   --> tests/fail/distinct_on_requires_matching_order_clause.rs:157:22
     |
 157 |         .distinct_on(users::name)
-    |          ^^^^^^^^^^^ expected struct `id`, found struct `name`
+    |          ----------- ^^^^^^^^^^^ the trait `query_dsl::order_dsl::ValidOrderingForDistinct<DistinctOnClause<columns::name>>` is not implemented for `diesel::query_builder::order_clause::OrderClause<(columns::id, columns::name)>`
+    |          |
+    |          required by a bound introduced by this call
     |
-    = note: required for `diesel::query_builder::order_clause::OrderClause<(columns::id, columns::name)>` to implement `query_dsl::order_dsl::ValidOrderingForDistinct<DistinctOnClause<columns::name>>`
+    = help: the following other types implement trait `query_dsl::order_dsl::ValidOrderingForDistinct<D>`:
+              <diesel::query_builder::order_clause::OrderClause<(T,)> as query_dsl::order_dsl::ValidOrderingForDistinct<DistinctOnClause<T>>>
+              <diesel::query_builder::order_clause::OrderClause<(T0, T1)> as query_dsl::order_dsl::ValidOrderingForDistinct<DistinctOnClause<(T0, T1, T2)>>>
+              <diesel::query_builder::order_clause::OrderClause<(T0, T1)> as query_dsl::order_dsl::ValidOrderingForDistinct<DistinctOnClause<(T0,)>>>
+              <diesel::query_builder::order_clause::OrderClause<(T0, T1)> as query_dsl::order_dsl::ValidOrderingForDistinct<DistinctOnClause<T0>>>
+              <diesel::query_builder::order_clause::OrderClause<(T0, T1, T2)> as query_dsl::order_dsl::ValidOrderingForDistinct<DistinctOnClause<(T0, T1)>>>
+              <diesel::query_builder::order_clause::OrderClause<(T0, T1, diesel::expression::operators::Asc<T2>)> as query_dsl::order_dsl::ValidOrderingForDistinct<DistinctOnClause<(T0, T1, T2)>>>
+              <diesel::query_builder::order_clause::OrderClause<(T0, T1, diesel::expression::operators::Desc<T2>)> as query_dsl::order_dsl::ValidOrderingForDistinct<DistinctOnClause<(T0, T1, T2)>>>
+              <diesel::query_builder::order_clause::OrderClause<(T0, T2, T1)> as query_dsl::order_dsl::ValidOrderingForDistinct<DistinctOnClause<(T0,)>>>
+            and $N others
     = note: required for `SelectStatement<FromClause<table>, DefaultSelectClause<FromClause<table>>, NoDistinctClause, ..., ...>` to implement `DistinctOnDsl<columns::name>`
+note: required by a bound in `diesel::QueryDsl::distinct_on`
+   --> $DIESEL/src/query_dsl/mod.rs
+    |
+    |         Self: methods::DistinctOnDsl<Expr>,
+    |               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `QueryDsl::distinct_on`
 
 error[E0277]: the trait bound `diesel::query_builder::order_clause::OrderClause<columns::id>: query_dsl::order_dsl::ValidOrderingForDistinct<DistinctOnClause<columns::name>>` is not satisfied
    --> tests/fail/distinct_on_requires_matching_order_clause.rs:164:19
@@ -152,14 +232,14 @@ error[E0277]: the trait bound `diesel::query_builder::order_clause::OrderClause<
     |          required by a bound introduced by this call
     |
     = help: the following other types implement trait `query_dsl::order_dsl::ValidOrderingForDistinct<D>`:
-              <diesel::query_builder::order_clause::OrderClause<(ST1, ST0)> as query_dsl::order_dsl::ValidOrderingForDistinct<DistinctOnClause<(T1,)>>>
-              <diesel::query_builder::order_clause::OrderClause<(ST1, ST0)> as query_dsl::order_dsl::ValidOrderingForDistinct<DistinctOnClause<T1>>>
-              <diesel::query_builder::order_clause::OrderClause<(ST1, ST2, ST0)> as query_dsl::order_dsl::ValidOrderingForDistinct<DistinctOnClause<(T1, T2)>>>
-              <diesel::query_builder::order_clause::OrderClause<(ST1, ST2, ST3, ST0)> as query_dsl::order_dsl::ValidOrderingForDistinct<DistinctOnClause<(T1, T2, T3)>>>
-              <diesel::query_builder::order_clause::OrderClause<(ST1, ST2, ST3, ST4, ST0)> as query_dsl::order_dsl::ValidOrderingForDistinct<DistinctOnClause<(T1, T2, T3, T4)>>>
-              <diesel::query_builder::order_clause::OrderClause<(ST2, ST0, ST1)> as query_dsl::order_dsl::ValidOrderingForDistinct<DistinctOnClause<(T2,)>>>
-              <diesel::query_builder::order_clause::OrderClause<(ST2, ST0, ST1)> as query_dsl::order_dsl::ValidOrderingForDistinct<DistinctOnClause<T2>>>
-              <diesel::query_builder::order_clause::OrderClause<(ST2, ST3, ST0, ST1)> as query_dsl::order_dsl::ValidOrderingForDistinct<DistinctOnClause<(T2, T3)>>>
+              <diesel::query_builder::order_clause::OrderClause<(T,)> as query_dsl::order_dsl::ValidOrderingForDistinct<DistinctOnClause<T>>>
+              <diesel::query_builder::order_clause::OrderClause<(T0, T1)> as query_dsl::order_dsl::ValidOrderingForDistinct<DistinctOnClause<(T0, T1, T2)>>>
+              <diesel::query_builder::order_clause::OrderClause<(T0, T1)> as query_dsl::order_dsl::ValidOrderingForDistinct<DistinctOnClause<(T0,)>>>
+              <diesel::query_builder::order_clause::OrderClause<(T0, T1)> as query_dsl::order_dsl::ValidOrderingForDistinct<DistinctOnClause<T0>>>
+              <diesel::query_builder::order_clause::OrderClause<(T0, T1, T2)> as query_dsl::order_dsl::ValidOrderingForDistinct<DistinctOnClause<(T0, T1)>>>
+              <diesel::query_builder::order_clause::OrderClause<(T0, T1, diesel::expression::operators::Asc<T2>)> as query_dsl::order_dsl::ValidOrderingForDistinct<DistinctOnClause<(T0, T1, T2)>>>
+              <diesel::query_builder::order_clause::OrderClause<(T0, T1, diesel::expression::operators::Desc<T2>)> as query_dsl::order_dsl::ValidOrderingForDistinct<DistinctOnClause<(T0, T1, T2)>>>
+              <diesel::query_builder::order_clause::OrderClause<(T0, T2, T1)> as query_dsl::order_dsl::ValidOrderingForDistinct<DistinctOnClause<(T0,)>>>
             and $N others
     = note: required for `SelectStatement<FromClause<table>, DefaultSelectClause<FromClause<table>>, DistinctOnClause<name>>` to implement `OrderDsl<columns::id>`
 note: required by a bound in `order_by`
diff --git a/diesel_tests/tests/distinct.rs b/diesel_tests/tests/distinct.rs
index 3e4866091270..de7a9acd6151 100644
--- a/diesel_tests/tests/distinct.rs
+++ b/diesel_tests/tests/distinct.rs
@@ -270,10 +270,54 @@ fn distinct_of_multiple_columns() {
         .load(&mut connection);
     let expected = vec![
         (posts[1].clone(), sean.clone()),
-        (posts[0].clone(), sean),
+        (posts[0].clone(), sean.clone()),
         (posts[5].clone(), tess.clone()),
-        (posts[4].clone(), tess),
+        (posts[4].clone(), tess.clone()),
+    ];
+
+    assert_eq!(Ok(expected), data);
+
+    // with arbitary expressions
+
+    let data = posts::table
+        .left_join(users::table)
+        .order((users::id.nullable(), posts::body.nullable().desc()))
+        .distinct_on((users::id.nullable(), posts::body.nullable()))
+        .load(&mut connection);
+
+    let expected = vec![
+        (posts[1].clone(), Some(sean.clone())),
+        (posts[0].clone(), Some(sean.clone())),
+        (posts[7].clone(), Some(tess.clone())),
+        (posts[6].clone(), Some(tess.clone())),
+    ];
+
+    assert_eq!(Ok(expected), data);
+
+    let data = posts::table
+        .left_join(users::table)
+        .order((users::id.nullable(), posts::body.nullable().desc()))
+        .distinct_on(users::id.nullable())
+        .load(&mut connection);
+
+    let expected = vec![
+        (posts[1].clone(), Some(sean.clone())),
+        (posts[7].clone(), Some(tess.clone())),
     ];
 
     assert_eq!(Ok(expected), data);
+
+    let data = posts::table
+        .left_join(users::table)
+        .order(users::id.nullable())
+        .distinct_on((users::id.nullable(), posts::body.nullable()))
+        .load(&mut connection);
+
+    let expected = vec![
+        (posts[0].clone(), Some(sean.clone())),
+        (posts[1].clone(), Some(sean)),
+        (posts[4].clone(), Some(tess.clone())),
+        (posts[7].clone(), Some(tess)),
+    ];
+    assert_eq!(Ok(expected), data);
 }