public inbox for [email protected]
help / color / mirror / Atom feedFrom: Chao Li <[email protected]>
To: Amit Langote <[email protected]>
Cc: SATYANARAYANA NARLAPURAM <[email protected]>
Cc: PostgreSQL Hackers <[email protected]>
Subject: Re: pg_overexplain produces invalid JSON with RANGE_TABLE option
Date: Thu, 16 Apr 2026 09:22:03 +0800
Message-ID: <[email protected]> (raw)
In-Reply-To: <CA+HiwqFMboUmHtoGjpLfNAWKitjA4T=jnfca9QrYvoBWrrmY0g@mail.gmail.com>
References: <CAHg+QDdDrdqMr98a_OBYDYmK3RaT7XwCEShZfvDYKZpZTfOEjQ@mail.gmail.com>
<CA+HiwqFMboUmHtoGjpLfNAWKitjA4T=jnfca9QrYvoBWrrmY0g@mail.gmail.com>
> On Apr 16, 2026, at 08:06, Amit Langote <[email protected]> wrote:
>
> Hi,
>
> On Thu, Apr 16, 2026 at 6:36 AM SATYANARAYANA NARLAPURAM
> <[email protected]> wrote:
>>
>> Hi Hackers,
>>
>> It appears that pg_overexplain produces invalid JSON output when
>> EXPLAIN (FORMAT JSON, RANGE_TABLE) is used. The "Unprunable RTIs" and
>> "Result RTIs" properties are emitted as key:value pairs directly inside
>> the "Range Table" JSON array, which is structurally invalid.
>
> Thanks for the report and the patch. That makes sense.
>
>> Attempted to fix this by moving ExplainCloseGroup() before the two overexplain_bitmapset()
>> calls, so the properties are emitted as siblings of "Range Table" in the parent object rather
>> than inside the array.
>>
>> Attached a patch to address this which also includes a test.
>
> I have added a commit message. Will commit shortly to master and v18.
>
> --
> Thanks, Amit Langote
> <v1-0001-Fix-pg_overexplain-to-emit-valid-output-with-RANG.patch>
Hi Amit, as the commit message mentions YAML format as well, but I don’t find a test case in pg_overexplain.sql, would it make sense to also add a test case for YAML. I tried to add one, see the attached diff file.
Best regards,
--
Chao Li (Evan)
HighGo Software Co., Ltd.
https://www.highgo.com/
Attachments:
[application/octet-stream] yaml_test.diff (5.7K, 2-yaml_test.diff)
download | inline diff:
diff --git a/contrib/pg_overexplain/expected/pg_overexplain.out b/contrib/pg_overexplain/expected/pg_overexplain.out
index 12ab92629ab..f331c236ae4 100644
--- a/contrib/pg_overexplain/expected/pg_overexplain.out
+++ b/contrib/pg_overexplain/expected/pg_overexplain.out
@@ -419,6 +419,102 @@ $$);
]
(1 row)
+-- Test YAML format with RANGE_TABLE to verify valid YAML structure.
+SELECT explain_filter($$
+EXPLAIN (RANGE_TABLE, FORMAT YAML, COSTS OFF)
+SELECT genus, array_agg(name ORDER BY name) FROM vegetables GROUP BY genus
+$$);
+ explain_filter
+-----------------------------------------------
+ - Plan: +
+ Node Type: "Aggregate" +
+ Strategy: "Sorted" +
+ Partial Mode: "Simple" +
+ Parallel Aware: false +
+ Async Capable: false +
+ Disabled: false +
+ Group Key: +
+ - "vegetables.genus" +
+ Plans: +
+ - Node Type: "Sort" +
+ Parent Relationship: "Outer" +
+ Parallel Aware: false +
+ Async Capable: false +
+ Disabled: false +
+ Sort Key: +
+ - "vegetables.genus" +
+ - "vegetables.name" +
+ Plans: +
+ - Node Type: "Append" +
+ Parent Relationship: "Outer" +
+ Parallel Aware: false +
+ Async Capable: false +
+ Disabled: false +
+ Append RTIs: "1" +
+ Child Append RTIs: "none" +
+ Subplans Removed: 0 +
+ Plans: +
+ - Node Type: "Seq Scan" +
+ Parent Relationship: "Member"+
+ Parallel Aware: false +
+ Async Capable: false +
+ Relation Name: "brassica" +
+ Alias: "vegetables_1" +
+ Disabled: false +
+ Scan RTI: 3 +
+ - Node Type: "Seq Scan" +
+ Parent Relationship: "Member"+
+ Parallel Aware: false +
+ Async Capable: false +
+ Relation Name: "daucus" +
+ Alias: "vegetables_2" +
+ Disabled: false +
+ Scan RTI: 4 +
+ Range Table: +
+ - RTI: 1 +
+ Kind: "relation" +
+ Inherited: true +
+ In From Clause: true +
+ Eref: "vegetables (id, name, genus)" +
+ Relation: "vegetables" +
+ Relation Kind: "partitioned_table" +
+ Relation Lock Mode: "AccessShareLock" +
+ Permission Info Index: 1 +
+ Security Barrier: false +
+ Lateral: false +
+ - RTI: 2 +
+ Kind: "group" +
+ Inherited: false +
+ In From Clause: false +
+ Eref: "\"*GROUP*\" (genus)" +
+ Security Barrier: false +
+ Lateral: false +
+ - RTI: 3 +
+ Kind: "relation" +
+ Inherited: false +
+ In From Clause: true +
+ Alias: "vegetables (id, name, genus)" +
+ Eref: "vegetables (id, name, genus)" +
+ Relation: "brassica" +
+ Relation Kind: "relation" +
+ Relation Lock Mode: "AccessShareLock" +
+ Security Barrier: false +
+ Lateral: false +
+ - RTI: 4 +
+ Kind: "relation" +
+ Inherited: false +
+ In From Clause: true +
+ Alias: "vegetables (id, name, genus)" +
+ Eref: "vegetables (id, name, genus)" +
+ Relation: "daucus" +
+ Relation Kind: "relation" +
+ Relation Lock Mode: "AccessShareLock" +
+ Security Barrier: false +
+ Lateral: false +
+ Unprunable RTIs: "1 3 4" +
+ Result RTIs: "none"
+(1 row)
+
-- Test just the DEBUG option. Verify that it shows information about
-- disabled nodes, parallel safety, and the parallelModeNeeded flag.
SET enable_seqscan = false;
diff --git a/contrib/pg_overexplain/sql/pg_overexplain.sql b/contrib/pg_overexplain/sql/pg_overexplain.sql
index 3f17b61a2da..8cb6f2718fb 100644
--- a/contrib/pg_overexplain/sql/pg_overexplain.sql
+++ b/contrib/pg_overexplain/sql/pg_overexplain.sql
@@ -72,6 +72,12 @@ EXPLAIN (RANGE_TABLE, FORMAT JSON, COSTS OFF)
SELECT genus, array_agg(name ORDER BY name) FROM vegetables GROUP BY genus
$$);
+-- Test YAML format with RANGE_TABLE to verify valid YAML structure.
+SELECT explain_filter($$
+EXPLAIN (RANGE_TABLE, FORMAT YAML, COSTS OFF)
+SELECT genus, array_agg(name ORDER BY name) FROM vegetables GROUP BY genus
+$$);
+
-- Test just the DEBUG option. Verify that it shows information about
-- disabled nodes, parallel safety, and the parallelModeNeeded flag.
SET enable_seqscan = false;
view thread (5+ messages) latest in thread
reply
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Reply to all the recipients using the --to and --cc options:
reply via email
To: [email protected]
Cc: [email protected], [email protected], [email protected], [email protected]
Subject: Re: pg_overexplain produces invalid JSON with RANGE_TABLE option
In-Reply-To: <[email protected]>
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
This inbox is served by agora; see mirroring instructions
for how to clone and mirror all data and code used for this inbox