jonahgao commented on code in PR #9352:
URL: https://github.com/apache/arrow-datafusion/pull/9352#discussion_r1503716528
##########
datafusion/functions-array/src/kernels.rs:
##########
@@ -252,3 +253,67 @@ pub(super) fn array_to_string(args: &[ArrayRef]) ->
datafusion_common::Result<Ar
Ok(Arc::new(string_arr))
}
+
+use arrow::array::ListArray;
+use arrow::buffer::OffsetBuffer;
+use arrow::datatypes::Field;
+/// Generates an array of integers from start to stop with a given step.
+///
+/// This function takes 1 to 3 ArrayRefs as arguments, representing start,
stop, and step values.
+/// It returns a `Result<ArrayRef>` representing the resulting ListArray after
the operation.
+///
+/// # Arguments
+///
+/// * `args` - An array of 1 to 3 ArrayRefs representing start, stop, and
step(step value can not be zero.) values.
+///
+/// # Examples
+///
+/// gen_range(3) => [0, 1, 2]
+/// gen_range(1, 4) => [1, 2, 3]
+/// gen_range(1, 7, 2) => [1, 3, 5]
+pub fn gen_range(
+ args: &[ArrayRef],
+ include_upper: i64,
+) -> datafusion_common::Result<ArrayRef> {
+ let (start_array, stop_array, step_array) = match args.len() {
+ 1 => (None, as_int64_array(&args[0])?, None),
+ 2 => (
+ Some(as_int64_array(&args[0])?),
+ as_int64_array(&args[1])?,
+ None,
+ ),
+ 3 => (
+ Some(as_int64_array(&args[0])?),
+ as_int64_array(&args[1])?,
+ Some(as_int64_array(&args[2])?),
+ ),
+ _ => return exec_err!("gen_range expects 1 to 3 arguments"),
+ };
+
+ let mut values = vec![];
+ let mut offsets = vec![0];
+ for (idx, stop) in stop_array.iter().enumerate() {
+ let stop = stop.unwrap_or(0) + include_upper;
Review Comment:
> I think we don't have i128Array yet, so probably this panic is unavoidable
until we support it.
I tried it in the following way, and then it worked, but I haven't checked
it carefully yet.
```rust
for (idx, stop) in stop_array.iter().enumerate() {
let stop = stop.unwrap_or(0);
let start = start_array.as_ref().map(|arr|
arr.value(idx)).unwrap_or(0);
let step = step_array.as_ref().map(|arr|
arr.value(idx)).unwrap_or(1);
if step == 0 {
return exec_err!("step can't be 0 for function range(start [,
stop, step]");
}
if step < 0 {
// Decreasing range
values.extend((stop + 1..start + 1).rev().step_by((-step) as
usize));
} else {
// Increasing range
values.extend((start..stop).step_by(step as usize));
}
// TODO: include_upper should be a boolean flag
if include_upper > 0 {
match values.last() {
Some(&last) if last + step == stop => {
values.push(stop);
}
None => {
values.push(stop);
}
_ => {}
}
}
offsets.push(values.len() as i32);
}
```
**UPDATE**:
Still panic on the following queries:
- `select generate_series(9223372036854775807, 9223372036854775807, -1)`
- `select generate_series(-9223372036854775807, -9223372036854775808, -2)`
Additional checks might be needed regarding negative step values.
--
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]