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]

Reply via email to