Hi,

On 2/13/23 8:40 AM, Kyotaro Horiguchi wrote:
At Mon, 13 Feb 2023 08:09:50 +0100, "Drouvot, Bertrand" 
<bertranddrouvot...@gmail.com> wrote in
I think this is useful beyond being able to generate those functions
with
macros. The fact that we had to deal with transactional code in
pgstatfuncs.c
meant that a lot of the relevant itnernals had to be exposed "outside"
pgstat,
which seems architecturally not great.

Right, good point.

Agreed.

Removing the pfrees in V2 attached.

Ah, that sound good.

        if (!entry_ref)
+       {
                entry_ref = pgstat_fetch_pending_entry(PGSTAT_KIND_RELATION, 
InvalidOid, rel_id);
+               return tablestatus;
+       }

We should return something if the call returns a non-null value?

What we do is: if entry_ref is NULL then we return NULL (so that the caller 
returns 0).

If entry_ref is not NULL then we return a copy of entry_ref->pending (with or 
without subtrans).


So, since we want to hide the internal from pgstatfuncs, the
additional flag should be gone.

I think there is pros and cons for both but I don't have a strong opinion about 
that.

So also proposing V3 attached without the flag in case this is the preferred 
approach.

Regards,

--
Bertrand Drouvot
PostgreSQL Contributors Team
RDS Open Source Databases
Amazon Web Services: https://aws.amazon.com
diff --git a/src/backend/utils/activity/pgstat_relation.c 
b/src/backend/utils/activity/pgstat_relation.c
index f793ac1516..2e22d190bf 100644
--- a/src/backend/utils/activity/pgstat_relation.c
+++ b/src/backend/utils/activity/pgstat_relation.c
@@ -477,14 +477,35 @@ 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);
+               return tablestatus;
+       }
+
+       tabentry = (PgStat_TableStatus *) entry_ref->pending;
+       tablestatus = palloc(sizeof(PgStat_TableStatus));
+       *tablestatus = *tabentry;
+
+       /*
+        * Live subtransactions' counts aren't in t_counts yet. This is not a 
hot
+        * code path so it sounds ok to reconcile for tuples_inserted,
+        * tuples_updated and tuples_deleted even if this is not what the caller
+        * is interested in.
+        */
+       for (trans = tabentry->trans; trans != NULL; trans = trans->upper)
+       {
+               tablestatus->t_counts.t_tuples_inserted += 
trans->tuples_inserted;
+               tablestatus->t_counts.t_tuples_updated += trans->tuples_updated;
+               tablestatus->t_counts.t_tuples_deleted += trans->tuples_deleted;
+       }
 
-       if (entry_ref)
-               return entry_ref->pending;
-       return NULL;
+       return tablestatus;
 }
 
 /*
diff --git a/src/backend/utils/adt/pgstatfuncs.c 
b/src/backend/utils/adt/pgstatfuncs.c
index 924698e6ae..c37d521f08 100644
--- a/src/backend/utils/adt/pgstatfuncs.c
+++ b/src/backend/utils/adt/pgstatfuncs.c
@@ -1407,17 +1407,11 @@ pg_stat_get_xact_tuples_inserted(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->t_counts.t_tuples_inserted;
-               /* live subtransactions' counts aren't in t_tuples_inserted yet 
*/
-               for (trans = tabentry->trans; trans != NULL; trans = 
trans->upper)
-                       result += trans->tuples_inserted;
-       }
+               result = (int64) (tabentry->t_counts.t_tuples_inserted);
 
        PG_RETURN_INT64(result);
 }
@@ -1428,17 +1422,11 @@ 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->t_counts.t_tuples_updated;
-               /* live subtransactions' counts aren't in t_tuples_updated yet 
*/
-               for (trans = tabentry->trans; trans != NULL; trans = 
trans->upper)
-                       result += trans->tuples_updated;
-       }
+               result = (int64) (tabentry->t_counts.t_tuples_updated);
 
        PG_RETURN_INT64(result);
 }
@@ -1449,17 +1437,11 @@ 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->t_counts.t_tuples_deleted;
-               /* live subtransactions' counts aren't in t_tuples_deleted yet 
*/
-               for (trans = tabentry->trans; trans != NULL; trans = 
trans->upper)
-                       result += trans->tuples_deleted;
-       }
+               result = (int64) (tabentry->t_counts.t_tuples_deleted);
 
        PG_RETURN_INT64(result);
 }

Reply via email to