github-actions[bot] commented on code in PR #68022:
URL: https://github.com/apache/doris/pull/68022#discussion_r4055873880


##########
be/src/exprs/lambda_function/varray_map_function.cpp:
##########
@@ -144,35 +144,90 @@ class ArrayMapFunction : public LambdaFunction {
 
             // here is the array column
             const auto& col_array = assert_cast<const 
ColumnArray&>(*column_array);
+            lambda_offsets[i] = col_array.get_offsets_ptr();
 
             if (i == 0) {
                 nested_array_column_rows = col_array.get_data_ptr()->size();
-                first_array_offsets = col_array.get_offsets_ptr();
                 const auto& off_data = col_array.get_offsets_column();
                 array_column_offset = 
off_data.clone_resized(col_array.get_offsets_column().size());
                 args_info.offsets_ptr = &col_array.get_offsets();
-            } else {
-                // select array_map((x,y)->x+y,c_array1,[0,1,2,3]) from 
array_test2;
-                // c_array1: [0,1,2,3,4,5,6,7,8,9]
-                const auto& array_offsets =
-                        assert_cast<const 
ColumnArray::ColumnOffsets&>(*first_array_offsets)
-                                .get_data();
-                if (nested_array_column_rows != 
col_array.get_data_ptr()->size() ||
-                    (!array_offsets.empty() &&
-                     memcmp(array_offsets.data(), 
col_array.get_offsets().data(),
-                            sizeof(array_offsets[0]) * array_offsets.size()) 
!= 0)) {
-                    return Status::InvalidArgument(
-                            "in array map function, the input column size "
-                            "are "
-                            "not equal completely, nested column data rows 1st 
size is {}, {}th "
-                            "size is {}.",
-                            nested_array_column_rows, i + 1, 
col_array.get_data_ptr()->size());
-                }
             }
             lambda_datas[i] = col_array.get_data_ptr();
             const auto& col_type = assert_cast<const 
DataTypeArray&>(*type_array);
             lambda_argument_types[i] = col_type.get_nested_type();
         }
+
+        const auto& first_array_offsets =
+                assert_cast<const 
ColumnArray::ColumnOffsets&>(*lambda_offsets[0]).get_data();
+        const auto& null_map_data = outside_null_map->get_data();
+        const bool has_null =
+                std::ranges::any_of(null_map_data, [](uint8_t is_null) { 
return is_null; });
+        bool has_hidden_nested_data = false;
+        if (!has_null) {
+            // select array_map((x,y)->x+y,c_array1,[0,1,2,3]) from 
array_test2;
+            // c_array1: [0,1,2,3,4,5,6,7,8,9]
+            for (int i = 1; i < arguments.size(); ++i) {
+                const auto& offsets =
+                        assert_cast<const 
ColumnArray::ColumnOffsets&>(*lambda_offsets[i])
+                                .get_data();
+                if (nested_array_column_rows != lambda_datas[i]->size() ||
+                    (!first_array_offsets.empty() &&
+                     memcmp(first_array_offsets.data(), offsets.data(),
+                            sizeof(first_array_offsets[0]) * 
first_array_offsets.size()) != 0)) {
+                    return Status::InvalidArgument(
+                            "in array map function, the input column size are 
not equal "
+                            "completely, nested column data rows 1st size is 
{}, {}th size is {}.",
+                            nested_array_column_rows, i + 1, 
lambda_datas[i]->size());
+                }
+            }
+        } else {
+            std::vector<size_t> previous_offsets(arguments.size(), 0);
+            for (size_t row = 0; row < count; ++row) {
+                const size_t first_row_size = first_array_offsets[row] - 
previous_offsets[0];
+                has_hidden_nested_data |= null_map_data[row] != 0 && 
first_row_size > 0;
+                for (int i = 1; i < arguments.size(); ++i) {
+                    const auto& offsets =
+                            assert_cast<const 
ColumnArray::ColumnOffsets&>(*lambda_offsets[i])
+                                    .get_data();
+                    const size_t row_size = offsets[row] - previous_offsets[i];
+                    has_hidden_nested_data |= null_map_data[row] != 0 && 
row_size > 0;
+                    if (null_map_data[row] == 0 && first_row_size != row_size) 
{
+                        return Status::InvalidArgument(
+                                "in array map function, the input column size 
are not equal "
+                                "completely at row {}, 1st size is {}, {}th 
size is {}.",
+                                row, first_row_size, i + 1, row_size);
+                    }
+                    previous_offsets[i] = offsets[row];
+                }
+                previous_offsets[0] = first_array_offsets[row];
+            }
+        }
+
+        // NULL rows are skipped. If they retain hidden payload, rebuild only 
result offsets;
+        // the bounded execution path reads each argument through its own 
original offsets.
+        if (has_hidden_nested_data) {
+            auto res_offsets = ColumnArray::ColumnOffsets::create();
+            auto& res_offsets_data = res_offsets->get_data();
+            res_offsets_data.reserve(count);
+            size_t previous_offset = 0;
+            size_t compacted_rows = 0;
+            for (size_t row = 0; row < count; ++row) {
+                const size_t current_offset = first_array_offsets[row];
+                if (null_map_data[row] == 0) {
+                    const size_t row_size = current_offset - previous_offset;
+                    compacted_rows += row_size;
+                }
+                res_offsets_data.push_back(compacted_rows);

Review Comment:
   [P1] Keep the compacted result compatible with direct `array_sortby`
   
   This still leaves a distinct two-array consumer broken. If nullable `a` has 
physical offsets `[2,4]` and null map `[1,0]`, this branch makes `array_map(x 
-> x, a)` use offsets `[0,2]`. For `array_sortby(array_map(x -> x, a), a)`, row 
0 is NULL in both arguments, so `FunctionArraySortBy` takes its key-NULL branch 
and adds the compacted source length (0) to `null_step` instead of compensating 
for the key's two hidden elements. On row 1 it then maps key indices 2 and 3 
directly into the two-element compacted source, producing out-of-range selector 
indices (or wrong data). This is separate from the already-raised 
zip/split/enumerate consumers; please normalize/skip the both-NULL row in 
`array_sortby` and add this direct composition regression.



-- 
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]


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to