mirror of
https://github.com/postgres/postgres.git
synced 2026-05-15 19:10:30 -04:00
Fix pg_overexplain to emit valid output with RANGE_TABLE option.
overexplain_range_table() emitted the "Unprunable RTIs" and "Result RTIs" properties before closing the "Range Table" group. In the JSON and YAML formats the Range Table group is rendered as an array of RTE objects, so emitting key/value pairs inside it produced structurally invalid output. The XML format had a related oddity, with these elements nested inside <Range-Table> rather than appearing as its siblings. These fields are properties of the PlannedStmt as a whole, not of any individual RTE, so close the Range Table group before emitting them. They now appear as siblings of "Range Table" in the parent Query object, which is what was intended. Also add a test exercising FORMAT JSON with RANGE_TABLE so that any future regression in the output structure is caught. Reported-by: Satyanarayana Narlapuram <satyanarlapuram@gmail.com> Author: Satyanarayana Narlapuram <satyanarlapuram@gmail.com> Reviewed-by: Amit Langote <amitlangote09@gmail.com> Reviewed-by: Chao Li <li.evan.chao@gmail.com> Discussion: https://postgr.es/m/CAHg+QDdDrdqMr98a_OBYDYmK3RaT7XwCEShZfvDYKZpZTfOEjQ@mail.gmail.com Backpatch-through: 18
This commit is contained in:
parent
b5062a4e57
commit
059cf7f58d
3 changed files with 134 additions and 6 deletions
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
Loading…
Reference in a new issue