jacktengg commented on code in PR #67981:
URL: https://github.com/apache/doris/pull/67981#discussion_r4016880736
##########
be/src/exprs/function/cast/cast_base.cpp:
##########
@@ -17,11 +17,70 @@
#include "exprs/function/cast/cast_base.h"
+#include <algorithm>
#include <cstdint>
+#include <utility>
#include "util/jsonb_writer.h"
namespace doris::CastWrapper {
+namespace {
+
+/// A nullable column keeps an all zero NULL map when it has no NULL row, and
there is nothing to
+/// inherit from such a column.
+bool has_masked_row(const NullMap::value_type* null_map, size_t rows) {
+ return std::any_of(null_map, null_map + rows,
+ [](const NullMap::value_type value) { return value !=
0; });
+}
+
+} // namespace
+
+ChildNullMask build_child_null_mask(const NullMap::value_type* parent_null_map,
+ const IColumn::Offsets64* offsets, const
ColumnPtr& child) {
+ if (parent_null_map == nullptr) {
+ return {.column = child, .null_map = nullptr, .mask_holder = nullptr};
+ }
+ const size_t rows = offsets == nullptr ? child->size() : offsets->size();
+ if (!has_masked_row(parent_null_map, rows)) {
+ return {.column = child, .null_map = nullptr, .mask_holder = nullptr};
+ }
+
+ auto mask = ColumnUInt8::create(child->size(), 0);
+ auto& mask_data = mask->get_data();
+ if (offsets == nullptr) {
+ // The children of a STRUCT share the rows of their parent.
+ std::copy_n(parent_null_map, rows, mask_data.begin());
+ } else {
+ // ARRAY and MAP children are flattened, so the NULL of a row has to
be expanded to every
+ // element/entry that belongs to it.
+ for (size_t row = 0; row < rows; ++row) {
+ if (parent_null_map[row] == 0) {
+ continue;
+ }
+ const size_t first_child = row == 0 ? 0 : (*offsets)[row - 1];
+ std::fill(mask_data.begin() + first_child, mask_data.begin() +
(*offsets)[row], 1);
+ }
+ }
+
+ const auto* nullable_child =
check_and_get_column<ColumnNullable>(child.get());
+ if (nullable_child == nullptr) {
+ return {.column = child, .null_map = mask_data.data(), .mask_holder =
std::move(mask)};
+ }
+
+ // The NULL state of a child is the union of its own NULL map and the mask
inherited from the
+ // rows of its parent.
+ auto merged_mask = ColumnUInt8::create(child->size(), 0);
Review Comment:
fixed
##########
be/src/exprs/function/cast/cast_to_struct.h:
##########
@@ -68,21 +68,25 @@ WrapperType create_struct_wrapper(FunctionContext* context,
const DataTypePtr& f
size_t elements_num = to_element_types.size();
Columns converted_columns(elements_num);
for (size_t i = 0; i < elements_num; ++i) {
- ColumnWithTypeAndName from_element_column
{from_col_struct->get_column_ptr(i),
- from_element_types[i],
""};
+ /// A field of a row that is NULL is a hidden payload as well.
Fields share the rows of
+ /// their parent, so the mask of the parent can be used as is.
+ auto child_mask =
Review Comment:
fixed
--
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]