This is an automated email from the ASF dual-hosted git repository.
github-bot 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 451c79fc00 fix: Fix `array_to_string` with columnar third arg (#20536)
451c79fc00 is described below
commit 451c79fc0067399076a06a25c69be41f61c1bd0d
Author: Neil Conway <[email protected]>
AuthorDate: Fri Feb 27 11:03:32 2026 -0500
fix: Fix `array_to_string` with columnar third arg (#20536)
## Which issue does this PR close?
- Closes #20535
## Rationale for this change
The previous coding used the `null_string` value for the first row as
the value for the remainder of the rows. This is wrong if `null_string`
is columnar.
## What changes are included in this PR?
## Are these changes tested?
Yes; added new SLT test.
## Are there any user-facing changes?
No, other than fixing the behavior of `array_to_string` in this
scenario.
---
datafusion/functions-nested/src/string.rs | 49 +++++++++++++---------------
datafusion/sqllogictest/test_files/array.slt | 19 +++++++++++
2 files changed, 41 insertions(+), 27 deletions(-)
diff --git a/datafusion/functions-nested/src/string.rs
b/datafusion/functions-nested/src/string.rs
index 1c8d58fca8..c296f1969e 100644
--- a/datafusion/functions-nested/src/string.rs
+++ b/datafusion/functions-nested/src/string.rs
@@ -347,21 +347,20 @@ fn array_to_string_inner(args: &[ArrayRef]) ->
Result<ArrayRef> {
}
};
- let mut null_string = String::from("");
- let mut with_null_string = false;
- if args.len() == 3 {
- null_string = match args[2].data_type() {
- Utf8 => args[2].as_string::<i32>().value(0).to_string(),
- Utf8View => args[2].as_string_view().value(0).to_string(),
- LargeUtf8 => args[2].as_string::<i64>().value(0).to_string(),
+ let null_strings = if args.len() == 3 {
+ Some(match args[2].data_type() {
+ Utf8 => args[2].as_string::<i32>().iter().collect(),
+ Utf8View => args[2].as_string_view().iter().collect(),
+ LargeUtf8 => args[2].as_string::<i64>().iter().collect(),
other => {
return exec_err!(
- "unsupported type for second argument to array_to_string
function as {other:?}"
+ "unsupported type for third argument to array_to_string
function as {other:?}"
);
}
- };
- with_null_string = true;
- }
+ })
+ } else {
+ None
+ };
/// Creates a single string from single element of a ListArray (which is
/// itself another Array)
@@ -469,18 +468,24 @@ fn array_to_string_inner(args: &[ArrayRef]) ->
Result<ArrayRef> {
fn generate_string_array<O: OffsetSizeTrait>(
list_arr: &GenericListArray<O>,
delimiters: &[Option<&str>],
- null_string: &str,
- with_null_string: bool,
+ null_strings: &Option<Vec<Option<&str>>>,
) -> Result<StringArray> {
let mut res: Vec<Option<String>> = Vec::new();
- for (arr, &delimiter) in list_arr.iter().zip(delimiters.iter()) {
+ for (i, (arr, &delimiter)) in
list_arr.iter().zip(delimiters.iter()).enumerate() {
if let (Some(arr), Some(delimiter)) = (arr, delimiter) {
+ let (null_string, with_null_string) = match null_strings {
+ Some(ns) => match ns[i] {
+ Some(s) => (s.to_string(), true),
+ None => (String::new(), false),
+ },
+ None => (String::new(), false),
+ };
let mut arg = String::from("");
let s = compute_array_to_string(
&mut arg,
&arr,
delimiter.to_string(),
- null_string.to_string(),
+ null_string,
with_null_string,
)?
.clone();
@@ -501,21 +506,11 @@ fn array_to_string_inner(args: &[ArrayRef]) ->
Result<ArrayRef> {
let string_arr = match arr.data_type() {
List(_) => {
let list_array = as_list_array(&arr)?;
- generate_string_array::<i32>(
- list_array,
- &delimiters,
- &null_string,
- with_null_string,
- )?
+ generate_string_array::<i32>(list_array, &delimiters,
&null_strings)?
}
LargeList(_) => {
let list_array = as_large_list_array(&arr)?;
- generate_string_array::<i64>(
- list_array,
- &delimiters,
- &null_string,
- with_null_string,
- )?
+ generate_string_array::<i64>(list_array, &delimiters,
&null_strings)?
}
// Signature guards against this arm
_ => return exec_err!("array_to_string expects list as first
argument"),
diff --git a/datafusion/sqllogictest/test_files/array.slt
b/datafusion/sqllogictest/test_files/array.slt
index 889106c085..5113b9718c 100644
--- a/datafusion/sqllogictest/test_files/array.slt
+++ b/datafusion/sqllogictest/test_files/array.slt
@@ -5248,6 +5248,25 @@ NULL 1.2.3
51_52_*_54_55_56_57_58_59_60 1.2.3
61_62_63_64_65_66_67_68_69_70 1.2.3
+# array_to_string with per-row null_string column
+statement ok
+CREATE TABLE test_null_str_col AS VALUES
+ (make_array(1, NULL, 3), ',', 'N/A'),
+ (make_array(NULL, 5, NULL), ',', 'MISSING'),
+ (make_array(10, NULL, 12), '-', 'X'),
+ (make_array(20, NULL, 21), '-', NULL);
+
+query T
+SELECT array_to_string(column1, column2, column3) FROM test_null_str_col;
+----
+1,N/A,3
+MISSING,5,MISSING
+10-X-12
+20-21
+
+statement ok
+DROP TABLE test_null_str_col;
+
## cardinality
# cardinality scalar function
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]