Fix crash in filterPushDown

This commit is contained in:
vdimir 2023-11-06 16:11:27 +00:00
parent cc25f66b03
commit 43bf718318
No known key found for this signature in database
GPG Key ID: 6EE4CE2BEDC51862
4 changed files with 44 additions and 14 deletions

View File

@ -464,12 +464,19 @@ void ActionsDAG::removeUnusedActions(const Names & required_names, bool allow_re
void ActionsDAG::removeUnusedActions(bool allow_remove_inputs, bool allow_constant_folding)
{
std::unordered_set<const Node *> visited_nodes;
std::unordered_set<const Node *> used_inputs;
std::stack<Node *> stack;
if (!allow_remove_inputs)
{
for (const auto * input : inputs)
used_inputs.insert(input);
}
removeUnusedActions(used_inputs, allow_constant_folding);
}
for (const auto * input : inputs)
used_inputs.insert(input);
void ActionsDAG::removeUnusedActions(const std::unordered_set<const Node *> & used_inputs, bool allow_constant_folding)
{
std::unordered_set<const Node *> visited_nodes;
std::stack<Node *> stack;
for (const auto * node : outputs)
{
@ -488,7 +495,7 @@ void ActionsDAG::removeUnusedActions(bool allow_remove_inputs, bool allow_consta
stack.push(&node);
}
if (node.type == ActionType::INPUT && !allow_remove_inputs && used_inputs.contains(&node))
if (node.type == ActionType::INPUT && used_inputs.contains(&node))
visited_nodes.insert(&node);
}
@ -2187,14 +2194,6 @@ ActionsDAGPtr ActionsDAG::cloneActionsForFilterPushDown(
{
/// If filter column is not needed, remove it from output nodes.
std::erase_if(outputs, [&](const Node * node) { return node == predicate; });
/// At the very end of this method we'll call removeUnusedActions() with allow_remove_inputs=false,
/// so we need to manually remove predicate if it is an input node.
if (predicate->type == ActionType::INPUT)
{
std::erase_if(inputs, [&](const Node * node) { return node == predicate; });
nodes.remove_if([&](const Node & node) { return &node == predicate; });
}
}
else
{
@ -2261,7 +2260,15 @@ ActionsDAGPtr ActionsDAG::cloneActionsForFilterPushDown(
}
}
removeUnusedActions(false);
std::unordered_set<const Node *> used_inputs;
for (const auto * input : inputs)
{
if (can_remove_filter && input == predicate)
continue;
used_inputs.insert(input);
}
removeUnusedActions(used_inputs);
return actions;
}

View File

@ -182,6 +182,9 @@ public:
/// Remove actions that are not needed to compute output nodes
void removeUnusedActions(bool allow_remove_inputs = true, bool allow_constant_folding = true);
/// Remove actions that are not needed to compute output nodes. Keep inputs from used_inputs.
void removeUnusedActions(const std::unordered_set<const Node *> & used_inputs, bool allow_constant_folding = true);
/// Remove actions that are not needed to compute output nodes with required names
void removeUnusedActions(const Names & required_names, bool allow_remove_inputs = true, bool allow_constant_folding = true);

View File

@ -0,0 +1,2 @@
2
1

View File

@ -0,0 +1,18 @@
DROP TABLE IF EXISTS t1;
DROP TABLE IF EXISTS t2;
CREATE TABLE t1 (key UInt8) ENGINE = MergeTree ORDER BY key;
INSERT INTO t1 VALUES (1),(2);
CREATE TABLE t2 (key UInt32) ENGINE = MergeTree ORDER BY key;
INSERT INTO t2 VALUES (1),(2);
SELECT a FROM ( SELECT key + 1 as a, key FROM t1 GROUP BY key ) WHERE key;
SET join_algorithm = 'full_sorting_merge';
SET max_rows_in_set_to_optimize_join = 0;
SELECT key FROM ( SELECT key FROM t1 GROUP BY key ) t1 JOIN (SELECT key FROM t2) t2 ON t1.key = t2.key WHERE key;
DROP TABLE IF EXISTS t1;
DROP TABLE IF EXISTS t2;