mbutrovich commented on code in PR #11407:
URL: https://github.com/apache/arrow-rs/pull/11407#discussion_r4275023113


##########
arrow-cmp/src/lib.rs:
##########
@@ -798,6 +867,186 @@ mod tests {
         assert_eq!(Ordering::Greater, cmp(1, 3));
     }
 
+    #[test]
+    fn dict_fixed_size_binary_fast_path_derefs_values_both_directions() {
+        let shared_keys = || Int32Array::from(vec![0_i32, 1]);
+        let left_values =
+            FixedSizeBinaryArray::try_from_iter([b"zz".as_ref(), 
b"aa".as_ref()].into_iter())
+                .unwrap();
+        let right_values =
+            FixedSizeBinaryArray::try_from_iter([b"aa".as_ref(), 
b"zz".as_ref()].into_iter())
+                .unwrap();
+        let left = DictionaryArray::<Int32Type>::new(shared_keys(), 
Arc::new(left_values));
+        let right = DictionaryArray::<Int32Type>::new(shared_keys(), 
Arc::new(right_values));
+
+        let ascending = make_comparator(&left, &right, 
SortOptions::default()).unwrap();
+        assert_eq!(ascending(0, 0), Ordering::Greater);
+        assert_eq!(ascending(1, 1), Ordering::Less);
+
+        let descending = make_comparator(
+            &left,
+            &right,
+            SortOptions {
+                descending: true,
+                nulls_first: true,
+            },
+        )
+        .unwrap();
+        assert_eq!(descending(0, 0), Ordering::Less);
+        assert_eq!(descending(1, 1), Ordering::Greater);
+    }
+
+    #[test]
+    fn dict_bytes_fast_path_derefs_values_both_directions() {
+        let shared_keys = || Int32Array::from(vec![0_i32, 1]);
+        let left = DictionaryArray::<Int32Type>::new(
+            shared_keys(),
+            Arc::new(StringArray::from(vec!["z", "a"])),
+        );
+        let right = DictionaryArray::<Int32Type>::new(
+            shared_keys(),
+            Arc::new(StringArray::from(vec!["a", "z"])),
+        );
+
+        let ascending = make_comparator(&left, &right, 
SortOptions::default()).unwrap();
+        assert_eq!(ascending(0, 0), Ordering::Greater);
+        assert_eq!(ascending(1, 1), Ordering::Less);
+
+        let descending = make_comparator(
+            &left,
+            &right,
+            SortOptions {
+                descending: true,
+                nulls_first: true,
+            },
+        )
+        .unwrap();
+        assert_eq!(descending(0, 0), Ordering::Less);
+        assert_eq!(descending(1, 1), Ordering::Greater);
+    }
+
+    #[test]
+    fn dict_bytes_fallback_handles_key_and_value_nulls() {

Review Comment:
   Should we drop `fallback` from this name, and from the ones on lines 948 and 
1002? With the separate no-null closures gone, there's no fallback path left in 
`compare_dict_bytes` or `compare_dict_fixed_size_binary`. A reader could take 
"fallback" to mean the generic `make_comparator` path in `compare_dict`, and 
these tests don't reach that path.
   
   ```suggestion
       fn dict_bytes_handles_key_and_value_nulls() {
   ```



##########
arrow-cmp/src/lib.rs:
##########
@@ -220,6 +220,25 @@ fn compare_dict<K: ArrowDictionaryKeyType>(
 ) -> Result<DynComparator, ArrowError> {
     let left = left.as_dictionary::<K>();
     let right = right.as_dictionary::<K>();
+    let value_dtype = left.values().data_type();
+    if value_dtype == right.values().data_type() {
+        match value_dtype {
+            DataType::Utf8 => return Ok(compare_dict_bytes::<K, 
Utf8Type>(left, right, opts)),
+            DataType::LargeUtf8 => {
+                return Ok(compare_dict_bytes::<K, LargeUtf8Type>(left, right, 
opts));
+            }
+            DataType::Binary => {
+                return Ok(compare_dict_bytes::<K, BinaryType>(left, right, 
opts));
+            }
+            DataType::LargeBinary => {
+                return Ok(compare_dict_bytes::<K, LargeBinaryType>(left, 
right, opts));
+            }

Review Comment:
   Could we add a test that goes through the `LargeUtf8`, `Binary` and 
`LargeBinary` arms? The new tests all build `StringArray` or 
`FixedSizeBinaryArray` values, so these three arms still aren't reached by any 
test (this was part of 
https://github.com/apache/arrow-rs/pull/11407#discussion_r4264007280). A 
generic helper in the style of 
[`test_bytes_impl`](https://github.com/apache/arrow-rs/blob/b76b9b62f6015d74e8b4b70ca4c647a9082dd33a/arrow-cmp/src/lib.rs#L1254-L1270)
 would cover all four byte types in a few lines:
   
   ```rust
   fn test_dict_bytes_impl<T: ByteArrayType>() {
       let offsets = OffsetBuffer::from_lengths([1, 1]);
       let values = GenericByteArray::<T>::new(offsets, b"za".into(), None);
       let keys = Int32Array::from(vec![Some(0), None, Some(1)]);
       let dict = DictionaryArray::<Int32Type>::new(keys, Arc::new(values));
   
       let cmp = make_comparator(&dict, &dict, SortOptions::default()).unwrap();
       assert_eq!(cmp(0, 2), Ordering::Greater);
       assert_eq!(cmp(1, 2), Ordering::Less);
       assert_eq!(cmp(1, 1), Ordering::Equal);
   }
   
   #[test]
   fn test_dict_bytes() {
       test_dict_bytes_impl::<Utf8Type>();
       test_dict_bytes_impl::<LargeUtf8Type>();
       test_dict_bytes_impl::<BinaryType>();
       test_dict_bytes_impl::<LargeBinaryType>();
   }
   ```
   
   The out-of-bounds test also only covers `compare_dict_bytes`. What do you 
think about adding the same `#[should_panic]` case for a `FixedSizeBinary` 
dictionary?



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]

Reply via email to