Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Skip to content

Commit 566a1d4

Browse files
committed
Improve contrib/pg_stat_statements' handling of PREPARE/EXECUTE statements.
It's actually more useful for the module to ignore these. Ignoring EXECUTE (and not incrementing the nesting level) allows the executor hooks to charge the time to the underlying prepared query, which shows up as a stats entry with the original PREPARE as query string (possibly modified by suppression of constants, which might not be terribly useful here but it's not worth avoiding). This is much more useful than cluttering the stats table with a distinct entry for each textually distinct EXECUTE. Experimentation with this idea shows that it's also preferable to ignore PREPARE. If we don't, we get two stats table entries, one with the query string hash and one with the jumble-derived hash, but with the same visible query string (modulo those constants). This is confusing and not very helpful, since the first entry will only receive costs associated with initial planning of the query, which is not something counted at all normally by pg_stat_statements. (And if we do start tracking planning costs, we'd want them blamed on the other hash table entry anyway.)
1 parent e0e4ebe commit 566a1d4

File tree

1 file changed

+17
-2
lines changed

1 file changed

+17
-2
lines changed

contrib/pg_stat_statements/pg_stat_statements.c

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -174,7 +174,7 @@ typedef struct pgssJumbleState
174174

175175
/*---- Local variables ----*/
176176

177-
/* Current nesting depth of ExecutorRun calls */
177+
/* Current nesting depth of ExecutorRun+ProcessUtility calls */
178178
static int nested_level = 0;
179179

180180
/* Saved hook values in case of unload */
@@ -773,7 +773,22 @@ pgss_ProcessUtility(Node *parsetree, const char *queryString,
773773
ParamListInfo params, bool isTopLevel,
774774
DestReceiver *dest, char *completionTag)
775775
{
776-
if (pgss_track_utility && pgss_enabled())
776+
/*
777+
* If it's an EXECUTE statement, we don't track it and don't increment
778+
* the nesting level. This allows the cycles to be charged to the
779+
* underlying PREPARE instead (by the Executor hooks), which is much more
780+
* useful.
781+
*
782+
* We also don't track execution of PREPARE. If we did, we would get one
783+
* hash table entry for the PREPARE (with hash calculated from the query
784+
* string), and then a different one with the same query string (but hash
785+
* calculated from the query tree) would be used to accumulate costs of
786+
* ensuing EXECUTEs. This would be confusing, and inconsistent with other
787+
* cases where planning time is not included at all.
788+
*/
789+
if (pgss_track_utility && pgss_enabled() &&
790+
!IsA(parsetree, ExecuteStmt) &&
791+
!IsA(parsetree, PrepareStmt))
777792
{
778793
instr_time start;
779794
instr_time duration;

0 commit comments

Comments
 (0)