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

zhangstar333 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 6c86c91bb84 [bug](analytic) fix partition by column when it overflow 
haven't convert to column64 (#65240)
6c86c91bb84 is described below

commit 6c86c91bb8451d2e804726f927ceb096b7bd1f1f
Author: zhangstar333 <[email protected]>
AuthorDate: Tue Jul 7 11:14:26 2026 +0800

    [bug](analytic) fix partition by column when it overflow haven't convert to 
column64 (#65240)
    
    ### What problem does this PR solve?
    when insert into partition by column, will be call
    insert_range_from_ignore_overflow function,
    the dst column maybe overflow, so need add the
    convert_column_if_overflow function to convert to column64。
---
 be/src/core/column/column_string.cpp               | 56 +++++++++++++---------
 be/src/exec/operator/analytic_sink_operator.cpp    |  8 ++++
 be/test/core/column/column_string_test.cpp         | 20 ++++++++
 .../window_functions/test_column_boundary.out      |  3 +-
 4 files changed, 62 insertions(+), 25 deletions(-)

diff --git a/be/src/core/column/column_string.cpp 
b/be/src/core/column/column_string.cpp
index a2e128d0d79..b8b7a6c451e 100644
--- a/be/src/core/column/column_string.cpp
+++ b/be/src/core/column/column_string.cpp
@@ -99,33 +99,43 @@ void ColumnStr<T>::insert_range_from_ignore_overflow(const 
doris::IColumn& src,
         return;
     }
 
-    const auto& src_concrete = assert_cast<const ColumnStr<T>&>(src);
-    if (start + length > src_concrete.offsets.size()) {
-        throw doris::Exception(doris::ErrorCode::INTERNAL_ERROR,
-                               "Parameter out of bound in "
-                               
"IColumnStr<T>::insert_range_from_ignore_overflow method.");
-    }
+    auto do_insert = [&](const auto& src_concrete) {
+        const auto& src_offsets = src_concrete.get_offsets();
+        const auto& src_chars = src_concrete.get_chars();
+        if (start + length > src_offsets.size()) {
+            throw doris::Exception(doris::ErrorCode::INTERNAL_ERROR,
+                                   "Parameter out of bound in "
+                                   
"IColumnStr<T>::insert_range_from_ignore_overflow method.");
+        }
 
-    auto nested_offset = src_concrete.offset_at(start);
-    auto nested_length = src_concrete.offsets[start + length - 1] - 
nested_offset;
+        auto nested_offset = src_offsets[static_cast<ssize_t>(start) - 1];
+        auto nested_length = src_offsets[start + length - 1] - nested_offset;
 
-    size_t old_chars_size = chars.size();
-    chars.resize(old_chars_size + nested_length);
-    memcpy(&chars[old_chars_size], &src_concrete.chars[nested_offset], 
nested_length);
+        size_t old_chars_size = chars.size();
+        chars.resize(old_chars_size + nested_length);
+        memcpy(&chars[old_chars_size], &src_chars[nested_offset], 
nested_length);
 
-    if (start == 0 && offsets.empty()) {
-        offsets.assign(src_concrete.offsets.begin(), 
src_concrete.offsets.begin() + length);
-    } else {
-        size_t old_size = offsets.size();
-        auto prev_max_offset = offsets.back(); /// -1th index is Ok, see 
PaddedPODArray
-        offsets.resize(old_size + length);
-
-        for (size_t i = 0; i < length; ++i) {
-            // unsinged integer overflow is well defined in C++,
-            // so we don't need to check the overflow here.
-            offsets[old_size + i] =
-                    src_concrete.offsets[start + i] - nested_offset + 
prev_max_offset;
+        using OffsetsType = std::decay_t<decltype(src_offsets)>;
+        if (std::is_same_v<T, typename OffsetsType::value_type> && start == 0 
&& offsets.empty()) {
+            offsets.assign(src_offsets.begin(), src_offsets.begin() + length);
+        } else {
+            size_t old_size = offsets.size();
+            auto prev_max_offset = offsets.back(); /// -1th index is Ok, see 
PaddedPODArray
+            offsets.resize(old_size + length);
+
+            for (size_t i = 0; i < length; ++i) {
+                // unsinged integer overflow is well defined in C++,
+                // so we don't need to check the overflow here.
+                offsets[old_size + i] =
+                        static_cast<T>(src_offsets[start + i] - nested_offset) 
+ prev_max_offset;
+            }
         }
+    };
+
+    if (src.is_column_string64()) {
+        do_insert(assert_cast<const ColumnStr<uint64_t>&>(src));
+    } else {
+        do_insert(assert_cast<const ColumnStr<uint32_t>&>(src));
     }
 
 #ifndef NDEBUG
diff --git a/be/src/exec/operator/analytic_sink_operator.cpp 
b/be/src/exec/operator/analytic_sink_operator.cpp
index 534cf0b841c..f0d26ec627e 100644
--- a/be/src/exec/operator/analytic_sink_operator.cpp
+++ b/be/src/exec/operator/analytic_sink_operator.cpp
@@ -768,6 +768,12 @@ Status 
AnalyticSinkOperatorX::_add_input_block(doris::RuntimeState* state, Block
     
local_state._input_block_first_row_positions.emplace_back(local_state._input_total_rows);
     size_t block_rows = input_block->rows();
     local_state._input_total_rows += block_rows;
+    auto convert_column_if_overflow = [](MutableColumnPtr& column) {
+        auto converted_column = column->convert_column_if_overflow();
+        if (converted_column.get() != column.get()) {
+            column = converted_column->assert_mutable();
+        }
+    };
 
     // record origin columns, maybe be after this, could cast some column but 
no need to output
     auto column_to_keep = input_block->columns();
@@ -788,6 +794,7 @@ Status 
AnalyticSinkOperatorX::_add_input_block(doris::RuntimeState* state, Block
             RETURN_IF_ERROR(
                     _insert_range_column(input_block, 
local_state._partition_by_eq_expr_ctxs[i],
                                          
local_state._partition_by_columns[i].get(), block_rows));
+            convert_column_if_overflow(local_state._partition_by_columns[i]);
         }
     }
     {
@@ -796,6 +803,7 @@ Status 
AnalyticSinkOperatorX::_add_input_block(doris::RuntimeState* state, Block
             RETURN_IF_ERROR(_insert_range_column(input_block, 
local_state._order_by_eq_expr_ctxs[i],
                                                  
local_state._order_by_columns[i].get(),
                                                  block_rows));
+            convert_column_if_overflow(local_state._order_by_columns[i]);
         }
     }
     {
diff --git a/be/test/core/column/column_string_test.cpp 
b/be/test/core/column/column_string_test.cpp
index 37de6fe56e2..08ac03dcd99 100644
--- a/be/test/core/column/column_string_test.cpp
+++ b/be/test/core/column/column_string_test.cpp
@@ -190,6 +190,26 @@ TEST_F(ColumnStringTest, is_variable_length) {
     ColumnString64::MutablePtr col64 = ColumnString64::create();
     EXPECT_TRUE(col64->is_variable_length());
 }
+
+TEST(ColumnStringStandaloneTest, 
insert_range_from_ignore_overflow_to_string64_from_string32) {
+    auto src = ColumnString::create();
+    src->insert_data("a", 1);
+    src->insert_data("bc", 2);
+    src->insert_data("def", 3);
+
+    auto dst = ColumnString64::create();
+    dst->insert_range_from_ignore_overflow(*src, 0, src->size());
+    ASSERT_EQ(dst->size(), 3);
+    EXPECT_EQ(dst->get_data_at(0).to_string(), "a");
+    EXPECT_EQ(dst->get_data_at(1).to_string(), "bc");
+    EXPECT_EQ(dst->get_data_at(2).to_string(), "def");
+
+    dst->insert_range_from_ignore_overflow(*src, 1, 2);
+    ASSERT_EQ(dst->size(), 5);
+    EXPECT_EQ(dst->get_data_at(3).to_string(), "bc");
+    EXPECT_EQ(dst->get_data_at(4).to_string(), "def");
+}
+
 TEST_F(ColumnStringTest, sanity_check) {
     auto test_func = [](auto& col) {
         auto& chars = col->get_chars();
diff --git 
a/regression-test/data/query_p0/sql_functions/window_functions/test_column_boundary.out
 
b/regression-test/data/query_p0/sql_functions/window_functions/test_column_boundary.out
index 7a238f99935..33fb7867e55 100644
--- 
a/regression-test/data/query_p0/sql_functions/window_functions/test_column_boundary.out
+++ 
b/regression-test/data/query_p0/sql_functions/window_functions/test_column_boundary.out
@@ -3,5 +3,4 @@
 200000000
 
 -- !sql_2 --
-38135901019538738
-
+40000000000


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

Reply via email to