You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@doris.apache.org by da...@apache.org on 2023/01/02 14:53:10 UTC

[doris] branch master updated: [enhancement](compaction) vertical compaction support unique-key mow (#15353)

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

dataroaring pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/doris.git


The following commit(s) were added to refs/heads/master by this push:
     new 365c3eec16 [enhancement](compaction) vertical compaction support unique-key mow (#15353)
365c3eec16 is described below

commit 365c3eec16d777588838056798759c1cd4dd77b0
Author: yixiutt <10...@users.noreply.github.com>
AuthorDate: Mon Jan 2 22:53:04 2023 +0800

    [enhancement](compaction) vertical compaction support unique-key mow (#15353)
---
 be/src/olap/compaction.cpp                  |  3 --
 be/src/olap/merger.cpp                      | 20 +++++++++++
 be/src/vec/olap/vertical_block_reader.cpp   | 30 +++++++++++++---
 be/src/vec/olap/vertical_block_reader.h     |  6 +++-
 be/src/vec/olap/vertical_merge_iterator.cpp | 35 ++++++++++++++----
 be/src/vec/olap/vertical_merge_iterator.h   | 28 ++++++++++++---
 be/test/olap/rowid_conversion_test.cpp      | 55 ++++++++++++++++++++---------
 7 files changed, 139 insertions(+), 38 deletions(-)

diff --git a/be/src/olap/compaction.cpp b/be/src/olap/compaction.cpp
index d7627afeee..2089461e12 100644
--- a/be/src/olap/compaction.cpp
+++ b/be/src/olap/compaction.cpp
@@ -93,9 +93,6 @@ bool Compaction::should_vertical_compaction() {
     if (!config::enable_vertical_compaction) {
         return false;
     }
-    if (_tablet->enable_unique_key_merge_on_write()) {
-        return false;
-    }
     return true;
 }
 
diff --git a/be/src/olap/merger.cpp b/be/src/olap/merger.cpp
index 595158a7ee..19f8d727e2 100644
--- a/be/src/olap/merger.cpp
+++ b/be/src/olap/merger.cpp
@@ -182,6 +182,9 @@ Status Merger::vertical_compact_one_group(
                   std::inserter(reader_params.delete_predicates,
                                 reader_params.delete_predicates.begin()));
     }
+    if (is_key && stats_output && stats_output->rowid_conversion) {
+        reader_params.record_rowids = true;
+    }
     TabletSchemaSPtr merge_tablet_schema = std::make_shared<TabletSchema>();
     merge_tablet_schema->copy_from(*tablet_schema);
     // Merge the columns in delete predicate that not in latest schema in to current tablet schema
@@ -194,6 +197,17 @@ Status Merger::vertical_compact_one_group(
     reader_params.origin_return_columns = &reader_params.return_columns;
     RETURN_NOT_OK(reader.init(reader_params));
 
+    if (is_key && reader_params.record_rowids) {
+        stats_output->rowid_conversion->set_dst_rowset_id(dst_rowset_writer->rowset_id());
+        // init segment rowid map for rowid conversion
+        std::vector<uint32_t> segment_num_rows;
+        for (auto& rs_reader : reader_params.rs_readers) {
+            RETURN_NOT_OK(rs_reader->get_segment_num_rows(&segment_num_rows));
+            stats_output->rowid_conversion->init_segment_map(rs_reader->rowset()->rowset_id(),
+                                                             segment_num_rows);
+        }
+    }
+
     vectorized::Block block = tablet_schema->create_block(reader_params.return_columns);
     size_t output_rows = 0;
     bool eof = false;
@@ -206,6 +220,12 @@ Status Merger::vertical_compact_one_group(
                 dst_rowset_writer->add_columns(&block, column_group, is_key, max_rows_per_segment),
                 "failed to write block when merging rowsets of tablet " + tablet->full_name());
 
+        if (is_key && reader_params.record_rowids && block.rows() > 0) {
+            std::vector<uint32_t> segment_num_rows;
+            RETURN_IF_ERROR(dst_rowset_writer->get_segment_num_rows(&segment_num_rows));
+            stats_output->rowid_conversion->add(reader.current_block_row_locations(),
+                                                segment_num_rows);
+        }
         output_rows += block.rows();
         block.clear_column_data();
     }
diff --git a/be/src/vec/olap/vertical_block_reader.cpp b/be/src/vec/olap/vertical_block_reader.cpp
index 53c93523bb..dc7d3b58c6 100644
--- a/be/src/vec/olap/vertical_block_reader.cpp
+++ b/be/src/vec/olap/vertical_block_reader.cpp
@@ -38,7 +38,8 @@ VerticalBlockReader::~VerticalBlockReader() {
 
 Status VerticalBlockReader::_get_segment_iterators(const ReaderParams& read_params,
                                                    std::vector<RowwiseIterator*>* segment_iters,
-                                                   std::vector<bool>* iterator_init_flag) {
+                                                   std::vector<bool>* iterator_init_flag,
+                                                   std::vector<RowsetId>* rowset_ids) {
     std::vector<RowsetReaderSharedPtr> rs_readers;
     auto res = _capture_rs_readers(read_params, &rs_readers);
     if (!res.ok()) {
@@ -73,6 +74,9 @@ Status VerticalBlockReader::_get_segment_iterators(const ReaderParams& read_para
                 iterator_init_flag->push_back(false);
             }
         }
+        for (int i = 0; i < rs_reader->rowset()->num_segments(); ++i) {
+            rowset_ids->push_back(rs_reader->rowset()->rowset_id());
+        }
         rs_reader->reset_read_options();
     }
     return Status::OK();
@@ -82,7 +86,9 @@ Status VerticalBlockReader::_init_collect_iter(const ReaderParams& read_params)
     // get segment iterators
     std::vector<RowwiseIterator*> segment_iters;
     std::vector<bool> iterator_init_flag;
-    RETURN_IF_ERROR(_get_segment_iterators(read_params, &segment_iters, &iterator_init_flag));
+    std::vector<RowsetId> rowset_ids;
+    RETURN_IF_ERROR(
+            _get_segment_iterators(read_params, &segment_iters, &iterator_init_flag, &rowset_ids));
     CHECK(segment_iters.size() == iterator_init_flag.size());
 
     // build heap if key column iterator or build vertical merge iterator if value column
@@ -93,7 +99,7 @@ Status VerticalBlockReader::_init_collect_iter(const ReaderParams& read_params)
             seq_col_idx = read_params.tablet->tablet_schema()->sequence_col_idx();
         }
         _vcollect_iter = new_vertical_heap_merge_iterator(
-                segment_iters, iterator_init_flag, ori_return_col_size,
+                segment_iters, iterator_init_flag, rowset_ids, ori_return_col_size,
                 read_params.tablet->keys_type(), seq_col_idx, _row_sources_buffer);
     } else {
         _vcollect_iter = new_vertical_mask_merge_iterator(segment_iters, ori_return_col_size,
@@ -101,9 +107,10 @@ Status VerticalBlockReader::_init_collect_iter(const ReaderParams& read_params)
     }
     // init collect iterator
     StorageReadOptions opts;
+    opts.record_rowids = read_params.record_rowids;
     RETURN_IF_ERROR(_vcollect_iter->init(opts));
 
-    // In dup keys value columns compact, get first row for _init_agg_state
+    // In agg keys value columns compact, get first row for _init_agg_state
     if (!read_params.is_key_column_group && read_params.tablet->keys_type() == KeysType::AGG_KEYS) {
         auto st = _vcollect_iter->next_row(&_next_row);
         _eof = st.is<END_OF_FILE>();
@@ -150,7 +157,6 @@ Status VerticalBlockReader::init(const ReaderParams& read_params) {
     _batch_size = opts.block_row_max;
     RETURN_NOT_OK(TabletReader::init(read_params));
 
-    std::vector<RowsetReaderSharedPtr> rs_readers;
     auto status = _init_collect_iter(read_params);
     if (!status.ok()) {
         return status;
@@ -187,6 +193,13 @@ Status VerticalBlockReader::_direct_next_block(Block* block, MemPool* mem_pool,
     }
     *eof = (res.is<END_OF_FILE>());
     _eof = *eof;
+    if (_reader_context.is_key_column_group && UNLIKELY(_reader_context.record_rowids)) {
+        res = _vcollect_iter->current_block_row_locations(&_block_row_locations);
+        if (UNLIKELY(!res.ok() && res != Status::Error<END_OF_FILE>())) {
+            return res;
+        }
+        DCHECK_EQ(_block_row_locations.size(), block->rows());
+    }
     return Status::OK();
 }
 
@@ -350,6 +363,13 @@ Status VerticalBlockReader::_unique_key_next_block(Block* block, MemPool* mem_po
         if (UNLIKELY(!res.ok() && !res.is<END_OF_FILE>())) {
             return res;
         }
+        if (UNLIKELY(_reader_context.record_rowids)) {
+            auto ret = _vcollect_iter->current_block_row_locations(&_block_row_locations);
+            if (UNLIKELY(!ret.ok() && !ret.is<END_OF_FILE>())) {
+                return res;
+            }
+            DCHECK_EQ(_block_row_locations.size(), block->rows());
+        }
         auto block_rows = block->rows();
         if (_filter_delete && block_rows > 0) {
             int ori_delete_sign_idx = _reader_context.tablet_schema->field_index(DELETE_SIGN);
diff --git a/be/src/vec/olap/vertical_block_reader.h b/be/src/vec/olap/vertical_block_reader.h
index 184795c329..cc81898b7f 100644
--- a/be/src/vec/olap/vertical_block_reader.h
+++ b/be/src/vec/olap/vertical_block_reader.h
@@ -50,6 +50,7 @@ public:
         DCHECK(_vcollect_iter);
         return _vcollect_iter->merged_rows();
     }
+    std::vector<RowLocation> current_block_row_locations() { return _block_row_locations; }
 
 private:
     // Directly read row from rowset and pass to upper caller. No need to do aggregation.
@@ -66,7 +67,8 @@ private:
 
     Status _get_segment_iterators(const ReaderParams& read_params,
                                   std::vector<RowwiseIterator*>* segment_iters,
-                                  std::vector<bool>* iterator_init_flag);
+                                  std::vector<bool>* iterator_init_flag,
+                                  std::vector<RowsetId>* rowset_ids);
 
     void _init_agg_state(const ReaderParams& read_params);
     void _append_agg_data(MutableColumns& columns);
@@ -103,6 +105,8 @@ private:
     std::vector<bool> _stored_has_string_tag;
 
     phmap::flat_hash_map<const Block*, std::vector<std::pair<int, int>>> _temp_ref_map;
+
+    std::vector<RowLocation> _block_row_locations;
 };
 
 } // namespace vectorized
diff --git a/be/src/vec/olap/vertical_merge_iterator.cpp b/be/src/vec/olap/vertical_merge_iterator.cpp
index 0d553e187d..65af538baf 100644
--- a/be/src/vec/olap/vertical_merge_iterator.cpp
+++ b/be/src/vec/olap/vertical_merge_iterator.cpp
@@ -276,6 +276,7 @@ Status VerticalMergeIteratorContext::init(const StorageReadOptions& opts) {
         return Status::OK();
     }
     _block_row_max = opts.block_row_max;
+    _record_rowids = opts.record_rowids;
     RETURN_IF_ERROR(_load_next_block());
     if (valid()) {
         RETURN_IF_ERROR(advance());
@@ -331,6 +332,14 @@ Status VerticalMergeIteratorContext::_load_next_block() {
                 _block->erase(i);
             }
         }
+        if (UNLIKELY(_record_rowids)) {
+            RETURN_IF_ERROR(_iter->current_block_row_locations(&_block_row_locations));
+            for (auto i = 0; i < _block_row_locations.size(); i++) {
+                RowLocation& row_location = _block_row_locations[i];
+                _block_row_locations[i] =
+                        RowLocation(_rowset_id, row_location.segment_id, row_location.row_id);
+            }
+        }
     } while (_block->rows() == 0);
     _index_in_block = -1;
     _valid = true;
@@ -342,6 +351,9 @@ Status VerticalHeapMergeIterator::next_batch(Block* block) {
     size_t row_idx = 0;
     VerticalMergeIteratorContext* pre_ctx = nullptr;
     std::vector<RowSource> tmp_row_sources;
+    if (UNLIKELY(_record_rowids)) {
+        _block_row_locations.resize(_block_row_max);
+    }
     while (_get_size(block) < _block_row_max) {
         if (_merge_heap.empty()) {
             VLOG_NOTICE << "_merge_heap empty";
@@ -371,6 +383,9 @@ Status VerticalHeapMergeIterator::next_batch(Block* block) {
                 }
                 pre_ctx = ctx;
             }
+            if (UNLIKELY(_record_rowids)) {
+                _block_row_locations[row_idx] = ctx->current_row_location();
+            }
             row_idx++;
             if (ctx->is_cur_block_finished() || row_idx >= _block_row_max) {
                 // current block finished, ctx not advance
@@ -408,6 +423,9 @@ Status VerticalHeapMergeIterator::next_batch(Block* block) {
     if (!_merge_heap.empty()) {
         return Status::OK();
     }
+    if (UNLIKELY(_record_rowids)) {
+        _block_row_locations.resize(row_idx);
+    }
     return Status::EndOfFile("no more data in segment");
 }
 
@@ -417,6 +435,7 @@ Status VerticalHeapMergeIterator::init(const StorageReadOptions& opts) {
     }
     DCHECK(_origin_iters.size() == _iterator_init_flags.size());
     _schema = &(*_origin_iters.begin())->schema();
+    _record_rowids = opts.record_rowids;
 
     auto seg_order = 0;
     // Init contxt depends on _iterator_init_flags
@@ -427,8 +446,8 @@ Status VerticalHeapMergeIterator::init(const StorageReadOptions& opts) {
     // so this rowset can work in heap
     bool pre_iter_invalid = false;
     for (auto iter : _origin_iters) {
-        VerticalMergeIteratorContext* ctx =
-                new VerticalMergeIteratorContext(iter, _ori_return_cols, seg_order, _seq_col_idx);
+        VerticalMergeIteratorContext* ctx = new VerticalMergeIteratorContext(
+                iter, _rowset_ids[seg_order], _ori_return_cols, seg_order, _seq_col_idx);
         _ori_iter_ctx.push_back(ctx);
         if (_iterator_init_flags[seg_order] || pre_iter_invalid) {
             RETURN_IF_ERROR(ctx->init(opts));
@@ -562,8 +581,10 @@ Status VerticalMaskMergeIterator::init(const StorageReadOptions& opts) {
     _schema = &(*_origin_iters.begin())->schema();
     _opts = opts;
 
+    RowsetId rs_id;
     for (auto iter : _origin_iters) {
-        auto ctx = std::make_unique<VerticalMergeIteratorContext>(iter, _ori_return_cols, -1, -1);
+        auto ctx = std::make_unique<VerticalMergeIteratorContext>(iter, rs_id, _ori_return_cols, -1,
+                                                                  -1);
         _origin_iter_ctx.emplace_back(ctx.release());
     }
     _origin_iters.clear();
@@ -575,11 +596,11 @@ Status VerticalMaskMergeIterator::init(const StorageReadOptions& opts) {
 // interfaces to create vertical merge iterator
 std::shared_ptr<RowwiseIterator> new_vertical_heap_merge_iterator(
         std::vector<RowwiseIterator*> inputs, const std::vector<bool>& iterator_init_flag,
-        size_t ori_return_cols, KeysType keys_type, uint32_t seq_col_idx,
-        RowSourcesBuffer* row_sources) {
+        const std::vector<RowsetId>& rowset_ids, size_t ori_return_cols, KeysType keys_type,
+        uint32_t seq_col_idx, RowSourcesBuffer* row_sources) {
     return std::make_shared<VerticalHeapMergeIterator>(std::move(inputs), iterator_init_flag,
-                                                       ori_return_cols, keys_type, seq_col_idx,
-                                                       row_sources);
+                                                       rowset_ids, ori_return_cols, keys_type,
+                                                       seq_col_idx, row_sources);
 }
 
 std::shared_ptr<RowwiseIterator> new_vertical_mask_merge_iterator(
diff --git a/be/src/vec/olap/vertical_merge_iterator.h b/be/src/vec/olap/vertical_merge_iterator.h
index 61cf723afc..6ad5613f36 100644
--- a/be/src/vec/olap/vertical_merge_iterator.h
+++ b/be/src/vec/olap/vertical_merge_iterator.h
@@ -126,9 +126,10 @@ private:
 // takes ownership of rowwise iterator
 class VerticalMergeIteratorContext {
 public:
-    VerticalMergeIteratorContext(RowwiseIterator* iter, size_t ori_return_cols, uint32_t order,
-                                 uint32_t seq_col_idx)
+    VerticalMergeIteratorContext(RowwiseIterator* iter, RowsetId rowset_id, size_t ori_return_cols,
+                                 uint32_t order, uint32_t seq_col_idx)
             : _iter(iter),
+              _rowset_id(rowset_id),
               _ori_return_cols(ori_return_cols),
               _order(order),
               _seq_col_idx(seq_col_idx),
@@ -175,12 +176,17 @@ public:
         ref->row_pos = _index_in_block;
     }
     bool inited() const { return _inited; }
+    RowLocation current_row_location() {
+        DCHECK(_record_rowids);
+        return _block_row_locations[_index_in_block];
+    }
 
 private:
     // Load next block into _block
     Status _load_next_block();
 
     RowwiseIterator* _iter;
+    RowsetId _rowset_id;
     size_t _ori_return_cols = 0;
 
     // segment order, used to compare key
@@ -202,6 +208,8 @@ private:
     std::list<std::shared_ptr<Block>> _block_list;
     // use to identify whether it's first block load from RowwiseIterator
     bool _is_first_row = true;
+    bool _record_rowids = false;
+    std::vector<RowLocation> _block_row_locations;
 };
 
 // --------------- VerticalHeapMergeIterator ------------- //
@@ -209,11 +217,13 @@ class VerticalHeapMergeIterator : public RowwiseIterator {
 public:
     // VerticalMergeIterator takes the ownership of input iterators
     VerticalHeapMergeIterator(std::vector<RowwiseIterator*> iters,
-                              std::vector<bool> iterator_init_flags, size_t ori_return_cols,
+                              std::vector<bool> iterator_init_flags,
+                              std::vector<RowsetId> rowset_ids, size_t ori_return_cols,
                               KeysType keys_type, int32_t seq_col_idx,
                               RowSourcesBuffer* row_sources_buf)
             : _origin_iters(std::move(iters)),
               _iterator_init_flags(iterator_init_flags),
+              _rowset_ids(rowset_ids),
               _ori_return_cols(ori_return_cols),
               _keys_type(keys_type),
               _seq_col_idx(seq_col_idx),
@@ -231,6 +241,11 @@ public:
     Status next_batch(Block* block) override;
     const Schema& schema() const override { return *_schema; }
     uint64_t merged_rows() const override { return _merged_rows; }
+    Status current_block_row_locations(std::vector<RowLocation>* block_row_locations) override {
+        DCHECK(_record_rowids);
+        *block_row_locations = _block_row_locations;
+        return Status::OK();
+    }
 
 private:
     int _get_size(Block* block) { return block->rows(); }
@@ -239,6 +254,7 @@ private:
     // It will be released after '_merge_heap' has been built.
     std::vector<RowwiseIterator*> _origin_iters;
     std::vector<bool> _iterator_init_flags;
+    std::vector<RowsetId> _rowset_ids;
     size_t _ori_return_cols;
 
     const Schema* _schema = nullptr;
@@ -262,6 +278,8 @@ private:
     RowSourcesBuffer* _row_sources_buf;
     uint32_t _merged_rows = 0;
     StorageReadOptions _opts;
+    bool _record_rowids = false;
+    std::vector<RowLocation> _block_row_locations;
 };
 
 // --------------- VerticalMaskMergeIterator ------------- //
@@ -312,8 +330,8 @@ private:
 // segment merge iterator
 std::shared_ptr<RowwiseIterator> new_vertical_heap_merge_iterator(
         std::vector<RowwiseIterator*> inputs, const std::vector<bool>& iterator_init_flag,
-        size_t _ori_return_cols, KeysType key_type, uint32_t seq_col_idx,
-        RowSourcesBuffer* row_sources_buf);
+        const std::vector<RowsetId>& rowset_ids, size_t _ori_return_cols, KeysType key_type,
+        uint32_t seq_col_idx, RowSourcesBuffer* row_sources_buf);
 
 std::shared_ptr<RowwiseIterator> new_vertical_mask_merge_iterator(
         const std::vector<RowwiseIterator*>& inputs, size_t ori_return_cols,
diff --git a/be/test/olap/rowid_conversion_test.cpp b/be/test/olap/rowid_conversion_test.cpp
index 7d62d9f213..129f2cb513 100644
--- a/be/test/olap/rowid_conversion_test.cpp
+++ b/be/test/olap/rowid_conversion_test.cpp
@@ -43,7 +43,7 @@ using namespace ErrorCode;
 static const uint32_t MAX_PATH_LEN = 1024;
 static StorageEngine* k_engine = nullptr;
 
-class TestRowIdConversion : public testing::TestWithParam<std::tuple<KeysType, bool, bool>> {
+class TestRowIdConversion : public testing::TestWithParam<std::tuple<KeysType, bool, bool, bool>> {
 protected:
     void SetUp() override {
         char buffer[MAX_PATH_LEN];
@@ -305,7 +305,7 @@ protected:
     void check_rowid_conversion(KeysType keys_type, bool enable_unique_key_merge_on_write,
                                 uint32_t num_input_rowset, uint32_t num_segments,
                                 uint32_t rows_per_segment, const SegmentsOverlapPB& overlap,
-                                bool has_delete_handler) {
+                                bool has_delete_handler, bool is_vertical_merger) {
         // generate input data
         std::vector<std::vector<std::vector<std::tuple<int64_t, int64_t>>>> input_data;
         generate_input_data(num_input_rowset, num_segments, rows_per_segment, overlap, input_data);
@@ -338,7 +338,12 @@ protected:
         RowsetWriterContext writer_context;
         create_rowset_writer_context(tablet_schema, NONOVERLAPPING, 3456, &writer_context);
         std::unique_ptr<RowsetWriter> output_rs_writer;
-        Status s = RowsetFactory::create_rowset_writer(writer_context, false, &output_rs_writer);
+        Status s;
+        if (is_vertical_merger) {
+            s = RowsetFactory::create_rowset_writer(writer_context, true, &output_rs_writer);
+        } else {
+            s = RowsetFactory::create_rowset_writer(writer_context, false, &output_rs_writer);
+        }
         EXPECT_TRUE(s.ok());
 
         // merge input rowset
@@ -348,8 +353,14 @@ protected:
         Merger::Statistics stats;
         RowIdConversion rowid_conversion;
         stats.rowid_conversion = &rowid_conversion;
-        s = Merger::vmerge_rowsets(tablet, READER_BASE_COMPACTION, tablet_schema, input_rs_readers,
-                                   output_rs_writer.get(), &stats);
+        if (is_vertical_merger) {
+            s = Merger::vertical_merge_rowsets(tablet, READER_BASE_COMPACTION, tablet_schema,
+                                               input_rs_readers, output_rs_writer.get(), 10000000,
+                                               &stats);
+        } else {
+            s = Merger::vmerge_rowsets(tablet, READER_BASE_COMPACTION, tablet_schema,
+                                       input_rs_readers, output_rs_writer.get(), &stats);
+        }
         EXPECT_TRUE(s.ok());
         RowsetSharedPtr out_rowset = output_rs_writer->build();
 
@@ -535,19 +546,25 @@ TEST_F(TestRowIdConversion, Basic) {
 
 INSTANTIATE_TEST_SUITE_P(
         Parameters, TestRowIdConversion,
-        ::testing::ValuesIn(std::vector<std::tuple<KeysType, bool, bool>> {
-                // Parameters: data_type, enable_unique_key_merge_on_write, has_delete_handler
-                {DUP_KEYS, false, false},
-                {UNIQUE_KEYS, false, false},
-                {UNIQUE_KEYS, true, false},
-                {DUP_KEYS, false, true},
-                {UNIQUE_KEYS, false, true},
-                {UNIQUE_KEYS, true, true}}));
+        ::testing::ValuesIn(std::vector<std::tuple<KeysType, bool, bool, bool>> {
+                // Parameters: data_type, enable_unique_key_merge_on_write, has_delete_handler, is_vertical_merger
+                {DUP_KEYS, false, false, false},
+                {UNIQUE_KEYS, false, false, false},
+                {UNIQUE_KEYS, true, false, false},
+                {DUP_KEYS, false, true, false},
+                {UNIQUE_KEYS, false, true, false},
+                {UNIQUE_KEYS, true, true, false},
+                {UNIQUE_KEYS, false, false, true},
+                {UNIQUE_KEYS, true, false, true},
+                {DUP_KEYS, false, true, true},
+                {UNIQUE_KEYS, false, true, true},
+                {UNIQUE_KEYS, true, true, true}}));
 
 TEST_P(TestRowIdConversion, Conversion) {
     KeysType keys_type = std::get<0>(GetParam());
     bool enable_unique_key_merge_on_write = std::get<1>(GetParam());
     bool has_delete_handler = std::get<2>(GetParam());
+    bool is_vertical_merger = std::get<3>(GetParam());
 
     // if num_input_rowset = 2, VCollectIterator::Level1Iterator::_merge = flase
     // if num_input_rowset = 3, VCollectIterator::Level1Iterator::_merge = true
@@ -559,7 +576,8 @@ TEST_P(TestRowIdConversion, Conversion) {
             SegmentsOverlapPB overlap = NONOVERLAPPING;
             std::vector<std::vector<std::vector<std::tuple<int64_t, int64_t>>>> input_data;
             check_rowid_conversion(keys_type, enable_unique_key_merge_on_write, num_input_rowset,
-                                   num_segments, rows_per_segment, overlap, has_delete_handler);
+                                   num_segments, rows_per_segment, overlap, has_delete_handler,
+                                   is_vertical_merger);
         }
         // RowsetReader: VMergeIterator
         {
@@ -567,7 +585,8 @@ TEST_P(TestRowIdConversion, Conversion) {
             SegmentsOverlapPB overlap = OVERLAPPING;
             std::vector<std::vector<std::vector<std::tuple<int64_t, int64_t>>>> input_data;
             check_rowid_conversion(keys_type, enable_unique_key_merge_on_write, num_input_rowset,
-                                   num_segments, rows_per_segment, overlap, has_delete_handler);
+                                   num_segments, rows_per_segment, overlap, has_delete_handler,
+                                   is_vertical_merger);
         }
         // RowsetReader: VUnionIterator
         {
@@ -575,7 +594,8 @@ TEST_P(TestRowIdConversion, Conversion) {
             SegmentsOverlapPB overlap = NONOVERLAPPING;
             std::vector<std::vector<std::vector<std::tuple<int64_t, int64_t>>>> input_data;
             check_rowid_conversion(keys_type, enable_unique_key_merge_on_write, num_input_rowset,
-                                   num_segments, rows_per_segment, overlap, has_delete_handler);
+                                   num_segments, rows_per_segment, overlap, has_delete_handler,
+                                   is_vertical_merger);
         }
         // RowsetReader: VUnionIterator + VMergeIterator
         {
@@ -583,7 +603,8 @@ TEST_P(TestRowIdConversion, Conversion) {
             SegmentsOverlapPB overlap = OVERLAP_UNKNOWN;
             std::vector<std::vector<std::vector<std::tuple<int64_t, int64_t>>>> input_data;
             check_rowid_conversion(keys_type, enable_unique_key_merge_on_write, num_input_rowset,
-                                   num_segments, rows_per_segment, overlap, has_delete_handler);
+                                   num_segments, rows_per_segment, overlap, has_delete_handler,
+                                   is_vertical_merger);
         }
     }
 }


---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@doris.apache.org
For additional commands, e-mail: commits-help@doris.apache.org