From 906dc01ce6b02ed26bdb637bff89d9675a4ec892 Mon Sep 17 00:00:00 2001 From: Mryange Date: Tue, 22 Sep 2026 15:51:40 +0800 Subject: [PATCH] [fix](function) Handle constant NULL arrays in array pushback ### What problem does this PR solve? Problem Summary: array_pushback and array_append could read past the end of the NULL bitmap when a constant NULL array was evaluated for multiple rows. Use the constant-column row index consistently for NULL bitmap and array offset access. ### Release note Fix array_pushback and array_append with constant NULL arrays in multi-row execution. ### Check List (For Author) - Test: BE build, 396 focused array unit tests, and query_p0 array regression test - Behavior changed: Yes - Does this need documentation: No --- .../array/function_array_pushback.cpp | 7 ++-- .../test_array_functions_by_literal.out | 36 +++++++++++++++++++ .../test_array_functions_by_literal.groovy | 2 ++ 3 files changed, 42 insertions(+), 3 deletions(-) diff --git a/be/src/exprs/function/array/function_array_pushback.cpp b/be/src/exprs/function/array/function_array_pushback.cpp index 898c4d296902a6..7097613c7e2150 100644 --- a/be/src/exprs/function/array/function_array_pushback.cpp +++ b/be/src/exprs/function/array/function_array_pushback.cpp @@ -93,14 +93,15 @@ class FunctionArrayPushback : public IFunction { size_t off = 0; for (size_t i = 0; i < input_rows_count; ++i) { - if (array_null_map && array_null_map[i]) { + const size_t src_index = index_check_const(i, src_const); + if (array_null_map && array_null_map[src_index]) { result_null_map[i] = 1; result_offset_col[i] = off; continue; } - size_t src_off = src_offset_col[index_check_const(i, src_const) - 1]; - size_t src_len = src_offset_col[index_check_const(i, src_const)] - src_off; + size_t src_off = src_offset_col[src_index - 1]; + size_t src_len = src_offset_col[src_index] - src_off; result_nested_data_col.insert_range_from(src_nested_data_col, src_off, src_len); result_nested_data_col.insert((*right_column)[index_check_const(i, right_const)]); diff --git a/regression-test/data/query_p0/sql_functions/array_functions/test_array_functions_by_literal.out b/regression-test/data/query_p0/sql_functions/array_functions/test_array_functions_by_literal.out index 5ebef1618f9855..9fe328a301ffca 100644 --- a/regression-test/data/query_p0/sql_functions/array_functions/test_array_functions_by_literal.out +++ b/regression-test/data/query_p0/sql_functions/array_functions/test_array_functions_by_literal.out @@ -932,6 +932,42 @@ _ -- !sql -- [null, null, null, null, 80] +-- !sql -- +0 \N +1 \N +2 \N +3 \N +4 \N +5 \N +6 \N +7 \N +8 \N +9 \N +10 \N +11 \N +12 \N +13 \N +14 \N +15 \N + +-- !sql -- +0 \N +1 \N +2 \N +3 \N +4 \N +5 \N +6 \N +7 \N +8 \N +9 \N +10 \N +11 \N +12 \N +13 \N +14 \N +15 \N + -- !sql -- [0, 2, 129] diff --git a/regression-test/suites/query_p0/sql_functions/array_functions/test_array_functions_by_literal.groovy b/regression-test/suites/query_p0/sql_functions/array_functions/test_array_functions_by_literal.groovy index b51a0b6bd6bc24..600c6e3db93444 100644 --- a/regression-test/suites/query_p0/sql_functions/array_functions/test_array_functions_by_literal.groovy +++ b/regression-test/suites/query_p0/sql_functions/array_functions/test_array_functions_by_literal.groovy @@ -386,6 +386,8 @@ suite("test_array_functions_by_literal") { qt_sql "select array_pushback(array(cast (111.111 as decimalv3(6,3)),cast (222.222 as decimalv3(6,3))), cast (333.333 as decimalv3(6,3)))" qt_sql "select array_pushback([null,null], null)" qt_sql "select array_pushback([null,null,null,null], 80)" + qt_sql "select number, array_pushback(cast(null as array), number) from numbers('number'='16') order by number" + qt_sql "select number, array_append(cast(null as array), number) from numbers('number'='16') order by number" // array_cum_sum qt_sql "select array_cum_sum([0, 2, 127])"