diff --git a/be/src/exprs/bitmap_function.cpp b/be/src/exprs/bitmap_function.cpp index 76267bb0519b70..f0c0e6ff6dc0ce 100644 --- a/be/src/exprs/bitmap_function.cpp +++ b/be/src/exprs/bitmap_function.cpp @@ -477,6 +477,27 @@ StringVal BitmapFunctions::bitmap_and(FunctionContext* ctx, const StringVal& lhs return serialize(ctx, &bitmap); } +StringVal BitmapFunctions::bitmap_xor(FunctionContext* ctx, const StringVal& lhs, + const StringVal& rhs) { + if (lhs.is_null || rhs.is_null) { + return StringVal::null(); + } + BitmapValue bitmap; + if (lhs.len == 0) { + bitmap |= *reinterpret_cast(lhs.ptr); + } else { + bitmap |= BitmapValue((char*)lhs.ptr); + } + + if (rhs.len == 0) { + bitmap ^= *reinterpret_cast(rhs.ptr); + } else { + bitmap ^= BitmapValue((char*)rhs.ptr); + } + return serialize(ctx, &bitmap); +} + + StringVal BitmapFunctions::bitmap_to_string(FunctionContext* ctx, const StringVal& input) { if (input.is_null) { return StringVal::null(); diff --git a/be/src/exprs/bitmap_function.h b/be/src/exprs/bitmap_function.h index fa110cb3c637b0..21fbd89791c3c7 100644 --- a/be/src/exprs/bitmap_function.h +++ b/be/src/exprs/bitmap_function.h @@ -60,6 +60,7 @@ class BitmapFunctions { static StringVal to_bitmap(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); 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 diff --git a/be/src/util/bitmap_value.h b/be/src/util/bitmap_value.h index 9ccace7c5d21c4..f1ff0d1fbd19de 100644 --- a/be/src/util/bitmap_value.h +++ b/be/src/util/bitmap_value.h @@ -1087,6 +1087,63 @@ class BitmapValue { return *this; } + // Compute the symmetric union between the current bitmap and the provided bitmap. + // Possible type transitions are: + // SINGLE -> EMPTY + // BITMAP -> EMPTY + // BITMAP -> SINGLE + BitmapValue& operator^=(const BitmapValue& rhs) { + switch (rhs._type) { + case EMPTY: + break; + case SINGLE: + switch (_type) { + case EMPTY: + add(rhs._sv); + break; + case SINGLE: + if (_sv == rhs._sv) { + _type = EMPTY; + _bitmap.clear(); + } else { + add(rhs._sv); + } + break; + case BITMAP: + if (!_bitmap.contains(rhs._sv)) { + add(rhs._sv); + } else { + _bitmap.remove(rhs._sv); + } + break; + } + break; + case BITMAP: + switch (_type) { + case EMPTY: + _bitmap = rhs._bitmap; + _type = BITMAP; + break; + case SINGLE: + _bitmap = rhs._bitmap; + _type = BITMAP; + if (!rhs._bitmap.contains(_sv)) { + _bitmap.add(_sv); + } else { + _bitmap.remove(_sv); + } + break; + case BITMAP: + _bitmap ^= rhs._bitmap; + _convert_to_smaller_type(); + break; + } + break; + } + return *this; + } + + // check if value x is present bool contains(uint64_t x) { switch (_type) { diff --git a/docs/en/sql-reference/sql-functions/bitmap-functions/bitmap_xor.md b/docs/en/sql-reference/sql-functions/bitmap-functions/bitmap_xor.md new file mode 100644 index 00000000000000..2734f36b616046 --- /dev/null +++ b/docs/en/sql-reference/sql-functions/bitmap-functions/bitmap_xor.md @@ -0,0 +1,55 @@ +--- +{ + "title": "bitmap_xor", + "language": "en" +} +--- + + + +# bitmap_xor +## description +### Syntax + +`BITMAP BITMAP_XOR(BITMAP lhs, BITMAP rhs)` + +Compute the symmetric union of two input bitmaps, return the new bitmap. + +## example + +``` +mysql> select bitmap_count(bitmap_xor(bitmap_from_string('2,3'),bitmap_from_string('1,2,3,4'))) cnt; ++------+ +| cnt | ++------+ +| 2 | ++------+ + +mysql> select bitmap_to_string(bitmap_xor(bitmap_from_string('2,3'),bitmap_from_string('1,2,3,4'))); ++----------------------------------------------------------------------------------------+ +| bitmap_to_string(bitmap_xor(bitmap_from_string('2,3'), bitmap_from_string('1,2,3,4'))) | ++----------------------------------------------------------------------------------------+ +| 1,4 | ++----------------------------------------------------------------------------------------+ +``` + +## keyword + + BITMAP_XOR,BITMAP diff --git a/docs/zh-CN/sql-reference/sql-functions/bitmap-functions/bitmap_xor.md b/docs/zh-CN/sql-reference/sql-functions/bitmap-functions/bitmap_xor.md new file mode 100644 index 00000000000000..3e67e4fabe2288 --- /dev/null +++ b/docs/zh-CN/sql-reference/sql-functions/bitmap-functions/bitmap_xor.md @@ -0,0 +1,55 @@ +--- +{ + "title": "bitmap_xor", + "language": "zh-CN" +} +--- + + + +# bitmap_xor +## description +### Syntax + +`BITMAP BITMAP_XOR(BITMAP lhs, BITMAP rhs)` + +计算两个输入bitmap的差集,返回新的bitmap. + +## example + +``` +mysql> select bitmap_count(bitmap_xor(bitmap_from_string('2,3'),bitmap_from_string('1,2,3,4'))) cnt; ++------+ +| cnt | ++------+ +| 2 | ++------+ + +mysql> select bitmap_to_string(bitmap_xor(bitmap_from_string('2,3'),bitmap_from_string('1,2,3,4'))); ++----------------------------------------------------------------------------------------+ +| bitmap_to_string(bitmap_xor(bitmap_from_string('2,3'), bitmap_from_string('1,2,3,4'))) | ++----------------------------------------------------------------------------------------+ +| 1,4 | ++----------------------------------------------------------------------------------------+ +``` + +## keyword + + BITMAP_XOR,BITMAP diff --git a/gensrc/script/doris_builtins_functions.py b/gensrc/script/doris_builtins_functions.py index cb31d408ed5ffc..67742ba9ac8c98 100755 --- a/gensrc/script/doris_builtins_functions.py +++ b/gensrc/script/doris_builtins_functions.py @@ -800,6 +800,8 @@ '_ZN5doris15BitmapFunctions12bitmap_emptyEPN9doris_udf15FunctionContextE'], [['bitmap_or'], 'BITMAP', ['BITMAP','BITMAP'], '_ZN5doris15BitmapFunctions9bitmap_orEPN9doris_udf15FunctionContextERKNS1_9StringValES6_'], + [['bitmap_xor'], 'BITMAP', ['BITMAP','BITMAP'], + '_ZN5doris15BitmapFunctions10bitmap_xorEPN9doris_udf15FunctionContextERKNS1_9StringValES6_'], [['bitmap_and'], 'BITMAP', ['BITMAP','BITMAP'], '_ZN5doris15BitmapFunctions10bitmap_andEPN9doris_udf15FunctionContextERKNS1_9StringValES6_'], [['bitmap_to_string'], 'VARCHAR', ['BITMAP'],