v14-0001-Switch-EXPLAIN-to-unaligned-output-for-json-xml-.patch
text/x-patch
Filename: v14-0001-Switch-EXPLAIN-to-unaligned-output-for-json-xml-.patch
Type: text/x-patch
Part: 0
Patch
Same data as JSON:
GET /api/v1/attachments/:id/patch
the parsed metadata as JSON — format, series position, per-file stats; never the diff bytes.
API reference →
Format: format-patch
Series: patch v14-0001
Subject: Switch EXPLAIN to unaligned output for json/xml/yaml
| File | + | − |
|---|---|---|
| src/test/regress/expected/explain.out | 146 | 150 |
| src/test/regress/sql/explain.sql | 4 | 1 |
From 1270fb4c87b964021a66ffb261a901e0fdc929af Mon Sep 17 00:00:00 2001
From: Tomas Vondra <tomas@vondra.me>
Date: Tue, 31 Mar 2026 13:44:23 +0200
Subject: [PATCH v14 1/5] Switch EXPLAIN to unaligned output for json/xml/yaml
Use unaligned output for multiple EXPLAIN queries using non-text format
in regression tests. With aligned output adding/removing explain fields
can be very disruptive, as it often modifies the whole block because of
padding. Unaligned output does not have this issue.
Reviewed-by: Melanie Plageman <melanieplageman@gmail.com>
Reviewed-by: Lukas Fittl <lukas@fittl.com>
Reviewed-by: Andres Freund <andres@anarazel.de>
Discussion: https://postgr.es/m/flat/a177a6dd-240b-455a-8f25-aca0b1c08c6e%40vondra.me
---
src/test/regress/expected/explain.out | 296 +++++++++++++-------------
src/test/regress/sql/explain.sql | 5 +-
2 files changed, 150 insertions(+), 151 deletions(-)
diff --git a/src/test/regress/expected/explain.out b/src/test/regress/expected/explain.out
index 7c1f26b182c..dc31c7ce9f9 100644
--- a/src/test/regress/expected/explain.out
+++ b/src/test/regress/expected/explain.out
@@ -93,164 +93,160 @@ select explain_filter('explain (analyze, buffers, format text) select * from int
Execution Time: N.N ms
(3 rows)
-select explain_filter('explain (analyze, buffers, format xml) select * from int8_tbl i8');
- explain_filter
---------------------------------------------------------
- <explain xmlns="http://www.postgresql.org/N/explain"> +
- <Query> +
- <Plan> +
- <Node-Type>Seq Scan</Node-Type> +
- <Parallel-Aware>false</Parallel-Aware> +
- <Async-Capable>false</Async-Capable> +
- <Relation-Name>int8_tbl</Relation-Name> +
- <Alias>i8</Alias> +
- <Startup-Cost>N.N</Startup-Cost> +
- <Total-Cost>N.N</Total-Cost> +
- <Plan-Rows>N</Plan-Rows> +
- <Plan-Width>N</Plan-Width> +
- <Actual-Startup-Time>N.N</Actual-Startup-Time> +
- <Actual-Total-Time>N.N</Actual-Total-Time> +
- <Actual-Rows>N.N</Actual-Rows> +
- <Actual-Loops>N</Actual-Loops> +
- <Disabled>false</Disabled> +
- <Shared-Hit-Blocks>N</Shared-Hit-Blocks> +
- <Shared-Read-Blocks>N</Shared-Read-Blocks> +
- <Shared-Dirtied-Blocks>N</Shared-Dirtied-Blocks>+
- <Shared-Written-Blocks>N</Shared-Written-Blocks>+
- <Local-Hit-Blocks>N</Local-Hit-Blocks> +
- <Local-Read-Blocks>N</Local-Read-Blocks> +
- <Local-Dirtied-Blocks>N</Local-Dirtied-Blocks> +
- <Local-Written-Blocks>N</Local-Written-Blocks> +
- <Temp-Read-Blocks>N</Temp-Read-Blocks> +
- <Temp-Written-Blocks>N</Temp-Written-Blocks> +
- </Plan> +
- <Planning> +
- <Shared-Hit-Blocks>N</Shared-Hit-Blocks> +
- <Shared-Read-Blocks>N</Shared-Read-Blocks> +
- <Shared-Dirtied-Blocks>N</Shared-Dirtied-Blocks>+
- <Shared-Written-Blocks>N</Shared-Written-Blocks>+
- <Local-Hit-Blocks>N</Local-Hit-Blocks> +
- <Local-Read-Blocks>N</Local-Read-Blocks> +
- <Local-Dirtied-Blocks>N</Local-Dirtied-Blocks> +
- <Local-Written-Blocks>N</Local-Written-Blocks> +
- <Temp-Read-Blocks>N</Temp-Read-Blocks> +
- <Temp-Written-Blocks>N</Temp-Written-Blocks> +
- </Planning> +
- <Planning-Time>N.N</Planning-Time> +
- <Triggers> +
- </Triggers> +
- <Execution-Time>N.N</Execution-Time> +
- </Query> +
- </explain>
-(1 row)
-
-select explain_filter('explain (analyze, serialize, buffers, format yaml) select * from int8_tbl i8');
- explain_filter
--------------------------------
- - Plan: +
- Node Type: "Seq Scan" +
- Parallel Aware: false +
- Async Capable: false +
- Relation Name: "int8_tbl"+
- Alias: "i8" +
- Startup Cost: N.N +
- Total Cost: N.N +
- Plan Rows: N +
- Plan Width: N +
- Actual Startup Time: N.N +
- Actual Total Time: N.N +
- Actual Rows: N.N +
- Actual Loops: N +
- Disabled: false +
- Shared Hit Blocks: N +
- Shared Read Blocks: N +
- Shared Dirtied Blocks: N +
- Shared Written Blocks: N +
- Local Hit Blocks: N +
- Local Read Blocks: N +
- Local Dirtied Blocks: N +
- Local Written Blocks: N +
- Temp Read Blocks: N +
- Temp Written Blocks: N +
- Planning: +
- Shared Hit Blocks: N +
- Shared Read Blocks: N +
- Shared Dirtied Blocks: N +
- Shared Written Blocks: N +
- Local Hit Blocks: N +
- Local Read Blocks: N +
- Local Dirtied Blocks: N +
- Local Written Blocks: N +
- Temp Read Blocks: N +
- Temp Written Blocks: N +
- Planning Time: N.N +
- Triggers: +
- Serialization: +
- Time: N.N +
- Output Volume: N +
- Format: "text" +
- Shared Hit Blocks: N +
- Shared Read Blocks: N +
- Shared Dirtied Blocks: N +
- Shared Written Blocks: N +
- Local Hit Blocks: N +
- Local Read Blocks: N +
- Local Dirtied Blocks: N +
- Local Written Blocks: N +
- Temp Read Blocks: N +
- Temp Written Blocks: N +
- Execution Time: N.N
-(1 row)
-
select explain_filter('explain (buffers, format text) select * from int8_tbl i8');
explain_filter
---------------------------------------------------------
Seq Scan on int8_tbl i8 (cost=N.N..N.N rows=N width=N)
(1 row)
+\a
+select explain_filter('explain (analyze, buffers, format xml) select * from int8_tbl i8');
+explain_filter
+<explain xmlns="http://www.postgresql.org/N/explain">
+ <Query>
+ <Plan>
+ <Node-Type>Seq Scan</Node-Type>
+ <Parallel-Aware>false</Parallel-Aware>
+ <Async-Capable>false</Async-Capable>
+ <Relation-Name>int8_tbl</Relation-Name>
+ <Alias>i8</Alias>
+ <Startup-Cost>N.N</Startup-Cost>
+ <Total-Cost>N.N</Total-Cost>
+ <Plan-Rows>N</Plan-Rows>
+ <Plan-Width>N</Plan-Width>
+ <Actual-Startup-Time>N.N</Actual-Startup-Time>
+ <Actual-Total-Time>N.N</Actual-Total-Time>
+ <Actual-Rows>N.N</Actual-Rows>
+ <Actual-Loops>N</Actual-Loops>
+ <Disabled>false</Disabled>
+ <Shared-Hit-Blocks>N</Shared-Hit-Blocks>
+ <Shared-Read-Blocks>N</Shared-Read-Blocks>
+ <Shared-Dirtied-Blocks>N</Shared-Dirtied-Blocks>
+ <Shared-Written-Blocks>N</Shared-Written-Blocks>
+ <Local-Hit-Blocks>N</Local-Hit-Blocks>
+ <Local-Read-Blocks>N</Local-Read-Blocks>
+ <Local-Dirtied-Blocks>N</Local-Dirtied-Blocks>
+ <Local-Written-Blocks>N</Local-Written-Blocks>
+ <Temp-Read-Blocks>N</Temp-Read-Blocks>
+ <Temp-Written-Blocks>N</Temp-Written-Blocks>
+ </Plan>
+ <Planning>
+ <Shared-Hit-Blocks>N</Shared-Hit-Blocks>
+ <Shared-Read-Blocks>N</Shared-Read-Blocks>
+ <Shared-Dirtied-Blocks>N</Shared-Dirtied-Blocks>
+ <Shared-Written-Blocks>N</Shared-Written-Blocks>
+ <Local-Hit-Blocks>N</Local-Hit-Blocks>
+ <Local-Read-Blocks>N</Local-Read-Blocks>
+ <Local-Dirtied-Blocks>N</Local-Dirtied-Blocks>
+ <Local-Written-Blocks>N</Local-Written-Blocks>
+ <Temp-Read-Blocks>N</Temp-Read-Blocks>
+ <Temp-Written-Blocks>N</Temp-Written-Blocks>
+ </Planning>
+ <Planning-Time>N.N</Planning-Time>
+ <Triggers>
+ </Triggers>
+ <Execution-Time>N.N</Execution-Time>
+ </Query>
+</explain>
+(1 row)
+select explain_filter('explain (analyze, serialize, buffers, format yaml) select * from int8_tbl i8');
+explain_filter
+- Plan:
+ Node Type: "Seq Scan"
+ Parallel Aware: false
+ Async Capable: false
+ Relation Name: "int8_tbl"
+ Alias: "i8"
+ Startup Cost: N.N
+ Total Cost: N.N
+ Plan Rows: N
+ Plan Width: N
+ Actual Startup Time: N.N
+ Actual Total Time: N.N
+ Actual Rows: N.N
+ Actual Loops: N
+ Disabled: false
+ Shared Hit Blocks: N
+ Shared Read Blocks: N
+ Shared Dirtied Blocks: N
+ Shared Written Blocks: N
+ Local Hit Blocks: N
+ Local Read Blocks: N
+ Local Dirtied Blocks: N
+ Local Written Blocks: N
+ Temp Read Blocks: N
+ Temp Written Blocks: N
+ Planning:
+ Shared Hit Blocks: N
+ Shared Read Blocks: N
+ Shared Dirtied Blocks: N
+ Shared Written Blocks: N
+ Local Hit Blocks: N
+ Local Read Blocks: N
+ Local Dirtied Blocks: N
+ Local Written Blocks: N
+ Temp Read Blocks: N
+ Temp Written Blocks: N
+ Planning Time: N.N
+ Triggers:
+ Serialization:
+ Time: N.N
+ Output Volume: N
+ Format: "text"
+ Shared Hit Blocks: N
+ Shared Read Blocks: N
+ Shared Dirtied Blocks: N
+ Shared Written Blocks: N
+ Local Hit Blocks: N
+ Local Read Blocks: N
+ Local Dirtied Blocks: N
+ Local Written Blocks: N
+ Temp Read Blocks: N
+ Temp Written Blocks: N
+ Execution Time: N.N
+(1 row)
select explain_filter('explain (buffers, format json) select * from int8_tbl i8');
- explain_filter
-------------------------------------
- [ +
- { +
- "Plan": { +
- "Node Type": "Seq Scan", +
- "Parallel Aware": false, +
- "Async Capable": false, +
- "Relation Name": "int8_tbl",+
- "Alias": "i8", +
- "Startup Cost": N.N, +
- "Total Cost": N.N, +
- "Plan Rows": N, +
- "Plan Width": N, +
- "Disabled": false, +
- "Shared Hit Blocks": N, +
- "Shared Read Blocks": N, +
- "Shared Dirtied Blocks": N, +
- "Shared Written Blocks": N, +
- "Local Hit Blocks": N, +
- "Local Read Blocks": N, +
- "Local Dirtied Blocks": N, +
- "Local Written Blocks": N, +
- "Temp Read Blocks": N, +
- "Temp Written Blocks": N +
- }, +
- "Planning": { +
- "Shared Hit Blocks": N, +
- "Shared Read Blocks": N, +
- "Shared Dirtied Blocks": N, +
- "Shared Written Blocks": N, +
- "Local Hit Blocks": N, +
- "Local Read Blocks": N, +
- "Local Dirtied Blocks": N, +
- "Local Written Blocks": N, +
- "Temp Read Blocks": N, +
- "Temp Written Blocks": N +
- } +
- } +
- ]
+explain_filter
+[
+ {
+ "Plan": {
+ "Node Type": "Seq Scan",
+ "Parallel Aware": false,
+ "Async Capable": false,
+ "Relation Name": "int8_tbl",
+ "Alias": "i8",
+ "Startup Cost": N.N,
+ "Total Cost": N.N,
+ "Plan Rows": N,
+ "Plan Width": N,
+ "Disabled": false,
+ "Shared Hit Blocks": N,
+ "Shared Read Blocks": N,
+ "Shared Dirtied Blocks": N,
+ "Shared Written Blocks": N,
+ "Local Hit Blocks": N,
+ "Local Read Blocks": N,
+ "Local Dirtied Blocks": N,
+ "Local Written Blocks": N,
+ "Temp Read Blocks": N,
+ "Temp Written Blocks": N
+ },
+ "Planning": {
+ "Shared Hit Blocks": N,
+ "Shared Read Blocks": N,
+ "Shared Dirtied Blocks": N,
+ "Shared Written Blocks": N,
+ "Local Hit Blocks": N,
+ "Local Read Blocks": N,
+ "Local Dirtied Blocks": N,
+ "Local Written Blocks": N,
+ "Temp Read Blocks": N,
+ "Temp Written Blocks": N
+ }
+ }
+]
(1 row)
-
+\a
-- Check expansion of window definitions
select explain_filter('explain verbose select sum(unique1) over w, sum(unique2) over (w order by hundred), sum(tenthous) over (w order by hundred) from tenk1 window w as (partition by ten)');
explain_filter
diff --git a/src/test/regress/sql/explain.sql b/src/test/regress/sql/explain.sql
index ebdab42604b..8f10e1aff55 100644
--- a/src/test/regress/sql/explain.sql
+++ b/src/test/regress/sql/explain.sql
@@ -66,10 +66,13 @@ select explain_filter('explain select * from int8_tbl i8');
select explain_filter('explain (analyze, buffers off) select * from int8_tbl i8');
select explain_filter('explain (analyze, buffers off, verbose) select * from int8_tbl i8');
select explain_filter('explain (analyze, buffers, format text) select * from int8_tbl i8');
+select explain_filter('explain (buffers, format text) select * from int8_tbl i8');
+
+\a
select explain_filter('explain (analyze, buffers, format xml) select * from int8_tbl i8');
select explain_filter('explain (analyze, serialize, buffers, format yaml) select * from int8_tbl i8');
-select explain_filter('explain (buffers, format text) select * from int8_tbl i8');
select explain_filter('explain (buffers, format json) select * from int8_tbl i8');
+\a
-- Check expansion of window definitions
--
2.53.0