Support parenthesized table joins in FROM clause by alexey-milovidov · Pull Request #97650 · ClickHouse/ClickHouse · GitHub
Skip to content

Support parenthesized table joins in FROM clause#97650

Merged
alexey-milovidov merged 3 commits into
masterfrom
fix-parenthesized-from
Feb 27, 2026
Merged

Support parenthesized table joins in FROM clause#97650
alexey-milovidov merged 3 commits into
masterfrom
fix-parenthesized-from

Conversation

@alexey-milovidov

@alexey-milovidov alexey-milovidov commented Feb 22, 2026

Copy link
Copy Markdown
Member

Summary

Standard SQL allows parentheses around joined table expressions in FROM clauses:

SELECT * FROM (t1 CROSS JOIN t2)
SELECT * FROM (t1 INNER JOIN t2 ON t1.a = t2.a)

ClickHouse previously rejected this with SYNTAX_ERROR because ParserSubquery only accepted SELECT/EXPLAIN inside parentheses. This is valid syntax in PostgreSQL, MySQL, DuckDB, and SQLite.

The fix adds a fallback in ParserTableExpression: when all normal parse attempts fail (subquery, function, identifier) and the position is at (, try parsing the content as ParserTablesInSelectQuery. If it contains a join (more than one table element), convert it to SELECT * FROM <tables> and wrap as a subquery. Single-table parenthesization (t1) is intentionally not matched to avoid ambiguity with expression parentheses.

Test plan

  • Added tests/queries/0_stateless/03985_parenthesized_from_join.sql covering CROSS JOIN, INNER JOIN with ON, alias on the parenthesized expression, and nested usage
  • Verified no regressions: normal subqueries (SELECT ...), ORDER BY with tuple parens, IN with subqueries, CREATE TABLE with ORDER BY all work correctly
  • Verified system tables with ORDER BY (col1, col2) in metadata load correctly (the initial approach of modifying ParserSubquery broke this — fixed by only modifying ParserTableExpression)

Changelog category (leave one):

  • Improvement

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

Support parenthesized table join expressions in FROM clause, e.g. SELECT * FROM (t1 CROSS JOIN t2).

🤖 Generated with Claude Code

Version info

  • Merged into: 26.3.1.93

Standard SQL allows parentheses around joined table expressions:
`SELECT * FROM (t1 CROSS JOIN t2)`. ClickHouse previously rejected
this with a syntax error because `ParserSubquery` only accepted
SELECT/EXPLAIN inside parentheses.

The fix adds a fallback in `ParserTableExpression`: when all normal
parse attempts fail and the position is at `(`, try to parse the
content as `ParserTablesInSelectQuery`. If it contains a join (more
than one table element), convert it to `SELECT * FROM <tables>` and
wrap as a subquery. Single-table parenthesization `(t1)` is not
matched to avoid ambiguity with expression parentheses.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@clickhouse-gh

clickhouse-gh Bot commented Feb 22, 2026

Copy link
Copy Markdown
Contributor

@clickhouse-gh clickhouse-gh Bot added the pr-improvement Pull request with some product improvements label Feb 22, 2026
@alexey-milovidov

Copy link
Copy Markdown
Member Author

The AST fuzzer failure (Bad cast from ColumnFixedString to ColumnLowCardinality in concat) is unrelated to this PR and already fixed on master:

@alexey-milovidov alexey-milovidov added this pull request to the merge queue Feb 27, 2026
@alexey-milovidov alexey-milovidov self-assigned this Feb 27, 2026
Merged via the queue into master with commit d5119ed Feb 27, 2026
148 checks passed
@alexey-milovidov alexey-milovidov deleted the fix-parenthesized-from branch February 27, 2026 01:47
@robot-ch-test-poll1 robot-ch-test-poll1 added the pr-synced-to-cloud The PR is synced to the cloud repo label Feb 27, 2026
@PedroTadim

Copy link
Copy Markdown
Member

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

Labels

pr-improvement Pull request with some product improvements pr-synced-to-cloud The PR is synced to the cloud repo

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants