public inbox for [email protected]  
help / color / mirror / Atom feed
From: 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