This is an automated email from the ASF dual-hosted git repository. morningman pushed a commit to branch branch-1.1-lts in repository https://gitbox.apache.org/repos/asf/doris.git
The following commit(s) were added to refs/heads/branch-1.1-lts by this push: new 06ebb5e842 [fix](MV) Fix insert negative value to table with bitmap_union MV will cause count distinct result incorrect (#13700) 06ebb5e842 is described below commit 06ebb5e84247e8ee2e0a00a102c3b9068e35486c Author: Zhengguo Yang <yangz...@gmail.com> AuthorDate: Thu Oct 27 08:58:46 2022 +0800 [fix](MV) Fix insert negative value to table with bitmap_union MV will cause count distinct result incorrect (#13700) cherry-pick #13667 #13448 --- be/src/exprs/bitmap_function.cpp | 24 ++++++++++ be/src/exprs/bitmap_function.h | 5 +- be/src/olap/schema_change.cpp | 37 +++++++++------ be/src/vec/exec/vunion_node.cpp | 30 +++++++----- be/src/vec/functions/function.cpp | 5 +- .../vec/functions/function_always_not_nullable.h | 19 ++++++-- be/src/vec/functions/function_bitmap.cpp | 54 +++++++++++++++++++++- .../doris/analysis/CreateMaterializedViewStmt.java | 21 ++++++++- .../apache/doris/analysis/FunctionCallExpr.java | 4 ++ .../doris/analysis/MVColumnBitmapUnionPattern.java | 3 +- .../java/org/apache/doris/catalog/Function.java | 4 ++ .../java/org/apache/doris/catalog/FunctionSet.java | 1 + .../rewrite/mvrewrite/FunctionCallEqualRule.java | 1 + gensrc/script/doris_builtins_functions.py | 6 +++ 14 files changed, 175 insertions(+), 39 deletions(-) diff --git a/be/src/exprs/bitmap_function.cpp b/be/src/exprs/bitmap_function.cpp index 79e514bf6d..5a64a129ac 100644 --- a/be/src/exprs/bitmap_function.cpp +++ b/be/src/exprs/bitmap_function.cpp @@ -160,6 +160,30 @@ StringVal BitmapFunctions::to_bitmap(doris_udf::FunctionContext* ctx, return serialize(ctx, &bitmap); } +StringVal BitmapFunctions::to_bitmap_with_check(doris_udf::FunctionContext* ctx, + const doris_udf::StringVal& src) { + BitmapValue bitmap; + + if (!src.is_null) { + StringParser::ParseResult parse_result = StringParser::PARSE_SUCCESS; + uint64_t int_value = StringParser::string_to_unsigned_int<uint64_t>( + reinterpret_cast<char*>(src.ptr), src.len, &parse_result); + if (parse_result == StringParser::PARSE_SUCCESS) { + bitmap.add(int_value); + } else { + std::stringstream ss; + ss << "The input: " << src.to_string() + << " is not valid, to_bitmap only support bigint value from 0 to " + "18446744073709551615 currently, cannot load negative values to column with" + " to_bitmap MV on it."; + ctx->set_error(ss.str().c_str()); + return serialize(ctx, nullptr); + } + } + + return serialize(ctx, &bitmap); +} + StringVal BitmapFunctions::bitmap_hash(doris_udf::FunctionContext* ctx, const doris_udf::StringVal& src) { BitmapValue bitmap; diff --git a/be/src/exprs/bitmap_function.h b/be/src/exprs/bitmap_function.h index f2cee64823..79bb3aefe6 100644 --- a/be/src/exprs/bitmap_function.h +++ b/be/src/exprs/bitmap_function.h @@ -68,6 +68,7 @@ public: static StringVal bitmap_serialize(FunctionContext* ctx, const StringVal& src); static StringVal to_bitmap(FunctionContext* ctx, const StringVal& src); + static StringVal to_bitmap_with_check(FunctionContext* ctx, const StringVal& src); static StringVal bitmap_hash(FunctionContext* ctx, const StringVal& src); static StringVal bitmap_or(FunctionContext* ctx, const StringVal& src, const StringVal& dst); static StringVal bitmap_xor(FunctionContext* ctx, const StringVal& src, const StringVal& dst); @@ -87,9 +88,9 @@ public: static BigIntVal bitmap_or_count(FunctionContext* ctx, const StringVal& lhs, int num_args, const StringVal* bitmap_strs); static BigIntVal bitmap_and_count(FunctionContext* ctx, const StringVal& lhs, int num_args, - const StringVal* bitmap_strs); + const StringVal* bitmap_strs); static BigIntVal bitmap_xor_count(FunctionContext* ctx, const StringVal& lhs, int num_args, - const StringVal* bitmap_strs); + const StringVal* bitmap_strs); static StringVal bitmap_to_string(FunctionContext* ctx, const StringVal& input); // Convert a comma separated string to a Bitmap diff --git a/be/src/olap/schema_change.cpp b/be/src/olap/schema_change.cpp index 2a7b66c10e..799a0ccdf7 100644 --- a/be/src/olap/schema_change.cpp +++ b/be/src/olap/schema_change.cpp @@ -303,9 +303,11 @@ bool to_bitmap(RowCursor* read_helper, RowCursor* write_helper, const TabletColu switch (ref_column.type()) { case OLAP_FIELD_TYPE_TINYINT: if (*(int8_t*)src < 0) { - LOG(WARNING) << "The input: " << *(int8_t*)src - << " is not valid, to_bitmap only support bigint value from 0 to " - "18446744073709551615 currently"; + LOG(WARNING) + << "The input: " << *(int8_t*)src + << " is not valid, to_bitmap only support bigint value from 0 to " + "18446744073709551615 currently, cannot create MV with to_bitmap on " + "column with negative values."; return false; } origin_value = *(int8_t*)src; @@ -315,9 +317,11 @@ bool to_bitmap(RowCursor* read_helper, RowCursor* write_helper, const TabletColu break; case OLAP_FIELD_TYPE_SMALLINT: if (*(int16_t*)src < 0) { - LOG(WARNING) << "The input: " << *(int16_t*)src - << " is not valid, to_bitmap only support bigint value from 0 to " - "18446744073709551615 currently"; + LOG(WARNING) + << "The input: " << *(int16_t*)src + << " is not valid, to_bitmap only support bigint value from 0 to " + "18446744073709551615 currently, cannot create MV with to_bitmap on " + "column with negative values."; return false; } origin_value = *(int16_t*)src; @@ -327,9 +331,11 @@ bool to_bitmap(RowCursor* read_helper, RowCursor* write_helper, const TabletColu break; case OLAP_FIELD_TYPE_INT: if (*(int32_t*)src < 0) { - LOG(WARNING) << "The input: " << *(int32_t*)src - << " is not valid, to_bitmap only support bigint value from 0 to " - "18446744073709551615 currently"; + LOG(WARNING) + << "The input: " << *(int32_t*)src + << " is not valid, to_bitmap only support bigint value from 0 to " + "18446744073709551615 currently, cannot create MV with to_bitmap on " + "column with negative values."; return false; } origin_value = *(int32_t*)src; @@ -339,9 +345,11 @@ bool to_bitmap(RowCursor* read_helper, RowCursor* write_helper, const TabletColu break; case OLAP_FIELD_TYPE_BIGINT: if (*(int64_t*)src < 0) { - LOG(WARNING) << "The input: " << *(int64_t*)src - << " is not valid, to_bitmap only support bigint value from 0 to " - "18446744073709551615 currently"; + LOG(WARNING) + << "The input: " << *(int64_t*)src + << " is not valid, to_bitmap only support bigint value from 0 to " + "18446744073709551615 currently, cannot create MV with to_bitmap on " + "column with negative values."; return false; } origin_value = *(int64_t*)src; @@ -501,8 +509,9 @@ OLAPStatus RowBlockChanger::change_row_block(const RowBlock* ref_block, int32_t if (_schema_mapping[i].ref_column >= 0) { if (!_schema_mapping[i].materialized_function.empty()) { bool (*_do_materialized_transform)(RowCursor*, RowCursor*, const TabletColumn&, int, - int, MemPool*); - if (_schema_mapping[i].materialized_function == "to_bitmap") { + int, MemPool*) = nullptr; + if (_schema_mapping[i].materialized_function == "to_bitmap" || + _schema_mapping[i].materialized_function == "to_bitmap_with_check") { _do_materialized_transform = to_bitmap; } else if (_schema_mapping[i].materialized_function == "hll_hash") { _do_materialized_transform = hll_hash; diff --git a/be/src/vec/exec/vunion_node.cpp b/be/src/vec/exec/vunion_node.cpp index 5f1bfefa17..75d4ea4182 100644 --- a/be/src/vec/exec/vunion_node.cpp +++ b/be/src/vec/exec/vunion_node.cpp @@ -20,7 +20,6 @@ #include "gen_cpp/PlanNodes_types.h" #include "runtime/runtime_state.h" #include "util/runtime_profile.h" - #include "vec/core/block.h" #include "vec/exprs/vexpr.h" #include "vec/exprs/vexpr_context.h" @@ -125,8 +124,10 @@ Status VUnionNode::get_next_materialized(RuntimeState* state, Block* block) { DCHECK_LT(_child_idx, _children.size()); bool mem_reuse = block->mem_reuse(); - MutableBlock mblock = mem_reuse ? MutableBlock::build_mutable_block(block) : - MutableBlock(Block(VectorizedUtils::create_columns_with_type_and_name(row_desc()))); + MutableBlock mblock = + mem_reuse ? MutableBlock::build_mutable_block(block) + : MutableBlock(Block( + VectorizedUtils::create_columns_with_type_and_name(row_desc()))); Block child_block; while (has_more_materialized() && mblock.rows() <= state->batch_size()) { @@ -157,9 +158,9 @@ Status VUnionNode::get_next_materialized(RuntimeState* state, Block* block) { // Unless we are inside a subplan expecting to call open()/get_next() on the child // again, the child can be closed at this point. // TODO: Recheck whether is_in_subplan() is right -// if (!is_in_subplan()) { -// child(_child_idx)->close(state); -// } + // if (!is_in_subplan()) { + // child(_child_idx)->close(state); + // } ++_child_idx; } } @@ -177,19 +178,24 @@ Status VUnionNode::get_next_const(RuntimeState* state, Block* block) { DCHECK_LT(_const_expr_list_idx, _const_expr_lists.size()); bool mem_reuse = block->mem_reuse(); - MutableBlock mblock = mem_reuse ? MutableBlock::build_mutable_block(block) : - MutableBlock(Block(VectorizedUtils::create_columns_with_type_and_name(row_desc()))); + MutableBlock mblock = + mem_reuse ? MutableBlock::build_mutable_block(block) + : MutableBlock(Block( + VectorizedUtils::create_columns_with_type_and_name(row_desc()))); for (; _const_expr_list_idx < _const_expr_lists.size(); ++_const_expr_list_idx) { Block tmp_block; tmp_block.insert({vectorized::ColumnUInt8::create(1), - std::make_shared<vectorized::DataTypeUInt8>(), ""}); + std::make_shared<vectorized::DataTypeUInt8>(), ""}); int const_expr_lists_size = _const_expr_lists[_const_expr_list_idx].size(); std::vector<int> result_list(const_expr_lists_size); for (size_t i = 0; i < const_expr_lists_size; ++i) { - _const_expr_lists[_const_expr_list_idx][i]->execute(&tmp_block, &result_list[i]); + RETURN_IF_ERROR(_const_expr_lists[_const_expr_list_idx][i]->execute(&tmp_block, + &result_list[i])); } tmp_block.erase_not_in(result_list); - mblock.merge(tmp_block); + if (tmp_block.rows() > 0) { + mblock.merge(tmp_block); + } } if (!mem_reuse) { @@ -201,7 +207,7 @@ Status VUnionNode::get_next_const(RuntimeState* state, Block* block) { // need add one row to make sure the union node exec const expr return at least one row if (block->rows() == 0) { block->insert({vectorized::ColumnUInt8::create(1), - std::make_shared<vectorized::DataTypeUInt8>(), ""}); + std::make_shared<vectorized::DataTypeUInt8>(), ""}); } return Status::OK(); diff --git a/be/src/vec/functions/function.cpp b/be/src/vec/functions/function.cpp index 5c671284a4..231e621fe7 100644 --- a/be/src/vec/functions/function.cpp +++ b/be/src/vec/functions/function.cpp @@ -269,9 +269,8 @@ Status PreparedFunctionImpl::execute(FunctionContext* context, Block& block, // res.column = block_without_low_cardinality.safe_get_by_position(result).column; // } // } else - execute_without_low_cardinality_columns(context, block, args, result, input_rows_count, - dry_run); - return Status::OK(); + return execute_without_low_cardinality_columns(context, block, args, result, input_rows_count, + dry_run); } void FunctionBuilderImpl::check_number_of_arguments(size_t number_of_arguments) const { diff --git a/be/src/vec/functions/function_always_not_nullable.h b/be/src/vec/functions/function_always_not_nullable.h index 76b2b2a600..e7802ca9b4 100644 --- a/be/src/vec/functions/function_always_not_nullable.h +++ b/be/src/vec/functions/function_always_not_nullable.h @@ -24,7 +24,7 @@ namespace doris::vectorized { -template <typename Function> +template <typename Function, bool WithReturn = false> class FunctionAlwaysNotNullable : public IFunction { public: static constexpr auto name = Function::name; @@ -57,14 +57,25 @@ public: col_nullable->get_null_map_column_ptr().get()); if (col != nullptr && col_nullmap != nullptr) { - Function::vector_nullable(col->get_chars(), col->get_offsets(), - col_nullmap->get_data(), column_result); + if constexpr (WithReturn) { + RETURN_IF_ERROR(Function::vector_nullable(col->get_chars(), col->get_offsets(), + col_nullmap->get_data(), + column_result)); + } else { + Function::vector_nullable(col->get_chars(), col->get_offsets(), + col_nullmap->get_data(), column_result); + } block.replace_by_position(result, std::move(column_result)); return Status::OK(); } } else if (const ColumnString* col = check_and_get_column<ColumnString>(column.get())) { - Function::vector(col->get_chars(), col->get_offsets(), column_result); + if constexpr (WithReturn) { + RETURN_IF_ERROR( + Function::vector(col->get_chars(), col->get_offsets(), column_result)); + } else { + Function::vector(col->get_chars(), col->get_offsets(), column_result); + } block.replace_by_position(result, std::move(column_result)); return Status::OK(); diff --git a/be/src/vec/functions/function_bitmap.cpp b/be/src/vec/functions/function_bitmap.cpp index 69b5bd6737..a49daeff6e 100644 --- a/be/src/vec/functions/function_bitmap.cpp +++ b/be/src/vec/functions/function_bitmap.cpp @@ -21,12 +21,12 @@ #include "gutil/strings/numbers.h" #include "gutil/strings/split.h" #include "util/string_parser.hpp" +#include "vec/functions/function_always_not_nullable.h" #include "vec/functions/function_bitmap_min_or_max.h" #include "vec/functions/function_const.h" #include "vec/functions/function_string.h" #include "vec/functions/function_totype.h" #include "vec/functions/simple_function_factory.h" -#include "vec/functions/function_always_not_nullable.h" namespace doris::vectorized { @@ -75,6 +75,54 @@ struct ToBitmap { } }; +struct ToBitmapWithCheck { + static constexpr auto name = "to_bitmap_with_check"; + using ReturnType = DataTypeBitMap; + + static Status vector(const ColumnString::Chars& data, const ColumnString::Offsets& offsets, + MutableColumnPtr& col_res) { + return execute<false>(data, offsets, nullptr, col_res); + } + + static Status vector_nullable(const ColumnString::Chars& data, + const ColumnString::Offsets& offsets, const NullMap& nullmap, + MutableColumnPtr& col_res) { + return execute<true>(data, offsets, &nullmap, col_res); + } + template <bool arg_is_nullable> + static Status execute(const ColumnString::Chars& data, const ColumnString::Offsets& offsets, + const NullMap* nullmap, MutableColumnPtr& col_res) { + auto* res_column = reinterpret_cast<ColumnBitmap*>(col_res.get()); + auto& res_data = res_column->get_data(); + size_t size = offsets.size(); + + for (size_t i = 0; i < size; ++i) { + if (arg_is_nullable && ((*nullmap)[i])) { + continue; + } else { + const char* raw_str = reinterpret_cast<const char*>(&data[offsets[i - 1]]); + size_t str_size = offsets[i] - offsets[i - 1] - 1; + StringParser::ParseResult parse_result = StringParser::PARSE_SUCCESS; + uint64_t int_value = StringParser::string_to_unsigned_int<uint64_t>( + raw_str, str_size, &parse_result); + if (LIKELY(parse_result == StringParser::PARSE_SUCCESS)) { + res_data[i].add(int_value); + } else { + std::stringstream ss; + ss << "The input: " << std::string(raw_str, str_size) + << " is not valid, to_bitmap only support bigint value from 0 to " + "18446744073709551615 currently, cannot create MV with to_bitmap on " + "column with negative values or cannot load negative values to column " + "with to_bitmap MV on it."; + LOG(WARNING) << ss.str(); + return Status::InternalError(ss.str()); + } + } + } + return Status::OK(); + } +}; + struct BitmapFromString { static constexpr auto name = "bitmap_from_string"; @@ -155,7 +203,7 @@ struct BitmapHash { const char* raw_str = reinterpret_cast<const char*>(&data[offsets[i - 1]]); size_t str_size = offsets[i] - offsets[i - 1] - 1; uint32_t hash_value = - HashUtil::murmur_hash3_32(raw_str, str_size, HashUtil::MURMUR3_32_SEED); + HashUtil::murmur_hash3_32(raw_str, str_size, HashUtil::MURMUR3_32_SEED); res_data[i].add(hash_value); } } @@ -510,6 +558,7 @@ public: using FunctionBitmapEmpty = FunctionConst<BitmapEmpty, false>; using FunctionToBitmap = FunctionAlwaysNotNullable<ToBitmap>; +using FunctionToBitmapWithCheck = FunctionAlwaysNotNullable<ToBitmapWithCheck, true>; using FunctionBitmapFromString = FunctionBitmapAlwaysNull<BitmapFromString>; using FunctionBitmapHash = FunctionAlwaysNotNullable<BitmapHash>; @@ -537,6 +586,7 @@ using FunctionBitmapSubsetInRange = FunctionBitmapSubs<BitmapSubsetInRange>; void register_function_bitmap(SimpleFunctionFactory& factory) { factory.register_function<FunctionBitmapEmpty>(); factory.register_function<FunctionToBitmap>(); + factory.register_function<FunctionToBitmapWithCheck>(); factory.register_function<FunctionBitmapFromString>(); factory.register_function<FunctionBitmapHash>(); factory.register_function<FunctionBitmapCount>(); diff --git a/fe/fe-core/src/main/java/org/apache/doris/analysis/CreateMaterializedViewStmt.java b/fe/fe-core/src/main/java/org/apache/doris/analysis/CreateMaterializedViewStmt.java index b8125417ee..1e5a590c9d 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/analysis/CreateMaterializedViewStmt.java +++ b/fe/fe-core/src/main/java/org/apache/doris/analysis/CreateMaterializedViewStmt.java @@ -206,6 +206,25 @@ public class CreateMaterializedViewStmt extends DdlStmt { throw new AnalysisException( "The function " + functionName + " must match pattern:" + mvColumnPattern.toString()); } + + // for bitmap_union(to_bitmap(column)) function, we should check value is not negative + // in vectorized schema_change mode, so we should rewrite the function to + // bitmap_union(to_bitmap_with_check(column)) + if (functionName.equalsIgnoreCase("bitmap_union")) { + if (functionCallExpr.getChildren().size() == 1 + && functionCallExpr.getChild(0) instanceof FunctionCallExpr) { + Expr child = functionCallExpr.getChild(0); + FunctionCallExpr childFunctionCallExpr = (FunctionCallExpr) child; + if (childFunctionCallExpr.getFnName().getFunction().equalsIgnoreCase("to_bitmap")) { + childFunctionCallExpr.setFnName( + new FunctionName(childFunctionCallExpr.getFnName().getDb(), + "to_bitmap_with_check")); + childFunctionCallExpr.getFn().setName( + new FunctionName(childFunctionCallExpr.getFn().getFunctionName().getDb(), + "to_bitmap_with_check")); + } + } + } } // check duplicate column List<SlotRef> slots = new ArrayList<>(); @@ -444,7 +463,7 @@ public class CreateMaterializedViewStmt extends DdlStmt { CastExpr castExpr = new CastExpr(new TypeDef(Type.VARCHAR), baseSlotRef); List<Expr> params = Lists.newArrayList(); params.add(castExpr); - FunctionCallExpr defineExpr = new FunctionCallExpr(FunctionSet.TO_BITMAP, params); + FunctionCallExpr defineExpr = new FunctionCallExpr(FunctionSet.TO_BITMAP_WITH_CHECK, params); result.put(mvColumnBuilder(functionName, baseColumnName), defineExpr); } else { result.put(baseColumnName, null); diff --git a/fe/fe-core/src/main/java/org/apache/doris/analysis/FunctionCallExpr.java b/fe/fe-core/src/main/java/org/apache/doris/analysis/FunctionCallExpr.java index e249589f92..ff1551234c 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/analysis/FunctionCallExpr.java +++ b/fe/fe-core/src/main/java/org/apache/doris/analysis/FunctionCallExpr.java @@ -104,6 +104,10 @@ public class FunctionCallExpr extends Expr { isTableFnCall = tableFnCall; } + public void setFnName(FunctionName fnName) { + this.fnName = fnName; + } + public Function getFn() { return fn; } diff --git a/fe/fe-core/src/main/java/org/apache/doris/analysis/MVColumnBitmapUnionPattern.java b/fe/fe-core/src/main/java/org/apache/doris/analysis/MVColumnBitmapUnionPattern.java index 45bf9948f8..d7712eda73 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/analysis/MVColumnBitmapUnionPattern.java +++ b/fe/fe-core/src/main/java/org/apache/doris/analysis/MVColumnBitmapUnionPattern.java @@ -44,7 +44,8 @@ public class MVColumnBitmapUnionPattern implements MVColumnPattern { } } else if (fnExpr.getChild(0) instanceof FunctionCallExpr) { FunctionCallExpr child0FnExpr = (FunctionCallExpr) fnExpr.getChild(0); - if (!child0FnExpr.getFnName().getFunction().equalsIgnoreCase(FunctionSet.TO_BITMAP)) { + if (!child0FnExpr.getFnName().getFunction().equalsIgnoreCase(FunctionSet.TO_BITMAP) + && !child0FnExpr.getFnName().getFunction().equalsIgnoreCase(FunctionSet.TO_BITMAP_WITH_CHECK)) { return false; } SlotRef slotRef = child0FnExpr.getChild(0).unwrapSlotRef(); diff --git a/fe/fe-core/src/main/java/org/apache/doris/catalog/Function.java b/fe/fe-core/src/main/java/org/apache/doris/catalog/Function.java index bfc29d7dc2..abfab2e349 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/catalog/Function.java +++ b/fe/fe-core/src/main/java/org/apache/doris/catalog/Function.java @@ -199,6 +199,10 @@ public class Function implements Writable { location = loc; } + public void setName(FunctionName name) { + this.name = name; + } + public TFunctionBinaryType getBinaryType() { return binaryType; } diff --git a/fe/fe-core/src/main/java/org/apache/doris/catalog/FunctionSet.java b/fe/fe-core/src/main/java/org/apache/doris/catalog/FunctionSet.java index d040f46715..aa9020303a 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/catalog/FunctionSet.java +++ b/fe/fe-core/src/main/java/org/apache/doris/catalog/FunctionSet.java @@ -839,6 +839,7 @@ public class FunctionSet<min_initIN9doris_udf12DecimalV2ValEEEvPNS2_15FunctionCo .build(); public static final String TO_BITMAP = "to_bitmap"; + public static final String TO_BITMAP_WITH_CHECK = "to_bitmap_with_check"; public static final String BITMAP_UNION = "bitmap_union"; public static final String BITMAP_UNION_COUNT = "bitmap_union_count"; public static final String BITMAP_UNION_INT = "bitmap_union_int"; diff --git a/fe/fe-core/src/main/java/org/apache/doris/rewrite/mvrewrite/FunctionCallEqualRule.java b/fe/fe-core/src/main/java/org/apache/doris/rewrite/mvrewrite/FunctionCallEqualRule.java index aee0871851..4e9005f339 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/rewrite/mvrewrite/FunctionCallEqualRule.java +++ b/fe/fe-core/src/main/java/org/apache/doris/rewrite/mvrewrite/FunctionCallEqualRule.java @@ -41,6 +41,7 @@ public class FunctionCallEqualRule implements MVExprEqualRule { builder.put(FunctionSet.HLL_UNION, "hll_union"); builder.put(FunctionSet.HLL_UNION, "hll_raw_agg"); builder.put(FunctionSet.TO_BITMAP, FunctionSet.TO_BITMAP); + builder.put(FunctionSet.TO_BITMAP_WITH_CHECK, FunctionSet.TO_BITMAP_WITH_CHECK); builder.put(FunctionSet.HLL_HASH, FunctionSet.HLL_HASH); columnAggTypeMatchFnName = builder.build(); } diff --git a/gensrc/script/doris_builtins_functions.py b/gensrc/script/doris_builtins_functions.py index 2c44b50737..b758c00ead 100755 --- a/gensrc/script/doris_builtins_functions.py +++ b/gensrc/script/doris_builtins_functions.py @@ -1138,12 +1138,18 @@ visible_functions = [ [['to_bitmap'], 'BITMAP', ['VARCHAR'], '_ZN5doris15BitmapFunctions9to_bitmapEPN9doris_udf15FunctionContextERKNS1_9StringValE', '', '', 'vec', 'ALWAYS_NOT_NULLABLE'], + [['to_bitmap_with_check'], 'BITMAP', ['VARCHAR'], + '_ZN5doris15BitmapFunctions20to_bitmap_with_checkEPN9doris_udf15FunctionContextERKNS1_9StringValE', + '', '', 'vec', 'ALWAYS_NOT_NULLABLE'], [['bitmap_hash'], 'BITMAP', ['VARCHAR'], '_ZN5doris15BitmapFunctions11bitmap_hashEPN9doris_udf15FunctionContextERKNS1_9StringValE', '', '', 'vec', 'ALWAYS_NOT_NULLABLE'], [['to_bitmap'], 'BITMAP', ['STRING'], '_ZN5doris15BitmapFunctions9to_bitmapEPN9doris_udf15FunctionContextERKNS1_9StringValE', '', '', 'vec', 'ALWAYS_NOT_NULLABLE'], + [['to_bitmap_with_check'], 'BITMAP', ['STRING'], + '_ZN5doris15BitmapFunctions20to_bitmap_with_checkEPN9doris_udf15FunctionContextERKNS1_9StringValE', + '', '', 'vec', 'ALWAYS_NOT_NULLABLE'], [['bitmap_hash'], 'BITMAP', ['STRING'], '_ZN5doris15BitmapFunctions11bitmap_hashEPN9doris_udf15FunctionContextERKNS1_9StringValE', '', '', 'vec', 'ALWAYS_NOT_NULLABLE'], --------------------------------------------------------------------- To unsubscribe, e-mail: commits-unsubscr...@doris.apache.org For additional commands, e-mail: commits-h...@doris.apache.org