Skip to content

Commit 56083ff

Browse files
committed
pg_stat_statements: fetch stmt location/length before it disappears.
When executing a utility statement, we must fetch everything we need out of the PlannedStmt data structure before calling standard_ProcessUtility. In certain cases (possibly only ROLLBACK in extended query protocol), that data structure will get freed during command execution. The situation is probably often harmless in production builds, but in debug builds we intentionally overwrite the freed memory with garbage, leading to picking up garbage values of statement location and length, typically causing an assertion failure later in pg_stat_statements. In non-debug builds, if something did go wrong it would likely lead to storing garbage for the query string. Report and fix by zhaoqigui (with cosmetic adjustments by me). It's an old problem, so back-patch to all supported versions. Discussion: https://postgr.es/m/17663-a344fd0675f92128@postgresql.org Discussion: https://postgr.es/m/1667307420050.56657@hundsun.com
1 parent b02fc7d commit 56083ff

File tree

1 file changed

+11
-2
lines changed

1 file changed

+11
-2
lines changed

contrib/pg_stat_statements/pg_stat_statements.c

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -962,6 +962,8 @@ pgss_ProcessUtility(PlannedStmt *pstmt, const char *queryString,
962962
DestReceiver *dest, char *completionTag)
963963
{
964964
Node *parsetree = pstmt->utilityStmt;
965+
int saved_stmt_location = pstmt->stmt_location;
966+
int saved_stmt_len = pstmt->stmt_len;
965967

966968
/*
967969
* If it's an EXECUTE statement, we don't track it and don't increment the
@@ -1011,6 +1013,13 @@ pgss_ProcessUtility(PlannedStmt *pstmt, const char *queryString,
10111013
}
10121014
PG_END_TRY();
10131015

1016+
/*
1017+
* CAUTION: do not access the *pstmt data structure again below here.
1018+
* If it was a ROLLBACK or similar, that data structure may have been
1019+
* freed. We must copy everything we still need into local variables,
1020+
* which we did above.
1021+
*/
1022+
10141023
INSTR_TIME_SET_CURRENT(duration);
10151024
INSTR_TIME_SUBTRACT(duration, start);
10161025

@@ -1049,8 +1058,8 @@ pgss_ProcessUtility(PlannedStmt *pstmt, const char *queryString,
10491058

10501059
pgss_store(queryString,
10511060
0, /* signal that it's a utility stmt */
1052-
pstmt->stmt_location,
1053-
pstmt->stmt_len,
1061+
saved_stmt_location,
1062+
saved_stmt_len,
10541063
INSTR_TIME_GET_MILLISEC(duration),
10551064
rows,
10561065
&bufusage,

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy