| 67 | } |
| 68 | |
| 69 | FilterTransform::FilterTransform( |
| 70 | SharedHeader header_, |
| 71 | ExpressionActionsPtr expression_, |
| 72 | String filter_column_name_, |
| 73 | bool remove_filter_column_, |
| 74 | bool on_totals_, |
| 75 | std::shared_ptr<std::atomic<size_t>> rows_filtered_, |
| 76 | std::optional<std::pair<UInt64, String>> condition_) |
| 77 | : ISimpleTransform( |
| 78 | header_, |
| 79 | std::make_shared<const Block>(transformHeader(*header_, expression_ ? &expression_->getActionsDAG() : nullptr, filter_column_name_, remove_filter_column_)), |
| 80 | true) |
| 81 | , expression(std::move(expression_)) |
| 82 | , filter_column_name(std::move(filter_column_name_)) |
| 83 | , remove_filter_column(remove_filter_column_) |
| 84 | , on_totals(on_totals_) |
| 85 | , rows_filtered(rows_filtered_) |
| 86 | , condition(condition_) |
| 87 | { |
| 88 | /// Use transformHeader (which calls ActionsDAG::updateHeader) to compute the header. |
| 89 | /// This correctly handles constant propagation through dry-run evaluation, |
| 90 | /// unlike expression->execute() which would fail with not-ready sets. |
| 91 | const auto * dag = expression ? &expression->getActionsDAG() : nullptr; |
| 92 | transformed_header = transformHeader(getInputPort().getHeader(), dag, filter_column_name, /*remove_filter_column=*/false); |
| 93 | |
| 94 | if (expression) |
| 95 | { |
| 96 | /// Special check to stop queries like "WHERE ignore(...)" |
| 97 | const auto * node = &expression->getActionsDAG().findInOutputs(filter_column_name); |
| 98 | while (node->type == ActionsDAG::ActionType::ALIAS) |
| 99 | node = node->children[0]; |
| 100 | |
| 101 | if (node->type == ActionsDAG::ActionType::FUNCTION && node->function_base->getName() == "ignore") |
| 102 | always_false = true; |
| 103 | } |
| 104 | |
| 105 | filter_column_position = transformed_header.getPositionByName(filter_column_name); |
| 106 | |
| 107 | auto & column = transformed_header.getByPosition(filter_column_position).column; |
| 108 | if (column) |
| 109 | always_false = always_false || ConstantFilterDescription(*column).always_false; |
| 110 | |
| 111 | if (condition.has_value()) |
| 112 | query_condition_cache = Context::getGlobalContextInstance()->getQueryConditionCache(); |
| 113 | } |
| 114 | |
| 115 | IProcessor::Status FilterTransform::prepare() |
| 116 | { |
nothing calls this directly
no test coverage detected