This is an automated email from the ASF dual-hosted git repository.

yiguolei pushed a commit to branch branch-4.1
in repository https://gitbox.apache.org/repos/asf/doris.git


The following commit(s) were added to refs/heads/branch-4.1 by this push:
     new 0012df65a1f branch-4.1: [fix](exec) preserve NULL in pushed-down CHAR 
MIN/MAX #65952 (#66583)
0012df65a1f is described below

commit 0012df65a1f8c3cfac20ecb8bb201fe3dc9d02e7
Author: github-actions[bot] 
<41898282+github-actions[bot]@users.noreply.github.com>
AuthorDate: Sun Aug 9 07:25:07 2026 +0800

    branch-4.1: [fix](exec) preserve NULL in pushed-down CHAR MIN/MAX #65952 
(#66583)
    
    Cherry-picked from #65952
    
    Co-authored-by: Mryange <[email protected]>
---
 be/src/storage/iterator/vgeneric_iterators.cpp |  4 +-
 be/test/exec/scan/vgeneric_iterators_test.cpp  | 79 ++++++++++++++++++++++++++
 2 files changed, 81 insertions(+), 2 deletions(-)

diff --git a/be/src/storage/iterator/vgeneric_iterators.cpp 
b/be/src/storage/iterator/vgeneric_iterators.cpp
index 3fb2b360712..941c36ed5e3 100644
--- a/be/src/storage/iterator/vgeneric_iterators.cpp
+++ b/be/src/storage/iterator/vgeneric_iterators.cpp
@@ -82,8 +82,8 @@ Status VStatisticsIterator::next_batch(Block* block) {
                     _schema.column(cid)->type() == 
FieldType::OLAP_FIELD_TYPE_CHAR) {
                     auto col = columns[i]->clone_empty();
                     for (size_t j = 0; j < columns[i]->size(); ++j) {
-                        const auto& ref = 
columns[i]->get_data_at(j).trim_tail_padding_zero();
-                        
col->insert(Field::create_field<TYPE_CHAR>(ref.to_string()));
+                        const auto ref = 
columns[i]->get_data_at(j).trim_tail_padding_zero();
+                        col->insert_data(ref.data, ref.size);
                     }
                     columns[i].swap(col);
                 }
diff --git a/be/test/exec/scan/vgeneric_iterators_test.cpp 
b/be/test/exec/scan/vgeneric_iterators_test.cpp
index fae7b164f8c..cd43d149db4 100644
--- a/be/test/exec/scan/vgeneric_iterators_test.cpp
+++ b/be/test/exec/scan/vgeneric_iterators_test.cpp
@@ -23,15 +23,23 @@
 #include <memory>
 #include <vector>
 
+#include "core/assert_cast.h"
 #include "core/block/column_with_type_and_name.h"
 #include "core/column/column.h"
+#include "core/column/column_nullable.h"
 #include "core/data_type/data_type.h"
 #include "core/field.h"
 #include "gtest/gtest_pred_impl.h"
+#include "io/fs/file_writer.h"
+#include "io/fs/local_file_system.h"
 #include "storage/olap_common.h"
+#include "storage/row_cursor.h"
 #include "storage/schema.h"
 #include "storage/segment/column_reader.h"
+#include "storage/segment/segment.h"
+#include "storage/segment/test_segment_writer.h"
 #include "storage/tablet/tablet_schema.h"
+#include "storage/tablet/tablet_schema_helper.h"
 
 namespace doris {
 using namespace ErrorCode;
@@ -107,6 +115,77 @@ TEST(VGenericIteratorsTest, AutoIncrement) {
     }
 }
 
+TEST(VGenericIteratorsTest, StatisticsIteratorPreservesNullForNullableChar) {
+    constexpr auto test_dir = "./ut_dir/vgeneric_iterators_test";
+    constexpr auto segment_path = 
"./ut_dir/vgeneric_iterators_test/nullable_char_segment.dat";
+    constexpr auto row_count = 3;
+
+    auto fs = io::global_local_filesystem();
+    ASSERT_TRUE(fs->delete_directory(test_dir).ok());
+    ASSERT_TRUE(fs->create_directory(test_dir).ok());
+
+    auto tablet_schema = std::make_shared<TabletSchema>();
+    tablet_schema->append_column(*create_int_key(0, false));
+    auto nullable_char = std::make_shared<TabletColumn>();
+    nullable_char->set_unique_id(1);
+    nullable_char->set_name("1");
+    nullable_char->set_type(FieldType::OLAP_FIELD_TYPE_CHAR);
+    nullable_char->set_is_nullable(true);
+    nullable_char->set_length(8);
+    nullable_char->set_index_length(8);
+    
nullable_char->set_aggregation_method(FieldAggregationMethod::OLAP_FIELD_AGGREGATION_NONE);
+    tablet_schema->append_column(*nullable_char);
+    tablet_schema->set_storage_page_size(4096);
+
+    io::FileWriterPtr file_writer;
+    ASSERT_TRUE(fs->create_file(segment_path, &file_writer).ok());
+    SegmentWriterOptions writer_options;
+    writer_options.num_rows_per_block = 1024;
+    TestSegmentWriter writer(file_writer.get(), 0, tablet_schema, nullptr, 
nullptr, writer_options,
+                             nullptr);
+    ASSERT_TRUE(writer.init().ok());
+
+    RowCursor row;
+    std::vector<Field> fields(tablet_schema->num_columns(), 
Field(PrimitiveType::TYPE_NULL));
+    ASSERT_TRUE(row.init_scan_key(tablet_schema, std::move(fields)).ok());
+    for (int i = 0; i < row_count; ++i) {
+        row.mutable_field(0) = Field::create_field<TYPE_INT>(i);
+        ASSERT_TRUE(writer.append_row(row).ok());
+    }
+    uint64_t file_size = 0;
+    uint64_t index_size = 0;
+    ASSERT_TRUE(writer.finalize(&file_size, &index_size).ok());
+    ASSERT_TRUE(file_writer->close().ok());
+
+    std::shared_ptr<segment_v2::Segment> segment;
+    ASSERT_TRUE(segment_v2::Segment::open(fs, segment_path, 100, 0, RowsetId 
{.version = 1},
+                                          tablet_schema, io::FileReaderOptions 
{}, &segment)
+                        .ok());
+
+    std::vector<ColumnId> column_ids {0, 1};
+    Schema schema(tablet_schema->columns(), column_ids);
+    VStatisticsIterator iterator(segment, schema);
+    StorageReadOptions read_options;
+    OlapReaderStatistics stats;
+    read_options.push_down_agg_type_opt = TPushAggOp::MINMAX;
+    read_options.stats = &stats;
+    read_options.tablet_schema = tablet_schema;
+    ASSERT_TRUE(iterator.init(read_options).ok());
+
+    Block block;
+    create_block(schema, block);
+    ASSERT_TRUE(iterator.next_batch(&block).ok());
+    ASSERT_EQ(2, block.rows());
+
+    const auto& nullable_column =
+            assert_cast<const 
ColumnNullable&>(*block.get_by_position(1).column);
+    EXPECT_TRUE(nullable_column.is_null_at(0));
+    EXPECT_TRUE(nullable_column.is_null_at(1));
+    ASSERT_TRUE(iterator.next_batch(&block).is<ErrorCode::END_OF_FILE>());
+
+    ASSERT_TRUE(fs->delete_directory(test_dir).ok());
+}
+
 TEST(VGenericIteratorsTest, Union) {
     auto schema = create_schema();
     auto output_schema = std::make_shared<Schema>(schema);


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

Reply via email to