You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@doris.apache.org by mo...@apache.org on 2022/10/27 00:58:51 UTC
[doris] branch branch-1.1-lts updated: [fix](MV) Fix insert negative value to table with bitmap_union MV will cause count distinct result incorrect (#13700)
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 <ya...@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-unsubscribe@doris.apache.org
For additional commands, e-mail: commits-help@doris.apache.org