@@ -216,8 +216,8 @@ ColumnPtr IExecutableFunction::defaultImplementationForNulls(
216216 if (input_rows_count == 0 )
217217 return result_type->createColumn ();
218218
219- IColumn::Filter mask (input_rows_count, 1 );
220- MaskInfo mask_info = {. has_ones = true , . has_zeros = false } ;
219+ auto result_null_map = ColumnUInt8::create (input_rows_count, 0 );
220+ auto & result_null_map_data = result_null_map-> getData () ;
221221 bool all_columns_constant = true ;
222222 for (const auto & arg : args)
223223 {
@@ -236,29 +236,27 @@ ColumnPtr IExecutableFunction::defaultImplementationForNulls(
236236 }
237237 else
238238 {
239- const auto & null_map = assert_cast<const ColumnNullable &>(*arg.column ).getNullMapColumnPtr ();
240- mask_info = extractInvertedMask (mask, null_map);
239+ const auto & null_map = assert_cast<const ColumnNullable &>(*arg.column ).getNullMapData ();
240+ for (size_t i = 0 ; i < input_rows_count; ++i)
241+ result_null_map_data[i] |= null_map[i];
241242 }
242243 }
243-
244- // / Exit loop early if each row contains at least one null value
245- if (!mask_info.has_ones )
246- break ;
247244 }
248245
249- if (!mask_info.has_ones && !all_columns_constant)
246+ size_t rows_with_nulls = countBytesInFilter (result_null_map_data.data (), 0 , input_rows_count);
247+ size_t rows_without_nulls = input_rows_count - rows_with_nulls;
248+ ProfileEvents::increment (ProfileEvents::DefaultImplementationForNullsRows, input_rows_count);
249+ ProfileEvents::increment (ProfileEvents::DefaultImplementationForNullsRowsWithNulls, rows_with_nulls);
250+
251+ if (rows_without_nulls == 0 && !all_columns_constant)
250252 {
251253 // / Don't need to evaluate function if each row contains at least one null value and not all input columns are constant.
252254 return result_type->createColumnConstWithDefaultValue (input_rows_count)->convertToFullColumnIfConst ();
253255 }
254256
255- size_t rows_without_nulls = countBytesInFilter (mask.data (), 0 , mask.size ());
256- size_t rows_with_nulls = mask.size () - rows_without_nulls;
257- double null_ratio = rows_with_nulls / static_cast <double >(mask.size ());
257+ double null_ratio = rows_with_nulls / static_cast <double >(result_null_map_data.size ());
258258 bool should_short_circuit = short_circuit_function_evaluation_for_nulls && !all_columns_constant
259259 && null_ratio >= short_circuit_function_evaluation_for_nulls_threshold;
260- ProfileEvents::increment (ProfileEvents::DefaultImplementationForNullsRows, mask.size ());
261- ProfileEvents::increment (ProfileEvents::DefaultImplementationForNullsRowsWithNulls, rows_with_nulls);
262260
263261 ColumnsWithTypeAndName temporary_columns = createBlockWithNestedColumns (args);
264262 auto temporary_result_type = removeNullable (result_type);
@@ -267,13 +265,7 @@ ColumnPtr IExecutableFunction::defaultImplementationForNulls(
267265 {
268266 // / Each row should be evaluated if there are no nulls or short circuiting is disabled.
269267 auto res = executeWithoutLowCardinalityColumns (temporary_columns, temporary_result_type, input_rows_count, dry_run);
270-
271- // / Invert mask as null map
272- inverseMask (mask, mask_info);
273- auto null_map = ColumnUInt8::create ();
274- null_map->getData () = std::move (mask);
275-
276- auto new_res = wrapInNullable (res, std::move (null_map));
268+ auto new_res = wrapInNullable (res, std::move (result_null_map));
277269 return new_res;
278270 }
279271 else
@@ -282,18 +274,13 @@ ColumnPtr IExecutableFunction::defaultImplementationForNulls(
282274
283275 // / Filter every column by mask
284276 for (auto & col : temporary_columns)
285- col.column = col.column ->filter (mask , rows_without_nulls);
277+ col.column = col.column ->filter (result_null_map_data , rows_without_nulls);
286278
287279 auto res = executeWithoutLowCardinalityColumns (temporary_columns, temporary_result_type, rows_without_nulls, dry_run);
288280 auto mutable_res = IColumn::mutate (std::move (res));
289- mutable_res->expand (mask, false );
290-
291- // / Invert mask as null map
292- inverseMask (mask, mask_info);
293- auto null_map = ColumnUInt8::create ();
294- null_map->getData () = std::move (mask);
281+ mutable_res->expand (result_null_map_data, false );
295282
296- auto new_res = wrapInNullable (std::move (mutable_res), std::move (null_map ));
283+ auto new_res = wrapInNullable (std::move (mutable_res), std::move (result_null_map ));
297284 return new_res;
298285 }
299286 }
0 commit comments