0001-Fix-pg_overexplain-invalid-JSON-with-RANGE_TABLE.patch
application/octet-stream
Filename: 0001-Fix-pg_overexplain-invalid-JSON-with-RANGE_TABLE.patch
Type: application/octet-stream
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: unified
Series: patch 0001
| File | + | − |
|---|---|---|
| contrib/pg_overexplain/expected/pg_overexplain.out | 120 | 2 |
| contrib/pg_overexplain/pg_overexplain.c | 8 | 4 |
| contrib/pg_overexplain/sql/pg_overexplain.sql | 6 | 0 |
diff --git a/contrib/pg_overexplain/expected/pg_overexplain.out b/contrib/pg_overexplain/expected/pg_overexplain.out
index 05c6686d..12ab9262 100644
--- a/contrib/pg_overexplain/expected/pg_overexplain.out
+++ b/contrib/pg_overexplain/expected/pg_overexplain.out
@@ -294,13 +294,131 @@ $$);
<Security-Barrier>false</Security-Barrier> +
<Lateral>false</Lateral> +
</Range-Table-Entry> +
- <Unprunable-RTIs>1 3 4</Unprunable-RTIs> +
- <Result-RTIs>none</Result-RTIs> +
</Range-Table> +
+ <Unprunable-RTIs>1 3 4</Unprunable-RTIs> +
+ <Result-RTIs>none</Result-RTIs> +
</Query> +
</explain>
(1 row)
+-- Test JSON format with RANGE_TABLE to verify valid JSON structure.
+SELECT explain_filter($$
+EXPLAIN (RANGE_TABLE, FORMAT JSON, 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/pg_overexplain.c b/contrib/pg_overexplain/pg_overexplain.c
index 715eda8d..fb277e02 100644
--- a/contrib/pg_overexplain/pg_overexplain.c
+++ b/contrib/pg_overexplain/pg_overexplain.c
@@ -776,7 +776,14 @@ overexplain_range_table(PlannedStmt *plannedstmt, ExplainState *es)
ExplainCloseGroup("Range Table Entry", NULL, true, es);
}
- /* Print PlannedStmt fields that contain RTIs. */
+ /* Close the Range Table array before emitting PlannedStmt-level fields. */
+ ExplainCloseGroup("Range Table", "Range Table", false, es);
+
+ /*
+ * Print PlannedStmt fields that contain RTIs. These are properties of
+ * the PlannedStmt, not of individual RTEs, so they belong outside the
+ * Range Table array.
+ */
if (es->format != EXPLAIN_FORMAT_TEXT ||
!bms_is_empty(plannedstmt->unprunableRelids))
overexplain_bitmapset("Unprunable RTIs", plannedstmt->unprunableRelids,
@@ -785,9 +792,6 @@ overexplain_range_table(PlannedStmt *plannedstmt, ExplainState *es)
!bms_is_empty(plannedstmt->resultRelationRelids))
overexplain_bitmapset("Result RTIs", plannedstmt->resultRelationRelids,
es);
-
- /* Close group, we're all done */
- ExplainCloseGroup("Range Table", "Range Table", false, es);
}
/*
diff --git a/contrib/pg_overexplain/sql/pg_overexplain.sql b/contrib/pg_overexplain/sql/pg_overexplain.sql
index d07f9368..3f17b61a 100644
--- a/contrib/pg_overexplain/sql/pg_overexplain.sql
+++ b/contrib/pg_overexplain/sql/pg_overexplain.sql
@@ -66,6 +66,12 @@ EXPLAIN (DEBUG, RANGE_TABLE, FORMAT XML, COSTS OFF)
SELECT genus, array_agg(name ORDER BY name) FROM vegetables GROUP BY genus
$$);
+-- Test JSON format with RANGE_TABLE to verify valid JSON structure.
+SELECT explain_filter($$
+EXPLAIN (RANGE_TABLE, FORMAT JSON, 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;