diff --git a/be/src/exprs/bitmap_function.cpp b/be/src/exprs/bitmap_function.cpp index 7051eb0e24..f2576641e5 100644 --- a/be/src/exprs/bitmap_function.cpp +++ b/be/src/exprs/bitmap_function.cpp @@ -607,6 +607,24 @@ BooleanVal BitmapFunctions::bitmap_has_any(FunctionContext* ctx, const StringVal return {bitmap.cardinality() != 0}; } +BooleanVal BitmapFunctions::bitmap_has_all(FunctionContext *ctx, const StringVal &lhs, + const StringVal &rhs) { + if (lhs.is_null || rhs.is_null) { + return BooleanVal::null(); + } + + if (lhs.len != 0 && rhs.len != 0) { + BitmapValue bitmap = BitmapValue(reinterpret_cast(lhs.ptr)); + int64_t lhs_cardinality = bitmap.cardinality(); + bitmap |= BitmapValue(reinterpret_cast(rhs.ptr)); + return {bitmap.cardinality() == lhs_cardinality}; + } else if (rhs.len != 0) { + return {false}; + } else { + return {true}; + } +} + BigIntVal BitmapFunctions::bitmap_max(FunctionContext* ctx, const StringVal& src) { if (src.is_null) { return BigIntVal::null(); diff --git a/be/src/exprs/bitmap_function.h b/be/src/exprs/bitmap_function.h index 0679bab841..9c4f155b08 100644 --- a/be/src/exprs/bitmap_function.h +++ b/be/src/exprs/bitmap_function.h @@ -80,6 +80,8 @@ public: const BigIntVal& input); static BooleanVal bitmap_has_any(FunctionContext* ctx, const StringVal& lhs, const StringVal& rhs); + static BooleanVal bitmap_has_all(FunctionContext* ctx, const StringVal& lhs, + const StringVal& rhs); // intersect count template diff --git a/be/test/exprs/bitmap_function_test.cpp b/be/test/exprs/bitmap_function_test.cpp index 2b6511fbf7..f734e9f690 100644 --- a/be/test/exprs/bitmap_function_test.cpp +++ b/be/test/exprs/bitmap_function_test.cpp @@ -504,6 +504,41 @@ TEST_F(BitmapFunctionsTest, bitmap_has_any) { ASSERT_EQ(expected2, result1); } +TEST_F(BitmapFunctionsTest, bitmap_has_all) { + BitmapValue bitmap1({1, 4, 5, std::numeric_limits::max(), std::numeric_limits::min()}); + BitmapValue bitmap2({4, std::numeric_limits::max(), std::numeric_limits::min()}); + StringVal string_val1 = convert_bitmap_to_string(ctx, bitmap1); + StringVal string_val2 = convert_bitmap_to_string(ctx, bitmap2); + BooleanVal result = BitmapFunctions::bitmap_has_all(ctx, string_val1, string_val2); + ASSERT_EQ(BooleanVal{true}, result); + + bitmap1 = BitmapValue({0, 1, 2}); + bitmap2 = BitmapValue({0, 1, 2, std::numeric_limits::max()}); + string_val1 = convert_bitmap_to_string(ctx, bitmap1); + string_val2 = convert_bitmap_to_string(ctx, bitmap2); + result = BitmapFunctions::bitmap_has_all(ctx, string_val1, string_val2); + ASSERT_EQ(BooleanVal{false}, result); + + bitmap1 = BitmapValue(); + bitmap2 = BitmapValue({0, 1, 2}); + string_val1 = convert_bitmap_to_string(ctx, bitmap1); + string_val2 = convert_bitmap_to_string(ctx, bitmap2); + result = BitmapFunctions::bitmap_has_all(ctx, string_val1, string_val2); + ASSERT_EQ(BooleanVal{false}, result); + + bitmap1 = BitmapValue(); + bitmap2 = BitmapValue(); + string_val1 = convert_bitmap_to_string(ctx, bitmap1); + string_val2 = convert_bitmap_to_string(ctx, bitmap2); + result = BitmapFunctions::bitmap_has_all(ctx, string_val1, string_val2); + ASSERT_EQ(BooleanVal{true}, result); + + bitmap1 = BitmapValue(); + string_val1 = convert_bitmap_to_string(ctx, bitmap1); + result = BitmapFunctions::bitmap_has_all(ctx, string_val1, StringVal::null()); + ASSERT_TRUE(result.is_null); +} + TEST_F(BitmapFunctionsTest, bitmap_from_string) { FunctionUtils utils; { diff --git a/docs/.vuepress/sidebar/en.js b/docs/.vuepress/sidebar/en.js index 158d3615e0..61120b1c4e 100644 --- a/docs/.vuepress/sidebar/en.js +++ b/docs/.vuepress/sidebar/en.js @@ -411,6 +411,7 @@ module.exports = [ "bitmap_empty", "bitmap_from_string", "bitmap_has_any", + "bitmap_has_all", "bitmap_hash", "bitmap_intersect", "bitmap_or", diff --git a/docs/.vuepress/sidebar/zh-CN.js b/docs/.vuepress/sidebar/zh-CN.js index 7f678ca4fd..99f858c9d0 100644 --- a/docs/.vuepress/sidebar/zh-CN.js +++ b/docs/.vuepress/sidebar/zh-CN.js @@ -415,6 +415,7 @@ module.exports = [ "bitmap_empty", "bitmap_from_string", "bitmap_has_any", + "bitmap_has_all", "bitmap_hash", "bitmap_intersect", "bitmap_or", diff --git a/docs/en/sql-reference/sql-functions/bitmap-functions/bitmap_has_all.md b/docs/en/sql-reference/sql-functions/bitmap-functions/bitmap_has_all.md new file mode 100644 index 0000000000..e8eb6e15f0 --- /dev/null +++ b/docs/en/sql-reference/sql-functions/bitmap-functions/bitmap_has_all.md @@ -0,0 +1,56 @@ +--- +{ + "title": "bitmap_has_all", + "language": "en" +} +--- + + + +# bitmap_has_all +## description +### Syntax + +`B00LEAN BITMAP_HAS_ALL(BITMAP lhs, BITMAP rhs)` + +Returns true if the first bitmap contains all the elements of the second bitmap. +Returns true if the second bitmap contains an empty element. + +## example + +``` +mysql> select bitmap_has_all(bitmap_from_string("0, 1, 2"), bitmap_from_string("1, 2")) cnt; ++------+ +| cnt | ++------+ +| 1 | ++------+ + +mysql> select bitmap_has_all(bitmap_empty(), bitmap_from_string("1, 2")) cnt; ++------+ +| cnt | ++------+ +| 0 | ++------+ +``` + +## keyword + + BITMAP_HAS_ALL,BITMAP diff --git a/docs/zh-CN/sql-reference/sql-functions/bitmap-functions/bitmap_has_all.md b/docs/zh-CN/sql-reference/sql-functions/bitmap-functions/bitmap_has_all.md new file mode 100644 index 0000000000..71ec5d8006 --- /dev/null +++ b/docs/zh-CN/sql-reference/sql-functions/bitmap-functions/bitmap_has_all.md @@ -0,0 +1,56 @@ +--- +{ + "title": "bitmap_has_all", + "language": "zh-CN" +} +--- + + + +# bitmap_has_all +## description +### Syntax + +`B00LEAN BITMAP_HAS_ALL(BITMAP lhs, BITMAP rhs)` + +如果第一个bitmap包含第二个bitmap的全部元素,则返回true。 +如果第二个bitmap包含的元素为空,返回true。 + +## example + +``` +mysql> select bitmap_has_all(bitmap_from_string("0, 1, 2"), bitmap_from_string("1, 2")) cnt; ++------+ +| cnt | ++------+ +| 1 | ++------+ + +mysql> select bitmap_has_all(bitmap_empty(), bitmap_from_string("1, 2")) cnt; ++------+ +| cnt | ++------+ +| 0 | ++------+ +``` + +## keyword + + BITMAP_HAS_ALL,BITMAP diff --git a/gensrc/script/doris_builtins_functions.py b/gensrc/script/doris_builtins_functions.py index 651ea96926..eb3270c6ab 100755 --- a/gensrc/script/doris_builtins_functions.py +++ b/gensrc/script/doris_builtins_functions.py @@ -1205,6 +1205,9 @@ visible_functions = [ [['bitmap_has_any'], 'BOOLEAN', ['BITMAP','BITMAP'], '_ZN5doris15BitmapFunctions14bitmap_has_anyEPN9doris_udf15FunctionContextERKNS1_9StringValES6_', '', '', 'vec', ''], + [['bitmap_has_all'], 'BOOLEAN', ['BITMAP','BITMAP'], + '_ZN5doris15BitmapFunctions14bitmap_has_allEPN9doris_udf15FunctionContextERKNS1_9StringValES6_', + '', '', 'vec', ''], [['bitmap_min'], 'BIGINT', ['BITMAP'], '_ZN5doris15BitmapFunctions10bitmap_minEPN9doris_udf15FunctionContextERKNS1_9StringValE', '', '', 'vec', ''],