3131#include " core/block/column_with_type_and_name.h"
3232#include " core/column/column.h"
3333#include " core/column/column_complex.h"
34+ #include " core/column/column_const.h"
3435#include " core/column/column_nullable.h"
3536#include " core/column/column_vector.h"
3637#include " core/data_type/data_type.h"
@@ -156,6 +157,87 @@ BITMAP_FUNCTION_COUNT_VARIADIC(BitmapOrCount, bitmap_or_count, |=);
156157BITMAP_FUNCTION_COUNT_VARIADIC (BitmapAndCount, bitmap_and_count, &=);
157158BITMAP_FUNCTION_COUNT_VARIADIC (BitmapXorCount, bitmap_xor_count, ^=);
158159
160+ template <typename Impl>
161+ Status execute_binary_bitmap_count (const ColumnPtr& lhs_column, const ColumnPtr& rhs_column,
162+ size_t input_rows_count, ColumnInt64::Container& res) {
163+ struct BitmapColumnAccessor {
164+ const std::vector<BitmapValue>* values = nullptr ;
165+ const BitmapValue* const_value = nullptr ;
166+ const ColumnUInt8::value_type* null_map_data = nullptr ;
167+ bool is_const = false ;
168+ bool is_const_null = false ;
169+
170+ bool is_null_at (size_t row) const {
171+ return is_const ? is_const_null : (null_map_data && null_map_data[row]);
172+ }
173+
174+ const BitmapValue& get_value (size_t row) const {
175+ return is_const ? *const_value : (*values)[row];
176+ }
177+ };
178+
179+ auto make_accessor = [](const ColumnPtr& column) {
180+ BitmapColumnAccessor accessor;
181+ const IColumn* data_column = column.get ();
182+
183+ if (const auto * const_column = check_and_get_column<ColumnConst>(*data_column)) {
184+ accessor.is_const = true ;
185+ data_column = &const_column->get_data_column ();
186+ }
187+
188+ if (const auto * nullable = check_and_get_column<ColumnNullable>(*data_column)) {
189+ if (accessor.is_const ) {
190+ accessor.is_const_null = nullable->is_null_at (0 );
191+ } else {
192+ accessor.null_map_data = nullable->get_null_map_data ().data ();
193+ }
194+ data_column = nullable->get_nested_column_ptr ().get ();
195+ }
196+
197+ const auto * bitmap_column = assert_cast<const ColumnBitmap*>(data_column);
198+ if (accessor.is_const ) {
199+ accessor.const_value = &bitmap_column->get_data ()[0 ];
200+ } else {
201+ accessor.values = &bitmap_column->get_data ();
202+ }
203+
204+ return accessor;
205+ };
206+
207+ const auto lhs = make_accessor (lhs_column);
208+ const auto rhs = make_accessor (rhs_column);
209+
210+ for (size_t row = 0 ; row < input_rows_count; ++row) {
211+ const bool lhs_is_null = lhs.is_null_at (row);
212+ const bool rhs_is_null = rhs.is_null_at (row);
213+
214+ if constexpr (std::is_same_v<Impl, BitmapOrCount>) {
215+ if (lhs_is_null) {
216+ res[row] = rhs_is_null ? 0 : rhs.get_value (row).cardinality ();
217+ } else if (rhs_is_null) {
218+ res[row] = lhs.get_value (row).cardinality ();
219+ } else {
220+ res[row] = lhs.get_value (row).or_cardinality (rhs.get_value (row));
221+ }
222+ } else if constexpr (std::is_same_v<Impl, BitmapAndCount>) {
223+ res[row] = (lhs_is_null || rhs_is_null)
224+ ? 0
225+ : lhs.get_value (row).and_cardinality (rhs.get_value (row));
226+ } else {
227+ if (lhs_is_null || rhs_is_null) {
228+ res[row] = 0 ;
229+ } else {
230+ const auto & lhs_value = lhs.get_value (row);
231+ const auto & rhs_value = rhs.get_value (row);
232+ uint64_t inter = lhs_value.and_cardinality (rhs_value);
233+ res[row] = lhs_value.cardinality () + rhs_value.cardinality () - 2 * inter;
234+ }
235+ }
236+ }
237+
238+ return Status::OK ();
239+ }
240+
159241Status execute_bitmap_op_count_null_to_zero (
160242 FunctionContext* context, Block& block, const ColumnNumbers& arguments, uint32_t result,
161243 size_t input_rows_count,
@@ -219,12 +301,6 @@ class FunctionBitMapVariadic : public IFunction {
219301 const ColumnNumbers& arguments, uint32_t result,
220302 size_t input_rows_count) const {
221303 size_t argument_size = arguments.size ();
222- std::vector<ColumnPtr> argument_columns (argument_size);
223-
224- for (size_t i = 0 ; i < argument_size; ++i) {
225- argument_columns[i] =
226- block.get_by_position (arguments[i]).column ->convert_to_full_column_if_const ();
227- }
228304
229305 using ResultDataType = typename Impl::ResultDataType; // DataTypeBitMap or DataTypeInt64
230306 using ColVecResult = std::conditional_t <is_complex_v<ResultDataType::PType>,
@@ -244,8 +320,31 @@ class FunctionBitMapVariadic : public IFunction {
244320 auto & vec_res = col_res->get_data ();
245321 vec_res.resize (input_rows_count);
246322
247- RETURN_IF_ERROR (Impl::vector_vector (argument_columns.data (), argument_size,
248- input_rows_count, vec_res, col_res_nulls.get ()));
323+ if constexpr (std::is_same_v<Impl, BitmapOrCount> || std::is_same_v<Impl, BitmapAndCount> ||
324+ std::is_same_v<Impl, BitmapXorCount>) {
325+ if (argument_size == 2 ) {
326+ RETURN_IF_ERROR (execute_binary_bitmap_count<Impl>(
327+ block.get_by_position (arguments[0 ]).column ,
328+ block.get_by_position (arguments[1 ]).column , input_rows_count, vec_res));
329+ } else {
330+ std::vector<ColumnPtr> argument_columns (argument_size);
331+ for (size_t i = 0 ; i < argument_size; ++i) {
332+ argument_columns[i] = block.get_by_position (arguments[i])
333+ .column ->convert_to_full_column_if_const ();
334+ }
335+ RETURN_IF_ERROR (Impl::vector_vector (argument_columns.data (), argument_size,
336+ input_rows_count, vec_res,
337+ col_res_nulls.get ()));
338+ }
339+ } else {
340+ std::vector<ColumnPtr> argument_columns (argument_size);
341+ for (size_t i = 0 ; i < argument_size; ++i) {
342+ argument_columns[i] = block.get_by_position (arguments[i])
343+ .column ->convert_to_full_column_if_const ();
344+ }
345+ RETURN_IF_ERROR (Impl::vector_vector (argument_columns.data (), argument_size,
346+ input_rows_count, vec_res, col_res_nulls.get ()));
347+ }
249348 if (!use_default_implementation_for_nulls () && result_info.type ->is_nullable ()) {
250349 block.replace_by_position (
251350 result, ColumnNullable::create (std::move (col_res), std::move (col_res_nulls)));
@@ -277,4 +376,4 @@ void register_function_bitmap_variadic(SimpleFunctionFactory& factory) {
277376 factory.register_function <FunctionBitmapAndCount>();
278377 factory.register_function <FunctionBitmapXorCount>();
279378}
280- } // namespace doris
379+ } // namespace doris
0 commit comments