Skip to content

Commit 005f1d0

Browse files
Backport #51301 to 23.4: Fix fuzzer failure in ActionsDAG
1 parent fdcbd7d commit 005f1d0

3 files changed

Lines changed: 29 additions & 7 deletions

File tree

src/Interpreters/ActionsDAG.cpp

Lines changed: 22 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1874,10 +1874,10 @@ struct ConjunctionNodes
18741874
ActionsDAG::NodeRawConstPtrs rejected;
18751875
};
18761876

1877-
/// Take a node which result is predicate.
1877+
/// Take a node which result is a predicate.
18781878
/// Assuming predicate is a conjunction (probably, trivial).
18791879
/// Find separate conjunctions nodes. Split nodes into allowed and rejected sets.
1880-
/// Allowed predicate is a predicate which can be calculated using only nodes from allowed_nodes set.
1880+
/// Allowed predicate is a predicate which can be calculated using only nodes from the allowed_nodes set.
18811881
ConjunctionNodes getConjunctionNodes(ActionsDAG::Node * predicate, std::unordered_set<const ActionsDAG::Node *> allowed_nodes)
18821882
{
18831883
ConjunctionNodes conjunction;
@@ -2111,9 +2111,9 @@ ActionsDAGPtr ActionsDAG::cloneActionsForFilterPushDown(
21112111
Node * predicate = const_cast<Node *>(tryFindInOutputs(filter_name));
21122112
if (!predicate)
21132113
throw Exception(ErrorCodes::LOGICAL_ERROR,
2114-
"Output nodes for ActionsDAG do not contain filter column name {}. DAG:\n{}",
2115-
filter_name,
2116-
dumpDAG());
2114+
"Output nodes for ActionsDAG do not contain filter column name {}. DAG:\n{}",
2115+
filter_name,
2116+
dumpDAG());
21172117

21182118
/// If condition is constant let's do nothing.
21192119
/// It means there is nothing to push down or optimization was already applied.
@@ -2140,14 +2140,29 @@ ActionsDAGPtr ActionsDAG::cloneActionsForFilterPushDown(
21402140
}
21412141

21422142
auto conjunction = getConjunctionNodes(predicate, allowed_nodes);
2143-
if (conjunction.rejected.size() == 1 && WhichDataType{removeNullable(conjunction.rejected.front()->result_type)}.isFloat())
2143+
2144+
if (conjunction.allowed.empty())
21442145
return nullptr;
21452146

2147+
chassert(predicate->result_type);
2148+
2149+
if (conjunction.rejected.size() == 1)
2150+
{
2151+
chassert(conjunction.rejected.front()->result_type);
2152+
2153+
if (conjunction.allowed.front()->type == ActionType::COLUMN
2154+
&& !conjunction.rejected.front()->result_type->equals(*predicate->result_type))
2155+
{
2156+
/// No further optimization can be done
2157+
return nullptr;
2158+
}
2159+
}
2160+
21462161
auto actions = cloneActionsForConjunction(conjunction.allowed, all_inputs);
21472162
if (!actions)
21482163
return nullptr;
21492164

2150-
/// Now, when actions are created, update current DAG.
2165+
/// Now, when actions are created, update the current DAG.
21512166

21522167
if (conjunction.rejected.empty())
21532168
{

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)