This is an automated email from the ASF dual-hosted git repository. panxiaolei 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 1b49f847e2d [Chore](function) change hash set usage of all functions (#43289) 1b49f847e2d is described below commit 1b49f847e2df8e5288006e8438b747f378913c37 Author: Pxl <pxl...@qq.com> AuthorDate: Mon Nov 11 14:08:53 2024 +0800 [Chore](function) change hash set usage of all functions (#43289) remove all ck hash_set usage and use phmap_set some test results have changed because the order in which data is stored within the hash table has changed. --- .../aggregate_function_collect.h | 38 ++++++++++--------- .../aggregate_function_distinct.h | 44 +++++++++++----------- .../vec/functions/array/function_array_distinct.h | 10 ++--- .../vec/functions/array/function_array_except.cpp | 4 +- be/src/vec/functions/array/function_array_map.h | 1 - be/src/vec/functions/array/function_array_set.h | 5 +-- .../vec/functions/array/function_arrays_overlap.h | 9 ++--- .../test_vertical_compaction_agg_state.out | 4 +- .../data/function_p0/test_agg_foreach.out | 2 +- .../data/function_p0/test_agg_foreach_notnull.out | 2 +- .../agg_function/group_unique_array.out | 16 ++++---- .../test_aggregate_window_functions.out | 16 ++++---- .../test_vertical_compaction_agg_state.groovy | 4 +- .../agg_function/group_unique_array.groovy | 4 +- 14 files changed, 80 insertions(+), 79 deletions(-) diff --git a/be/src/vec/aggregate_functions/aggregate_function_collect.h b/be/src/vec/aggregate_functions/aggregate_function_collect.h index 68de426ea1f..02490be56a0 100644 --- a/be/src/vec/aggregate_functions/aggregate_function_collect.h +++ b/be/src/vec/aggregate_functions/aggregate_function_collect.h @@ -35,7 +35,6 @@ #include "vec/columns/column_string.h" #include "vec/columns/columns_number.h" #include "vec/common/assert_cast.h" -#include "vec/common/hash_table/hash_set.h" #include "vec/common/pod_array_fwd.h" #include "vec/common/string_buffer.hpp" #include "vec/common/string_ref.h" @@ -62,7 +61,7 @@ struct AggregateFunctionCollectSetData { using ColVecType = ColumnVectorOrDecimal<ElementType>; using ElementNativeType = typename NativeType<T>::Type; using SelfType = AggregateFunctionCollectSetData; - using Set = HashSetWithStackMemory<ElementNativeType, DefaultHash<ElementNativeType>, 4>; + using Set = phmap::flat_hash_set<ElementNativeType>; Set data_set; Int64 max_size = -1; @@ -83,20 +82,29 @@ struct AggregateFunctionCollectSetData { if (size() >= max_size) { return; } - data_set.insert(rhs_elem.get_value()); + data_set.insert(rhs_elem); } } else { - data_set.merge(rhs.data_set); + data_set.merge(Set(rhs.data_set)); } } void write(BufferWritable& buf) const { - data_set.write(buf); + write_var_uint(data_set.size(), buf); + for (const auto& value : data_set) { + write_binary(value, buf); + } write_var_int(max_size, buf); } void read(BufferReadable& buf) { - data_set.read(buf); + size_t new_size = 0; + read_var_uint(new_size, buf); + ElementNativeType x; + for (size_t i = 0; i < new_size; ++i) { + read_binary(x, buf); + data_set.insert(x); + } read_var_int(max_size, buf); } @@ -104,7 +112,7 @@ struct AggregateFunctionCollectSetData { auto& vec = assert_cast<ColVecType&>(to).get_data(); vec.reserve(size()); for (const auto& item : data_set) { - vec.push_back(item.key); + vec.push_back(item); } } @@ -116,23 +124,19 @@ struct AggregateFunctionCollectSetData<StringRef, HasLimit> { using ElementType = StringRef; using ColVecType = ColumnString; using SelfType = AggregateFunctionCollectSetData<ElementType, HasLimit>; - using Set = HashSetWithStackMemory<ElementType, DefaultHash<ElementType>, 4>; + using Set = phmap::flat_hash_set<ElementType>; Set data_set; Int64 max_size = -1; size_t size() const { return data_set.size(); } void add(const IColumn& column, size_t row_num, Arena* arena) { - Set::LookupResult it; - bool inserted; auto key = column.get_data_at(row_num); key.data = arena->insert(key.data, key.size); - data_set.emplace(key, it, inserted); + data_set.insert(key); } void merge(const SelfType& rhs, Arena* arena) { - bool inserted; - Set::LookupResult it; if (max_size == -1) { max_size = rhs.max_size; } @@ -145,16 +149,16 @@ struct AggregateFunctionCollectSetData<StringRef, HasLimit> { } } assert(arena != nullptr); - StringRef key = rhs_elem.get_value(); + StringRef key = rhs_elem; key.data = arena->insert(key.data, key.size); - data_set.emplace(key, it, inserted); + data_set.insert(key); } } void write(BufferWritable& buf) const { write_var_uint(size(), buf); for (const auto& elem : data_set) { - write_string_binary(elem.get_value(), buf); + write_string_binary(elem, buf); } write_var_int(max_size, buf); } @@ -174,7 +178,7 @@ struct AggregateFunctionCollectSetData<StringRef, HasLimit> { auto& vec = assert_cast<ColVecType&>(to); vec.reserve(size()); for (const auto& item : data_set) { - vec.insert_data(item.key.data, item.key.size); + vec.insert_data(item.data, item.size); } } diff --git a/be/src/vec/aggregate_functions/aggregate_function_distinct.h b/be/src/vec/aggregate_functions/aggregate_function_distinct.h index ec6936a128c..3cce558312b 100644 --- a/be/src/vec/aggregate_functions/aggregate_function_distinct.h +++ b/be/src/vec/aggregate_functions/aggregate_function_distinct.h @@ -35,7 +35,6 @@ #include "vec/aggregate_functions/aggregate_function.h" #include "vec/columns/column.h" #include "vec/common/assert_cast.h" -#include "vec/common/hash_table/hash_set.h" #include "vec/common/string_ref.h" #include "vec/core/types.h" #include "vec/data_types/data_type.h" @@ -59,8 +58,8 @@ namespace doris::vectorized { template <typename T, bool stable> struct AggregateFunctionDistinctSingleNumericData { /// When creating, the hash table must be small. - using Container = std::conditional_t<stable, phmap::flat_hash_map<T, uint32_t>, - HashSetWithStackMemory<T, DefaultHash<T>, 4>>; + using Container = + std::conditional_t<stable, phmap::flat_hash_map<T, uint32_t>, phmap::flat_hash_set<T>>; using Self = AggregateFunctionDistinctSingleNumericData<T, stable>; Container data; @@ -78,21 +77,30 @@ struct AggregateFunctionDistinctSingleNumericData { void merge(const Self& rhs, Arena*) { DCHECK(!stable); if constexpr (!stable) { - data.merge(rhs.data); + data.merge(Container(rhs.data)); } } void serialize(BufferWritable& buf) const { DCHECK(!stable); if constexpr (!stable) { - data.write(buf); + write_var_uint(data.size(), buf); + for (const auto& value : data) { + write_binary(value, buf); + } } } void deserialize(BufferReadable& buf, Arena*) { DCHECK(!stable); if constexpr (!stable) { - data.read(buf); + size_t new_size = 0; + read_var_uint(new_size, buf); + T x; + for (size_t i = 0; i < new_size; ++i) { + read_binary(x, buf); + data.insert(x); + } } } @@ -108,7 +116,7 @@ struct AggregateFunctionDistinctSingleNumericData { } } else { for (const auto& elem : data) { - argument_columns[0]->insert(elem.get_value()); + argument_columns[0]->insert(elem); } } @@ -120,19 +128,17 @@ template <bool stable> struct AggregateFunctionDistinctGenericData { /// When creating, the hash table must be small. using Container = std::conditional_t<stable, phmap::flat_hash_map<StringRef, uint32_t>, - HashSetWithStackMemory<StringRef, StringRefHash, 4>>; + phmap::flat_hash_set<StringRef, StringRefHash>>; using Self = AggregateFunctionDistinctGenericData; Container data; void merge(const Self& rhs, Arena* arena) { DCHECK(!stable); if constexpr (!stable) { - typename Container::LookupResult it; - bool inserted; for (const auto& elem : rhs.data) { - StringRef key = elem.get_value(); + StringRef key = elem; key.data = arena->insert(key.data, key.size); - data.emplace(key, it, inserted); + data.emplace(key); } } } @@ -142,7 +148,7 @@ struct AggregateFunctionDistinctGenericData { if constexpr (!stable) { write_var_uint(data.size(), buf); for (const auto& elem : data) { - write_string_binary(elem.get_value(), buf); + write_string_binary(elem, buf); } } } @@ -174,9 +180,7 @@ struct AggregateFunctionDistinctSingleGenericData if constexpr (stable) { data.emplace(key, data.size()); } else { - typename Base::Container::LookupResult it; - bool inserted; - data.emplace(key, it, inserted); + data.insert(key); } } @@ -193,7 +197,7 @@ struct AggregateFunctionDistinctSingleGenericData } } else { for (const auto& elem : data) { - argument_columns[0]->insert_data(elem.get_value().data, elem.get_value().size); + argument_columns[0]->insert_data(elem.data, elem.size); } } @@ -218,9 +222,7 @@ struct AggregateFunctionDistinctMultipleGenericData if constexpr (stable) { data.emplace(key, data.size()); } else { - typename Base::Container::LookupResult it; - bool inserted; - data.emplace(key, it, inserted); + data.emplace(key); } } @@ -243,7 +245,7 @@ struct AggregateFunctionDistinctMultipleGenericData } } else { for (const auto& elem : data) { - const char* begin = elem.get_value().data; + const char* begin = elem.data; for (auto& column : argument_columns) { begin = column->deserialize_and_insert_from_arena(begin); } diff --git a/be/src/vec/functions/array/function_array_distinct.h b/be/src/vec/functions/array/function_array_distinct.h index 6f477f3b671..4b7e3e6f035 100644 --- a/be/src/vec/functions/array/function_array_distinct.h +++ b/be/src/vec/functions/array/function_array_distinct.h @@ -35,7 +35,6 @@ #include "vec/columns/columns_number.h" #include "vec/common/assert_cast.h" #include "vec/common/hash_table/hash.h" -#include "vec/common/hash_table/hash_set.h" #include "vec/common/pod_array_fwd.h" #include "vec/common/string_ref.h" #include "vec/core/block.h" @@ -146,8 +145,7 @@ private: auto& dest_data_concrete = reinterpret_cast<ColumnType&>(dest_column); PaddedPODArray<NestType>& dest_datas = dest_data_concrete.get_data(); - using Set = HashSetWithStackMemory<ElementNativeType, DefaultHash<ElementNativeType>, - INITIAL_SIZE_DEGREE>; + using Set = phmap::flat_hash_set<ElementNativeType, DefaultHash<ElementNativeType>>; Set set; size_t prev_src_offset = 0; @@ -171,7 +169,7 @@ private: continue; } - if (!set.find(src_datas[j])) { + if (!set.contains(src_datas[j])) { set.insert(src_datas[j]); dest_datas.push_back(src_datas[j]); if (dest_null_map) { @@ -201,7 +199,7 @@ private: ColumnString::Offsets& column_string_offsets = dest_column_string.get_offsets(); column_string_chars.reserve(src_column.size()); - using Set = HashSetWithStackMemory<StringRef, DefaultHash<StringRef>, INITIAL_SIZE_DEGREE>; + using Set = phmap::flat_hash_set<StringRef, DefaultHash<StringRef>>; Set set; size_t prev_src_offset = 0; @@ -225,7 +223,7 @@ private: } StringRef src_str_ref = src_data_concrete->get_data_at(j); - if (!set.find(src_str_ref)) { + if (!set.contains(src_str_ref)) { set.insert(src_str_ref); // copy the src data to column_string_chars const size_t old_size = column_string_chars.size(); diff --git a/be/src/vec/functions/array/function_array_except.cpp b/be/src/vec/functions/array/function_array_except.cpp index 2e8d0532f45..3740de69231 100644 --- a/be/src/vec/functions/array/function_array_except.cpp +++ b/be/src/vec/functions/array/function_array_except.cpp @@ -61,12 +61,12 @@ struct ExceptAction { template <bool is_left> bool apply(Set& set, Set& result_set, const Element& elem) { if constexpr (is_left) { - if (!set.find(elem)) { + if (!set.contains(elem)) { set.insert(elem); return true; } } else { - if (!set.find(elem)) { + if (!set.contains(elem)) { set.insert(elem); } } diff --git a/be/src/vec/functions/array/function_array_map.h b/be/src/vec/functions/array/function_array_map.h index a586e262cb2..74b0a19f0f0 100644 --- a/be/src/vec/functions/array/function_array_map.h +++ b/be/src/vec/functions/array/function_array_map.h @@ -22,7 +22,6 @@ #include "vec/columns/column_array.h" #include "vec/columns/column_string.h" #include "vec/common/hash_table/hash_map.h" -#include "vec/common/hash_table/hash_set.h" #include "vec/data_types/data_type_array.h" #include "vec/functions/array/function_array_utils.h" #include "vec/functions/function_helpers.h" diff --git a/be/src/vec/functions/array/function_array_set.h b/be/src/vec/functions/array/function_array_set.h index fe51863d9ea..1ecf6d72531 100644 --- a/be/src/vec/functions/array/function_array_set.h +++ b/be/src/vec/functions/array/function_array_set.h @@ -21,7 +21,6 @@ #include "vec/columns/column_array.h" #include "vec/columns/column_string.h" -#include "vec/common/hash_table/hash_set.h" #include "vec/data_types/data_type_array.h" #include "vec/functions/array/function_array_utils.h" #include "vec/functions/function_helpers.h" @@ -48,7 +47,7 @@ template <SetOperation operation, typename ColumnType> struct OpenSetImpl { using Element = typename ColumnType::value_type; using ElementNativeType = typename NativeType<Element>::Type; - using Set = HashSetWithStackMemory<ElementNativeType, DefaultHash<ElementNativeType>, 4>; + using Set = phmap::flat_hash_set<ElementNativeType>; using Action = typename ActionImpl<Set, Element, operation>::Action; Action action; Set set; @@ -85,7 +84,7 @@ struct OpenSetImpl { template <SetOperation operation> struct OpenSetImpl<operation, ColumnString> { - using Set = HashSetWithStackMemory<StringRef, DefaultHash<StringRef>, 4>; + using Set = phmap::flat_hash_set<StringRef>; using Action = typename ActionImpl<Set, StringRef, operation>::Action; Action action; Set set; diff --git a/be/src/vec/functions/array/function_arrays_overlap.h b/be/src/vec/functions/array/function_arrays_overlap.h index 7c851f5c160..dd993100885 100644 --- a/be/src/vec/functions/array/function_arrays_overlap.h +++ b/be/src/vec/functions/array/function_arrays_overlap.h @@ -33,7 +33,6 @@ #include "vec/columns/columns_number.h" #include "vec/common/assert_cast.h" #include "vec/common/hash_table/hash.h" -#include "vec/common/hash_table/hash_set.h" #include "vec/common/string_ref.h" #include "vec/core/block.h" #include "vec/core/column_numbers.h" @@ -62,7 +61,7 @@ using ColumnString = ColumnStr<UInt32>; template <typename T> struct OverlapSetImpl { using ElementNativeType = typename NativeType<typename T::value_type>::Type; - using Set = HashSetWithStackMemory<ElementNativeType, DefaultHash<ElementNativeType>, 4>; + using Set = phmap::flat_hash_set<ElementNativeType, DefaultHash<ElementNativeType>>; Set set; void insert_array(const IColumn* column, size_t start, size_t size) { const auto& vec = assert_cast<const T&>(*column).get_data(); @@ -73,7 +72,7 @@ struct OverlapSetImpl { bool find_any(const IColumn* column, size_t start, size_t size) { const auto& vec = assert_cast<const T&>(*column).get_data(); for (size_t i = start; i < start + size; ++i) { - if (set.find(vec[i])) { + if (set.contains(vec[i])) { return true; } } @@ -83,7 +82,7 @@ struct OverlapSetImpl { template <> struct OverlapSetImpl<ColumnString> { - using Set = HashSetWithStackMemory<StringRef, DefaultHash<StringRef>, 4>; + using Set = phmap::flat_hash_set<StringRef, DefaultHash<StringRef>>; Set set; void insert_array(const IColumn* column, size_t start, size_t size) { for (size_t i = start; i < start + size; ++i) { @@ -92,7 +91,7 @@ struct OverlapSetImpl<ColumnString> { } bool find_any(const IColumn* column, size_t start, size_t size) { for (size_t i = start; i < start + size; ++i) { - if (set.find(column->get_data_at(i))) { + if (set.contains(column->get_data_at(i))) { return true; } } diff --git a/regression-test/data/compaction/test_vertical_compaction_agg_state.out b/regression-test/data/compaction/test_vertical_compaction_agg_state.out index 62a7a629187..668e00d9179 100644 --- a/regression-test/data/compaction/test_vertical_compaction_agg_state.out +++ b/regression-test/data/compaction/test_vertical_compaction_agg_state.out @@ -3,10 +3,10 @@ a ["aa", "a"] -- !select_default -- -a ["aaa", "aa", "a"] +a ["a", "aa", "aaa"] b ["b"] -- !select_default -- -a ["aaa", "aa", "a"] +a ["a", "aa", "aaa"] b ["b"] diff --git a/regression-test/data/function_p0/test_agg_foreach.out b/regression-test/data/function_p0/test_agg_foreach.out index c37f6d919c5..c45ae9f67a9 100644 --- a/regression-test/data/function_p0/test_agg_foreach.out +++ b/regression-test/data/function_p0/test_agg_foreach.out @@ -39,7 +39,7 @@ ["ab", "123", "114514"] [1, 2, 3] -- !sql -- -[[100, 20, 1], [2], [3]] [["efg", "cd", "ab"], ["c", "123"], ["114514"]] [[1], [2], [3]] +[[20, 1, 100], [2], [3]] [["cd", "efg", "ab"], ["123", "c"], ["114514"]] [[1], [2], [3]] -- !sql -- [[1, 20, 100], [2, 2], [3]] [["ab", "cd", "efg"], ["123", "c"], ["114514"]] [[1], [2, 2], [3]] diff --git a/regression-test/data/function_p0/test_agg_foreach_notnull.out b/regression-test/data/function_p0/test_agg_foreach_notnull.out index c37f6d919c5..c45ae9f67a9 100644 --- a/regression-test/data/function_p0/test_agg_foreach_notnull.out +++ b/regression-test/data/function_p0/test_agg_foreach_notnull.out @@ -39,7 +39,7 @@ ["ab", "123", "114514"] [1, 2, 3] -- !sql -- -[[100, 20, 1], [2], [3]] [["efg", "cd", "ab"], ["c", "123"], ["114514"]] [[1], [2], [3]] +[[20, 1, 100], [2], [3]] [["cd", "efg", "ab"], ["123", "c"], ["114514"]] [[1], [2], [3]] -- !sql -- [[1, 20, 100], [2, 2], [3]] [["ab", "cd", "efg"], ["123", "c"], ["114514"]] [[1], [2, 2], [3]] diff --git a/regression-test/data/nereids_function_p0/agg_function/group_unique_array.out b/regression-test/data/nereids_function_p0/agg_function/group_unique_array.out index 74c053e38f6..50bb595d007 100644 --- a/regression-test/data/nereids_function_p0/agg_function/group_unique_array.out +++ b/regression-test/data/nereids_function_p0/agg_function/group_unique_array.out @@ -1,6 +1,6 @@ -- This file is automatically generated. You should know what you did if you want to edit this -- !1 -- -[4, 2, 1, 3] [2, 1] +[1, 2, 3, 4] [1, 2] -- !2 -- 1 ["2023-01-01"] ["hello"] @@ -9,11 +9,11 @@ 4 ["2023-01-02", "2023-01-03"] ["sql"] -- !3 -- -["doris", "world", "hello", "sql"] -["doris", "world", "hello", "sql"] -["doris", "world", "hello", "sql"] -["doris", "world", "hello", "sql"] -["doris", "world", "hello", "sql"] -["doris", "world", "hello", "sql"] -["doris", "world", "hello", "sql"] +["doris", "hello", "world", "sql"] +["doris", "hello", "world", "sql"] +["doris", "hello", "world", "sql"] +["doris", "hello", "world", "sql"] +["doris", "hello", "world", "sql"] +["doris", "hello", "world", "sql"] +["doris", "hello", "world", "sql"] diff --git a/regression-test/data/nereids_p0/sql_functions/aggregate_functions/test_aggregate_window_functions.out b/regression-test/data/nereids_p0/sql_functions/aggregate_functions/test_aggregate_window_functions.out index 6729ea26bc1..e2f8ac48979 100644 --- a/regression-test/data/nereids_p0/sql_functions/aggregate_functions/test_aggregate_window_functions.out +++ b/regression-test/data/nereids_p0/sql_functions/aggregate_functions/test_aggregate_window_functions.out @@ -365,11 +365,11 @@ sichuan [{"cbe":{},"notnull":0,"null":1,"all":1}] 2 4.03456789E8 2 4.03456789E8 2 4.03456789E8 -3 4.03456789E8 -3 4.03456789E8 -3 4.03456789E8 -3 4.03456789E8 -3 4.03456789E8 +3 4.0345678917999995E8 +3 4.0345678917999995E8 +3 4.0345678917999995E8 +3 4.0345678917999995E8 +3 4.0345678917999995E8 -- !agg_window_percentile_array -- 1 [273456789, 423456789, 523456789] @@ -593,13 +593,13 @@ sichuan [{"cbe":{},"notnull":0,"null":1,"all":1}] 1 ["1,2"] 1 ["1,3", "1,2"] 1 [] -2 ["2,3", "2,4"] 2 ["2,3"] 2 ["2,3"] +2 ["2,4", "2,3"] +3 ["3", "4", "5"] 3 ["3", "4"] 3 ["3"] -3 ["5", "3", "4"] -3 ["5", "3", "6", "4"] +3 ["4", "6", "3", "5"] -- !agg_window_array_agg -- 1 [null, "1,2", "1,2", "1,3"] diff --git a/regression-test/suites/compaction/test_vertical_compaction_agg_state.groovy b/regression-test/suites/compaction/test_vertical_compaction_agg_state.groovy index 209f816785c..40a86812fd2 100644 --- a/regression-test/suites/compaction/test_vertical_compaction_agg_state.groovy +++ b/regression-test/suites/compaction/test_vertical_compaction_agg_state.groovy @@ -72,7 +72,7 @@ suite("test_vertical_compaction_agg_state") { ('a',collect_set_state('aaa')) """ - qt_select_default """ SELECT user_id,collect_set_merge(agg_user_id) FROM ${tableName} t group by user_id ORDER BY user_id;""" + qt_select_default """ SELECT user_id,array_sort(collect_set_merge(agg_user_id)) FROM ${tableName} t group by user_id ORDER BY user_id;""" def tablets = sql_return_maparray """ show tablets from ${tableName}; """ @@ -124,7 +124,7 @@ suite("test_vertical_compaction_agg_state") { } } assert (rowCount < 8 * replicaNum) - qt_select_default """ SELECT user_id,collect_set_merge(agg_user_id) FROM ${tableName} t group by user_id ORDER BY user_id;""" + qt_select_default """ SELECT user_id,array_sort(collect_set_merge(agg_user_id)) FROM ${tableName} t group by user_id ORDER BY user_id;""" } finally { try_sql("DROP TABLE IF EXISTS ${tableName}") } diff --git a/regression-test/suites/nereids_function_p0/agg_function/group_unique_array.groovy b/regression-test/suites/nereids_function_p0/agg_function/group_unique_array.groovy index f110f1a50c9..c64941e4d5e 100644 --- a/regression-test/suites/nereids_function_p0/agg_function/group_unique_array.groovy +++ b/regression-test/suites/nereids_function_p0/agg_function/group_unique_array.groovy @@ -43,10 +43,10 @@ suite("group_unique_array") { (4, "2023-01-03", "sql") """ qt_1 """ - select collect_set(k1),collect_set(k1,2) from test_group_unique_array_table; + select array_sort(collect_set(k1)),array_sort(collect_set(k1,2)) from test_group_unique_array_table; """ qt_2 """ - select k1,collect_set(k2),collect_set(k3,1) from test_group_unique_array_table group by k1 order by k1; + select k1,array_sort(collect_set(k2)),array_sort(collect_set(k3,1)) from test_group_unique_array_table group by k1 order by k1; """ qt_3 """ select collect_set(k3) over() from test_group_unique_array_table; --------------------------------------------------------------------- To unsubscribe, e-mail: commits-unsubscr...@doris.apache.org For additional commands, e-mail: commits-h...@doris.apache.org