Jefffrey commented on code in PR #9023:
URL: https://github.com/apache/arrow-datafusion/pull/9023#discussion_r1468726417
##########
datafusion/physical-expr/src/array_expressions.rs:
##########
@@ -2766,6 +2766,73 @@ where
)?))
}
+/// array_reverse SQL function
+pub fn array_reverse(arg: &[ArrayRef]) -> Result<ArrayRef> {
+ if arg.len() != 1 {
+ return exec_err!("array_reverse needs one argument");
+ }
+
+ match &arg[0].data_type() {
+ DataType::List(field) => {
+ let array = as_list_array(&arg[0])?;
+ general_array_reverse::<i32>(array, &field)
+ }
+ DataType::LargeList(field) => {
+ let array = as_large_list_array(&arg[0])?;
+ general_array_reverse::<i64>(array, &field)
+ }
+ DataType::Null => Ok(arg[0].clone()),
+ array_type => exec_err!("array_reverse does not support type
'{array_type:?}'."),
+ }
+}
+
+fn general_array_reverse<O: OffsetSizeTrait>(
+ array: &GenericListArray<O>,
+ field: &FieldRef,
+) -> Result<ArrayRef>
+where
+ O: TryFrom<i64>,
+{
+ let values = array.values();
+ let original_data = values.to_data();
+ let capacity = Capacities::Array(original_data.len());
+ let mut offsets = vec![O::usize_as(0)];
+ let mut nulls = vec![];
+ let mut mutable =
+ MutableArrayData::with_capacities(vec![&original_data], false,
capacity);
+
+ for (row_index, offset_window) in array.offsets().windows(2).enumerate() {
+ let start = offset_window[0];
+ let end = offset_window[1];
+
+ let mut index = end - O::one();
+ let mut cnt = 0;
+ let stride: O = (-1 as i64).try_into().map_err(|_| {
+ internal_datafusion_err!("array_reverse: failed to convert size to
i64")
+ })?;
+ while index >= start {
+ mutable.extend(0, index.to_usize().unwrap(),
index.to_usize().unwrap() + 1);
+ index += stride;
+ cnt += 1;
+ }
Review Comment:
Technically, if the slot is null, we could skip this entire bit and just
push into `offsets` with `cnt = 0`? Not sure if worth the extra code
complexity, but worth a thought :thinking:
##########
datafusion/physical-expr/src/array_expressions.rs:
##########
@@ -2766,6 +2766,72 @@ where
)?))
}
+/// array_reverse SQL function
+pub fn array_reverse(arg: &[ArrayRef]) -> Result<ArrayRef> {
+ if arg.len() != 1 {
+ return exec_err!("array_reverse needs one argument");
+ }
+
+ match &arg[0].data_type() {
+ DataType::List(field) => {
+ let array = as_list_array(&arg[0])?;
+ general_array_reverse::<i32>(array, &field)
+ }
+ DataType::LargeList(field) => {
+ let array = as_large_list_array(&arg[0])?;
+ general_array_reverse::<i64>(array, &field)
+ }
+ DataType::Null => Ok(arg[0].clone()),
Review Comment:
Ah makes sense. So this would be done in a later PR, if I understand
correctly?
Else if it should already work with `FixedSizeList` then can add that as a
test case in slt
--
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]