Cherry pick #107407 to 26.4: Fix logical error in disjunction filter push-down through JOIN with type-changing USING key by robot-ch-test-poll4 · Pull Request #108755 · ClickHouse/ClickHouse · GitHub
Skip to content

Cherry pick #107407 to 26.4: Fix logical error in disjunction filter push-down through JOIN with type-changing USING key#108755

Merged
robot-clickhouse merged 4 commits into
backport/26.4/107407from
cherrypick/26.4/107407
Jun 30, 2026
Merged

Cherry pick #107407 to 26.4: Fix logical error in disjunction filter push-down through JOIN with type-changing USING key#108755
robot-clickhouse merged 4 commits into
backport/26.4/107407from
cherrypick/26.4/107407

Conversation

@robot-ch-test-poll4

Copy link
Copy Markdown
Contributor

Original pull-request #107407

Do not merge this PR manually

This pull-request is a first step of an automated backporting.
It contains changes similar to calling git cherry-pick locally.
If you intend to continue backporting the changes, then resolve all conflicts if any.
Otherwise, if you do not want to backport them, then just close this pull-request.

The check results does not matter at this step - you can safely ignore them.

Troubleshooting

If the conflicts were resolved in a wrong way

If this cherry-pick PR is completely screwed by a wrong conflicts resolution, and you want to recreate it:

  • delete the pr-cherrypick label from the PR
  • delete this branch from the repository

You also need to check the Original pull-request for pr-backports-created label, and delete if it's presented there

The PR source

The PR is created in the CI job

groeneai and others added 3 commits June 13, 2026 22:29
…ype-changing USING key

The disjunction (partial predicate) push-down path built a FilterStep directly
against the JOIN input header without the type-fixup that the main push-down path
applies via fix_predicate_for_join_logical_step. When a USING key is widened by the
JOIN (e.g. UInt32 vs Nullable(UInt32)), a pushed predicate over that column kept the
JOIN-output result type while its arguments were re-evaluated against the narrower
input type, tripping the result-type check in executeActionForPartialResult:
"Unexpected return type from equals. Expected Nullable(UInt8). Got UInt8".

Restrict the disjunction push-down to columns whose type is stable across the JOIN
boundary via a require_stable_types flag on get_available_columns_for_filter. Partial
push-down is an opportunistic broadening pre-filter (the full filter still runs above
the JOIN), so skipping type-changing columns is safe; push-down for stable-type
columns is unchanged.

Found by the AST fuzzer (arm_asan_ubsan, STID 3262-3b6a). Same class as issue #89802.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
scope.join_using_columns is a list of raw pointers to a stack-local map
(join_using_column_name_to_column_node) that tryResolveIdentifierFromJoin
pushes while recursing into one JOIN side and pops afterwards. The push/pop
wrapped the recursive tryResolveIdentifierFromJoinTreeNode call without an
exception guard, so when that recursion threw the pop was skipped.

The throw is reachable from normal analysis: the if/multiIf constant-fold
special cases in resolveFunction.cpp resolve statically-dead branches inside
a try/catch and swallow the exception. If a dead branch references an unknown
identifier (UNKNOWN_IDENTIFIER), the throw unwound past the pop, the stack-local
map was destroyed, and its pointer was left dangling in scope.join_using_columns.
A later tryBindIdentifierToJoinUsingColumn iterated the list and dereferenced the
dangling pointer, segfaulting (NULL pointer read) in the analyzer.

Make the pop run on every exit path with SCOPE_EXIT, and balance it against a
captured flag so a push is always matched by exactly one pop.

Found by the AST fuzzer (amd_debug, targeted, STID 5737-6ff0) on PR #107407,
which mutated the new 04330 JOIN USING / EXPLAIN seed query into a form with a
dead if/multiIf branch referencing a non-existent qualifier. Pre-existing bug,
independent of the disjunction push-down change in this PR. Regression query
added to 04330_join_disjunctions_pushdown_using_type_mismatch.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…n-using-type-mismatch

Fix logical error in disjunction filter push-down through JOIN with type-changing USING key
@robot-ch-test-poll4 robot-ch-test-poll4 added pr-cherrypick Cherry-pick of merge-commit before backporting. Do not use manually - automated use only! do not test disable testing on pull request pr-bugfix Pull request with bugfix, not backported by default labels Jun 28, 2026
…ypick/26.4/107407

# Conflicts:
#	src/Analyzer/Resolve/IdentifierResolver.cpp
@alexey-milovidov

Copy link
Copy Markdown
Member

@robot-clickhouse robot-clickhouse merged commit b82f663 into backport/26.4/107407 Jun 30, 2026
1 check passed
@robot-clickhouse robot-clickhouse deleted the cherrypick/26.4/107407 branch June 30, 2026 07:04
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

do not test disable testing on pull request pr-bugfix Pull request with bugfix, not backported by default pr-cherrypick Cherry-pick of merge-commit before backporting. Do not use manually - automated use only!

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants