diff --git a/datafusion/src/logical_plan/expr.rs b/datafusion/src/logical_plan/expr.rs index eb46099dff646..baec3e28a14a1 100644 --- a/datafusion/src/logical_plan/expr.rs +++ b/datafusion/src/logical_plan/expr.rs @@ -217,7 +217,7 @@ impl fmt::Display for Column { /// assert_eq!(op, Operator::Eq); /// } /// ``` -#[derive(Clone, PartialEq)] +#[derive(Clone, PartialEq, PartialOrd)] pub enum Expr { /// An expression with a specific name. Alias(Box, String), @@ -2070,4 +2070,18 @@ mod tests { test_unary_scalar_expr!(Trim, trim); test_unary_scalar_expr!(Upper, upper); } + + #[test] + fn test_partial_ord() { + // Test validates that partial ord is defined for Expr, not + // intended to exhaustively test all possibilities + let exp1 = col("a") + lit(1); + let exp2 = col("a") + lit(2); + let exp3 = !(col("a") + lit(2)); + + assert!(exp1 < exp2); + assert!(exp2 > exp1); + assert!(exp2 < exp3); + assert!(exp3 > exp2); + } } diff --git a/datafusion/src/logical_plan/operators.rs b/datafusion/src/logical_plan/operators.rs index b3ff72cf2cac8..4e9ccb7484633 100644 --- a/datafusion/src/logical_plan/operators.rs +++ b/datafusion/src/logical_plan/operators.rs @@ -20,7 +20,7 @@ use std::{fmt, ops}; use super::{binary_expr, Expr}; /// Operators applied to expressions -#[derive(Debug, Copy, Clone, PartialEq, Eq)] +#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd)] pub enum Operator { /// Expressions are equal Eq, diff --git a/datafusion/src/logical_plan/window_frames.rs b/datafusion/src/logical_plan/window_frames.rs index 8aaebd3155c19..d65ed005231ce 100644 --- a/datafusion/src/logical_plan/window_frames.rs +++ b/datafusion/src/logical_plan/window_frames.rs @@ -34,7 +34,7 @@ use std::fmt; /// The ending frame boundary can be omitted (if the BETWEEN and AND keywords that surround the /// starting frame boundary are also omitted), in which case the ending frame boundary defaults to /// CURRENT ROW. -#[derive(Debug, Clone, Copy, PartialEq, Eq)] +#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd)] pub struct WindowFrame { /// A frame type - either ROWS, RANGE or GROUPS pub units: WindowFrameUnits, @@ -211,7 +211,7 @@ impl WindowFrameBound { /// There are three frame types: ROWS, GROUPS, and RANGE. The frame type determines how the /// starting and ending boundaries of the frame are measured. -#[derive(Debug, Clone, Copy, PartialEq, Eq)] +#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd)] pub enum WindowFrameUnits { /// The ROWS frame type means that the starting and ending boundaries for the frame are /// determined by counting individual rows relative to the current row. diff --git a/datafusion/src/physical_plan/aggregates.rs b/datafusion/src/physical_plan/aggregates.rs index 57c9b61c91fd4..2f34b1704cac0 100644 --- a/datafusion/src/physical_plan/aggregates.rs +++ b/datafusion/src/physical_plan/aggregates.rs @@ -47,7 +47,7 @@ pub type StateTypeFunction = Arc Result>> + Send + Sync>; /// Enum of all built-in scalar functions -#[derive(Debug, Clone, PartialEq, Eq)] +#[derive(Debug, Clone, PartialEq, Eq, PartialOrd)] pub enum AggregateFunction { /// count Count, diff --git a/datafusion/src/physical_plan/functions.rs b/datafusion/src/physical_plan/functions.rs index a005f56dd02af..cc89f557ce959 100644 --- a/datafusion/src/physical_plan/functions.rs +++ b/datafusion/src/physical_plan/functions.rs @@ -57,7 +57,7 @@ use std::convert::From; use std::{any::Any, fmt, str::FromStr, sync::Arc}; /// A function's signature, which defines the function's supported argument types. -#[derive(Debug, Clone, PartialEq)] +#[derive(Debug, Clone, PartialEq, PartialOrd)] pub enum Signature { /// arbitrary number of arguments of an common type out of a list of valid types // A function such as `concat` is `Variadic(vec![DataType::Utf8, DataType::LargeUtf8])` @@ -94,7 +94,7 @@ pub type ReturnTypeFunction = Arc Result> + Send + Sync>; /// Enum of all built-in scalar functions -#[derive(Debug, Clone, PartialEq, Eq)] +#[derive(Debug, Clone, PartialEq, Eq, PartialOrd)] pub enum BuiltinScalarFunction { // math functions /// abs diff --git a/datafusion/src/physical_plan/udaf.rs b/datafusion/src/physical_plan/udaf.rs index c6d65ad5dd607..d9d14041a48c8 100644 --- a/datafusion/src/physical_plan/udaf.rs +++ b/datafusion/src/physical_plan/udaf.rs @@ -71,6 +71,17 @@ impl PartialEq for AggregateUDF { } } +impl PartialOrd for AggregateUDF { + fn partial_cmp(&self, other: &Self) -> Option { + let c = self.name.partial_cmp(&other.name); + if matches!(c, Some(std::cmp::Ordering::Equal)) { + self.signature.partial_cmp(&other.signature) + } else { + c + } + } +} + impl AggregateUDF { /// Create a new AggregateUDF pub fn new( diff --git a/datafusion/src/physical_plan/udf.rs b/datafusion/src/physical_plan/udf.rs index a79c0a8a36059..39265c0eb5efa 100644 --- a/datafusion/src/physical_plan/udf.rs +++ b/datafusion/src/physical_plan/udf.rs @@ -69,6 +69,17 @@ impl PartialEq for ScalarUDF { } } +impl PartialOrd for ScalarUDF { + fn partial_cmp(&self, other: &Self) -> Option { + let c = self.name.partial_cmp(&other.name); + if matches!(c, Some(std::cmp::Ordering::Equal)) { + self.signature.partial_cmp(&other.signature) + } else { + c + } + } +} + impl ScalarUDF { /// Create a new ScalarUDF pub fn new( diff --git a/datafusion/src/physical_plan/window_functions.rs b/datafusion/src/physical_plan/window_functions.rs index e2b460644479c..708b099f14d63 100644 --- a/datafusion/src/physical_plan/window_functions.rs +++ b/datafusion/src/physical_plan/window_functions.rs @@ -35,7 +35,7 @@ use std::sync::Arc; use std::{fmt, str::FromStr}; /// WindowFunction -#[derive(Debug, Clone, PartialEq, Eq)] +#[derive(Debug, Clone, PartialEq, Eq, PartialOrd)] pub enum WindowFunction { /// window function that leverages an aggregate function AggregateFunction(AggregateFunction), @@ -90,7 +90,7 @@ impl fmt::Display for WindowFunction { } /// An aggregate function that is part of a built-in window function -#[derive(Debug, Clone, PartialEq, Eq)] +#[derive(Debug, Clone, PartialEq, Eq, PartialOrd)] pub enum BuiltInWindowFunction { /// number of the current row within its partition, counting from 1 RowNumber,