1#include <Functions/FunctionFactory.h>
2#include <Functions/FunctionBinaryArithmetic.h>
3#include <DataTypes/NumberTraits.h>
4
5
6namespace DB
7{
8 namespace ErrorCodes
9 {
10 extern const int BAD_CAST;
11 }
12
13 /// Working with UInt8: last bit = can be true, previous = can be false (Like dbms/src/Storages/MergeTree/BoolMask.h).
14 /// This function provides "AND" operation for BoolMasks.
15 /// Returns: "can be true" = A."can be true" AND B."can be true"
16 /// "can be false" = A."can be false" OR B."can be false"
17 template <typename A, typename B>
18 struct BitBoolMaskAndImpl
19 {
20 using ResultType = UInt8;
21
22 template <typename Result = ResultType>
23 static inline Result apply(A left, B right)
24 {
25 if constexpr (!std::is_same_v<A, ResultType> || !std::is_same_v<B, ResultType>)
26 throw DB::Exception("It's a bug! Only UInt8 type is supported by __bitBoolMaskAnd.", ErrorCodes::BAD_CAST);
27 return static_cast<ResultType>(
28 ((static_cast<ResultType>(left) & static_cast<ResultType>(right)) & 1)
29 | ((((static_cast<ResultType>(left) >> 1) | (static_cast<ResultType>(right) >> 1)) & 1) << 1));
30 }
31
32#if USE_EMBEDDED_COMPILER
33 static constexpr bool compilable = false;
34
35#endif
36 };
37
38 struct NameBitBoolMaskAnd { static constexpr auto name = "__bitBoolMaskAnd"; };
39 using FunctionBitBoolMaskAnd = FunctionBinaryArithmetic<BitBoolMaskAndImpl, NameBitBoolMaskAnd>;
40
41 void registerFunctionBitBoolMaskAnd(FunctionFactory & factory)
42 {
43 factory.registerFunction<FunctionBitBoolMaskAnd>();
44 }
45
46}
47