diff --git a/src/backend/utils/activity/pgstat_relation.c b/src/backend/utils/activity/pgstat_relation.c index 9876e0c1e8..f5d726e292 100644 --- a/src/backend/utils/activity/pgstat_relation.c +++ b/src/backend/utils/activity/pgstat_relation.c @@ -478,20 +478,52 @@ pgstat_fetch_stat_tabentry_ext(bool shared, Oid reloid) * Find any existing PgStat_TableStatus entry for rel_id in the current * database. If not found, try finding from shared tables. * - * If no entry found, return NULL, don't create a new one + * If an entry is found, copy it and increment the copy's counters with their + * subtransaction counterparts, then return the copy. The caller may need to + * pfree() the copy. + * + * If no entry found, return NULL, don't create a new one. */ PgStat_TableStatus * find_tabstat_entry(Oid rel_id) { PgStat_EntryRef *entry_ref; + PgStat_TableXactStatus *trans; + PgStat_TableStatus *tabentry = NULL; + PgStat_TableStatus *tablestatus = NULL; entry_ref = pgstat_fetch_pending_entry(PGSTAT_KIND_RELATION, MyDatabaseId, rel_id); if (!entry_ref) + { entry_ref = pgstat_fetch_pending_entry(PGSTAT_KIND_RELATION, InvalidOid, rel_id); + if (!entry_ref) + return tablestatus; + } - if (entry_ref) - return entry_ref->pending; - return NULL; + tabentry = (PgStat_TableStatus *) entry_ref->pending; + tablestatus = palloc(sizeof(PgStat_TableStatus)); + *tablestatus = *tabentry; + + /* + * Reset tablestatus->trans in the copy of PgStat_TableStatus as it may + * point to a shared memory area. Its data is saved below, so removing it + * does not matter. + */ + tablestatus->trans = NULL; + + /* + * Live subtransaction counts are not included yet. This is not a hot + * code path so reconcile tuples_inserted, tuples_updated and + * tuples_deleted even if the caller may not be interested in this data. + */ + for (trans = tabentry->trans; trans != NULL; trans = trans->upper) + { + tablestatus->counts.tuples_inserted += trans->tuples_inserted; + tablestatus->counts.tuples_updated += trans->tuples_updated; + tablestatus->counts.tuples_deleted += trans->tuples_deleted; + } + + return tablestatus; } /* diff --git a/src/backend/utils/adt/pgstatfuncs.c b/src/backend/utils/adt/pgstatfuncs.c index 6468b6a805..998c69e241 100644 --- a/src/backend/utils/adt/pgstatfuncs.c +++ b/src/backend/utils/adt/pgstatfuncs.c @@ -1588,68 +1588,14 @@ PG_STAT_GET_XACT_RELENTRY_INT64(blocks_fetched) /* pg_stat_get_xact_blocks_hit */ PG_STAT_GET_XACT_RELENTRY_INT64(blocks_hit) -Datum -pg_stat_get_xact_tuples_inserted(PG_FUNCTION_ARGS) -{ - Oid relid = PG_GETARG_OID(0); - int64 result; - PgStat_TableStatus *tabentry; - PgStat_TableXactStatus *trans; +/* pg_stat_get_xact_tuples_inserted */ +PG_STAT_GET_XACT_RELENTRY_INT64(tuples_inserted) - if ((tabentry = find_tabstat_entry(relid)) == NULL) - result = 0; - else - { - result = tabentry->counts.tuples_inserted; - /* live subtransactions' counts aren't in tuples_inserted yet */ - for (trans = tabentry->trans; trans != NULL; trans = trans->upper) - result += trans->tuples_inserted; - } +/* pg_stat_get_xact_tuples_updated */ +PG_STAT_GET_XACT_RELENTRY_INT64(tuples_updated) - PG_RETURN_INT64(result); -} - -Datum -pg_stat_get_xact_tuples_updated(PG_FUNCTION_ARGS) -{ - Oid relid = PG_GETARG_OID(0); - int64 result; - PgStat_TableStatus *tabentry; - PgStat_TableXactStatus *trans; - - if ((tabentry = find_tabstat_entry(relid)) == NULL) - result = 0; - else - { - result = tabentry->counts.tuples_updated; - /* live subtransactions' counts aren't in tuples_updated yet */ - for (trans = tabentry->trans; trans != NULL; trans = trans->upper) - result += trans->tuples_updated; - } - - PG_RETURN_INT64(result); -} - -Datum -pg_stat_get_xact_tuples_deleted(PG_FUNCTION_ARGS) -{ - Oid relid = PG_GETARG_OID(0); - int64 result; - PgStat_TableStatus *tabentry; - PgStat_TableXactStatus *trans; - - if ((tabentry = find_tabstat_entry(relid)) == NULL) - result = 0; - else - { - result = tabentry->counts.tuples_deleted; - /* live subtransactions' counts aren't in tuples_deleted yet */ - for (trans = tabentry->trans; trans != NULL; trans = trans->upper) - result += trans->tuples_deleted; - } - - PG_RETURN_INT64(result); -} +/* pg_stat_get_xact_tuples_deleted */ +PG_STAT_GET_XACT_RELENTRY_INT64(tuples_deleted) Datum pg_stat_get_xact_function_calls(PG_FUNCTION_ARGS)