EXPLAIN SYNTAX: return a single record and default oneline to 1 - #107925
EXPLAIN SYNTAX: return a single record and default oneline to 1#107925groeneai wants to merge 14 commits into
Conversation
Pre-PR validation gate
Session id: cron:clickhouse-worker-slot-1:20260618-235400 |
|
cc @alexey-milovidov @KochetovNicolai — could you review this? It implements #80410: |
|
@groeneai, provide a setting to turn this behavior on/off. Make it one-line by default, but update the tests so that reference files don't change. |
3f7a297 to
f8c8598
Compare
|
Workflow [PR], commit [c838bc5] Summary: ✅
AI ReviewSummaryThis PR changes Final Verdict
|
f8c8598 to
8449e86
Compare
|
@alexey-milovidov done. Gated behind an
I made it an EXPLAIN-local option rather than a server setting, matching the existing |
Pre-PR validation gate
Session id: cron:clickhouse-worker-slot-0:20260619-040100 |
8449e86 to
8b5ed2b
Compare
|
CI fully finished on head
No PR-caused failures. All reds are pre-existing flaky/trunk signatures unrelated to the EXPLAIN SYNTAX change. |
|
@groeneai Could you add one top-level output-format test for this as well? The existing subquery checks cover the row shape through with a reference like: This asserts that |
|
@cv4g Added a top-level EXPLAIN SYNTAX single_record = 1 SELECT 1 FROM system.one WHERE dummy = 0 FORMAT JSONEachRow;
-- {"explain":"SELECT 1\nFROM system.one\nWHERE equals(dummy, 0)"}
EXPLAIN SYNTAX SELECT 1 FROM system.one WHERE dummy = 0 FORMAT JSONEachRow;
-- {"explain":"SELECT 1"} / {"explain":"FROM system.one"} / {"explain":"WHERE equals(dummy, 0)"}This asserts directly that One change from your example: the predicate is |
Pre-PR validation gate (click to expand) — top-level JSONEachRow test add
Validation: 50/50 with randomization, 30/30 with Session id: cron:clickhouse-worker-slot-1:20260630-164700 |
CI finish ledger — ebff1a0Every failure below has an owner (a fixing PR). Only
No PR-caused failures. Session id: cron:our-pr-ci-monitor:20260701-000000 |
|
How is this different from existing SELECT EXPLAIN option |
|
@rschu1ze They are orthogonal.
Same query with In short: |
|
We are over-complicating this. We should rather keep EXPLAIN SYNTAX simple and dumb and its defaults reasonable. @groeneai Do not introduce |
|
@rschu1ze Understood, simpler is better. One thing to align before I rework, because it collides with an earlier directive on this PR. @alexey-milovidov asked (2026-06-19) to gate the single-multi-line-record behavior behind a setting, keep it off by default, and specifically so that no Your ask is the opposite: make it the default and drop the extra option. Making a single multi-line record the default is a behavior change for Also note Which do you both want?
Happy to implement either immediately once you agree. |
|
I want option 1.: Default ON (drop single_record, single multi-line record becomes the default, accept the ~140 reference updates). |
|
@rschu1ze Ack, proceeding with option 1: dropping @alexey-milovidov this reverses your 2026-06-19 request to gate it behind a setting with default off. If you disagree with defaulting it on, say so before I push the rework. |
EXPLAIN SYNTAX now returns the reformatted query as one multi-line record instead of one record per line, so the output is directly copy-pasteable (issue ClickHouse#80410). PLAN/PIPELINE/AST keep their per-line tree output. Regenerated the affected stateless .reference files (row-per-line to single-record collapse) and updated 04338_explain_syntax_single_record to assert the new default behavior. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
EXPLAIN SYNTAX now emits a single physical line by default (oneline=1). The 02428_parameterized_view test is tagged `long`, so the earlier reference regeneration (which ran with --no-long) missed it. Its lone EXPLAIN SYNTAX output line was still in the old multi-line escaped form. Regenerated to the single-line form; verified the full test passes. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
|
Fixed a further Comprehensive re-check: ran all 142 tests that use |
…default The oneline=1 EXPLAIN SYNTAX default (f3f2035) collapses multi-line reformatted queries to a single physical line. Prior slots regenerated the default .reference files but not the .oldanalyzer.reference variants used by the old-analyzer CI jobs, causing Stateless coverage-job failures on 3e03fa6. Regenerated all 28 stale .oldanalyzer.reference files (whitespace-insensitive content identical to the old form; pure multi-line -> single-line reformat). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
|
Regenerated the |
long drops these tests from every --no-long sweep (LLVM coverage etc.), not just flaky-check. That side effect already bit this PR: 02428 was skipped during the oneline=1 reference regeneration pass, so its stale reference survived a CI round. The actual problem is only flaky-check's per-run TOO_LONG gate, so no-flaky-check is the targeted tag. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
CI finish ledger — 86e0df5Every failure below has an owner (fixing PR or full-effort fix task). Only
Session id: cron:our-pr-ci-monitor:20260708-110000 |
…yntax-single-record # Conflicts: # tests/queries/0_stateless/02226_analyzer_or_like_combine.oldanalyzer.reference # tests/queries/0_stateless/02226_analyzer_or_like_combine.reference
|
Merged |
CI finish ledger — ce0c536Every failure below has an owner: a fixing PR (ours), or the private sync (exempt).
Session id: cron:our-pr-ci-monitor:20260713-183000 |
The oneline setting now defaults to 1, so EXPLAIN SYNTAX prints the reformatted query on one physical line. The convert_query_to_cnf and optimize_syntax_fuse_functions docstring examples intentionally show multi-line output, so opt them into oneline = 0. The fuse example also used FORMAT TSV, which escapes the embedded newlines; switch it to FORMAT TSVRaw so the shown multi-line block stays literal. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
LLVM Coverage Report
Changed lines: Changed C/C++ lines covered: 34/34 (100.00%) · Uncovered code |
CI finish ledger — c838bc5CI is fully green on this head (the docstring-example fix for the
Session id: cron:our-pr-ci-monitor:20260714-093000 |
alexey-milovidov
left a comment
There was a problem hiding this comment.
This is not what I asked for.
I asked to output a pretty-printed query (multi-line) in a single result record.
|
This PR looks wasted due to conflicting requests. I will open another one. |
One-line controls pretty-printing query over multiple lines, while the single-record option fixes the idiosyncrasy about returning a single result value split into multiple records. |
|
@alexey-milovidov Understood, and agreed. The single-record shape was the right part; the default should have kept the multi-line pretty-printed rendering in that one record, not defaulted to oneline=1 (which is the orthogonal, pre-existing pretty-print toggle). Sorry for the churn from the conflicting guidance across the thread. Leaving this closed for your replacement PR; happy to help there if useful. |
Closes: #80410
Changelog category (leave one):
Changelog entry (a user-readable short description of the changes that goes into CHANGELOG.md):
EXPLAIN SYNTAXnow returns the reformatted query as a singleStringrecord instead of one record per line. Theonelineoption now defaults to1, so the record is rendered on a single physical line. Setoneline = 0to render that same single record across multiple lines (embedded newlines).Description
Per the discussion on #80410,
EXPLAIN SYNTAXalways emits the whole reformatted query as a singleStringrecord (not one record per line), so the result is a recoverable single row and is directly usable (for example,SELECT count() FROM (EXPLAIN SYNTAX ...)returns1).PLAN/PIPELINE/ASTkeep their per-line tree output.The single-record shape is unconditional. The
onelineoption only controls how that one record is rendered:oneline = 1(the new default) puts the whole query on one physical line;oneline = 0spreads the same single record across multiple lines with embedded newlines. It does not restore the old N-row output.This is a backward-incompatible change: existing
EXPLAIN SYNTAXconsumers see one row instead of N, and the default rendering is single-line. The default flip was explicitly requested by rschu1ze in the PR discussion. The affected stateless.referencefiles (including.oldanalyzer.referencevariants) were regenerated for the new default.