Fix `DESCRIBE TABLE (...) AS ...` syntax by yariks5s · Pull Request #100205 · ClickHouse/ClickHouse · GitHub
Skip to content

Fix DESCRIBE TABLE (...) AS ... syntax#100205

Merged
alexey-milovidov merged 13 commits into
masterfrom
yarik/describe-subquery-alias-fix
Jun 24, 2026
Merged

Fix DESCRIBE TABLE (...) AS ... syntax#100205
alexey-milovidov merged 13 commits into
masterfrom
yarik/describe-subquery-alias-fix

Conversation

@yariks5s

@yariks5s yariks5s commented Mar 20, 2026

Copy link
Copy Markdown
Member

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):

Fixes the case where an alias after a subquery in DESCRIBE TABLE is not accepted by the parser and results in a syntax error. Fixes #100031.

Documentation entry for user-facing changes

  • Documentation is written (mandatory for new features)

Version info

  • Merged into: 26.6.1.1195

@clickhouse-gh

clickhouse-gh Bot commented Mar 20, 2026

Copy link
Copy Markdown
Contributor

@clickhouse-gh clickhouse-gh Bot added the pr-bugfix Pull request with bugfix, not backported by default label Mar 20, 2026
@alexey-milovidov

Copy link
Copy Markdown
Member

The failures of 00175_obfuscator_schema_inference and 00096_obfuscator_save_load in Stateless tests (amd_tsan, parallel) are NOT caused by this PR.

They were introduced by #104690 ("Add UntrackedMemory asynchronous metric"), which made clickhouse-obfuscator abort (SIGABRT) on process teardown: the query results are correct, but the Aborted line on stderr fails the test. #104690 has now been reverted (#106365).

#104690 was merged in violation of the ClickHouse team rules: its own CI already showed these two tests failing (10 times between May 12 and June 1) before it was merged.

Please update your branch to pick up the revert; the tests should pass again.

Comment thread src/Parsers/ParserDescribeTableQuery.cpp Outdated
alexey-milovidov and others added 2 commits June 6, 2026 06:33
…Expression

The previous guard `pos->type != TokenType::OpeningRoundBracket` diverted
every parenthesized `DESCRIBE` source to `ParserTableExpression`, which
consumes only the first `(SELECT ...)` and leaves any following set operator
unparsed. This regressed valid queries such as
`DESCRIBE (SELECT 1) UNION ALL (SELECT 2)`.

Instead, speculatively parse a `SELECT` first and keep it only when it is a
bare `SELECT` or a genuine set operation (more than one element). A lone
parenthesized `SELECT` is rolled back so `ParserTableExpression` can pick up a
trailing alias, fixing `DESCRIBE (SELECT 1) AS source` without breaking set
operations.

Extends test 04053_describe_subquery_alias with UNION ALL coverage for both
parser branches.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@alexey-milovidov

Copy link
Copy Markdown
Member

Picked up this PR, merged the latest master, and addressed the AI Review blocker.

AI Review blocker (fixed in 0915825): the previous guard pos->type != TokenType::OpeningRoundBracket routed every parenthesized DESCRIBE source through ParserTableExpression, which consumes only the first (SELECT ...) and leaves a following set operator unparsed — regressing valid queries like DESCRIBE (SELECT 1) UNION ALL (SELECT 2).

The parser now speculatively parses a SELECT first and keeps the SELECT path only for a bare SELECT or a genuine set operation (more than one element in the union); a lone parenthesized SELECT is rolled back so ParserTableExpression can pick up a trailing alias. Both branches are now covered in 04053_describe_subquery_alias (added UNION ALL).

Verified with a freshly built binary; the test output is byte-identical to the reference:

DESCRIBE (SELECT 1 AS a) AS source            -> a UInt8
DESCRIBE (SELECT 1 AS a) UNION ALL (SELECT 2) -> a UInt8
DESCRIBE (SELECT 1 AS a) INTERSECT (SELECT 2) -> a UInt8
DESCRIBE (SELECT 1 AS a) EXCEPT (SELECT 2)    -> a UInt8
DESCRIBE SELECT 1 AS a                        -> a UInt8
DESCRIBE numbers(10)                          -> number UInt64

CI: the only failures on the previous run were the Performance Comparison (arm_release) jobs, where every flagged query (entropy, rand, logical_functions_small, parallel_hash_join_various) appears in both ::old and ::new — i.e. environmental perf noise, not a regression a DESCRIBE-parser change could cause. The 00175_obfuscator_schema_inference / 00096_obfuscator_save_load failures you noted earlier are already resolved: the branch now contains the revert of #104690 (#106365).

Comment thread src/Parsers/ParserDescribeTableQuery.cpp Outdated
alexey-milovidov and others added 5 commits June 8, 2026 03:42
The previous fix kept the speculative `SELECT` path whenever the parsed
`ASTSelectWithUnionQuery` had more than one element in `list_of_selects`.
But `ParserSelectWithUnionQuery` lifts up a single parenthesized inner
union, so a lone parenthesized subquery whose body is a set operation,
such as `DESCRIBE (SELECT 1 AS a UNION ALL SELECT 2) AS source`, also
produces two elements. As a result it stayed on the `SELECT` path and the
trailing `AS source` was left unconsumed, producing the same syntax error
this pull request fixes.

Disambiguate by inspecting what follows the parenthesis matching the
leading `(` instead of the element count: keep the `SELECT` path only when
that parenthesis is immediately followed by a set-operation keyword
(`UNION`, `EXCEPT`, `INTERSECT`), i.e. a genuine top-level set operation
like `(SELECT 1) UNION ALL (SELECT 2)`. A lone parenthesized subquery,
even one whose body is a set operation, is rolled back to
`ParserTableExpression` so the trailing alias is accepted.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…uery-alias-fix

Pick up the master fix for the 01951_distributed_push_down_limit and
01952_optimize_distributed_group_by_sharding_key Fast test (arm_darwin)
failures, which were a master-wide transient regression (the distributed
query plan EXPLAIN output changed ReadFromRemote into an inlined local
plan) unrelated to this DESCRIBE parser change.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@alexey-milovidov

Copy link
Copy Markdown
Member

Merged the latest master to refresh CI (the branch was ~700 commits behind and the previous run was red only on unrelated jobs). The PR code is unchanged — the three DESCRIBE source files are byte-identical to the previous head.

The red checks on the previous run are all unrelated to this DESCRIBE-parser change:

  • Stress test (arm_msan)Logical error: Bad cast from type A to B (STID: 4054-600e), an AST-fuzzer exception while building a MergeTreeIndexMinMax / KeyCondition (RPNBuilder), with no DESCRIBE involved. It is a known master-wide flake, tracked as Logical error: Bad cast from type A to B (STID: 4054-600e) #107598 (it fires on master itself and on many unrelated PRs over the last week), and the CI summary already links that issue.
  • Performance Comparison (arm_release, 4/6 and 6/6) — every flagged query (hash_table_sizes_stats, array_reduce, group_by_fixed_keys, count_from_formats, aggregate_functions_of_group_by_keys, index_bulk_filtering, …) is flagged in both ::old and ::new, i.e. environmental noise on the arm runners. A change confined to ParserDescribeTableQuery cannot affect the runtime of aggregation/join workloads.

AI Review verdict is ✅ Approve, there are no unresolved review threads, and coverage of the changed lines is 25/25 (100%). Re-running CI on a current master for a clean confirmation before merge.

Refresh CI: branch was 553 commits behind master and the previous run was
red only on unrelated master-wide flakes (refreshable mat view integration
test, arm_msan Hung check, BuzzHouse fault-injection harness). The PR code is
unchanged - master touched none of the three DESCRIBE source files.
@alexey-milovidov

Copy link
Copy Markdown
Member

Merged the latest master to refresh CI (919e667b46a..4c5fee8ce95). The branch was 553 commits behind and the previous run was red only on unrelated, master-wide flakes. The PR code is unchanged — the merge net diff vs master is exactly the three DESCRIBE files (src/Parsers/ParserDescribeTableQuery.cpp and the 04053_describe_subquery_alias test/reference), all byte-identical to the previous head. master touched none of these files.

The previous run's failures are not caused by this PR:

  • test_refreshable_mat_view_replicated/test.py::test_circular_dependencies_survive_restart (max_t not unique) — a refreshable-materialized-view flake that fails across many PRs and on master itself (PR=0), ~2–6 times/day; nothing to do with the DESCRIBE parser.
  • Stress test (arm_msan)Hung check failed, possible deadlock found — a chronic master-wide burst (≈45–50 PRs/day on 2026-06-16…19), tracked in Hung check failed, possible deadlock found #107941. The stack trace is in the AST fuzzer (executeASTFuzzerQueries), unrelated to this change.
  • BuzzHouse (arm_asan_ubsan) — the run aborted on the injected fault point tcp_handler_fail_connection_setup (MEMORY_LIMIT_EXCEEDED), i.e. a fault-injection harness artifact, not a real crash and not related to the parser.

AI Review is ✅ Approve, all review threads are resolved, and changed-line coverage is complete. The remaining blocker is a human approval.

Refresh CI on the latest master. The previous run's only red was a job-level
cancellation of the 'Integration tests (amd_asan_ubsan, db disk, old analyzer, 5/6)'
shard: test_storage_iceberg_concurrent/test_concurrent_reads hung (the known-flaky
test fixed by the merged #108075), which pushed the shard past its time budget and
caused the operation to be canceled; the in-flight tests (test_huge_concurrent_restore,
test_azure_disk_unreachable) were marked failed only because of that cancellation.
This merge brings in #108075 (merged after the previous merge-base), which fixes the
hang. The DESCRIBE parser code is unchanged - master touched none of the PR's three
files, so the merge net diff vs master is exactly those files, byte-identical.
@alexey-milovidov

Copy link
Copy Markdown
Member

Merged the latest master to refresh CI (4c5fee8ce95..250b67baacf). The PR code is unchangedmaster touched none of the PR's three files (src/Parsers/ParserDescribeTableQuery.cpp and the 04053_describe_subquery_alias test/reference), so the merge net diff vs master is exactly those three files (96 insertions / 2 deletions), all byte-identical to the previous head.

This merge is not just to refresh drift — it brings in a fix for the only red on the previous run. That run's sole failure was a job-level cancellation of Integration tests (amd_asan_ubsan, db disk, old analyzer, 5/6): test_storage_iceberg_concurrent/test_concurrent_reads.py::test_concurrent_reads hung for ~50 minutes, pushing the shard past its time budget (##[error]The operation was canceled.). The other tests reported as failed in that shard (test_huge_concurrent_restore, test_azure_disk_unreachable) were merely in flight at the moment of cancellation, not real failures — the shard's own test report shows 0 failures. The hang is the known-flaky test fixed by #108075, which was merged after the previous merge-base, so this merge picks up the fix.

AI Review is ✅ Approve, all review threads are resolved, and changed-line coverage is complete. The remaining blocker is a human approval.

@clickhouse-gh

clickhouse-gh Bot commented Jun 22, 2026

Copy link
Copy Markdown
Contributor

LLVM Coverage Report

Metric Baseline Current Δ
Lines 85.40% 85.30% -0.10%
Functions 92.60% 92.60% +0.00%
Branches 77.60% 77.60% +0.00%

Changed lines: Changed C/C++ lines covered by tests: 25/25 (100.00%) | Lost baseline coverage: none · Uncovered code

Full report · Diff report

@alexey-milovidov alexey-milovidov self-assigned this Jun 24, 2026
@alexey-milovidov alexey-milovidov added this pull request to the merge queue Jun 24, 2026
Merged via the queue into master with commit 1257fef Jun 24, 2026
167 checks passed
@alexey-milovidov alexey-milovidov deleted the yarik/describe-subquery-alias-fix branch June 24, 2026 02:13
@robot-ch-test-poll2 robot-ch-test-poll2 added the pr-synced-to-cloud The PR is synced to the cloud repo label Jun 24, 2026
alexey-milovidov added a commit that referenced this pull request Jun 24, 2026
Add changelog entries for PRs that landed on the 26.6 release line after
the first pass: #82414, #108042 (New Feature), #107428 (Improvement),
and #108128, #108288, #100205, #108029 (Bug Fix).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@clickgapai

Copy link
Copy Markdown
Contributor

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 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.

DESCRIBE TABLE (...) AS <alias> syntax broken since version 26

4 participants