Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion datafusion/expr/src/expr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -748,7 +748,10 @@ impl PartialOrd for Alias {
let Some(Ordering::Equal) = cmp else {
return cmp;
};
self.name.partial_cmp(&other.name)
self.name
.partial_cmp(&other.name)
// TODO (https://github.com/apache/datafusion/issues/17477) avoid recomparing all fields
.filter(|cmp| *cmp != Ordering::Equal || self == other)
}
}

Expand Down
27 changes: 24 additions & 3 deletions datafusion/expr/src/logical_plan/ddl.rs
Original file line number Diff line number Diff line change
Expand Up @@ -292,7 +292,10 @@ impl PartialOrd for CreateExternalTable {
unbounded: &other.unbounded,
constraints: &other.constraints,
};
comparable_self.partial_cmp(&comparable_other)
comparable_self
.partial_cmp(&comparable_other)
// TODO (https://github.com/apache/datafusion/issues/17477) avoid recomparing all fields
.filter(|cmp| *cmp != Ordering::Equal || self == other)
}
}

Expand Down Expand Up @@ -348,6 +351,8 @@ impl PartialOrd for CreateCatalog {
Some(Ordering::Equal) => self.if_not_exists.partial_cmp(&other.if_not_exists),
cmp => cmp,
}
// TODO (https://github.com/apache/datafusion/issues/17477) avoid recomparing all fields
.filter(|cmp| *cmp != Ordering::Equal || self == other)
}
}

Expand All @@ -369,6 +374,8 @@ impl PartialOrd for CreateCatalogSchema {
Some(Ordering::Equal) => self.if_not_exists.partial_cmp(&other.if_not_exists),
cmp => cmp,
}
// TODO (https://github.com/apache/datafusion/issues/17477) avoid recomparing all fields
.filter(|cmp| *cmp != Ordering::Equal || self == other)
}
}

Expand All @@ -390,6 +397,8 @@ impl PartialOrd for DropTable {
Some(Ordering::Equal) => self.if_exists.partial_cmp(&other.if_exists),
cmp => cmp,
}
// TODO (https://github.com/apache/datafusion/issues/17477) avoid recomparing all fields
.filter(|cmp| *cmp != Ordering::Equal || self == other)
}
}

Expand All @@ -411,6 +420,8 @@ impl PartialOrd for DropView {
Some(Ordering::Equal) => self.if_exists.partial_cmp(&other.if_exists),
cmp => cmp,
}
// TODO (https://github.com/apache/datafusion/issues/17477) avoid recomparing all fields
.filter(|cmp| *cmp != Ordering::Equal || self == other)
}
}

Expand All @@ -437,6 +448,8 @@ impl PartialOrd for DropCatalogSchema {
},
cmp => cmp,
}
// TODO (https://github.com/apache/datafusion/issues/17477) avoid recomparing all fields
.filter(|cmp| *cmp != Ordering::Equal || self == other)
}
}

Expand Down Expand Up @@ -486,7 +499,10 @@ impl PartialOrd for CreateFunction {
return_type: &other.return_type,
params: &other.params,
};
comparable_self.partial_cmp(&comparable_other)
comparable_self
.partial_cmp(&comparable_other)
// TODO (https://github.com/apache/datafusion/issues/17477) avoid recomparing all fields
.filter(|cmp| *cmp != Ordering::Equal || self == other)
}
}

Expand Down Expand Up @@ -566,6 +582,8 @@ impl PartialOrd for DropFunction {
Some(Ordering::Equal) => self.if_exists.partial_cmp(&other.if_exists),
cmp => cmp,
}
// TODO (https://github.com/apache/datafusion/issues/17477) avoid recomparing all fields
.filter(|cmp| *cmp != Ordering::Equal || self == other)
}
}

Expand Down Expand Up @@ -608,7 +626,10 @@ impl PartialOrd for CreateIndex {
unique: &other.unique,
if_not_exists: &other.if_not_exists,
};
comparable_self.partial_cmp(&comparable_other)
comparable_self
.partial_cmp(&comparable_other)
// TODO (https://github.com/apache/datafusion/issues/17477) avoid recomparing all fields
.filter(|cmp| *cmp != Ordering::Equal || self == other)
}
}

Expand Down
4 changes: 4 additions & 0 deletions datafusion/expr/src/logical_plan/dml.rs
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,8 @@ impl PartialOrd for CopyTo {
},
cmp => cmp,
}
// TODO (https://github.com/apache/datafusion/issues/17477) avoid recomparing all fields
.filter(|cmp| *cmp != Ordering::Equal || self == other)
}
}

Expand Down Expand Up @@ -217,6 +219,8 @@ impl PartialOrd for DmlStatement {
},
cmp => cmp,
}
// TODO (https://github.com/apache/datafusion/issues/17477) avoid recomparing all fields
.filter(|cmp| *cmp != Ordering::Equal || self == other)
}
}

Expand Down
7 changes: 5 additions & 2 deletions datafusion/expr/src/logical_plan/extension.rs
Original file line number Diff line number Diff line change
Expand Up @@ -150,7 +150,7 @@ pub trait UserDefinedLogicalNode: fmt::Debug + Send + Sync {
/// directly because it must remain object safe.
fn dyn_hash(&self, state: &mut dyn Hasher);

/// Compare `other`, respecting requirements from [std::cmp::Eq].
/// Compare `other`, respecting requirements from [Eq].
///
/// Note: consider using [`UserDefinedLogicalNodeCore`] instead of
/// [`UserDefinedLogicalNode`] directly.
Expand Down Expand Up @@ -188,6 +188,9 @@ pub trait UserDefinedLogicalNode: fmt::Debug + Send + Sync {
/// Note: [`UserDefinedLogicalNode`] is not constrained by [`Eq`]
/// directly because it must remain object safe.
fn dyn_eq(&self, other: &dyn UserDefinedLogicalNode) -> bool;

/// Compare `other`, respecting requirements from [PartialOrd].
/// Must return `Some(Equal)` if and only if `self.dyn_eq(other)`.
fn dyn_ord(&self, other: &dyn UserDefinedLogicalNode) -> Option<Ordering>;

/// Returns `true` if a limit can be safely pushed down through this
Expand Down Expand Up @@ -312,7 +315,7 @@ pub trait UserDefinedLogicalNodeCore:
}

/// Automatically derive UserDefinedLogicalNode to `UserDefinedLogicalNode`
/// to avoid boiler plate for implementing `as_any`, `Hash` and `PartialEq`
/// to avoid boiler plate for implementing `as_any`, `Hash`, `PartialEq` and `PartialOrd`.
impl<T: UserDefinedLogicalNodeCore> UserDefinedLogicalNode for T {
fn as_any(&self) -> &dyn Any {
self
Expand Down
48 changes: 40 additions & 8 deletions datafusion/expr/src/logical_plan/plan.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2060,7 +2060,10 @@ pub struct EmptyRelation {
// Manual implementation needed because of `schema` field. Comparison excludes this field.
impl PartialOrd for EmptyRelation {
fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
self.produce_one_row.partial_cmp(&other.produce_one_row)
self.produce_one_row
.partial_cmp(&other.produce_one_row)
// TODO (https://github.com/apache/datafusion/issues/17477) avoid recomparing all fields
.filter(|cmp| *cmp != Ordering::Equal || self == other)
}
}

Expand Down Expand Up @@ -2114,7 +2117,10 @@ pub struct Values {
// Manual implementation needed because of `schema` field. Comparison excludes this field.
impl PartialOrd for Values {
fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
self.values.partial_cmp(&other.values)
self.values
.partial_cmp(&other.values)
// TODO (https://github.com/apache/datafusion/issues/17477) avoid recomparing all fields
.filter(|cmp| *cmp != Ordering::Equal || self == other)
}
}

Expand All @@ -2139,6 +2145,8 @@ impl PartialOrd for Projection {
Some(Ordering::Equal) => self.input.partial_cmp(&other.input),
cmp => cmp,
}
// TODO (https://github.com/apache/datafusion/issues/17477) avoid recomparing all fields
.filter(|cmp| *cmp != Ordering::Equal || self == other)
}
}

Expand Down Expand Up @@ -2249,6 +2257,8 @@ impl PartialOrd for SubqueryAlias {
Some(Ordering::Equal) => self.alias.partial_cmp(&other.alias),
cmp => cmp,
}
// TODO (https://github.com/apache/datafusion/issues/17477) avoid recomparing all fields
.filter(|cmp| *cmp != Ordering::Equal || self == other)
}
}

Expand Down Expand Up @@ -2592,7 +2602,10 @@ impl PartialOrd for TableScan {
filters: &other.filters,
fetch: &other.fetch,
};
comparable_self.partial_cmp(&comparable_other)
comparable_self
.partial_cmp(&comparable_other)
// TODO (https://github.com/apache/datafusion/issues/17477) avoid recomparing all fields
.filter(|cmp| *cmp != Ordering::Equal || self == other)
}
}

Expand Down Expand Up @@ -2915,7 +2928,10 @@ impl Union {
// Manual implementation needed because of `schema` field. Comparison excludes this field.
impl PartialOrd for Union {
fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
self.inputs.partial_cmp(&other.inputs)
self.inputs
.partial_cmp(&other.inputs)
// TODO (https://github.com/apache/datafusion/issues/17477) avoid recomparing all fields
.filter(|cmp| *cmp != Ordering::Equal || self == other)
}
}

Expand Down Expand Up @@ -3196,7 +3212,10 @@ impl PartialOrd for Explain {
stringified_plans: &other.stringified_plans,
logical_optimization_succeeded: &other.logical_optimization_succeeded,
};
comparable_self.partial_cmp(&comparable_other)
comparable_self
.partial_cmp(&comparable_other)
// TODO (https://github.com/apache/datafusion/issues/17477) avoid recomparing all fields
.filter(|cmp| *cmp != Ordering::Equal || self == other)
}
}

Expand All @@ -3219,6 +3238,8 @@ impl PartialOrd for Analyze {
Some(Ordering::Equal) => self.input.partial_cmp(&other.input),
cmp => cmp,
}
// TODO (https://github.com/apache/datafusion/issues/17477) avoid recomparing all fields
.filter(|cmp| *cmp != Ordering::Equal || self == other)
}
}

Expand Down Expand Up @@ -3446,7 +3467,10 @@ impl PartialOrd for DistinctOn {
sort_expr: &other.sort_expr,
input: &other.input,
};
comparable_self.partial_cmp(&comparable_other)
comparable_self
.partial_cmp(&comparable_other)
// TODO (https://github.com/apache/datafusion/issues/17477) avoid recomparing all fields
.filter(|cmp| *cmp != Ordering::Equal || self == other)
}
}

Expand Down Expand Up @@ -3633,6 +3657,8 @@ impl PartialOrd for Aggregate {
}
cmp => cmp,
}
// TODO (https://github.com/apache/datafusion/issues/17477) avoid recomparing all fields
.filter(|cmp| *cmp != Ordering::Equal || self == other)
}
}

Expand Down Expand Up @@ -3905,7 +3931,10 @@ impl PartialOrd for Join {
join_constraint: &other.join_constraint,
null_equality: &other.null_equality,
};
comparable_self.partial_cmp(&comparable_other)
comparable_self
.partial_cmp(&comparable_other)
// TODO (https://github.com/apache/datafusion/issues/17477) avoid recomparing all fields
.filter(|cmp| *cmp != Ordering::Equal || self == other)
}
}

Expand Down Expand Up @@ -4070,7 +4099,10 @@ impl PartialOrd for Unnest {
dependency_indices: &other.dependency_indices,
options: &other.options,
};
comparable_self.partial_cmp(&comparable_other)
comparable_self
.partial_cmp(&comparable_other)
// TODO (https://github.com/apache/datafusion/issues/17477) avoid recomparing all fields
.filter(|cmp| *cmp != Ordering::Equal || self == other)
}
}

Expand Down
6 changes: 2 additions & 4 deletions datafusion/expr/src/udaf.rs
Original file line number Diff line number Diff line change
Expand Up @@ -978,16 +978,14 @@ impl PartialEq for dyn AggregateUDFImpl {
}
}

// TODO (https://github.com/apache/datafusion/issues/17064) PartialOrd is not consistent with PartialEq for `dyn AggregateUDFImpl` and it should be
// Manual implementation of `PartialOrd`
// There might be some wackiness with it, but this is based on the impl of eq for AggregateUDFImpl
// https://users.rust-lang.org/t/how-to-compare-two-trait-objects-for-equality/88063/5
impl PartialOrd for dyn AggregateUDFImpl {
fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
match self.name().partial_cmp(other.name()) {
Some(Ordering::Equal) => self.signature().partial_cmp(other.signature()),
cmp => cmp,
}
// TODO (https://github.com/apache/datafusion/issues/17477) avoid recomparing all fields
.filter(|cmp| *cmp != Ordering::Equal || self == other)
}
}

Expand Down
3 changes: 2 additions & 1 deletion datafusion/expr/src/udwf.rs
Original file line number Diff line number Diff line change
Expand Up @@ -434,13 +434,14 @@ impl PartialEq for dyn WindowUDFImpl {
}
}

// TODO (https://github.com/apache/datafusion/issues/17064) PartialOrd is not consistent with PartialEq for `dyn WindowUDFImpl` and it should be
impl PartialOrd for dyn WindowUDFImpl {
fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
match self.name().partial_cmp(other.name()) {
Some(Ordering::Equal) => self.signature().partial_cmp(other.signature()),
cmp => cmp,
}
// TODO (https://github.com/apache/datafusion/issues/17477) avoid recomparing all fields
.filter(|cmp| *cmp != Ordering::Equal || self == other)
}
}

Expand Down
4 changes: 4 additions & 0 deletions datafusion/optimizer/src/optimize_projections/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -902,6 +902,8 @@ mod tests {
Some(Ordering::Equal) => self.input.partial_cmp(&other.input),
cmp => cmp,
}
// TODO (https://github.com/apache/datafusion/issues/17477) avoid recomparing all fields
.filter(|cmp| *cmp != Ordering::Equal || self == other)
}
}

Expand Down Expand Up @@ -989,6 +991,8 @@ mod tests {
}
cmp => cmp,
}
// TODO (https://github.com/apache/datafusion/issues/17477) avoid recomparing all fields
.filter(|cmp| *cmp != Ordering::Equal || self == other)
}
}

Expand Down
5 changes: 4 additions & 1 deletion datafusion/optimizer/src/push_down_filter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1966,7 +1966,10 @@ mod tests {
// Manual implementation needed because of `schema` field. Comparison excludes this field.
impl PartialOrd for NoopPlan {
fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
self.input.partial_cmp(&other.input)
self.input
.partial_cmp(&other.input)
// TODO (https://github.com/apache/datafusion/issues/17477) avoid recomparing all fields
.filter(|cmp| *cmp != Ordering::Equal || self == other)
}
}

Expand Down
10 changes: 8 additions & 2 deletions datafusion/optimizer/src/push_down_limit.rs
Original file line number Diff line number Diff line change
Expand Up @@ -312,7 +312,10 @@ mod test {
// Manual implementation needed because of `schema` field. Comparison excludes this field.
impl PartialOrd for NoopPlan {
fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
self.input.partial_cmp(&other.input)
self.input
.partial_cmp(&other.input)
// TODO (https://github.com/apache/datafusion/issues/17477) avoid recomparing all fields
.filter(|cmp| *cmp != Ordering::Equal || self == other)
}
}

Expand Down Expand Up @@ -365,7 +368,10 @@ mod test {
// Manual implementation needed because of `schema` field. Comparison excludes this field.
impl PartialOrd for NoLimitNoopPlan {
fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
self.input.partial_cmp(&other.input)
self.input
.partial_cmp(&other.input)
// TODO (https://github.com/apache/datafusion/issues/17477) avoid recomparing all fields
.filter(|cmp| *cmp != Ordering::Equal || self == other)
}
}

Expand Down
2 changes: 2 additions & 0 deletions datafusion/substrait/tests/cases/roundtrip_logical_plan.rs
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,8 @@ impl PartialOrd for MockUserDefinedLogicalPlan {
Some(Ordering::Equal) => self.inputs.partial_cmp(&other.inputs),
cmp => cmp,
}
// TODO (https://github.com/apache/datafusion/issues/17477) avoid recomparing all fields
.filter(|cmp| *cmp != Ordering::Equal || self == other)
}
}

Expand Down