@@ -20,7 +20,6 @@ use crate::utils::{
20
20
first_byte_from_slice, overflow_error, slice_from_slice, try_binary_search_range_by,
21
21
} ;
22
22
use crate :: variant:: { Variant , VariantMetadata } ;
23
- use std:: collections:: HashMap ;
24
23
25
24
use arrow_schema:: ArrowError ;
26
25
@@ -221,6 +220,7 @@ impl<'m, 'v> VariantObject<'m, 'v> {
221
220
222
221
let mut field_ids_iter =
223
222
map_bytes_to_offsets ( field_id_buffer, self . header . field_id_size ) ;
223
+
224
224
// Validate all field ids exist in the metadata dictionary and the corresponding field names are lexicographically sorted
225
225
if self . metadata . is_sorted ( ) {
226
226
// Since the metadata dictionary has unique and sorted field names, we can also guarantee this object's field names
@@ -263,7 +263,7 @@ impl<'m, 'v> VariantObject<'m, 'v> {
263
263
let next_field_name = self . metadata . get ( field_id) ?;
264
264
265
265
if let Some ( current_name) = current_field_name {
266
- if next_field_name <= current_name {
266
+ if next_field_name < current_name {
267
267
return Err ( ArrowError :: InvalidArgumentError (
268
268
"field names not sorted" . to_string ( ) ,
269
269
) ) ;
@@ -412,26 +412,20 @@ impl<'m, 'v> VariantObject<'m, 'v> {
412
412
// checks whether the field values are equal -- regardless of their order
413
413
impl < ' m , ' v > PartialEq for VariantObject < ' m , ' v > {
414
414
fn eq ( & self , other : & Self ) -> bool {
415
- let mut is_equal = self . metadata == other. metadata
416
- && self . header == other. header
417
- && self . num_elements == other. num_elements
418
- && self . first_field_offset_byte == other. first_field_offset_byte
419
- && self . first_value_byte == other. first_value_byte
420
- && self . validated == other. validated ;
421
-
422
- // value validation
423
- let other_fields: HashMap < & str , Variant > = HashMap :: from_iter ( other. iter ( ) ) ;
424
-
425
- for ( field_name, variant) in self . iter ( ) {
426
- match other_fields. get ( field_name as & str ) {
427
- Some ( other_variant) => {
428
- is_equal = is_equal && variant == * other_variant;
429
- }
430
- None => return false ,
415
+ if self . num_elements != other. num_elements {
416
+ return false ;
417
+ }
418
+
419
+ // IFF two objects are valid and logically equal, they will have the same
420
+ // field names in the same order, because the spec requires the object
421
+ // fields to be sorted lexicographically.
422
+ for ( ( name_a, value_a) , ( name_b, value_b) ) in self . iter ( ) . zip ( other. iter ( ) ) {
423
+ if name_a != name_b || value_a != value_b {
424
+ return false ;
431
425
}
432
426
}
433
427
434
- is_equal
428
+ true
435
429
}
436
430
}
437
431
@@ -938,28 +932,66 @@ mod tests {
938
932
939
933
o. finish ( ) . unwrap ( ) ;
940
934
941
- let ( m , v ) = b. finish ( ) ;
935
+ let ( meta1 , value1 ) = b. finish ( ) ;
942
936
943
- let v1 = Variant :: try_new ( & m , & v ) . unwrap ( ) ;
937
+ let v1 = Variant :: try_new ( & meta1 , & value1 ) . unwrap ( ) ;
944
938
// v1 is sorted
945
939
assert ! ( v1. metadata( ) . unwrap( ) . is_sorted( ) ) ;
946
940
947
941
// create a second object with different insertion order
948
- let mut b = VariantBuilder :: new ( ) ;
942
+ let mut b = VariantBuilder :: new ( ) . with_field_names ( [ "d" , "c" , "b" , "a" ] . into_iter ( ) ) ;
949
943
let mut o = b. new_object ( ) ;
950
944
951
945
o. insert ( "b" , 4.3 ) ;
952
946
o. insert ( "a" , ( ) ) ;
953
947
954
948
o. finish ( ) . unwrap ( ) ;
955
949
956
- let ( m , v ) = b. finish ( ) ;
950
+ let ( meta2 , value2 ) = b. finish ( ) ;
957
951
958
- let v2 = Variant :: try_new ( & m , & v ) . unwrap ( ) ;
952
+ let v2 = Variant :: try_new ( & meta2 , & value2 ) . unwrap ( ) ;
959
953
// v2 is not sorted
960
954
assert ! ( !v2. metadata( ) . unwrap( ) . is_sorted( ) ) ;
961
955
956
+ // object metadata are not the same
957
+ assert_ne ! ( v1. metadata( ) , v2. metadata( ) ) ;
958
+
962
959
// objects are still logically equal
963
960
assert_eq ! ( v1, v2) ;
964
961
}
962
+
963
+ #[ test]
964
+ fn test_compare_object_with_unsorted_dictionary_vs_sorted_dictionary ( ) {
965
+ // create a sorted object
966
+ let mut b = VariantBuilder :: new ( ) ;
967
+ let mut o = b. new_object ( ) ;
968
+
969
+ o. insert ( "a" , false ) ;
970
+ o. insert ( "b" , false ) ;
971
+
972
+ o. finish ( ) . unwrap ( ) ;
973
+
974
+ let ( m, v) = b. finish ( ) ;
975
+
976
+ let v1 = Variant :: try_new ( & m, & v) . unwrap ( ) ;
977
+
978
+ // Create metadata with an unsorted dictionary (field names are "a", "a", "b")
979
+ // Since field names are not unique, it is considered not sorted.
980
+ let metadata_bytes = vec ! [
981
+ 0b0000_0001 ,
982
+ 3 , // dictionary size
983
+ 0 , // "a"
984
+ 1 , // "b"
985
+ 2 , // "a"
986
+ 3 ,
987
+ b'a' ,
988
+ b'b' ,
989
+ b'a' ,
990
+ ] ;
991
+ let m = VariantMetadata :: try_new ( & metadata_bytes) . unwrap ( ) ;
992
+ assert ! ( !m. is_sorted( ) ) ;
993
+
994
+ let v2 = Variant :: new_with_metadata ( m, & v) ;
995
+ assert_eq ! ( v1, v2) ;
996
+ }
965
997
}
0 commit comments