// Licensed to the Apache Software Foundation (ASF) under one // or more contributor license agreements. See the NOTICE file // distributed with this work for additional information // regarding copyright ownership. The ASF licenses this file // to you under the Apache License, Version 2.0 (the // "License"); you may not use this file except in compliance // with the License. You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, // software distributed under the License is distributed on an // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY // KIND, either express or implied. See the License for the // specific language governing permissions and limitations // under the License. #include "exprs/bitmap_function.h" #include "exprs/anyval_util.h" #include "gutil/strings/numbers.h" #include "gutil/strings/split.h" #include "util/bitmap_intersect.h" #include "util/bitmap_value.h" #include "util/string_parser.hpp" namespace doris { static StringVal serialize(FunctionContext* ctx, BitmapValue* value) { if (!value) { BitmapValue empty_bitmap; StringVal result(ctx, empty_bitmap.getSizeInBytes()); empty_bitmap.write((char*)result.ptr); return result; } else { StringVal result(ctx, value->getSizeInBytes()); value->write((char*)result.ptr); return result; } } void BitmapFunctions::init() {} void BitmapFunctions::bitmap_init(FunctionContext* ctx, StringVal* dst) { dst->is_null = false; dst->len = sizeof(BitmapValue); dst->ptr = (uint8_t*)new BitmapValue(); } StringVal BitmapFunctions::bitmap_empty(FunctionContext* ctx) { BitmapValue bitmap; return serialize(ctx, &bitmap); } template void BitmapFunctions::bitmap_update_int(FunctionContext* ctx, const T& src, StringVal* dst) { if (src.is_null) { return; } auto dst_bitmap = reinterpret_cast(dst->ptr); dst_bitmap->add(src.val); } BigIntVal BitmapFunctions::bitmap_finalize(FunctionContext* ctx, const StringVal& src) { auto src_bitmap = reinterpret_cast(src.ptr); BigIntVal result(src_bitmap->cardinality()); delete src_bitmap; return result; } BigIntVal BitmapFunctions::bitmap_get_value(FunctionContext* ctx, const StringVal& src) { if (src.is_null) { return 0; } auto src_bitmap = reinterpret_cast(src.ptr); BigIntVal result(src_bitmap->cardinality()); return result; } void BitmapFunctions::bitmap_union(FunctionContext* ctx, const StringVal& src, StringVal* dst) { if (src.is_null) { return; } auto dst_bitmap = reinterpret_cast(dst->ptr); // zero size means the src input is a agg object if (src.len == 0) { (*dst_bitmap) |= *reinterpret_cast(src.ptr); } else { (*dst_bitmap) |= BitmapValue((char*)src.ptr); } } // the dst value could be null void BitmapFunctions::nullable_bitmap_init(FunctionContext* ctx, StringVal* dst) { dst->ptr = nullptr; dst->len = 0; } void BitmapFunctions::bitmap_intersect(FunctionContext* ctx, const StringVal& src, StringVal* dst) { if (src.is_null) { return; } // if dst is null, the src input is the first value if (UNLIKELY(dst->ptr == nullptr)) { dst->is_null = false; dst->len = sizeof(BitmapValue); dst->ptr = (uint8_t*)new BitmapValue((char*)src.ptr); return; } auto dst_bitmap = reinterpret_cast(dst->ptr); // zero size means the src input is a agg object if (src.len == 0) { (*dst_bitmap) &= *reinterpret_cast(src.ptr); } else { (*dst_bitmap) &= BitmapValue((char*)src.ptr); } } BigIntVal BitmapFunctions::bitmap_count(FunctionContext* ctx, const StringVal& src) { if (src.is_null) { return 0; } // zero size means the src input is a agg object if (src.len == 0) { auto bitmap = reinterpret_cast(src.ptr); return {static_cast(bitmap->cardinality())}; } else { BitmapValue bitmap((char*)src.ptr); return {static_cast(bitmap.cardinality())}; } } BigIntVal BitmapFunctions::bitmap_min(FunctionContext* ctx, const StringVal& src) { if (src.is_null) { return BigIntVal::null(); } if (src.len == 0) { return reinterpret_cast(src.ptr)->minimum(); } else { auto bitmap = BitmapValue((char*)src.ptr); return bitmap.minimum(); } } StringVal BitmapFunctions::to_bitmap(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( reinterpret_cast(src.ptr), src.len, &parse_result); if (parse_result == StringParser::PARSE_SUCCESS) { bitmap.add(int_value); } } return serialize(ctx, &bitmap); } StringVal BitmapFunctions::bitmap_hash(doris_udf::FunctionContext* ctx, const doris_udf::StringVal& src) { BitmapValue bitmap; if (!src.is_null) { uint32_t hash_value = HashUtil::murmur_hash3_32(src.ptr, src.len, HashUtil::MURMUR3_32_SEED); bitmap.add(hash_value); } return serialize(ctx, &bitmap); } StringVal BitmapFunctions::bitmap_hash64(doris_udf::FunctionContext* ctx, const doris_udf::StringVal& src) { BitmapValue bitmap; if (!src.is_null) { uint64_t hash_value = 0; murmur_hash3_x64_64(src.ptr, src.len, 0, &hash_value); bitmap.add(hash_value); } return serialize(ctx, &bitmap); } StringVal BitmapFunctions::bitmap_serialize(FunctionContext* ctx, const StringVal& src) { if (src.is_null) { // bitmap functions should never return nullable value return serialize(ctx, nullptr); } auto src_bitmap = reinterpret_cast(src.ptr); StringVal result = serialize(ctx, src_bitmap); delete src_bitmap; return result; } // This is a init function for intersect_count not for bitmap_intersect, not for _orthogonal_bitmap_intersect(bitmap,t,t) template void BitmapFunctions::bitmap_intersect_init(FunctionContext* ctx, StringVal* dst) { dst->is_null = false; dst->len = sizeof(BitmapIntersect); auto intersect = new BitmapIntersect(); // constant args start from index 2 for (int i = 2; i < ctx->get_num_constant_args(); ++i) { DCHECK(ctx->is_arg_constant(i)); ValType* arg = reinterpret_cast(ctx->get_constant_arg(i)); intersect->add_key(detail::Helper::get_val(*arg)); } dst->ptr = (uint8_t*)intersect; } // This is a update function for intersect_count/ORTHOGONAL_BITMAP_INTERSECT_COUNT/ORTHOGONAL_BITMAP_INTERSECT(bitmap,t,t) // not for bitmap_intersect(Bitmap) template void BitmapFunctions::bitmap_intersect_update(FunctionContext* ctx, const StringVal& src, const ValType& key, int num_key, const ValType* keys, const StringVal* dst) { auto* dst_bitmap = reinterpret_cast*>(dst->ptr); // zero size means the src input is a agg object if (src.len == 0) { dst_bitmap->update(detail::Helper::get_val(key), *reinterpret_cast(src.ptr)); } else { dst_bitmap->update(detail::Helper::get_val(key), BitmapValue((char*)src.ptr)); } } //only for intersect_count(bitmap,t,t) template void BitmapFunctions::bitmap_intersect_merge(FunctionContext* ctx, const StringVal& src, const StringVal* dst) { auto* dst_bitmap = reinterpret_cast*>(dst->ptr); dst_bitmap->merge(BitmapIntersect((char*)src.ptr)); } //only for intersect_count(bitmap,t,t) template StringVal BitmapFunctions::bitmap_intersect_serialize(FunctionContext* ctx, const StringVal& src) { auto* src_bitmap = reinterpret_cast*>(src.ptr); StringVal result(ctx, src_bitmap->size()); src_bitmap->serialize((char*)result.ptr); delete src_bitmap; return result; } //only for intersect_count(bitmap,t,t) template BigIntVal BitmapFunctions::bitmap_intersect_finalize(FunctionContext* ctx, const StringVal& src) { auto* src_bitmap = reinterpret_cast*>(src.ptr); BigIntVal result = BigIntVal(src_bitmap->intersect_count()); delete src_bitmap; return result; } StringVal BitmapFunctions::bitmap_or(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_or(FunctionContext* ctx, const StringVal& lhs, int num_args, const StringVal* bitmap_strs) { DCHECK_GE(num_args, 1); if (lhs.is_null || bitmap_strs->is_null) { return StringVal::null(); } BitmapValue bitmap; if (lhs.len == 0) { bitmap |= *reinterpret_cast(lhs.ptr); } else { bitmap |= BitmapValue((char*)lhs.ptr); } for (int i = 0; i < num_args; ++i) { if (bitmap_strs[i].is_null) { return StringVal::null(); } if (bitmap_strs[i].len == 0) { bitmap |= *reinterpret_cast(bitmap_strs[i].ptr); } else { bitmap |= BitmapValue((char*)bitmap_strs[i].ptr); } } return serialize(ctx, &bitmap); } StringVal BitmapFunctions::bitmap_and(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_and(FunctionContext* ctx, const StringVal& lhs, int num_args, const StringVal* bitmap_strs) { DCHECK_GE(num_args, 1); if (lhs.is_null || bitmap_strs->is_null) { return StringVal::null(); } BitmapValue bitmap; if (lhs.len == 0) { bitmap |= *reinterpret_cast(lhs.ptr); } else { bitmap |= BitmapValue((char*)lhs.ptr); } for (int i = 0; i < num_args; ++i) { if (bitmap_strs[i].is_null) { return StringVal::null(); } if (bitmap_strs[i].len == 0) { bitmap &= *reinterpret_cast(bitmap_strs[i].ptr); } else { bitmap &= BitmapValue((char*)bitmap_strs[i].ptr); } } return serialize(ctx, &bitmap); } BigIntVal BitmapFunctions::bitmap_and_count(FunctionContext* ctx, const StringVal& lhs, const StringVal& rhs) { if (lhs.is_null || rhs.is_null) { return BigIntVal::null(); } BitmapValue bitmap; if (lhs.len == 0) { bitmap |= *reinterpret_cast(lhs.ptr); } else { bitmap |= BitmapValue((char*)lhs.ptr); } if (rhs.len == 0) { return bitmap.and_cardinality(*reinterpret_cast(rhs.ptr)); } else { return bitmap.and_cardinality(BitmapValue((char*)rhs.ptr)); } } BigIntVal BitmapFunctions::bitmap_and_count(FunctionContext* ctx, const StringVal& lhs, int num_args, const StringVal* bitmap_strs) { DCHECK_GE(num_args, 1); if (lhs.is_null || bitmap_strs->is_null) { return BigIntVal::null(); } BitmapValue bitmap; if (lhs.len == 0) { bitmap |= *reinterpret_cast(lhs.ptr); } else { bitmap |= BitmapValue((char*)lhs.ptr); } for (int i = 0; i < num_args; i++) { if (bitmap_strs[i].is_null) { return BigIntVal::null(); } if (bitmap_strs[i].len == 0) { bitmap &= *reinterpret_cast(bitmap_strs[i].ptr); } else { bitmap &= BitmapValue((char*)bitmap_strs[i].ptr); } } return {static_cast(bitmap.cardinality())}; } BigIntVal BitmapFunctions::bitmap_or_count(FunctionContext* ctx, const StringVal& lhs, const StringVal& rhs) { if (lhs.is_null || rhs.is_null) { return BigIntVal::null(); } BitmapValue bitmap; if (lhs.len == 0) { bitmap |= *reinterpret_cast(lhs.ptr); } else { bitmap |= BitmapValue((char*)lhs.ptr); } if (rhs.len == 0) { return bitmap.or_cardinality(*reinterpret_cast(rhs.ptr)); } else { return bitmap.or_cardinality(BitmapValue((char*)rhs.ptr)); } } BigIntVal BitmapFunctions::bitmap_or_count(FunctionContext* ctx, const StringVal& lhs, int num_args, const StringVal* bitmap_strs) { DCHECK_GE(num_args, 1); if (lhs.is_null || bitmap_strs->is_null) { return BigIntVal::null(); } BitmapValue bitmap; if (lhs.len == 0) { bitmap |= *reinterpret_cast(lhs.ptr); } else { bitmap |= BitmapValue((char*)lhs.ptr); } for (int i = 0; i < num_args; i++) { if (bitmap_strs[i].is_null) { return BigIntVal::null(); } if (bitmap_strs[i].len == 0) { bitmap |= *reinterpret_cast(bitmap_strs[i].ptr); } else { bitmap |= BitmapValue((char*)bitmap_strs[i].ptr); } } return {static_cast(bitmap.cardinality())}; } 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_xor(FunctionContext* ctx, const StringVal& lhs, int num_args, const StringVal* bitmap_strs) { DCHECK_GE(num_args, 1); if (lhs.is_null || bitmap_strs->is_null) { return StringVal::null(); } BitmapValue bitmap; if (lhs.len == 0) { bitmap |= *reinterpret_cast(lhs.ptr); } else { bitmap |= BitmapValue((char*)lhs.ptr); } for (int i = 0; i < num_args; ++i) { if (bitmap_strs[i].is_null) { return StringVal::null(); } if (bitmap_strs[i].len == 0) { bitmap ^= *reinterpret_cast(bitmap_strs[i].ptr); } else { bitmap ^= BitmapValue((char*)bitmap_strs[i].ptr); } } return serialize(ctx, &bitmap); } BigIntVal BitmapFunctions::bitmap_xor_count(FunctionContext* ctx, const StringVal& lhs, const StringVal& rhs) { if (lhs.is_null || rhs.is_null) { return BigIntVal::null(); } BitmapValue bitmap; if (lhs.len == 0) { bitmap |= *reinterpret_cast(lhs.ptr); } else { bitmap |= BitmapValue((char*)lhs.ptr); } if (rhs.len == 0) { return bitmap.xor_cardinality(*reinterpret_cast(rhs.ptr)); } else { return bitmap.xor_cardinality(BitmapValue((char*)rhs.ptr)); } } BigIntVal BitmapFunctions::bitmap_xor_count(FunctionContext* ctx, const StringVal& lhs, int num_args, const StringVal* bitmap_strs) { DCHECK_GE(num_args, 1); if (lhs.is_null || bitmap_strs->is_null) { return BigIntVal::null(); } BitmapValue bitmap; if (lhs.len == 0) { bitmap |= *reinterpret_cast(lhs.ptr); } else { bitmap |= BitmapValue((char*)lhs.ptr); } for (int i = 0; i < num_args; i++) { if (bitmap_strs[i].is_null) { return BigIntVal::null(); } if (bitmap_strs[i].len == 0) { bitmap ^= *reinterpret_cast(bitmap_strs[i].ptr); } else { bitmap ^= BitmapValue((char*)bitmap_strs[i].ptr); } } return {static_cast(bitmap.cardinality())}; } StringVal BitmapFunctions::bitmap_not(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_and_not(FunctionContext* ctx, const StringVal& lhs, const StringVal& rhs) { return bitmap_xor(ctx, lhs, bitmap_and(ctx, lhs, rhs)); } BigIntVal BitmapFunctions::bitmap_and_not_count(FunctionContext* ctx, const StringVal& lhs, const StringVal& rhs) { if (lhs.is_null || rhs.is_null) { return BigIntVal::null(); } BitmapValue bitmap; if (lhs.len == 0) { bitmap |= *reinterpret_cast(lhs.ptr); } else { bitmap |= BitmapValue((char*)lhs.ptr); } if (rhs.len == 0) { return bitmap.andnot_cardinality(*reinterpret_cast(rhs.ptr)); } else { return bitmap.andnot_cardinality(BitmapValue((char*)rhs.ptr)); } } StringVal BitmapFunctions::bitmap_to_string(FunctionContext* ctx, const StringVal& input) { if (input.is_null) { return StringVal::null(); } std::string str; if (input.len == 0) { str = reinterpret_cast(input.ptr)->to_string(); } else { BitmapValue bitmap((char*)input.ptr); str = bitmap.to_string(); } return AnyValUtil::from_string_temp(ctx, str); } StringVal BitmapFunctions::bitmap_from_string(FunctionContext* ctx, const StringVal& input) { if (input.is_null) { return StringVal::null(); } std::vector bits; // The constructor of `stringPiece` only support int type. if ((input.len > INT32_MAX) || !SplitStringAndParse({(const char*)input.ptr, (int)input.len}, ",", &safe_strtou64, &bits)) { return StringVal::null(); } BitmapValue bitmap(bits); return serialize(ctx, &bitmap); } 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)}; } BitmapValue 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(); } 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 {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(); } if (src.len == 0) { return reinterpret_cast(src.ptr)->maximum(); } else { auto bitmap = BitmapValue((char*)src.ptr); return bitmap.maximum(); } } StringVal BitmapFunctions::bitmap_subset_in_range(FunctionContext* ctx, const StringVal& src, const BigIntVal& range_start, const BigIntVal& range_end) { if (src.is_null || range_start.is_null || range_end.is_null) { return StringVal::null(); } if (range_start.val >= range_end.val || range_start.val < 0 || range_end.val < 0) { return StringVal::null(); } BitmapValue ret_bitmap; if (src.len == 0) { ret_bitmap = *reinterpret_cast(src.ptr); } else { BitmapValue bitmap = BitmapValue((char*)src.ptr); bitmap.sub_range(range_start.val, range_end.val, &ret_bitmap); } return serialize(ctx, &ret_bitmap); } StringVal BitmapFunctions::sub_bitmap(FunctionContext* ctx, const StringVal& src, const BigIntVal& offset, const BigIntVal& cardinality_limit) { if (src.is_null || offset.is_null || cardinality_limit.is_null || cardinality_limit.val <= 0) { return StringVal::null(); } BitmapValue ret_bitmap; if (src.len == 0) { ret_bitmap = *reinterpret_cast(src.ptr); } else { BitmapValue bitmap = BitmapValue((char*)src.ptr); if (bitmap.offset_limit(offset.val, cardinality_limit.val, &ret_bitmap) == 0) { return StringVal::null(); } } return serialize(ctx, &ret_bitmap); } StringVal BitmapFunctions::bitmap_subset_limit(FunctionContext* ctx, const StringVal& src, const BigIntVal& range_start, const BigIntVal& cardinality_limit) { if (src.is_null || range_start.is_null || cardinality_limit.is_null) { return StringVal::null(); } if (range_start.val < 0 || cardinality_limit.val < 0) { return StringVal::null(); } BitmapValue ret_bitmap; if (src.len == 0) { ret_bitmap = *reinterpret_cast(src.ptr); } else { BitmapValue bitmap = BitmapValue((char*)src.ptr); bitmap.sub_limit(range_start.val, cardinality_limit.val, &ret_bitmap); } return serialize(ctx, &ret_bitmap); } // init ORTHOGONAL_BITMAP_UNION_COUNT(bitmap) // update bitmap_union() void BitmapFunctions::orthogonal_bitmap_union_count_init(FunctionContext* ctx, StringVal* dst) { dst->is_null = false; dst->len = sizeof(BitmapValue); dst->ptr = (uint8_t*)new BitmapValue(); } // serialize for ORTHOGONAL_BITMAP_UNION_COUNT(bitmap) StringVal BitmapFunctions::orthogonal_bitmap_count_serialize(FunctionContext* ctx, const StringVal& src) { if (src.is_null) { return src; } auto src_bitmap = reinterpret_cast(src.ptr); int64_t val = src_bitmap->cardinality(); StringVal result(ctx, sizeof(int64_t)); *(int64_t*)result.ptr = val; delete src_bitmap; return result; } // This is a init function for orthogonal_bitmap_intersect(bitmap,t,t). template void BitmapFunctions::orthogonal_bitmap_intersect_init(FunctionContext* ctx, StringVal* dst) { // constant args start from index 2 if (ctx->get_num_constant_args() > 1) { dst->is_null = false; dst->len = sizeof(BitmapIntersect); auto intersect = new BitmapIntersect(); for (int i = 2; i < ctx->get_num_constant_args(); ++i) { ValType* arg = reinterpret_cast(ctx->get_constant_arg(i)); intersect->add_key(detail::Helper::get_val(*arg)); } dst->ptr = (uint8_t*)intersect; } else { dst->is_null = false; dst->len = sizeof(BitmapValue); dst->ptr = (uint8_t*)new BitmapValue(); } } // This is a init function for orthogonal_bitmap_intersect_count(bitmap,t,t). template void BitmapFunctions::orthogonal_bitmap_intersect_count_init(FunctionContext* ctx, StringVal* dst) { if (ctx->get_num_constant_args() > 1) { dst->is_null = false; dst->len = sizeof(BitmapIntersect); auto intersect = new BitmapIntersect(); // constant args start from index 2 for (int i = 2; i < ctx->get_num_constant_args(); ++i) { ValType* arg = reinterpret_cast(ctx->get_constant_arg(i)); intersect->add_key(detail::Helper::get_val(*arg)); } dst->ptr = (uint8_t*)intersect; } else { dst->is_null = false; dst->len = sizeof(int64_t); dst->ptr = (uint8_t*)new int64_t; *(int64_t*)dst->ptr = 0; } } // This is a serialize function for orthogonal_bitmap_intersect(bitmap,t,t). // merge is ths simple bitmap_union() function LINE(80); // finalize is the bitmap_serialize() function LINE(173) template StringVal BitmapFunctions::orthogonal_bitmap_intersect_serialize(FunctionContext* ctx, const StringVal& src) { auto* src_bitmap = reinterpret_cast*>(src.ptr); BitmapValue bitmap_val = src_bitmap->intersect(); StringVal result = serialize(ctx, &bitmap_val); delete src_bitmap; return result; } template BigIntVal BitmapFunctions::orthogonal_bitmap_intersect_finalize(FunctionContext* ctx, const StringVal& src) { auto* src_bitmap = reinterpret_cast*>(src.ptr); BigIntVal result = BigIntVal(src_bitmap->intersect_count()); delete src_bitmap; return result; } // This is a merge function for orthogonal_bitmap_intersect_count(bitmap,t,t). // and merge for ORTHOGONAL_BITMAP_UNION_COUNT(bitmap) void BitmapFunctions::orthogonal_bitmap_count_merge(FunctionContext* context, const StringVal& src, StringVal* dst) { if (dst->len != sizeof(int64_t)) { auto dst_bitmap = reinterpret_cast(dst->ptr); delete dst_bitmap; dst->is_null = false; dst->len = sizeof(int64_t); dst->ptr = (uint8_t*)new int64_t; *(int64_t*)dst->ptr = 0; } *(int64_t*)dst->ptr += *(int64_t*)src.ptr; } // This is a finalize function for orthogonal_bitmap_intersect_count(bitmap,t,t). // finalize for ORTHOGONAL_BITMAP_UNION_COUNT(bitmap) BigIntVal BitmapFunctions::orthogonal_bitmap_count_finalize(FunctionContext* context, const StringVal& src) { if (src.is_null) { return BigIntVal::null(); } else if (src.len == sizeof(int64_t)) { auto* pval = reinterpret_cast(src.ptr); BigIntVal result = BigIntVal(*pval); delete pval; return result; } else { auto src_bitmap = reinterpret_cast(src.ptr); BigIntVal result = BigIntVal(src_bitmap->cardinality()); delete src_bitmap; return result; } } // This is a serialize function for orthogonal_bitmap_intersect_count(bitmap,t,t). template StringVal BitmapFunctions::orthogonal_bitmap_intersect_count_serialize(FunctionContext* ctx, const StringVal& src) { auto* src_bitmap = reinterpret_cast*>(src.ptr); int64_t val = src_bitmap->intersect_count(); StringVal result(ctx, sizeof(int64_t)); *(int64_t*)result.ptr = val; delete src_bitmap; return result; } template void BitmapFunctions::bitmap_update_int(FunctionContext* ctx, const TinyIntVal& src, StringVal* dst); template void BitmapFunctions::bitmap_update_int(FunctionContext* ctx, const SmallIntVal& src, StringVal* dst); template void BitmapFunctions::bitmap_update_int(FunctionContext* ctx, const IntVal& src, StringVal* dst); template void BitmapFunctions::bitmap_update_int(FunctionContext* ctx, const BigIntVal& src, StringVal* dst); // this is init function for intersect_count not for bitmap_intersect template void BitmapFunctions::bitmap_intersect_init(FunctionContext* ctx, StringVal* dst); template void BitmapFunctions::bitmap_intersect_init(FunctionContext* ctx, StringVal* dst); template void BitmapFunctions::bitmap_intersect_init(FunctionContext* ctx, StringVal* dst); template void BitmapFunctions::bitmap_intersect_init(FunctionContext* ctx, StringVal* dst); template void BitmapFunctions::bitmap_intersect_init<__int128, LargeIntVal>(FunctionContext* ctx, StringVal* dst); template void BitmapFunctions::bitmap_intersect_init(FunctionContext* ctx, StringVal* dst); template void BitmapFunctions::bitmap_intersect_init(FunctionContext* ctx, StringVal* dst); template void BitmapFunctions::bitmap_intersect_init( FunctionContext* ctx, StringVal* dst); template void BitmapFunctions::bitmap_intersect_init( FunctionContext* ctx, StringVal* dst); template void BitmapFunctions::bitmap_intersect_init(FunctionContext* ctx, StringVal* dst); template void BitmapFunctions::bitmap_intersect_update( FunctionContext* ctx, const StringVal& src, const TinyIntVal& key, int num_key, const TinyIntVal* keys, const StringVal* dst); template void BitmapFunctions::bitmap_intersect_update( FunctionContext* ctx, const StringVal& src, const SmallIntVal& key, int num_key, const SmallIntVal* keys, const StringVal* dst); template void BitmapFunctions::bitmap_intersect_update( FunctionContext* ctx, const StringVal& src, const IntVal& key, int num_key, const IntVal* keys, const StringVal* dst); template void BitmapFunctions::bitmap_intersect_update( FunctionContext* ctx, const StringVal& src, const BigIntVal& key, int num_key, const BigIntVal* keys, const StringVal* dst); template void BitmapFunctions::bitmap_intersect_update<__int128, LargeIntVal>( FunctionContext* ctx, const StringVal& src, const LargeIntVal& key, int num_key, const LargeIntVal* keys, const StringVal* dst); template void BitmapFunctions::bitmap_intersect_update( FunctionContext* ctx, const StringVal& src, const FloatVal& key, int num_key, const FloatVal* keys, const StringVal* dst); template void BitmapFunctions::bitmap_intersect_update( FunctionContext* ctx, const StringVal& src, const DoubleVal& key, int num_key, const DoubleVal* keys, const StringVal* dst); template void BitmapFunctions::bitmap_intersect_update( FunctionContext* ctx, const StringVal& src, const DateTimeVal& key, int num_key, const DateTimeVal* keys, const StringVal* dst); template void BitmapFunctions::bitmap_intersect_update( FunctionContext* ctx, const StringVal& src, const DecimalV2Val& key, int num_key, const DecimalV2Val* keys, const StringVal* dst); template void BitmapFunctions::bitmap_intersect_update( FunctionContext* ctx, const StringVal& src, const StringVal& key, int num_key, const StringVal* keys, const StringVal* dst); template void BitmapFunctions::bitmap_intersect_merge(FunctionContext* ctx, const StringVal& src, const StringVal* dst); template void BitmapFunctions::bitmap_intersect_merge(FunctionContext* ctx, const StringVal& src, const StringVal* dst); template void BitmapFunctions::bitmap_intersect_merge(FunctionContext* ctx, const StringVal& src, const StringVal* dst); template void BitmapFunctions::bitmap_intersect_merge(FunctionContext* ctx, const StringVal& src, const StringVal* dst); template void BitmapFunctions::bitmap_intersect_merge<__int128>(FunctionContext* ctx, const StringVal& src, const StringVal* dst); template void BitmapFunctions::bitmap_intersect_merge(FunctionContext* ctx, const StringVal& src, const StringVal* dst); template void BitmapFunctions::bitmap_intersect_merge(FunctionContext* ctx, const StringVal& src, const StringVal* dst); template void BitmapFunctions::bitmap_intersect_merge(FunctionContext* ctx, const StringVal& src, const StringVal* dst); template void BitmapFunctions::bitmap_intersect_merge(FunctionContext* ctx, const StringVal& src, const StringVal* dst); template void BitmapFunctions::bitmap_intersect_merge(FunctionContext* ctx, const StringVal& src, const StringVal* dst); template StringVal BitmapFunctions::bitmap_intersect_serialize(FunctionContext* ctx, const StringVal& src); template StringVal BitmapFunctions::bitmap_intersect_serialize(FunctionContext* ctx, const StringVal& src); template StringVal BitmapFunctions::bitmap_intersect_serialize(FunctionContext* ctx, const StringVal& src); template StringVal BitmapFunctions::bitmap_intersect_serialize(FunctionContext* ctx, const StringVal& src); template StringVal BitmapFunctions::bitmap_intersect_serialize<__int128>(FunctionContext* ctx, const StringVal& src); template StringVal BitmapFunctions::bitmap_intersect_serialize(FunctionContext* ctx, const StringVal& src); template StringVal BitmapFunctions::bitmap_intersect_serialize(FunctionContext* ctx, const StringVal& src); template StringVal BitmapFunctions::bitmap_intersect_serialize(FunctionContext* ctx, const StringVal& src); template StringVal BitmapFunctions::bitmap_intersect_serialize( FunctionContext* ctx, const StringVal& src); template StringVal BitmapFunctions::bitmap_intersect_serialize(FunctionContext* ctx, const StringVal& src); template BigIntVal BitmapFunctions::bitmap_intersect_finalize(FunctionContext* ctx, const StringVal& src); template BigIntVal BitmapFunctions::bitmap_intersect_finalize(FunctionContext* ctx, const StringVal& src); template BigIntVal BitmapFunctions::bitmap_intersect_finalize(FunctionContext* ctx, const StringVal& src); template BigIntVal BitmapFunctions::bitmap_intersect_finalize(FunctionContext* ctx, const StringVal& src); template BigIntVal BitmapFunctions::bitmap_intersect_finalize<__int128>(FunctionContext* ctx, const StringVal& src); template BigIntVal BitmapFunctions::bitmap_intersect_finalize(FunctionContext* ctx, const StringVal& src); template BigIntVal BitmapFunctions::bitmap_intersect_finalize(FunctionContext* ctx, const StringVal& src); template BigIntVal BitmapFunctions::bitmap_intersect_finalize(FunctionContext* ctx, const StringVal& src); template BigIntVal BitmapFunctions::bitmap_intersect_finalize(FunctionContext* ctx, const StringVal& src); template BigIntVal BitmapFunctions::bitmap_intersect_finalize(FunctionContext* ctx, const StringVal& src); template void BitmapFunctions::orthogonal_bitmap_intersect_count_init( FunctionContext* ctx, StringVal* dst); template void BitmapFunctions::orthogonal_bitmap_intersect_count_init( FunctionContext* ctx, StringVal* dst); template void BitmapFunctions::orthogonal_bitmap_intersect_count_init( FunctionContext* ctx, StringVal* dst); template void BitmapFunctions::orthogonal_bitmap_intersect_count_init( FunctionContext* ctx, StringVal* dst); template void BitmapFunctions::orthogonal_bitmap_intersect_count_init( FunctionContext* ctx, StringVal* dst); template void BitmapFunctions::orthogonal_bitmap_intersect_count_init( FunctionContext* ctx, StringVal* dst); template void BitmapFunctions::orthogonal_bitmap_intersect_count_init( FunctionContext* ctx, StringVal* dst); template void BitmapFunctions::orthogonal_bitmap_intersect_init( FunctionContext* ctx, StringVal* dst); template void BitmapFunctions::orthogonal_bitmap_intersect_init( FunctionContext* ctx, StringVal* dst); template void BitmapFunctions::orthogonal_bitmap_intersect_init( FunctionContext* ctx, StringVal* dst); template void BitmapFunctions::orthogonal_bitmap_intersect_init( FunctionContext* ctx, StringVal* dst); template void BitmapFunctions::orthogonal_bitmap_intersect_init( FunctionContext* ctx, StringVal* dst); template void BitmapFunctions::orthogonal_bitmap_intersect_init( FunctionContext* ctx, StringVal* dst); template void BitmapFunctions::orthogonal_bitmap_intersect_init( FunctionContext* ctx, StringVal* dst); template StringVal BitmapFunctions::orthogonal_bitmap_intersect_serialize( FunctionContext* ctx, const StringVal& src); template StringVal BitmapFunctions::orthogonal_bitmap_intersect_serialize( FunctionContext* ctx, const StringVal& src); template StringVal BitmapFunctions::orthogonal_bitmap_intersect_serialize( FunctionContext* ctx, const StringVal& src); template StringVal BitmapFunctions::orthogonal_bitmap_intersect_serialize( FunctionContext* ctx, const StringVal& src); template StringVal BitmapFunctions::orthogonal_bitmap_intersect_serialize( FunctionContext* ctx, const StringVal& src); template StringVal BitmapFunctions::orthogonal_bitmap_intersect_serialize( FunctionContext* ctx, const StringVal& src); template StringVal BitmapFunctions::orthogonal_bitmap_intersect_serialize( FunctionContext* ctx, const StringVal& src); template BigIntVal BitmapFunctions::orthogonal_bitmap_intersect_finalize( FunctionContext* ctx, const StringVal& src); template BigIntVal BitmapFunctions::orthogonal_bitmap_intersect_finalize( FunctionContext* ctx, const StringVal& src); template BigIntVal BitmapFunctions::orthogonal_bitmap_intersect_finalize( FunctionContext* ctx, const StringVal& src); template BigIntVal BitmapFunctions::orthogonal_bitmap_intersect_finalize( FunctionContext* ctx, const StringVal& src); template BigIntVal BitmapFunctions::orthogonal_bitmap_intersect_finalize( FunctionContext* ctx, const StringVal& src); template BigIntVal BitmapFunctions::orthogonal_bitmap_intersect_finalize( FunctionContext* ctx, const StringVal& src); template BigIntVal BitmapFunctions::orthogonal_bitmap_intersect_finalize( FunctionContext* ctx, const StringVal& src); template StringVal BitmapFunctions::orthogonal_bitmap_intersect_count_serialize( FunctionContext* ctx, const StringVal& src); template StringVal BitmapFunctions::orthogonal_bitmap_intersect_count_serialize( FunctionContext* ctx, const StringVal& src); template StringVal BitmapFunctions::orthogonal_bitmap_intersect_count_serialize( FunctionContext* ctx, const StringVal& src); template StringVal BitmapFunctions::orthogonal_bitmap_intersect_count_serialize( FunctionContext* ctx, const StringVal& src); template StringVal BitmapFunctions::orthogonal_bitmap_intersect_count_serialize( FunctionContext* ctx, const StringVal& src); template StringVal BitmapFunctions::orthogonal_bitmap_intersect_count_serialize( FunctionContext* ctx, const StringVal& src); template StringVal BitmapFunctions::orthogonal_bitmap_intersect_count_serialize( FunctionContext* ctx, const StringVal& src); } // namespace doris