Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commite0e4ebe

Browse files
committed
Improve handling of utility statements containing plannable statements.
When tracking nested statements, contrib/pg_stat_statements formerlydouble-counted the execution costs of utility statements that directlycontain an executable statement, such as EXPLAIN and DECLARE CURSOR.This was not obvious since the ProcessUtility and Executor hookswould each add their measured costs to the same stats table entry.However, with the new implementation that hashes utility and plannablestatements differently, this showed up as seemingly-duplicate statsentries. Fix that by disabling the Executor hooks when the query has aqueryId of zero, which was the case already for such statements but is nowmore clearly specified in the code. (The zero queryId was causing problemsanyway because all such statements would add to a single bogus entry.)The PREPARE/EXECUTE case still results in counting the same executionin two different stats table entries, but it should be much less surprisingto users that there are two entries in such cases.In passing, include a CommonTableExpr's ctename in the query hash.I had left it out originally on the grounds that we wanted to omit allinessential aliases, but since RTE_CTE RTEs are hashing their referencednames, we'd better hash the CTE names too to make sure we don't hashsemantically different queries the same.
1 parent2005b77 commite0e4ebe

File tree

1 file changed

+29
-8
lines changed

1 file changed

+29
-8
lines changed

‎contrib/pg_stat_statements/pg_stat_statements.c

Lines changed: 29 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -602,9 +602,19 @@ pgss_post_parse_analyze(ParseState *pstate, Query *query)
602602
if (!pgss|| !pgss_hash)
603603
return;
604604

605-
/* We do nothing with utility statements at this stage */
605+
/*
606+
* Utility statements get queryId zero. We do this even in cases where
607+
* the statement contains an optimizable statement for which a queryId
608+
* could be derived (such as EXPLAIN or DECLARE CURSOR). For such cases,
609+
* runtime control will first go through ProcessUtility and then the
610+
* executor, and we don't want the executor hooks to do anything, since
611+
* we are already measuring the statement's costs at the utility level.
612+
*/
606613
if (query->utilityStmt)
614+
{
615+
query->queryId=0;
607616
return;
617+
}
608618

609619
/* Set up workspace for query jumbling */
610620
jstate.jumble= (unsignedchar*)palloc(JUMBLE_SIZE);
@@ -618,6 +628,13 @@ pgss_post_parse_analyze(ParseState *pstate, Query *query)
618628
JumbleQuery(&jstate,query);
619629
query->queryId=hash_any(jstate.jumble,jstate.jumble_len);
620630

631+
/*
632+
* If we are unlucky enough to get a hash of zero, use 1 instead, to
633+
* prevent confusion with the utility-statement case.
634+
*/
635+
if (query->queryId==0)
636+
query->queryId=1;
637+
621638
/*
622639
* If we were able to identify any ignorable constants, we immediately
623640
* create a hash table entry for the query, so that we can record the
@@ -649,7 +666,12 @@ pgss_ExecutorStart(QueryDesc *queryDesc, int eflags)
649666
else
650667
standard_ExecutorStart(queryDesc,eflags);
651668

652-
if (pgss_enabled())
669+
/*
670+
* If query has queryId zero, don't track it. This prevents double
671+
* counting of optimizable statements that are directly contained in
672+
* utility statements.
673+
*/
674+
if (pgss_enabled()&&queryDesc->plannedstmt->queryId!=0)
653675
{
654676
/*
655677
* Set up to track total elapsed time in ExecutorRun. Make sure the
@@ -719,13 +741,10 @@ pgss_ExecutorFinish(QueryDesc *queryDesc)
719741
staticvoid
720742
pgss_ExecutorEnd(QueryDesc*queryDesc)
721743
{
722-
if (queryDesc->totaltime&&pgss_enabled())
723-
{
724-
uint32queryId;
725-
726-
/* Query's ID should have been filled in by post-analyze hook */
727-
queryId=queryDesc->plannedstmt->queryId;
744+
uint32queryId=queryDesc->plannedstmt->queryId;
728745

746+
if (queryId!=0&&queryDesc->totaltime&&pgss_enabled())
747+
{
729748
/*
730749
* Make sure stats accumulation is done. (Note: it's okay if several
731750
* levels of hook all do this.)
@@ -1794,6 +1813,8 @@ JumbleExpr(pgssJumbleState * jstate, Node *node)
17941813
{
17951814
CommonTableExpr*cte= (CommonTableExpr*)node;
17961815

1816+
/* we store the string name because RTE_CTE RTEs need it */
1817+
APP_JUMB_STRING(cte->ctename);
17971818
JumbleQuery(jstate, (Query*)cte->ctequery);
17981819
}
17991820
break;

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp