From 06c8f5ac6b1bf31d3e4d5ec34c3f333d3f843315 Mon Sep 17 00:00:00 2001 From: Jonah Gao Date: Fri, 17 May 2024 09:34:04 +0800 Subject: [PATCH] fix: `array_slice` panics (#10547) * fix: array_slice panics * add test * add test * update test * fix comment * fix clippy --- datafusion/functions-array/src/extract.rs | 11 ++++------- datafusion/sqllogictest/test_files/array.slt | 12 ++++++++++++ 2 files changed, 16 insertions(+), 7 deletions(-) diff --git a/datafusion/functions-array/src/extract.rs b/datafusion/functions-array/src/extract.rs index b4999d8cb06a..152e5f3c4b13 100644 --- a/datafusion/functions-array/src/extract.rs +++ b/datafusion/functions-array/src/extract.rs @@ -418,19 +418,16 @@ where if let (Some(from), Some(to)) = (from_index, to_index) { let stride = stride.map(|s| s.value(row_index)); - // array_slice with stride in duckdb, return empty array if stride is not supported and from > to. - if stride.is_none() && from > to { - // return empty array - offsets.push(offsets[row_index]); - continue; - } + // Default stride is 1 if not provided let stride = stride.unwrap_or(1); if stride.is_zero() { return exec_err!( "array_slice got invalid stride: {:?}, it cannot be 0", stride ); - } else if from <= to && stride.is_negative() { + } else if (from <= to && stride.is_negative()) + || (from > to && stride.is_positive()) + { // return empty array offsets.push(offsets[row_index]); continue; diff --git a/datafusion/sqllogictest/test_files/array.slt b/datafusion/sqllogictest/test_files/array.slt index eeb5dc01b6e7..9b8b50201243 100644 --- a/datafusion/sqllogictest/test_files/array.slt +++ b/datafusion/sqllogictest/test_files/array.slt @@ -1963,6 +1963,18 @@ select array_slice(arrow_cast(make_array(1, 2, 3, 4, 5), 'LargeList(Int64)'), co [1, 2, 3, 4, 5] [43, 44, 45, 46] [41, 42, 43, 44, 45] [5] [, 54, 55, 56, 57, 58, 59, 60] [55] +# Test issue: https://github.com/apache/datafusion/issues/10425 +# `from` may be larger than `to` and `stride` is positive +query ???? +select array_slice(a, -1, 2, 1), array_slice(a, -1, 2), + array_slice(a, 3, 2, 1), array_slice(a, 3, 2) + from (values ([1.0, 2.0, 3.0, 3.0]), ([4.0, 5.0, 3.0]), ([6.0])) t(a); +---- +[] [] [] [] +[] [] [] [] +[6.0] [6.0] [] [] + + # make_array with nulls query ??????? select make_array(make_array('a','b'), null),