This is an automated email from the ASF dual-hosted git repository.

comphead pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/datafusion.git


The following commit(s) were added to refs/heads/main by this push:
     new 5ebc49dc17 feat: support fixed size list for array reverse (#16423)
5ebc49dc17 is described below

commit 5ebc49dc176c5b933ed3d0f1e851d338ad2a7862
Author: Chen Chongchen <chenkov...@qq.com>
AuthorDate: Thu Jun 19 00:06:29 2025 +0800

    feat: support fixed size list for array reverse (#16423)
    
    * feat: support fixed size list for array reverse
    
    * update
    
    * Update array.slt
---
 datafusion/functions-nested/src/reverse.rs   | 50 ++++++++++++++++++++++++++--
 datafusion/sqllogictest/test_files/array.slt | 12 ++++---
 2 files changed, 54 insertions(+), 8 deletions(-)

diff --git a/datafusion/functions-nested/src/reverse.rs 
b/datafusion/functions-nested/src/reverse.rs
index 140cd19aef..eb36047e09 100644
--- a/datafusion/functions-nested/src/reverse.rs
+++ b/datafusion/functions-nested/src/reverse.rs
@@ -19,12 +19,15 @@
 
 use crate::utils::make_scalar_function;
 use arrow::array::{
-    Array, ArrayRef, Capacities, GenericListArray, MutableArrayData, 
OffsetSizeTrait,
+    Array, ArrayRef, Capacities, FixedSizeListArray, GenericListArray, 
MutableArrayData,
+    OffsetSizeTrait,
 };
 use arrow::buffer::OffsetBuffer;
-use arrow::datatypes::DataType::{LargeList, List, Null};
+use arrow::datatypes::DataType::{FixedSizeList, LargeList, List, Null};
 use arrow::datatypes::{DataType, FieldRef};
-use datafusion_common::cast::{as_large_list_array, as_list_array};
+use datafusion_common::cast::{
+    as_fixed_size_list_array, as_large_list_array, as_list_array,
+};
 use datafusion_common::{exec_err, utils::take_function_args, Result};
 use datafusion_expr::{
     ColumnarValue, Documentation, ScalarUDFImpl, Signature, Volatility,
@@ -125,6 +128,10 @@ pub fn array_reverse_inner(arg: &[ArrayRef]) -> 
Result<ArrayRef> {
             let array = as_large_list_array(input_array)?;
             general_array_reverse::<i64>(array, field)
         }
+        FixedSizeList(field, _) => {
+            let array = as_fixed_size_list_array(input_array)?;
+            fixed_size_array_reverse(array, field)
+        }
         Null => Ok(Arc::clone(input_array)),
         array_type => exec_err!("array_reverse does not support type 
'{array_type:?}'."),
     }
@@ -175,3 +182,40 @@ fn general_array_reverse<O: OffsetSizeTrait + 
TryFrom<i64>>(
         Some(nulls.into()),
     )?))
 }
+
+fn fixed_size_array_reverse(
+    array: &FixedSizeListArray,
+    field: &FieldRef,
+) -> Result<ArrayRef> {
+    let values = array.values();
+    let original_data = values.to_data();
+    let capacity = Capacities::Array(original_data.len());
+    let mut nulls = vec![];
+    let mut mutable =
+        MutableArrayData::with_capacities(vec![&original_data], false, 
capacity);
+    let value_length = array.value_length() as usize;
+
+    for row_index in 0..array.len() {
+        // skip the null value
+        if array.is_null(row_index) {
+            nulls.push(false);
+            mutable.extend(0, 0, 1);
+            continue;
+        } else {
+            nulls.push(true);
+        }
+        let start = row_index * value_length;
+        let end = start + value_length;
+        for idx in (start..end).rev() {
+            mutable.extend(0, idx, idx + 1);
+        }
+    }
+
+    let data = mutable.freeze();
+    Ok(Arc::new(FixedSizeListArray::try_new(
+        Arc::clone(field),
+        array.value_length(),
+        arrow::array::make_array(data),
+        Some(nulls.into()),
+    )?))
+}
diff --git a/datafusion/sqllogictest/test_files/array.slt 
b/datafusion/sqllogictest/test_files/array.slt
index a2640fa988..cb2394af06 100644
--- a/datafusion/sqllogictest/test_files/array.slt
+++ b/datafusion/sqllogictest/test_files/array.slt
@@ -7853,11 +7853,13 @@ select array_reverse(arrow_cast(make_array(1, 2, 3), 
'LargeList(Int64)')), array
 ----
 [3, 2, 1] [1]
 
-#TODO: support after FixedSizeList type coercion
-#query ??
-#select array_reverse(arrow_cast(make_array(1, 2, 3), 'FixedSizeList(3, 
Int64)')), array_reverse(arrow_cast(make_array(1), 'FixedSizeList(1, Int64)'));
-#----
-#[3, 2, 1] [1]
+query ????
+select array_reverse(arrow_cast(make_array(1, 2, 3), 'FixedSizeList(3, 
Int64)')), 
+  array_reverse(arrow_cast(make_array(1), 'FixedSizeList(1, Int64)')),
+  array_reverse(arrow_cast(make_array(1, NULL, 3), 'FixedSizeList(3, Int64)')),
+  array_reverse(arrow_cast(make_array(NULL, NULL, NULL), 'FixedSizeList(3, 
Int64)'));
+----
+[3, 2, 1] [1] [3, NULL, 1] [NULL, NULL, NULL]
 
 query ??
 select array_reverse(NULL), array_reverse([]);


---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscr...@datafusion.apache.org
For additional commands, e-mail: commits-h...@datafusion.apache.org

Reply via email to