Remove object_storage_cluster_join_mode=local - #2228
Conversation
|
@codex review |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 317db7ca6f
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| case ObjectStorageClusterJoinMode::LOCAL: // Legacy mode, equal to 'allow' | ||
| return; |
There was a problem hiding this comment.
Preserve initiator-local joins for legacy local mode
When local is selected for an object-storage cluster query that joins a table existing only on the initiator—the scenario in tests/integration/test_s3_cluster/test.py::test_joins—returning here leaves the join in query_to_send, which is dispatched to every shard; for example, s0_1_0 cannot resolve the test's join_table. The previous LOCAL path stripped the join and forced FetchColumns so it ran on the initiator, whereas the new ALLOW behavior requests WithMergeableState; therefore existing local queries and the integration test fail rather than retaining compatible behavior.
Useful? React with 👍 / 👎.
| - `local` — Replaces the database and table in the subquery with local ones for the destination server (shard), leaving the normal `IN`/`JOIN.` | ||
| - `global` — Replaces the `IN`/`JOIN` query with `GLOBAL IN`/`GLOBAL JOIN.` Right table executes first and is added to the secondary query as temporay table. | ||
| - `allow` — Default value. Allows the use of these types of subqueries. | ||
| - `local` — deprecated, legacy mode. The same as 'allow'. |
There was a problem hiding this comment.
Format the allow setting value as inline code
Replace the prose quotation 'allow' with the inline-code form `allow`. This is a literal ClickHouse setting value, and the repository requires such literals in documentation and comments to be wrapped in inline code.
AGENTS.md reference: AGENTS.md:L7-L7
Useful? React with 👍 / 👎.
…al tables Read the left object-storage table on cluster nodes and run `JOIN` / local `IN` on the initiator, including with `allow_experimental_analyzer=0`, so the right table does not need to exist on remote nodes. Keep `local` as a legacy alias of `allow`. Co-authored-by: Cursor <cursoragent@cursor.com>
…uster` The previous initiator-local rewrite duplicated planner/`removeJoin` logic. Call `extractLeftTableExpression`, `buildQueryToReadColumnsFromTableExpression`, and `removeJoin` instead. Co-authored-by: Cursor <cursoragent@cursor.com>
`GLOBAL IN` becomes `ASTTableIdentifier` `_subqueryN`, which `as<ASTIdentifier>` does not match, so remotes still received `GLOBAL IN (_subqueryN)` with analyzer disabled. Co-authored-by: Cursor <cursoragent@cursor.com>
Rewrite JOIN/IN to `GLOBAL JOIN`/`GLOBAL IN` in the old interpreter so `GlobalSubqueriesVisitor` can broadcast right tables, and send those external tables with the remote query. Co-authored-by: Cursor <cursoragent@cursor.com>
|
@codex review |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: f10d74d7e4
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| && (rhs->as<ASTSubquery>() || rhs->as<ASTSelectQuery>() || rhs->as<ASTSelectWithUnionQuery>() | ||
| || rhs->as<ASTIdentifier>() || rhs->as<ASTTableIdentifier>())) |
There was a problem hiding this comment.
Do not globalize expression aliases used as IN sets
When allow_experimental_analyzer=0 and object_storage_cluster_join_mode='global', a valid constant-set alias such as WITH (1, 2) AS vals ... WHERE key IN vals remains an ASTIdentifier; this branch converts it to globalIn, but GlobalSubqueriesMatcher::Data::addExternalStorage accepts only an ASTTableIdentifier, ASTSubquery, or ASTTableExpression, so analysis throws WRONG_GLOBAL_SUBQUERY instead of evaluating the set. Restrict this rewrite to actual table/subquery operands or resolve expression aliases first.
Useful? React with 👍 / 👎.
There was a problem hiding this comment.
This reproduction does not fail. rewriteASTInFunctionsToGlobalIn runs before TreeRewriter. For WITH (1, 2) AS vals ... WHERE key IN vals, the RHS is still an ASTIdentifier at that point, so it is rewritten to globalIn. Then QueryNormalizer inlines the WITH alias to the constant tuple, and GlobalSubqueriesVisitor sees a literal/function RHS and converts globalIn back to in. addExternalStorage is not invoked, so there is no WRONG_GLOBAL_SUBQUERY.
The suggested fix — skip ASTIdentifier and only rewrite table/subquery operands — would be incorrect here. At rewrite time, IN join_table is also an ASTIdentifier; MarkTableIdentifiersVisitor has not run yet. Dropping that case would skip the rewrite that object_storage_cluster_join_mode=global needs for initiator-local tables.
No code change for this comment.
Changelog category (leave one):
Changelog entry (a user-readable short description of the changes that goes to CHANGELOG.md):
Remove object_storage_cluster_join_mode=local
Solved #1827
Improved default 'allow' behavior to work in swarm mode (when remote nodes do not have knowledge about tables).
Improved 'global' mode to work with old analyzer.
Documentation entry for user-facing changes
'local' is a legacy setting, behavior is the same as 'allow' after changes in upstream.
CI/CD Options
Exclude tests:
Regression jobs to run: