Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions src/operators/logical_create_filter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ LogicalCreateFilter::LogicalCreateFilter() : LogicalExtensionOperator() {
}

LogicalCreateFilter::LogicalCreateFilter(const FilterOperation &filter_op)
: LogicalExtensionOperator(), filter_operation(filter_op) {
: LogicalExtensionOperator(), filter_operation(filter_op), input_bindings(filter_op.build_columns) {
this->type = LogicalOperatorType::LOGICAL_EXTENSION_OPERATOR;
message = "CREATE_FILTER";
}
Expand Down Expand Up @@ -82,7 +82,7 @@ PhysicalOperator &LogicalCreateFilter::CreatePlan(ClientContext &context, Physic
// built.
// TODO: optimize: Use a map for filter_operation.build_columns to speed up lookup
vector<idx_t> resolved_indices;
for (const ColumnBinding &column_binding : filter_operation.build_columns) {
for (const ColumnBinding &column_binding : input_bindings) {
// find the position of the filter column ColumnBinding in the chunk columns
for (idx_t i = 0; i < child_bindings.size(); i++) {
if (child_bindings[i].table_index == column_binding.table_index &&
Expand Down
1 change: 1 addition & 0 deletions src/operators/logical_create_filter.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ class LogicalCreateFilter : public LogicalExtensionOperator {

bool can_stop = false;
FilterOperation filter_operation;
vector<ColumnBinding> input_bindings;
PhysicalCreateFilter *physical = nullptr;

vector<LogicalProbeFilter *> related_probe_filter;
Expand Down
4 changes: 2 additions & 2 deletions src/operators/logical_probe_filter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ LogicalProbeFilter::LogicalProbeFilter() : LogicalExtensionOperator() {
}

LogicalProbeFilter::LogicalProbeFilter(const FilterOperation &filter_op)
: LogicalExtensionOperator(), filter_operation(filter_op) {
: LogicalExtensionOperator(), filter_operation(filter_op), input_bindings(filter_op.probe_columns) {
this->type = LogicalOperatorType::LOGICAL_EXTENSION_OPERATOR;
}

Expand Down Expand Up @@ -67,7 +67,7 @@ PhysicalOperator &LogicalProbeFilter::CreatePlan(ClientContext &context, Physica
}
#endif

for (const ColumnBinding &column_binding : filter_operation.probe_columns) {
for (const ColumnBinding &column_binding : input_bindings) {
D_PRINTF("[RESOLVE] Looking for probe_column: table_idx=%llu, col_idx=%llu",
(unsigned long long)column_binding.table_index, (unsigned long long)column_binding.column_index);
// find the position of the filter column ColumnBinding in the chunk columns
Expand Down
1 change: 1 addition & 0 deletions src/operators/logical_probe_filter.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ class LogicalProbeFilter final : public LogicalExtensionOperator {
FilterOperation filter_operation;
LogicalCreateFilter *related_create_filter = nullptr;
bool is_passthrough = false;
vector<ColumnBinding> input_bindings;

PhysicalProbeFilter *physical = nullptr;

Expand Down
76 changes: 65 additions & 11 deletions src/optimizer/robust_optimizer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1583,6 +1583,38 @@ static LogicalOperator *FindDeepestCreateFilter(LogicalOperator *node) {
return deepest;
}

// find the deepest FILTER chain starting with a PROBE_FILTER
static pair<LogicalOperator *, LogicalOperator *> FindDeepestFilterChain(LogicalOperator *node) {
LogicalOperator *deepest = nullptr;
LogicalOperator *parent = nullptr;
LogicalOperator *create = nullptr;
while (node) {
if (node->children.size() != 1 || node->children[0]->type == LogicalOperatorType::LOGICAL_DELIM_JOIN ||
node->children[0]->type == LogicalOperatorType::LOGICAL_MATERIALIZED_CTE) {
break;
}
if (node->children[0]->type == LogicalOperatorType::LOGICAL_EXTENSION_OPERATOR) {
deepest = node;
node = node->children[0].get();
while (node->type == LogicalOperatorType::LOGICAL_EXTENSION_OPERATOR) {
if (node->children.size() != 1 || node->children[0]->type == LogicalOperatorType::LOGICAL_DELIM_JOIN ||
node->children[0]->type == LogicalOperatorType::LOGICAL_MATERIALIZED_CTE) {
break;
}
if (node->type == LogicalOperatorType::LOGICAL_EXTENSION_OPERATOR &&
dynamic_cast<LogicalCreateFilter *>(node)) {
parent = deepest;
create = node;
}
node = node->children[0].get();
}
return {parent, create};
}
node = node->children[0].get();
}
return {parent, create};
}

void RobustOptimizerContextState::LiftCreateFilterAboveMarkJoin(unique_ptr<LogicalOperator> &plan) {
if (!plan) {
return;
Expand Down Expand Up @@ -1628,19 +1660,41 @@ void RobustOptimizerContextState::LiftCreateFilterAboveFilter(unique_ptr<Logical
return;
}

auto *deepest = FindDeepestCreateFilter(plan->children[0].get());
if (!deepest) {
auto p = FindDeepestFilterChain(plan.get());
LogicalOperator *parent = p.first;
LogicalOperator *create = p.second;
if (!parent || !create) {
return;
}

// same block-detach logic as LiftCreateFilterAboveMarkJoin
auto below_deepest = std::move(deepest->children[0]);
deepest->children.clear();
auto block = std::move(plan->children[0]);
plan->children[0] = std::move(below_deepest);

deepest->AddChild(std::move(plan));
plan = std::move(block);
auto beginning = std::move(parent->children[0]);
parent->children[0] = std::move(create->children[0]);
create->children[0] = (std::move(plan));
plan = std::move(beginning);
LogicalOperator *cur = plan.get();
while (cur->type == LogicalOperatorType::LOGICAL_EXTENSION_OPERATOR) {
if (auto *createCur = dynamic_cast<LogicalCreateFilter *>(cur)) {
auto &filter = createCur->filter_operation;
createCur->input_bindings.clear();
for (auto &baseBinding : filter.build_columns) {
for (auto &binding : createCur->GetColumnBindings()) {
if (ResolveColumnBinding(binding) == ResolveColumnBinding(baseBinding)) {
createCur->input_bindings.push_back(binding);
}
}
}
} else if (auto *probeCur = dynamic_cast<LogicalProbeFilter *>(cur)) {
auto &filter = probeCur->filter_operation;
probeCur->input_bindings.clear();
for (auto &baseBinding : filter.probe_columns) {
for (auto &binding : probeCur->GetColumnBindings()) {
if (ResolveColumnBinding(binding) == ResolveColumnBinding(baseBinding)) {
probeCur->input_bindings.push_back(binding);
}
}
}
}
cur = cur->children[0].get();
}
}

unique_ptr<LogicalOperator> RobustOptimizerContextState::PreOptimize(unique_ptr<LogicalOperator> plan) {
Expand Down
Loading