@@ -2927,7 +2927,7 @@ impl fmt::Display for OrderBy {
29272927pub struct OrderByExpr {
29282928 /// The expression to order by.
29292929 pub expr : Expr ,
2930- /// Ordering options such as `ASC`/`DESC` and `NULLS` behavior.
2930+ /// Ordering options such as `ASC`/`DESC`/`USING <operator>` and `NULLS` behavior.
29312931 pub options : OrderByOptions ,
29322932 /// Optional `WITH FILL` clause (ClickHouse extension) which specifies how to fill gaps.
29332933 pub with_fill : Option < WithFill > ,
@@ -2945,7 +2945,8 @@ impl From<Ident> for OrderByExpr {
29452945
29462946impl fmt:: Display for OrderByExpr {
29472947 fn fmt ( & self , f : & mut fmt:: Formatter ) -> fmt:: Result {
2948- write ! ( f, "{}{}" , self . expr, self . options) ?;
2948+ write ! ( f, "{}" , self . expr) ?;
2949+ write ! ( f, "{}" , self . options) ?;
29492950 if let Some ( ref with_fill) = self . with_fill {
29502951 write ! ( f, " {with_fill}" ) ?
29512952 }
@@ -3020,22 +3021,47 @@ impl fmt::Display for InterpolateExpr {
30203021 }
30213022}
30223023
3023- #[ derive( Default , Debug , Copy , Clone , PartialEq , PartialOrd , Eq , Ord , Hash ) ]
3024+ /// The sort order for an `ORDER BY` expression.
3025+ ///
3026+ /// See PostgreSQL `USING` operator:
3027+ /// <https://www.postgresql.org/docs/current/sql-select.html>
3028+ #[ derive( Debug , Clone , PartialEq , PartialOrd , Eq , Ord , Hash ) ]
30243029#[ cfg_attr( feature = "serde" , derive( Serialize , Deserialize ) ) ]
30253030#[ cfg_attr( feature = "visitor" , derive( Visit , VisitMut ) ) ]
3026- /// Options for an `ORDER BY` expression (ASC/DESC and NULLS FIRST/LAST).
3031+ pub enum OrderBySort {
3032+ /// `ASC`
3033+ Asc ,
3034+ /// `DESC`
3035+ Desc ,
3036+ /// PostgreSQL `USING <operator>` ordering.
3037+ ///
3038+ /// See <https://www.postgresql.org/docs/current/sql-select.html>
3039+ Using ( ObjectName ) ,
3040+ }
3041+
3042+ #[ derive( Default , Debug , Clone , PartialEq , PartialOrd , Eq , Ord , Hash ) ]
3043+ #[ cfg_attr( feature = "serde" , derive( Serialize , Deserialize ) ) ]
3044+ #[ cfg_attr( feature = "visitor" , derive( Visit , VisitMut ) ) ]
3045+ /// Options for an `ORDER BY` expression.
30273046pub struct OrderByOptions {
3028- /// Optional `ASC` (`Some(true)`) or `DESC` (`Some(false)`) .
3029- pub asc : Option < bool > ,
3047+ /// Optional sort order: `ASC`, `DESC`, or `USING <operator>` .
3048+ pub sort : Option < OrderBySort > ,
30303049 /// Optional `NULLS FIRST` (`Some(true)`) or `NULLS LAST` (`Some(false)`).
30313050 pub nulls_first : Option < bool > ,
30323051}
30333052
30343053impl fmt:: Display for OrderByOptions {
30353054 fn fmt ( & self , f : & mut fmt:: Formatter ) -> fmt:: Result {
3036- match self . asc {
3037- Some ( true ) => write ! ( f, " ASC" ) ?,
3038- Some ( false ) => write ! ( f, " DESC" ) ?,
3055+ match & self . sort {
3056+ Some ( OrderBySort :: Asc ) => write ! ( f, " ASC" ) ?,
3057+ Some ( OrderBySort :: Desc ) => write ! ( f, " DESC" ) ?,
3058+ Some ( OrderBySort :: Using ( op) ) => {
3059+ if op. 0 . len ( ) > 1 {
3060+ write ! ( f, " USING OPERATOR({op})" ) ?;
3061+ } else {
3062+ write ! ( f, " USING {op}" ) ?;
3063+ }
3064+ }
30393065 None => ( ) ,
30403066 }
30413067 match self . nulls_first {
0 commit comments