Age Owner Branch data TLA Line data Source code
1 : : /*-------------------------------------------------------------------------
2 : : *
3 : : * multixactfuncs.c
4 : : * Functions for accessing multixact-related data.
5 : : *
6 : : * Portions Copyright (c) 1996-2025, PostgreSQL Global Development Group
7 : : * Portions Copyright (c) 1994, Regents of the University of California
8 : : *
9 : : * IDENTIFICATION
10 : : * src/backend/utils/adt/multixactfuncs.c
11 : : *
12 : : *-------------------------------------------------------------------------
13 : : */
14 : :
15 : : #include "postgres.h"
16 : :
17 : : #include "access/multixact.h"
18 : : #include "funcapi.h"
19 : : #include "utils/builtins.h"
20 : :
21 : : /*
22 : : * pg_get_multixact_members
23 : : *
24 : : * Returns information about the MultiXactMembers of the specified
25 : : * MultiXactId.
26 : : */
27 : : Datum
19 michael@paquier.xyz 28 :UNC 0 : pg_get_multixact_members(PG_FUNCTION_ARGS)
29 : : {
30 : : typedef struct
31 : : {
32 : : MultiXactMember *members;
33 : : int nmembers;
34 : : int iter;
35 : : } mxact;
36 : 0 : MultiXactId mxid = PG_GETARG_TRANSACTIONID(0);
37 : : mxact *multi;
38 : : FuncCallContext *funccxt;
39 : :
40 [ # # ]: 0 : if (mxid < FirstMultiXactId)
41 [ # # ]: 0 : ereport(ERROR,
42 : : (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
43 : : errmsg("invalid MultiXactId: %u", mxid)));
44 : :
45 [ # # ]: 0 : if (SRF_IS_FIRSTCALL())
46 : : {
47 : : MemoryContext oldcxt;
48 : : TupleDesc tupdesc;
49 : :
50 : 0 : funccxt = SRF_FIRSTCALL_INIT();
51 : 0 : oldcxt = MemoryContextSwitchTo(funccxt->multi_call_memory_ctx);
52 : :
53 : 0 : multi = palloc(sizeof(mxact));
54 : : /* no need to allow for old values here */
55 : 0 : multi->nmembers = GetMultiXactIdMembers(mxid, &multi->members, false,
56 : : false);
57 : 0 : multi->iter = 0;
58 : :
59 [ # # ]: 0 : if (get_call_result_type(fcinfo, NULL, &tupdesc) != TYPEFUNC_COMPOSITE)
60 [ # # ]: 0 : elog(ERROR, "return type must be a row type");
61 : 0 : funccxt->tuple_desc = tupdesc;
62 : 0 : funccxt->attinmeta = TupleDescGetAttInMetadata(tupdesc);
63 : 0 : funccxt->user_fctx = multi;
64 : :
65 : 0 : MemoryContextSwitchTo(oldcxt);
66 : : }
67 : :
68 : 0 : funccxt = SRF_PERCALL_SETUP();
69 : 0 : multi = (mxact *) funccxt->user_fctx;
70 : :
71 [ # # ]: 0 : while (multi->iter < multi->nmembers)
72 : : {
73 : : HeapTuple tuple;
74 : : char *values[2];
75 : :
76 : 0 : values[0] = psprintf("%u", multi->members[multi->iter].xid);
77 : 0 : values[1] = mxstatus_to_string(multi->members[multi->iter].status);
78 : :
79 : 0 : tuple = BuildTupleFromCStrings(funccxt->attinmeta, values);
80 : :
81 : 0 : multi->iter++;
82 : 0 : pfree(values[0]);
83 : 0 : SRF_RETURN_NEXT(funccxt, HeapTupleGetDatum(tuple));
84 : : }
85 : :
86 : 0 : SRF_RETURN_DONE(funccxt);
87 : : }
|