Skip to content

Fix Column identifier is already registered with additional_result_filter in UNION/EXCEPT#101051

Open
alexey-milovidov wants to merge 6 commits intomasterfrom
fix-column-identifier-additional-result-filter
Open

Fix Column identifier is already registered with additional_result_filter in UNION/EXCEPT#101051
alexey-milovidov wants to merge 6 commits intomasterfrom
fix-column-identifier-additional-result-filter

Conversation

@alexey-milovidov
Copy link
Copy Markdown
Member

When multiple UNION/EXCEPT branches share the same GlobalPlannerContext and each applies additional_result_filter, the addAdditionalFilterStepIfNeeded function creates a fake TableNode without an alias for each branch. Both branches try to register the same bare column identifier (e.g. a) in the shared context, causing the second to throw a LOGICAL_ERROR exception.

Fix by giving each fake table expression a unique alias so that column identifiers become unique across branches.

Fixes #99931

CI report: https://s3.amazonaws.com/clickhouse-test-reports/json.html?PR=100947&sha=d0c5ef2315e4d001a6d34cf2e54a9ee2b176a538&name_0=PR&name_1=Stress%20test%20%28amd_debug%29

Changelog category (leave one):

  • Bug Fix (user-visible misbehavior in an official stable release)

Changelog entry (a user-readable short description of the changes that goes into CHANGELOG.md):

Fix LOGICAL_ERROR exception "Column identifier is already registered" when additional_result_filter setting is used with UNION or EXCEPT queries.

Documentation entry for user-facing changes

  • Documentation is written (mandatory for new features)

…_filter` in UNION/EXCEPT

When multiple UNION branches share the same `GlobalPlannerContext` and each
applies `additional_result_filter`, the `addAdditionalFilterStepIfNeeded`
function creates a fake `TableNode` without an alias for each branch. Both
branches try to register the same bare column identifier (e.g. "a") in the
shared context, causing the second to throw a LOGICAL_ERROR.

Fix by giving each fake table expression a unique alias so that column
identifiers become unique across branches (e.g. "_additional_result_filter_0.a"
and "_additional_result_filter_1.a").

Fixes #99931
https://s3.amazonaws.com/clickhouse-test-reports/json.html?PR=100947&sha=d0c5ef2315e4d001a6d34cf2e54a9ee2b176a538&name_0=PR&name_1=Stress%20test%20%28amd_debug%29

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@clickhouse-gh
Copy link
Copy Markdown
Contributor

clickhouse-gh bot commented Mar 29, 2026

Workflow [PR], commit [52ac032]

Summary:

job_name test_name status info comment
Stress test (amd_tsan) failure
Logical error: Shard number is greater than shard count: shard_num=A shard_count=B cluster=C (STID: 5066-457d) FAIL cidb
Stress test (arm_msan) failure
MemorySanitizer: use-of-uninitialized-value (STID: 2410-543a) FAIL cidb

AI Review

Summary

This PR fixes additional_result_filter failures for UNION/EXCEPT by assigning a synthetic alias to the temporary table expression used for filter analysis, and adds a regression test. The direction is correct, but the current alias generation remains deterministic and can still collide with user-defined aliases, so I request changes.

Findings
  • ⚠️ Majors
    • [src/Planner/Planner.cpp:1685] The synthetic alias _additional_result_filter_<id> is deterministic and can collide with real user aliases, reintroducing Column identifier ... is already registered in GlobalPlannerContext.
    • Suggested fix: generate aliases with collision checks against existing identifiers in GlobalPlannerContext (retry until no <alias>.<projection_column> conflicts), or use a suffix scheme that is guaranteed not to overlap with user aliases.
ClickHouse Rules
Item Status Notes
Deletion logging
Serialization versioning
Core-area scrutiny
No test removal
Experimental gate
No magic constants
Backward compatibility ⚠️ Potential remaining LOGICAL_ERROR path due to deterministic alias collision with user aliases
SettingsChangesHistory.cpp
PR metadata quality
Safe rollout ⚠️ Rollout risk remains until alias collision is fully prevented
Compilation time
Final Verdict
  • Status: ⚠️ Request changes
  • Minimum required actions:
    • Make synthetic alias generation collision-resistant against existing identifiers in shared GlobalPlannerContext.
    • Keep/extend the regression test to cover a user alias that matches the synthetic alias pattern.

@clickhouse-gh clickhouse-gh bot added the pr-bugfix Pull request with bugfix, not backported by default label Mar 29, 2026
/// When multiple UNION branches share the same GlobalPlannerContext and each applies additional_result_filter,
/// the bare column names (e.g. "a") would collide. Give the fake table expression a unique alias
/// so that identifiers become unique (e.g. "_additional_result_filter_0.a").
auto unique_alias = "_additional_result_filter_" + std::to_string(planner_context->getGlobalPlannerContext()->nextUniqueId());
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ This alias is deterministic and can still collide with real query aliases. For example, if a user has a source alias _additional_result_filter_0 and a projected column a, GlobalPlannerContext::createColumnIdentifier can still throw Column identifier ... is already registered for _additional_result_filter_0.a.

Please make the synthetic alias collision-resistant against existing identifiers in the shared context, e.g. loop over generated aliases until alias + "." + projection_column does not exist in GlobalPlannerContext (or use a truly unique suffix that cannot appear in user aliases).

@clickhouse-gh
Copy link
Copy Markdown
Contributor

clickhouse-gh bot commented Mar 31, 2026

LLVM Coverage Report

Metric Baseline Current Δ
Lines 84.10% 84.10% +0.00%
Functions 90.90% 90.90% +0.00%
Branches 76.70% 76.70% +0.00%

Changed lines: 87.50% (7/8) · Uncovered code

Full report · Diff report

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

pr-bugfix Pull request with bugfix, not backported by default

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Logical error: Column identifier A is already registered (STID: 4697-4326)

2 participants