From bcc472b4d92a90c4699bc884aa88af61f72ce72b Mon Sep 17 00:00:00 2001 From: Crystal Zhou Date: Thu, 28 Aug 2025 16:00:34 -0400 Subject: [PATCH 1/6] Add hash to udf udaf udwf and unit test --- datafusion/ffi/src/udaf/mod.rs | 37 +++++++++++++++++++++--- datafusion/ffi/src/udf/mod.rs | 45 +++++++++++++++++++++++++++-- datafusion/ffi/src/udwf/mod.rs | 52 +++++++++++++++++++++++++++++++--- 3 files changed, 123 insertions(+), 11 deletions(-) diff --git a/datafusion/ffi/src/udaf/mod.rs b/datafusion/ffi/src/udaf/mod.rs index a2525e6ad4f4d..cfb595e574a73 100644 --- a/datafusion/ffi/src/udaf/mod.rs +++ b/datafusion/ffi/src/udaf/mod.rs @@ -39,7 +39,7 @@ use datafusion::{ }; use datafusion_proto_common::from_proto::parse_proto_fields_to_fields; use groups_accumulator::{FFI_GroupsAccumulator, ForeignGroupsAccumulator}; -use std::hash::{Hash, Hasher}; +use std::hash::{DefaultHasher, Hash, Hasher}; use std::{ffi::c_void, sync::Arc}; use crate::util::{rvec_wrapped_to_vec_fieldref, vec_fieldref_to_rvec_wrapped}; @@ -141,6 +141,9 @@ pub struct FFI_AggregateUDF { /// Release the memory of the private data when it is no longer being used. pub release: unsafe extern "C" fn(udaf: &mut Self), + /// Internal hash function. + pub hash: unsafe extern "C" fn(udaf: &Self) -> u64, + /// Internal data. This is only to be accessed by the provider of the udaf. /// A [`ForeignAggregateUDF`] should never attempt to access this data. pub private_data: *mut c_void, @@ -326,6 +329,12 @@ unsafe extern "C" fn clone_fn_wrapper(udaf: &FFI_AggregateUDF) -> FFI_AggregateU Arc::clone(udaf.inner()).into() } +unsafe extern "C" fn hash_fn_wrapper(udaf: &FFI_AggregateUDF) -> u64 { + let mut hasher = DefaultHasher::new(); + udaf.inner().hash(&mut hasher); + hasher.finish() +} + impl Clone for FFI_AggregateUDF { fn clone(&self) -> Self { unsafe { (self.clone)(self) } @@ -357,6 +366,7 @@ impl From> for FFI_AggregateUDF { coerce_types: coerce_types_fn_wrapper, clone: clone_fn_wrapper, release: release_fn_wrapper, + hash: hash_fn_wrapper, private_data: Box::into_raw(private_data) as *mut c_void, } } @@ -386,14 +396,17 @@ unsafe impl Sync for ForeignAggregateUDF {} impl PartialEq for ForeignAggregateUDF { fn eq(&self, other: &Self) -> bool { - // FFI_AggregateUDF cannot be compared, so identity equality is the best we can do. - std::ptr::eq(self, other) + // Compare using hash values for equality + let self_hash = unsafe { (self.udaf.hash)(&self.udaf) }; + let other_hash = unsafe { (other.udaf.hash)(&other.udaf) }; + self_hash == other_hash } } impl Eq for ForeignAggregateUDF {} impl Hash for ForeignAggregateUDF { fn hash(&self, state: &mut H) { - std::ptr::hash(self, state) + let function_hash = unsafe { (self.udaf.hash)(&self.udaf) }; + function_hash.hash(state) } } @@ -740,4 +753,20 @@ mod tests { test_round_trip_order_sensitivity(AggregateOrderSensitivity::SoftRequirement); test_round_trip_order_sensitivity(AggregateOrderSensitivity::Beneficial); } + + #[test] + fn test_eq() -> Result<()> { + // Test that identical UDAFs are equal + let sum_udaf1 = create_test_foreign_udaf(Sum::new())?; + let sum_udaf2 = create_test_foreign_udaf(Sum::new())?; + assert_eq!(sum_udaf1, sum_udaf2); + + // Test that different UDAFs are not equal + let count_udaf = create_test_foreign_udaf( + datafusion::functions_aggregate::count::Count::new(), + )?; + assert_ne!(sum_udaf1, count_udaf); + + Ok(()) + } } diff --git a/datafusion/ffi/src/udf/mod.rs b/datafusion/ffi/src/udf/mod.rs index 390b03fe621bb..24f866aaef17c 100644 --- a/datafusion/ffi/src/udf/mod.rs +++ b/datafusion/ffi/src/udf/mod.rs @@ -47,7 +47,7 @@ use datafusion::{ use return_type_args::{ FFI_ReturnFieldArgs, ForeignReturnFieldArgs, ForeignReturnFieldArgsOwned, }; -use std::hash::{Hash, Hasher}; +use std::hash::{DefaultHasher, Hash, Hasher}; use std::{ffi::c_void, sync::Arc}; pub mod return_type_args; @@ -111,6 +111,9 @@ pub struct FFI_ScalarUDF { /// Release the memory of the private data when it is no longer being used. pub release: unsafe extern "C" fn(udf: &mut Self), + /// Hash function for the UDF. Used for equality comparison. + pub hash: unsafe extern "C" fn(udf: &Self) -> u64, + /// Internal data. This is only to be accessed by the provider of the udf. /// A [`ForeignScalarUDF`] should never attempt to access this data. pub private_data: *mut c_void, @@ -236,6 +239,14 @@ unsafe extern "C" fn clone_fn_wrapper(udf: &FFI_ScalarUDF) -> FFI_ScalarUDF { Arc::clone(&udf_data.udf).into() } +unsafe extern "C" fn hash_fn_wrapper(udf: &FFI_ScalarUDF) -> u64 { + let private_data = udf.private_data as *const ScalarUDFPrivateData; + let udf = &(*private_data).udf; + let mut hasher = DefaultHasher::new(); + udf.hash(&mut hasher); + hasher.finish() +} + impl Clone for FFI_ScalarUDF { fn clone(&self) -> Self { unsafe { (self.clone)(self) } @@ -262,6 +273,7 @@ impl From> for FFI_ScalarUDF { coerce_types: coerce_types_fn_wrapper, clone: clone_fn_wrapper, release: release_fn_wrapper, + hash: hash_fn_wrapper, private_data: Box::into_raw(private_data) as *mut c_void, } } @@ -300,8 +312,8 @@ impl PartialEq for ForeignScalarUDF { } = self; name == &other.name && aliases == &other.aliases - && std::ptr::eq(udf, &other.udf) && signature == &other.signature + && unsafe { (udf.hash)(&udf) == (other.udf.hash)(&other.udf) } } } impl Eq for ForeignScalarUDF {} @@ -316,8 +328,9 @@ impl Hash for ForeignScalarUDF { } = self; name.hash(state); aliases.hash(state); - std::ptr::hash(udf, state); signature.hash(state); + let udf_hash = unsafe { (udf.hash)(udf) }; + udf_hash.hash(state); } } @@ -463,4 +476,30 @@ mod tests { Ok(()) } + + fn create_test_foreign_udf( + original_udf: impl ScalarUDFImpl + 'static, + ) -> Result { + let original_udf = Arc::new(ScalarUDF::from(original_udf)); + let local_udf: FFI_ScalarUDF = Arc::clone(&original_udf).into(); + let foreign_udf: ForeignScalarUDF = (&local_udf).try_into()?; + Ok(foreign_udf.into()) + } + + #[test] + fn test_eq() -> Result<()> { + // Test that identical UDFs are equal + let abs_udf1 = + create_test_foreign_udf(datafusion::functions::math::abs::AbsFunc::new())?; + let abs_udf2 = + create_test_foreign_udf(datafusion::functions::math::abs::AbsFunc::new())?; + assert_eq!(abs_udf1, abs_udf2); + + // Test that different UDFs are not equal + let sqrt_udf = + create_test_foreign_udf(datafusion::functions::math::gcd::GcdFunc::new())?; + assert_ne!(abs_udf1, sqrt_udf); + + Ok(()) + } } diff --git a/datafusion/ffi/src/udwf/mod.rs b/datafusion/ffi/src/udwf/mod.rs index d17999e274e2f..5147326c2b175 100644 --- a/datafusion/ffi/src/udwf/mod.rs +++ b/datafusion/ffi/src/udwf/mod.rs @@ -40,7 +40,7 @@ use partition_evaluator::{FFI_PartitionEvaluator, ForeignPartitionEvaluator}; use partition_evaluator_args::{ FFI_PartitionEvaluatorArgs, ForeignPartitionEvaluatorArgs, }; -use std::hash::{Hash, Hasher}; +use std::hash::{DefaultHasher, Hash, Hasher}; use std::{ffi::c_void, sync::Arc}; mod partition_evaluator; @@ -99,6 +99,9 @@ pub struct FFI_WindowUDF { /// Release the memory of the private data when it is no longer being used. pub release: unsafe extern "C" fn(udf: &mut Self), + /// Hash function for the UDWF. Used for equality comparison. + pub hash: unsafe extern "C" fn(udwf: &Self) -> u64, + /// Internal data. This is only to be accessed by the provider of the udf. /// A [`ForeignWindowUDF`] should never attempt to access this data. pub private_data: *mut c_void, @@ -197,10 +200,18 @@ unsafe extern "C" fn clone_fn_wrapper(udwf: &FFI_WindowUDF) -> FFI_WindowUDF { field: field_fn_wrapper, clone: clone_fn_wrapper, release: release_fn_wrapper, + hash: hash_fn_wrapper, private_data: Box::into_raw(private_data) as *mut c_void, } } +unsafe extern "C" fn hash_fn_wrapper(udwf: &FFI_WindowUDF) -> u64 { + let inner = udwf.inner(); + let mut hasher = DefaultHasher::new(); + inner.hash(&mut hasher); + hasher.finish() +} + impl Clone for FFI_WindowUDF { fn clone(&self) -> Self { unsafe { (self.clone)(self) } @@ -226,6 +237,7 @@ impl From> for FFI_WindowUDF { field: field_fn_wrapper, clone: clone_fn_wrapper, release: release_fn_wrapper, + hash: hash_fn_wrapper, private_data: Box::into_raw(private_data) as *mut c_void, } } @@ -256,14 +268,32 @@ unsafe impl Sync for ForeignWindowUDF {} impl PartialEq for ForeignWindowUDF { fn eq(&self, other: &Self) -> bool { - // FFI_WindowUDF cannot be compared, so identity equality is the best we can do. - std::ptr::eq(self, other) + let Self { + name, + aliases, + udf, + signature, + } = self; + name == &other.name + && aliases == &other.aliases + && unsafe { (udf.hash)(udf) == (other.udf.hash)(&other.udf) } + && signature == &other.signature } } impl Eq for ForeignWindowUDF {} impl Hash for ForeignWindowUDF { fn hash(&self, state: &mut H) { - std::ptr::hash(self, state) + let Self { + name, + aliases, + udf, + signature, + } = self; + name.hash(state); + aliases.hash(state); + let udf_hash = unsafe { (udf.hash)(udf) }; + udf_hash.hash(state); + signature.hash(state); } } @@ -443,4 +473,18 @@ mod tests { Ok(()) } + + #[test] + fn test_eq() -> datafusion::common::Result<()> { + // Test that identical UDWFs are equal (using hash-based comparison) + let lag_udwf1 = create_test_foreign_udwf(WindowShift::lag())?; + let lag_udwf2 = create_test_foreign_udwf(WindowShift::lag())?; + assert_eq!(lag_udwf1, lag_udwf2); + + // Test that different UDWFs are not equal + let lead_udwf = create_test_foreign_udwf(WindowShift::lead())?; + assert_ne!(lag_udwf1, lead_udwf); + + Ok(()) + } } From 3d32a75a67c567f8917e35ea12a08daa64f8d4d6 Mon Sep 17 00:00:00 2001 From: Crystal Zhou Date: Thu, 28 Aug 2025 22:46:37 -0400 Subject: [PATCH 2/6] Formatting fix --- datafusion/ffi/src/udf/mod.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/datafusion/ffi/src/udf/mod.rs b/datafusion/ffi/src/udf/mod.rs index 24f866aaef17c..7693811ba9849 100644 --- a/datafusion/ffi/src/udf/mod.rs +++ b/datafusion/ffi/src/udf/mod.rs @@ -313,7 +313,7 @@ impl PartialEq for ForeignScalarUDF { name == &other.name && aliases == &other.aliases && signature == &other.signature - && unsafe { (udf.hash)(&udf) == (other.udf.hash)(&other.udf) } + && unsafe { (udf.hash)(udf) == (other.udf.hash)(&other.udf) } } } impl Eq for ForeignScalarUDF {} From 4822be8f3390567032a9852b60a5e3fee42c0892 Mon Sep 17 00:00:00 2001 From: Crystal Zhou Date: Tue, 2 Sep 2025 18:48:00 -0400 Subject: [PATCH 3/6] Address comments to create hash_value interfaces --- datafusion/ffi/src/udaf/mod.rs | 29 +++++++++++++++-------------- datafusion/ffi/src/udf/mod.rs | 22 ++++++++-------------- datafusion/ffi/src/udwf/mod.rs | 28 +++++++++------------------- 3 files changed, 32 insertions(+), 47 deletions(-) diff --git a/datafusion/ffi/src/udaf/mod.rs b/datafusion/ffi/src/udaf/mod.rs index cfb595e574a73..aad71bbecbdac 100644 --- a/datafusion/ffi/src/udaf/mod.rs +++ b/datafusion/ffi/src/udaf/mod.rs @@ -142,7 +142,7 @@ pub struct FFI_AggregateUDF { pub release: unsafe extern "C" fn(udaf: &mut Self), /// Internal hash function. - pub hash: unsafe extern "C" fn(udaf: &Self) -> u64, + pub hash_value: u64, /// Internal data. This is only to be accessed by the provider of the udaf. /// A [`ForeignAggregateUDF`] should never attempt to access this data. @@ -329,12 +329,6 @@ unsafe extern "C" fn clone_fn_wrapper(udaf: &FFI_AggregateUDF) -> FFI_AggregateU Arc::clone(udaf.inner()).into() } -unsafe extern "C" fn hash_fn_wrapper(udaf: &FFI_AggregateUDF) -> u64 { - let mut hasher = DefaultHasher::new(); - udaf.inner().hash(&mut hasher); - hasher.finish() -} - impl Clone for FFI_AggregateUDF { fn clone(&self) -> Self { unsafe { (self.clone)(self) } @@ -348,6 +342,10 @@ impl From> for FFI_AggregateUDF { let is_nullable = udaf.is_nullable(); let volatility = udaf.signature().volatility.into(); + let mut hasher = DefaultHasher::new(); + udaf.hash(&mut hasher); + let hash_value = hasher.finish(); + let private_data = Box::new(AggregateUDFPrivateData { udaf }); Self { @@ -366,7 +364,7 @@ impl From> for FFI_AggregateUDF { coerce_types: coerce_types_fn_wrapper, clone: clone_fn_wrapper, release: release_fn_wrapper, - hash: hash_fn_wrapper, + hash_value, private_data: Box::into_raw(private_data) as *mut c_void, } } @@ -396,17 +394,20 @@ unsafe impl Sync for ForeignAggregateUDF {} impl PartialEq for ForeignAggregateUDF { fn eq(&self, other: &Self) -> bool { - // Compare using hash values for equality - let self_hash = unsafe { (self.udaf.hash)(&self.udaf) }; - let other_hash = unsafe { (other.udaf.hash)(&other.udaf) }; - self_hash == other_hash + let Self { + signature, + aliases, + udaf, + } = self; + signature == &other.signature + && aliases == &other.aliases + && udaf.hash_value == other.udaf.hash_value } } impl Eq for ForeignAggregateUDF {} impl Hash for ForeignAggregateUDF { fn hash(&self, state: &mut H) { - let function_hash = unsafe { (self.udaf.hash)(&self.udaf) }; - function_hash.hash(state) + self.udaf.hash_value.hash(state); } } diff --git a/datafusion/ffi/src/udf/mod.rs b/datafusion/ffi/src/udf/mod.rs index 7693811ba9849..cfd5f6e17fb0c 100644 --- a/datafusion/ffi/src/udf/mod.rs +++ b/datafusion/ffi/src/udf/mod.rs @@ -111,8 +111,8 @@ pub struct FFI_ScalarUDF { /// Release the memory of the private data when it is no longer being used. pub release: unsafe extern "C" fn(udf: &mut Self), - /// Hash function for the UDF. Used for equality comparison. - pub hash: unsafe extern "C" fn(udf: &Self) -> u64, + /// Hash value for the UDF used for equality comparison. + pub hash_value: u64, /// Internal data. This is only to be accessed by the provider of the udf. /// A [`ForeignScalarUDF`] should never attempt to access this data. @@ -239,14 +239,6 @@ unsafe extern "C" fn clone_fn_wrapper(udf: &FFI_ScalarUDF) -> FFI_ScalarUDF { Arc::clone(&udf_data.udf).into() } -unsafe extern "C" fn hash_fn_wrapper(udf: &FFI_ScalarUDF) -> u64 { - let private_data = udf.private_data as *const ScalarUDFPrivateData; - let udf = &(*private_data).udf; - let mut hasher = DefaultHasher::new(); - udf.hash(&mut hasher); - hasher.finish() -} - impl Clone for FFI_ScalarUDF { fn clone(&self) -> Self { unsafe { (self.clone)(self) } @@ -259,6 +251,9 @@ impl From> for FFI_ScalarUDF { let aliases = udf.aliases().iter().map(|a| a.to_owned().into()).collect(); let volatility = udf.signature().volatility.into(); let short_circuits = udf.short_circuits(); + let mut hasher = DefaultHasher::new(); + udf.hash(&mut hasher); + let hash_value = hasher.finish(); let private_data = Box::new(ScalarUDFPrivateData { udf }); @@ -273,7 +268,7 @@ impl From> for FFI_ScalarUDF { coerce_types: coerce_types_fn_wrapper, clone: clone_fn_wrapper, release: release_fn_wrapper, - hash: hash_fn_wrapper, + hash_value, private_data: Box::into_raw(private_data) as *mut c_void, } } @@ -313,7 +308,7 @@ impl PartialEq for ForeignScalarUDF { name == &other.name && aliases == &other.aliases && signature == &other.signature - && unsafe { (udf.hash)(udf) == (other.udf.hash)(&other.udf) } + && udf.hash_value == other.udf.hash_value } } impl Eq for ForeignScalarUDF {} @@ -329,8 +324,7 @@ impl Hash for ForeignScalarUDF { name.hash(state); aliases.hash(state); signature.hash(state); - let udf_hash = unsafe { (udf.hash)(udf) }; - udf_hash.hash(state); + udf.hash_value.hash(state); } } diff --git a/datafusion/ffi/src/udwf/mod.rs b/datafusion/ffi/src/udwf/mod.rs index 5147326c2b175..0bfc5ad6c0f0a 100644 --- a/datafusion/ffi/src/udwf/mod.rs +++ b/datafusion/ffi/src/udwf/mod.rs @@ -100,7 +100,7 @@ pub struct FFI_WindowUDF { pub release: unsafe extern "C" fn(udf: &mut Self), /// Hash function for the UDWF. Used for equality comparison. - pub hash: unsafe extern "C" fn(udwf: &Self) -> u64, + pub hash_value: u64, /// Internal data. This is only to be accessed by the provider of the udf. /// A [`ForeignWindowUDF`] should never attempt to access this data. @@ -180,12 +180,6 @@ unsafe extern "C" fn release_fn_wrapper(udwf: &mut FFI_WindowUDF) { } unsafe extern "C" fn clone_fn_wrapper(udwf: &FFI_WindowUDF) -> FFI_WindowUDF { - // let private_data = udf.private_data as *const WindowUDFPrivateData; - // let udf_data = &(*private_data); - - // let private_data = Box::new(WindowUDFPrivateData { - // udf: Arc::clone(&udf_data.udf), - // }); let private_data = Box::new(WindowUDFPrivateData { udf: Arc::clone(udwf.inner()), }); @@ -200,18 +194,11 @@ unsafe extern "C" fn clone_fn_wrapper(udwf: &FFI_WindowUDF) -> FFI_WindowUDF { field: field_fn_wrapper, clone: clone_fn_wrapper, release: release_fn_wrapper, - hash: hash_fn_wrapper, + hash_value : udwf.hash_value.clone(), private_data: Box::into_raw(private_data) as *mut c_void, } } -unsafe extern "C" fn hash_fn_wrapper(udwf: &FFI_WindowUDF) -> u64 { - let inner = udwf.inner(); - let mut hasher = DefaultHasher::new(); - inner.hash(&mut hasher); - hasher.finish() -} - impl Clone for FFI_WindowUDF { fn clone(&self) -> Self { unsafe { (self.clone)(self) } @@ -225,6 +212,10 @@ impl From> for FFI_WindowUDF { let volatility = udf.signature().volatility.into(); let sort_options = udf.sort_options().map(|v| (&v).into()).into(); + let mut hasher = DefaultHasher::new(); + udf.hash(&mut hasher); + let hash_value = hasher.finish(); + let private_data = Box::new(WindowUDFPrivateData { udf }); Self { @@ -237,7 +228,7 @@ impl From> for FFI_WindowUDF { field: field_fn_wrapper, clone: clone_fn_wrapper, release: release_fn_wrapper, - hash: hash_fn_wrapper, + hash_value, private_data: Box::into_raw(private_data) as *mut c_void, } } @@ -276,8 +267,8 @@ impl PartialEq for ForeignWindowUDF { } = self; name == &other.name && aliases == &other.aliases - && unsafe { (udf.hash)(udf) == (other.udf.hash)(&other.udf) } && signature == &other.signature + && udf.hash_value == other.udf.hash_value } } impl Eq for ForeignWindowUDF {} @@ -291,8 +282,7 @@ impl Hash for ForeignWindowUDF { } = self; name.hash(state); aliases.hash(state); - let udf_hash = unsafe { (udf.hash)(udf) }; - udf_hash.hash(state); + udf.hash_value.hash(state); signature.hash(state); } } From e5f0150165939729d8b3886bdd588863dc9bed75 Mon Sep 17 00:00:00 2001 From: Crystal Zhou Date: Tue, 2 Sep 2025 18:51:17 -0400 Subject: [PATCH 4/6] Refine comments --- datafusion/ffi/src/udaf/mod.rs | 2 +- datafusion/ffi/src/udwf/mod.rs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/datafusion/ffi/src/udaf/mod.rs b/datafusion/ffi/src/udaf/mod.rs index aad71bbecbdac..97108294ca6e2 100644 --- a/datafusion/ffi/src/udaf/mod.rs +++ b/datafusion/ffi/src/udaf/mod.rs @@ -141,7 +141,7 @@ pub struct FFI_AggregateUDF { /// Release the memory of the private data when it is no longer being used. pub release: unsafe extern "C" fn(udaf: &mut Self), - /// Internal hash function. + /// Hash value for the UDAF used for equality comparison. pub hash_value: u64, /// Internal data. This is only to be accessed by the provider of the udaf. diff --git a/datafusion/ffi/src/udwf/mod.rs b/datafusion/ffi/src/udwf/mod.rs index 0bfc5ad6c0f0a..85c122704dd11 100644 --- a/datafusion/ffi/src/udwf/mod.rs +++ b/datafusion/ffi/src/udwf/mod.rs @@ -99,7 +99,7 @@ pub struct FFI_WindowUDF { /// Release the memory of the private data when it is no longer being used. pub release: unsafe extern "C" fn(udf: &mut Self), - /// Hash function for the UDWF. Used for equality comparison. + /// Hash value for the UDWF used for equality comparison. pub hash_value: u64, /// Internal data. This is only to be accessed by the provider of the udf. From 51c8b1a0f5ee91cc87f13c294fced17debecb90c Mon Sep 17 00:00:00 2001 From: Crystal Zhou Date: Tue, 2 Sep 2025 19:08:59 -0400 Subject: [PATCH 5/6] Simplify hash function --- datafusion/ffi/src/udf/mod.rs | 11 +---------- datafusion/ffi/src/udwf/mod.rs | 13 ++----------- 2 files changed, 3 insertions(+), 21 deletions(-) diff --git a/datafusion/ffi/src/udf/mod.rs b/datafusion/ffi/src/udf/mod.rs index cfd5f6e17fb0c..46186cf4f78e0 100644 --- a/datafusion/ffi/src/udf/mod.rs +++ b/datafusion/ffi/src/udf/mod.rs @@ -315,16 +315,7 @@ impl Eq for ForeignScalarUDF {} impl Hash for ForeignScalarUDF { fn hash(&self, state: &mut H) { - let Self { - name, - aliases, - udf, - signature, - } = self; - name.hash(state); - aliases.hash(state); - signature.hash(state); - udf.hash_value.hash(state); + self.udf.hash_value.hash(state); } } diff --git a/datafusion/ffi/src/udwf/mod.rs b/datafusion/ffi/src/udwf/mod.rs index 85c122704dd11..985c7cc207c28 100644 --- a/datafusion/ffi/src/udwf/mod.rs +++ b/datafusion/ffi/src/udwf/mod.rs @@ -194,7 +194,7 @@ unsafe extern "C" fn clone_fn_wrapper(udwf: &FFI_WindowUDF) -> FFI_WindowUDF { field: field_fn_wrapper, clone: clone_fn_wrapper, release: release_fn_wrapper, - hash_value : udwf.hash_value.clone(), + hash_value : udwf.hash_value, private_data: Box::into_raw(private_data) as *mut c_void, } } @@ -274,16 +274,7 @@ impl PartialEq for ForeignWindowUDF { impl Eq for ForeignWindowUDF {} impl Hash for ForeignWindowUDF { fn hash(&self, state: &mut H) { - let Self { - name, - aliases, - udf, - signature, - } = self; - name.hash(state); - aliases.hash(state); - udf.hash_value.hash(state); - signature.hash(state); + self.udf.hash_value.hash(state); } } From 5d3041baaa751aad90a709fb96039373f24b229f Mon Sep 17 00:00:00 2001 From: Crystal Zhou Date: Tue, 2 Sep 2025 19:12:11 -0400 Subject: [PATCH 6/6] Fix cargo fmt --- datafusion/ffi/src/udf/mod.rs | 2 +- datafusion/ffi/src/udwf/mod.rs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/datafusion/ffi/src/udf/mod.rs b/datafusion/ffi/src/udf/mod.rs index 46186cf4f78e0..01ec44c8db4ec 100644 --- a/datafusion/ffi/src/udf/mod.rs +++ b/datafusion/ffi/src/udf/mod.rs @@ -308,7 +308,7 @@ impl PartialEq for ForeignScalarUDF { name == &other.name && aliases == &other.aliases && signature == &other.signature - && udf.hash_value == other.udf.hash_value + && udf.hash_value == other.udf.hash_value } } impl Eq for ForeignScalarUDF {} diff --git a/datafusion/ffi/src/udwf/mod.rs b/datafusion/ffi/src/udwf/mod.rs index 985c7cc207c28..c926c53901edc 100644 --- a/datafusion/ffi/src/udwf/mod.rs +++ b/datafusion/ffi/src/udwf/mod.rs @@ -194,7 +194,7 @@ unsafe extern "C" fn clone_fn_wrapper(udwf: &FFI_WindowUDF) -> FFI_WindowUDF { field: field_fn_wrapper, clone: clone_fn_wrapper, release: release_fn_wrapper, - hash_value : udwf.hash_value, + hash_value: udwf.hash_value, private_data: Box::into_raw(private_data) as *mut c_void, } }