queryid-zero.patch
text/x-patch
Filename: queryid-zero.patch
Type: text/x-patch
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
| File | + | − |
|---|---|---|
| contrib/pg_stat_statements/pg_stat_statements.c | 0 | 0 |
diff --git a/contrib/pg_stat_statements/pg_stat_statements.c b/contrib/pg_stat_statements/pg_stat_statements.c
index 137b242..bebfff1 100644
*** a/contrib/pg_stat_statements/pg_stat_statements.c
--- b/contrib/pg_stat_statements/pg_stat_statements.c
*************** pgss_post_parse_analyze(ParseState *psta
*** 602,610 ****
if (!pgss || !pgss_hash)
return;
! /* We do nothing with utility statements at this stage */
if (query->utilityStmt)
return;
/* Set up workspace for query jumbling */
jstate.jumble = (unsigned char *) palloc(JUMBLE_SIZE);
--- 602,620 ----
if (!pgss || !pgss_hash)
return;
! /*
! * Utility statements get queryId zero. We do this even in cases where
! * the statement contains an optimizable statement for which a queryId
! * could be derived (such as EXPLAIN or DECLARE CURSOR). For such cases,
! * runtime control will first go through ProcessUtility and then the
! * executor, and we don't want the executor hooks to do anything, since
! * we are already measuring the statement's costs at the utility level.
! */
if (query->utilityStmt)
+ {
+ query->queryId = 0;
return;
+ }
/* Set up workspace for query jumbling */
jstate.jumble = (unsigned char *) palloc(JUMBLE_SIZE);
*************** pgss_post_parse_analyze(ParseState *psta
*** 619,624 ****
--- 629,641 ----
query->queryId = hash_any(jstate.jumble, jstate.jumble_len);
/*
+ * If we are unlucky enough to get a hash of zero, use 1 instead, to
+ * prevent confusion with the utility-statement case.
+ */
+ if (query->queryId == 0)
+ query->queryId = 1;
+
+ /*
* If we were able to identify any ignorable constants, we immediately
* create a hash table entry for the query, so that we can record the
* normalized form of the query string. If there were no such constants,
*************** pgss_ExecutorStart(QueryDesc *queryDesc,
*** 649,655 ****
else
standard_ExecutorStart(queryDesc, eflags);
! if (pgss_enabled())
{
/*
* Set up to track total elapsed time in ExecutorRun. Make sure the
--- 666,677 ----
else
standard_ExecutorStart(queryDesc, eflags);
! /*
! * If query has queryId zero, don't track it. This prevents double
! * counting of optimizable statements that are directly contained in
! * utility statements.
! */
! if (pgss_enabled() && queryDesc->plannedstmt->queryId != 0)
{
/*
* Set up to track total elapsed time in ExecutorRun. Make sure the
*************** pgss_ExecutorFinish(QueryDesc *queryDesc
*** 719,731 ****
static void
pgss_ExecutorEnd(QueryDesc *queryDesc)
{
! if (queryDesc->totaltime && pgss_enabled())
! {
! uint32 queryId;
!
! /* Query's ID should have been filled in by post-analyze hook */
! queryId = queryDesc->plannedstmt->queryId;
/*
* Make sure stats accumulation is done. (Note: it's okay if several
* levels of hook all do this.)
--- 741,750 ----
static void
pgss_ExecutorEnd(QueryDesc *queryDesc)
{
! uint32 queryId = queryDesc->plannedstmt->queryId;
+ if (queryId != 0 && queryDesc->totaltime && pgss_enabled())
+ {
/*
* Make sure stats accumulation is done. (Note: it's okay if several
* levels of hook all do this.)