Skip to content

Commit 374c1a8

Browse files
Backport #51301 to 23.5: Fix fuzzer failure in ActionsDAG
1 parent 9b52aef commit 374c1a8

3 files changed

Lines changed: 28 additions & 10 deletions

File tree

src/Interpreters/ActionsDAG.cpp

Lines changed: 21 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1876,10 +1876,10 @@ struct ConjunctionNodes
18761876
ActionsDAG::NodeRawConstPtrs rejected;
18771877
};
18781878

1879-
/// Take a node which result is predicate.
1879+
/// Take a node which result is a predicate.
18801880
/// Assuming predicate is a conjunction (probably, trivial).
18811881
/// Find separate conjunctions nodes. Split nodes into allowed and rejected sets.
1882-
/// Allowed predicate is a predicate which can be calculated using only nodes from allowed_nodes set.
1882+
/// Allowed predicate is a predicate which can be calculated using only nodes from the allowed_nodes set.
18831883
ConjunctionNodes getConjunctionNodes(ActionsDAG::Node * predicate, std::unordered_set<const ActionsDAG::Node *> allowed_nodes)
18841884
{
18851885
ConjunctionNodes conjunction;
@@ -2113,9 +2113,9 @@ ActionsDAGPtr ActionsDAG::cloneActionsForFilterPushDown(
21132113
Node * predicate = const_cast<Node *>(tryFindInOutputs(filter_name));
21142114
if (!predicate)
21152115
throw Exception(ErrorCodes::LOGICAL_ERROR,
2116-
"Output nodes for ActionsDAG do not contain filter column name {}. DAG:\n{}",
2117-
filter_name,
2118-
dumpDAG());
2116+
"Output nodes for ActionsDAG do not contain filter column name {}. DAG:\n{}",
2117+
filter_name,
2118+
dumpDAG());
21192119

21202120
/// If condition is constant let's do nothing.
21212121
/// It means there is nothing to push down or optimization was already applied.
@@ -2142,18 +2142,29 @@ ActionsDAGPtr ActionsDAG::cloneActionsForFilterPushDown(
21422142
}
21432143

21442144
auto conjunction = getConjunctionNodes(predicate, allowed_nodes);
2145-
if (conjunction.rejected.size() == 1 && !conjunction.rejected.front()->result_type->equals(*predicate->result_type)
2146-
&& conjunction.allowed.front()->type == ActionType::COLUMN)
2147-
{
2148-
// No further optimization can be done
2145+
2146+
if (conjunction.allowed.empty())
21492147
return nullptr;
2148+
2149+
chassert(predicate->result_type);
2150+
2151+
if (conjunction.rejected.size() == 1)
2152+
{
2153+
chassert(conjunction.rejected.front()->result_type);
2154+
2155+
if (conjunction.allowed.front()->type == ActionType::COLUMN
2156+
&& !conjunction.rejected.front()->result_type->equals(*predicate->result_type))
2157+
{
2158+
/// No further optimization can be done
2159+
return nullptr;
2160+
}
21502161
}
21512162

21522163
auto actions = cloneActionsForConjunction(conjunction.allowed, all_inputs);
21532164
if (!actions)
21542165
return nullptr;
21552166

2156-
/// Now, when actions are created, update current DAG.
2167+
/// Now, when actions are created, update the current DAG.
21572168

21582169
if (conjunction.rejected.empty())
21592170
{

tests/queries/0_stateless/02791_predicate_pushdown_different_types.reference

Whitespace-only changes.
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
# These queries triggered a crash in old ClickHouse versions:
2+
3+
CREATE TEMPORARY TABLE a (key UInt32, ID LowCardinality(String));
4+
CREATE TEMPORARY TABLE b (key UInt32);
5+
SELECT * FROM b JOIN a USING (key) WHERE ID = '1' HAVING ID = '1';
6+
7+
# PS. Predicate pushdown does not work for LowCardinality(String), but it's another problem.

0 commit comments

Comments
 (0)