@@ -199,7 +199,12 @@ Status VExprContext::execute_conjuncts(const VExprContextSPtrs& ctxs,
199199 return execute_conjuncts (ctxs, filters, false , block, result_filter, can_filter_all);
200200}
201201
202- // TODO: Performance Optimization
202+ Status VExprContext::execute_filter (const Block* block, uint8_t * __restrict result_filter_data,
203+ size_t rows, bool accept_null, bool * can_filter_all) {
204+ return _root->execute_filter (this , block, result_filter_data, rows, accept_null,
205+ can_filter_all);
206+ }
207+
203208Status VExprContext::execute_conjuncts (const VExprContextSPtrs& ctxs,
204209 const std::vector<IColumn::Filter*>* filters,
205210 bool accept_null, const Block* block,
@@ -209,85 +214,10 @@ Status VExprContext::execute_conjuncts(const VExprContextSPtrs& ctxs,
209214 *can_filter_all = false ;
210215 auto * __restrict result_filter_data = result_filter->data ();
211216 for (const auto & ctx : ctxs) {
212- // Statistics are only required when an rf wrapper exists in the expr.
213- bool is_rf_wrapper = ctx->root ()->is_rf_wrapper ();
214- ColumnPtr filter_column;
215- RETURN_IF_ERROR (ctx->execute (block, filter_column));
216- if (const auto * nullable_column = check_and_get_column<ColumnNullable>(*filter_column)) {
217- size_t column_size = nullable_column->size ();
218- if (column_size == 0 ) {
219- *can_filter_all = true ;
220- return Status::OK ();
221- } else {
222- const ColumnPtr& nested_column = nullable_column->get_nested_column_ptr ();
223- const IColumn::Filter& filter =
224- assert_cast<const ColumnUInt8&>(*nested_column).get_data ();
225- const auto * __restrict filter_data = filter.data ();
226- const auto * __restrict null_map_data = nullable_column->get_null_map_data ().data ();
227-
228- size_t input_rows =
229- rows - (is_rf_wrapper
230- ? simd::count_zero_num ((int8_t *)result_filter_data, rows)
231- : 0 );
232-
233- if (accept_null) {
234- for (size_t i = 0 ; i < rows; ++i) {
235- result_filter_data[i] &= (null_map_data[i]) || filter_data[i];
236- }
237- } else {
238- for (size_t i = 0 ; i < rows; ++i) {
239- result_filter_data[i] &= (!null_map_data[i]) & filter_data[i];
240- }
241- }
242-
243- size_t output_rows =
244- rows - (is_rf_wrapper
245- ? simd::count_zero_num ((int8_t *)result_filter_data, rows)
246- : 0 );
247-
248- if (is_rf_wrapper) {
249- ctx->root ()->do_judge_selectivity (input_rows - output_rows, input_rows);
250- }
251-
252- if ((is_rf_wrapper && output_rows == 0 ) ||
253- (!is_rf_wrapper && memchr (result_filter_data, 0x1 , rows) == nullptr )) {
254- *can_filter_all = true ;
255- return Status::OK ();
256- }
257- }
258- } else if (const auto * const_column = check_and_get_column<ColumnConst>(*filter_column)) {
259- // filter all
260- if (!const_column->get_bool (0 )) {
261- *can_filter_all = true ;
262- memset (result_filter_data, 0 , result_filter->size ());
263- return Status::OK ();
264- }
265- } else {
266- const IColumn::Filter& filter =
267- assert_cast<const ColumnUInt8&>(*filter_column).get_data ();
268- const auto * __restrict filter_data = filter.data ();
269-
270- size_t input_rows =
271- rows -
272- (is_rf_wrapper ? simd::count_zero_num ((int8_t *)result_filter_data, rows) : 0 );
273-
274- for (size_t i = 0 ; i < rows; ++i) {
275- result_filter_data[i] &= filter_data[i];
276- }
277-
278- size_t output_rows =
279- rows -
280- (is_rf_wrapper ? simd::count_zero_num ((int8_t *)result_filter_data, rows) : 0 );
281-
282- if (is_rf_wrapper) {
283- ctx->root ()->do_judge_selectivity (input_rows - output_rows, input_rows);
284- }
285-
286- if ((is_rf_wrapper && output_rows == 0 ) ||
287- (!is_rf_wrapper && memchr (result_filter_data, 0x1 , rows) == nullptr )) {
288- *can_filter_all = true ;
289- return Status::OK ();
290- }
217+ RETURN_IF_ERROR (
218+ ctx->execute_filter (block, result_filter_data, rows, accept_null, can_filter_all));
219+ if (*can_filter_all) {
220+ return Status::OK ();
291221 }
292222 }
293223 if (filters != nullptr ) {
0 commit comments