diff --git a/be/src/exprs/bitmap_function.cpp b/be/src/exprs/bitmap_function.cpp index 4868c974bf..80c91f5da7 100644 --- a/be/src/exprs/bitmap_function.cpp +++ b/be/src/exprs/bitmap_function.cpp @@ -465,6 +465,41 @@ StringVal BitmapFunctions::bitmap_from_string(FunctionContext* ctx, const String return result; } +BooleanVal BitmapFunctions::bitmap_contains(FunctionContext* ctx, const StringVal& src, const BigIntVal& input) { + if (src.is_null || input.is_null) { + return BooleanVal::null(); + } + + if (src.len == 0) { + auto bitmap = reinterpret_cast(src.ptr); + return {bitmap->contains(input.val)}; + } + + RoaringBitmap bitmap ((char*)src.ptr); + return {bitmap.contains(input.val)}; +} + +BooleanVal BitmapFunctions::bitmap_has_any(FunctionContext* ctx, const StringVal& lhs, const StringVal& rhs) { + if (lhs.is_null || rhs.is_null) { + return BooleanVal::null(); + } + + RoaringBitmap bitmap; + if (lhs.len == 0) { + bitmap.merge(*reinterpret_cast(lhs.ptr)); + } else { + bitmap.merge(RoaringBitmap((char*)lhs.ptr)); + } + + if (rhs.len == 0) { + bitmap.intersect(*reinterpret_cast(rhs.ptr)); + } else { + bitmap.intersect(RoaringBitmap((char*)rhs.ptr)); + } + + return {bitmap.cardinality() != 0}; +} + template void BitmapFunctions::bitmap_update_int( FunctionContext* ctx, const TinyIntVal& src, StringVal* dst); template void BitmapFunctions::bitmap_update_int( diff --git a/be/src/exprs/bitmap_function.h b/be/src/exprs/bitmap_function.h index bf00ba259b..5d1f6ce2b9 100644 --- a/be/src/exprs/bitmap_function.h +++ b/be/src/exprs/bitmap_function.h @@ -57,11 +57,13 @@ public: static StringVal bitmap_and(FunctionContext* ctx, const StringVal& src,const StringVal& dst); static StringVal bitmap_to_string(FunctionContext* ctx, const StringVal& input); // Convert a comma separated string to a Bitmap - // Example: + // Example: // "" will be converted to an empty Bitmap // "1,2,3" will be converted to Bitmap with its Bit 1, 2, 3 set. // "-1, 1" will get NULL, because -1 is not a valid bit for Bitmap static StringVal bitmap_from_string(FunctionContext* ctx, const StringVal& input); + static BooleanVal bitmap_contains(FunctionContext* ctx, const StringVal& src, const BigIntVal& input); + static BooleanVal bitmap_has_any(FunctionContext* ctx, const StringVal& lhs, const StringVal& rhs); // bitmap_intersect template diff --git a/be/test/exprs/bitmap_function_test.cpp b/be/test/exprs/bitmap_function_test.cpp index dd33a22a88..0fbed06cc7 100644 --- a/be/test/exprs/bitmap_function_test.cpp +++ b/be/test/exprs/bitmap_function_test.cpp @@ -280,6 +280,38 @@ TEST_F(BitmapFunctionsTest,bitmap_and) { BigIntVal expected(1); ASSERT_EQ(expected, result); } +TEST_F(BitmapFunctionsTest,bitmap_contains) { + RoaringBitmap bitmap(4); + bitmap.update(5); + StringVal bitmap_str = convert_bitmap_to_string(ctx,bitmap); + BooleanVal result = BitmapFunctions::bitmap_contains(ctx,bitmap_str,5); + BooleanVal expected(true); + ASSERT_EQ(expected,result); + + BooleanVal result2 = BitmapFunctions::bitmap_contains(ctx,bitmap_str,10); + BooleanVal expected2(false); + ASSERT_EQ(expected2,result2); +} + +TEST_F(BitmapFunctionsTest,bitmap_has_any) { + RoaringBitmap bitmap1(4); + bitmap1.update(5); + + RoaringBitmap bitmap2(4); + bitmap2.update(5); + + StringVal lhs = convert_bitmap_to_string(ctx,bitmap1); + StringVal rhs = convert_bitmap_to_string(ctx,bitmap2); + BooleanVal result = BitmapFunctions::bitmap_has_any(ctx,lhs,rhs); + BooleanVal expected(true); + ASSERT_EQ(expected,result); + + RoaringBitmap bitmap3(10); + StringVal r3 = convert_bitmap_to_string(ctx,bitmap3); + BooleanVal result1 = BitmapFunctions::bitmap_has_any(ctx,lhs,r3); + BooleanVal expected2(false); + ASSERT_EQ(expected2,result1); +} } diff --git a/docs/documentation/cn/sql-reference/sql-functions/bitmap-functions/bitmap_contains.md b/docs/documentation/cn/sql-reference/sql-functions/bitmap-functions/bitmap_contains.md new file mode 100644 index 0000000000..ed10b6bd17 --- /dev/null +++ b/docs/documentation/cn/sql-reference/sql-functions/bitmap-functions/bitmap_contains.md @@ -0,0 +1,48 @@ + + +# bitmap_contains +## description +### Syntax + +`B00LEAN BITMAP_CONTAINS(BITMAP bitmap, BIGINT input)` + +计算输入值是否在Bitmap列中,返回值是Boolean值. + +## example + +``` +mysql> select bitmap_contains(to_bitmap(1),2) cnt; ++------+ +| cnt | ++------+ +| 0 | ++------+ + +mysql> select bitmap_contains(to_bitmap(1),1) cnt; ++------+ +| cnt | ++------+ +| 1 | ++------+ +``` + +## keyword + + BITMAP_CONTAINS,BITMAP diff --git a/docs/documentation/cn/sql-reference/sql-functions/bitmap-functions/bitmap_has_any.md b/docs/documentation/cn/sql-reference/sql-functions/bitmap-functions/bitmap_has_any.md new file mode 100644 index 0000000000..7482107255 --- /dev/null +++ b/docs/documentation/cn/sql-reference/sql-functions/bitmap-functions/bitmap_has_any.md @@ -0,0 +1,48 @@ + + +# bitmap_has_any +## description +### Syntax + +`B00LEAN BITMAP_HAS_ANY(BITMAP lhs, BITMAP rhs)` + +计算两个Bitmap列是否存在相交元素,返回值是Boolean值. + +## example + +``` +mysql> select bitmap_has_any(to_bitmap(1),to_bitmap(2)) cnt; ++------+ +| cnt | ++------+ +| 0 | ++------+ + +mysql> select bitmap_has_any(to_bitmap(1),to_bitmap(1)) cnt; ++------+ +| cnt | ++------+ +| 1 | ++------+ +``` + +## keyword + + BITMAP_HAS_ANY,BITMAP diff --git a/docs/documentation/en/sql-reference/sql-functions/bitmap-functions/bitmap_contains_EN.md b/docs/documentation/en/sql-reference/sql-functions/bitmap-functions/bitmap_contains_EN.md new file mode 100644 index 0000000000..0cb2e06ad5 --- /dev/null +++ b/docs/documentation/en/sql-reference/sql-functions/bitmap-functions/bitmap_contains_EN.md @@ -0,0 +1,48 @@ + + +# bitmap_contains +## description +### Syntax + +`B00LEAN BITMAP_CONTAINS(BITMAP bitmap, BIGINT input)` + +Calculates whether the input value is in the Bitmap column and returns a Boolean value. + +## example + +``` +mysql> select bitmap_contains(to_bitmap(1),2) cnt; ++------+ +| cnt | ++------+ +| 0 | ++------+ + +mysql> select bitmap_contains(to_bitmap(1),1) cnt; ++------+ +| cnt | ++------+ +| 1 | ++------+ +``` + +## keyword + + BITMAP_CONTAINS,BITMAP diff --git a/docs/documentation/en/sql-reference/sql-functions/bitmap-functions/bitmap_has_any_EN.md b/docs/documentation/en/sql-reference/sql-functions/bitmap-functions/bitmap_has_any_EN.md new file mode 100644 index 0000000000..fc253d6097 --- /dev/null +++ b/docs/documentation/en/sql-reference/sql-functions/bitmap-functions/bitmap_has_any_EN.md @@ -0,0 +1,48 @@ + + +# bitmap_has_any +## description +### Syntax + +`B00LEAN BITMAP_HAS_ANY(BITMAP lhs, BITMAP rhs)` + +Calculate whether there are intersecting elements in the two Bitmap columns. The return value is Boolean. + +## example + +``` +mysql> select bitmap_has_any(to_bitmap(1),to_bitmap(2)) cnt; ++------+ +| cnt | ++------+ +| 0 | ++------+ + +mysql> select bitmap_has_any(to_bitmap(1),to_bitmap(1)) cnt; ++------+ +| cnt | ++------+ +| 1 | ++------+ +``` + +## keyword + + BITMAP_HAS_ANY,BITMAP diff --git a/gensrc/script/doris_builtins_functions.py b/gensrc/script/doris_builtins_functions.py index 25a6462267..0e9bbf2a96 100755 --- a/gensrc/script/doris_builtins_functions.py +++ b/gensrc/script/doris_builtins_functions.py @@ -620,6 +620,10 @@ visible_functions = [ '_ZN5doris15BitmapFunctions16bitmap_to_stringEPN9doris_udf15FunctionContextERKNS1_9StringValE'], [['bitmap_from_string'], 'BITMAP', ['VARCHAR'], '_ZN5doris15BitmapFunctions18bitmap_from_stringEPN9doris_udf15FunctionContextERKNS1_9StringValE'], + [['bitmap_contains'], 'BOOLEAN', ['BITMAP','BIGINT'], + '_ZN5doris15BitmapFunctions15bitmap_containsEPN9doris_udf15FunctionContextERKNS1_9StringValERKNS1_9BigIntValE'], + [['bitmap_has_any'], 'BOOLEAN', ['BITMAP','BITMAP'], + '_ZN5doris15BitmapFunctions14bitmap_has_anyEPN9doris_udf15FunctionContextERKNS1_9StringValES6_'], # hash functions [['murmur_hash3_32'], 'INT', ['VARCHAR', '...'],