aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--contrib/pg_stat_statements/pg_stat_statements.c16
1 files changed, 14 insertions, 2 deletions
diff --git a/contrib/pg_stat_statements/pg_stat_statements.c b/contrib/pg_stat_statements/pg_stat_statements.c
index 0beb56a8044..8567cc0ca2d 100644
--- a/contrib/pg_stat_statements/pg_stat_statements.c
+++ b/contrib/pg_stat_statements/pg_stat_statements.c
@@ -1083,6 +1083,8 @@ pgss_ProcessUtility(PlannedStmt *pstmt, const char *queryString,
{
Node *parsetree = pstmt->utilityStmt;
uint64 saved_queryId = pstmt->queryId;
+ int saved_stmt_location = pstmt->stmt_location;
+ int saved_stmt_len = pstmt->stmt_len;
/*
* Force utility statements to get queryId zero. We do this even in cases
@@ -1148,6 +1150,16 @@ pgss_ProcessUtility(PlannedStmt *pstmt, const char *queryString,
}
PG_END_TRY();
+ /*
+ * CAUTION: do not access the *pstmt data structure again below here.
+ * If it was a ROLLBACK or similar, that data structure may have been
+ * freed. We must copy everything we still need into local variables,
+ * which we did above.
+ *
+ * For the same reason, we can't risk restoring pstmt->queryId to its
+ * former value, which'd otherwise be a good idea.
+ */
+
INSTR_TIME_SET_CURRENT(duration);
INSTR_TIME_SUBTRACT(duration, start);
@@ -1172,8 +1184,8 @@ pgss_ProcessUtility(PlannedStmt *pstmt, const char *queryString,
pgss_store(queryString,
saved_queryId,
- pstmt->stmt_location,
- pstmt->stmt_len,
+ saved_stmt_location,
+ saved_stmt_len,
PGSS_EXEC,
INSTR_TIME_GET_MILLISEC(duration),
rows,