Move SQL-callable code related to multixacts into its own file
authorMichael Paquier <[email protected]>
Mon, 18 Aug 2025 05:52:34 +0000 (14:52 +0900)
committerMichael Paquier <[email protected]>
Mon, 18 Aug 2025 05:57:55 +0000 (14:57 +0900)
A patch is under discussion to add more SQL capabilities related to
multixacts, and this move avoids bloating the file more than necessary.
This affects pg_get_multixact_members().  A side effect of this move is
the requirement to add mxstatus_to_string() to multixact.h.

Extracted from a larger patch by the same author, tweaked by me.

Author: Naga Appani <[email protected]>
Reviewed-by: Michael Paquier <[email protected]>
Reviewed-by: Ashutosh Bapat <[email protected]>
Discussion: https://postgr.es/m/CA+QeY+AAsYK6WvBW4qYzHz4bahHycDAY_q5ECmHkEV_eB9ckzg@mail.gmail.com

src/backend/access/transam/multixact.c
src/backend/utils/adt/Makefile
src/backend/utils/adt/meson.build
src/backend/utils/adt/multixactfuncs.c [new file with mode: 0644]
src/include/access/multixact.h

index 3cb09c3d5987c2b0a45cc848c2c312d590cb2713..886740d2d553466c1094060b8f5d53fe5079da2b 100644 (file)
@@ -398,8 +398,6 @@ static int  mXactCacheGetById(MultiXactId multi, MultiXactMember **members);
 static void mXactCachePut(MultiXactId multi, int nmembers,
                          MultiXactMember *members);
 
-static char *mxstatus_to_string(MultiXactStatus status);
-
 /* management of SLRU infrastructure */
 static bool MultiXactOffsetPagePrecedes(int64 page1, int64 page2);
 static bool MultiXactMemberPagePrecedes(int64 page1, int64 page2);
@@ -1747,7 +1745,7 @@ mXactCachePut(MultiXactId multi, int nmembers, MultiXactMember *members)
    }
 }
 
-static char *
+char *
 mxstatus_to_string(MultiXactStatus status)
 {
    switch (status)
@@ -3414,68 +3412,6 @@ multixact_redo(XLogReaderState *record)
        elog(PANIC, "multixact_redo: unknown op code %u", info);
 }
 
-Datum
-pg_get_multixact_members(PG_FUNCTION_ARGS)
-{
-   typedef struct
-   {
-       MultiXactMember *members;
-       int         nmembers;
-       int         iter;
-   } mxact;
-   MultiXactId mxid = PG_GETARG_TRANSACTIONID(0);
-   mxact      *multi;
-   FuncCallContext *funccxt;
-
-   if (mxid < FirstMultiXactId)
-       ereport(ERROR,
-               (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
-                errmsg("invalid MultiXactId: %u", mxid)));
-
-   if (SRF_IS_FIRSTCALL())
-   {
-       MemoryContext oldcxt;
-       TupleDesc   tupdesc;
-
-       funccxt = SRF_FIRSTCALL_INIT();
-       oldcxt = MemoryContextSwitchTo(funccxt->multi_call_memory_ctx);
-
-       multi = palloc(sizeof(mxact));
-       /* no need to allow for old values here */
-       multi->nmembers = GetMultiXactIdMembers(mxid, &multi->members, false,
-                                               false);
-       multi->iter = 0;
-
-       if (get_call_result_type(fcinfo, NULL, &tupdesc) != TYPEFUNC_COMPOSITE)
-           elog(ERROR, "return type must be a row type");
-       funccxt->tuple_desc = tupdesc;
-       funccxt->attinmeta = TupleDescGetAttInMetadata(tupdesc);
-       funccxt->user_fctx = multi;
-
-       MemoryContextSwitchTo(oldcxt);
-   }
-
-   funccxt = SRF_PERCALL_SETUP();
-   multi = (mxact *) funccxt->user_fctx;
-
-   while (multi->iter < multi->nmembers)
-   {
-       HeapTuple   tuple;
-       char       *values[2];
-
-       values[0] = psprintf("%u", multi->members[multi->iter].xid);
-       values[1] = mxstatus_to_string(multi->members[multi->iter].status);
-
-       tuple = BuildTupleFromCStrings(funccxt->attinmeta, values);
-
-       multi->iter++;
-       pfree(values[0]);
-       SRF_RETURN_NEXT(funccxt, HeapTupleGetDatum(tuple));
-   }
-
-   SRF_RETURN_DONE(funccxt);
-}
-
 /*
  * Entrypoint for sync.c to sync offsets files.
  */
index ffeacf2b819f32edd10da1023aef9bf38dd538ce..cc68ac545a5f0f918a1fe4363bbf0d81eff60a75 100644 (file)
@@ -68,6 +68,7 @@ OBJS = \
    misc.o \
    multirangetypes.o \
    multirangetypes_selfuncs.o \
+   multixactfuncs.o \
    name.o \
    network.o \
    network_gist.o \
index ed9bbd7b9266bf69b6b818fe22a0bc79b2adb655..dac372c3bea3bc970ee002198eaa7765ebebed9c 100644 (file)
@@ -55,6 +55,7 @@ backend_sources += files(
   'misc.c',
   'multirangetypes.c',
   'multirangetypes_selfuncs.c',
+  'multixactfuncs.c',
   'name.c',
   'network.c',
   'network_gist.c',
diff --git a/src/backend/utils/adt/multixactfuncs.c b/src/backend/utils/adt/multixactfuncs.c
new file mode 100644 (file)
index 0000000..e74ea93
--- /dev/null
@@ -0,0 +1,87 @@
+/*-------------------------------------------------------------------------
+ *
+ * multixactfuncs.c
+ *   Functions for accessing multixact-related data.
+ *
+ * Portions Copyright (c) 1996-2025, PostgreSQL Global Development Group
+ * Portions Copyright (c) 1994, Regents of the University of California
+ *
+ * IDENTIFICATION
+ *   src/backend/utils/adt/multixactfuncs.c
+ *
+ *-------------------------------------------------------------------------
+ */
+
+#include "postgres.h"
+
+#include "access/multixact.h"
+#include "funcapi.h"
+#include "utils/builtins.h"
+
+/*
+ * pg_get_multixact_members
+ *
+ * Returns information about the MultiXactMembers of the specified
+ * MultiXactId.
+ */
+Datum
+pg_get_multixact_members(PG_FUNCTION_ARGS)
+{
+   typedef struct
+   {
+       MultiXactMember *members;
+       int         nmembers;
+       int         iter;
+   } mxact;
+   MultiXactId mxid = PG_GETARG_TRANSACTIONID(0);
+   mxact      *multi;
+   FuncCallContext *funccxt;
+
+   if (mxid < FirstMultiXactId)
+       ereport(ERROR,
+               (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
+                errmsg("invalid MultiXactId: %u", mxid)));
+
+   if (SRF_IS_FIRSTCALL())
+   {
+       MemoryContext oldcxt;
+       TupleDesc   tupdesc;
+
+       funccxt = SRF_FIRSTCALL_INIT();
+       oldcxt = MemoryContextSwitchTo(funccxt->multi_call_memory_ctx);
+
+       multi = palloc(sizeof(mxact));
+       /* no need to allow for old values here */
+       multi->nmembers = GetMultiXactIdMembers(mxid, &multi->members, false,
+                                               false);
+       multi->iter = 0;
+
+       if (get_call_result_type(fcinfo, NULL, &tupdesc) != TYPEFUNC_COMPOSITE)
+           elog(ERROR, "return type must be a row type");
+       funccxt->tuple_desc = tupdesc;
+       funccxt->attinmeta = TupleDescGetAttInMetadata(tupdesc);
+       funccxt->user_fctx = multi;
+
+       MemoryContextSwitchTo(oldcxt);
+   }
+
+   funccxt = SRF_PERCALL_SETUP();
+   multi = (mxact *) funccxt->user_fctx;
+
+   while (multi->iter < multi->nmembers)
+   {
+       HeapTuple   tuple;
+       char       *values[2];
+
+       values[0] = psprintf("%u", multi->members[multi->iter].xid);
+       values[1] = mxstatus_to_string(multi->members[multi->iter].status);
+
+       tuple = BuildTupleFromCStrings(funccxt->attinmeta, values);
+
+       multi->iter++;
+       pfree(values[0]);
+       SRF_RETURN_NEXT(funccxt, HeapTupleGetDatum(tuple));
+   }
+
+   SRF_RETURN_DONE(funccxt);
+}
index b876e98f46ed744c87105e8e5289275f936a471e..6607b645a1820fa3ca645cc5d1684904f57d8328 100644 (file)
@@ -158,5 +158,6 @@ extern void multixact_desc(StringInfo buf, XLogReaderState *record);
 extern const char *multixact_identify(uint8 info);
 extern char *mxid_to_string(MultiXactId multi, int nmembers,
                            MultiXactMember *members);
+extern char *mxstatus_to_string(MultiXactStatus status);
 
 #endif                         /* MULTIXACT_H */