* 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;
+ }
+
+ 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;
+ }
- if (entry_ref)
- return entry_ref->pending;
- return NULL;
+ return tablestatus;
}
/*
/* 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)