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 28 396156 : pg_get_multixact_members(PG_FUNCTION_ARGS) 29 : { 30 : typedef struct 31 : { 32 : MultiXactMember *members; 33 : int nmembers; 34 : int iter; 35 : } mxact; 36 396156 : MultiXactId mxid = PG_GETARG_TRANSACTIONID(0); 37 : mxact *multi; 38 : FuncCallContext *funccxt; 39 : 40 396156 : if (mxid < FirstMultiXactId) 41 0 : ereport(ERROR, 42 : (errcode(ERRCODE_INVALID_PARAMETER_VALUE), 43 : errmsg("invalid MultiXactId: %u", mxid))); 44 : 45 396156 : if (SRF_IS_FIRSTCALL()) 46 : { 47 : MemoryContext oldcxt; 48 : TupleDesc tupdesc; 49 : 50 19980 : funccxt = SRF_FIRSTCALL_INIT(); 51 19980 : oldcxt = MemoryContextSwitchTo(funccxt->multi_call_memory_ctx); 52 : 53 19980 : multi = palloc_object(mxact); 54 : /* no need to allow for old values here */ 55 19980 : multi->nmembers = GetMultiXactIdMembers(mxid, &multi->members, false, 56 : false); 57 19980 : multi->iter = 0; 58 : 59 19980 : if (get_call_result_type(fcinfo, NULL, &tupdesc) != TYPEFUNC_COMPOSITE) 60 0 : elog(ERROR, "return type must be a row type"); 61 19980 : funccxt->tuple_desc = tupdesc; 62 19980 : funccxt->attinmeta = TupleDescGetAttInMetadata(tupdesc); 63 19980 : funccxt->user_fctx = multi; 64 : 65 19980 : MemoryContextSwitchTo(oldcxt); 66 : } 67 : 68 396156 : funccxt = SRF_PERCALL_SETUP(); 69 396156 : multi = (mxact *) funccxt->user_fctx; 70 : 71 396156 : while (multi->iter < multi->nmembers) 72 : { 73 : HeapTuple tuple; 74 : char *values[2]; 75 : 76 376176 : values[0] = psprintf("%u", multi->members[multi->iter].xid); 77 376176 : values[1] = mxstatus_to_string(multi->members[multi->iter].status); 78 : 79 376176 : tuple = BuildTupleFromCStrings(funccxt->attinmeta, values); 80 : 81 376176 : multi->iter++; 82 376176 : pfree(values[0]); 83 376176 : SRF_RETURN_NEXT(funccxt, HeapTupleGetDatum(tuple)); 84 : } 85 : 86 19980 : SRF_RETURN_DONE(funccxt); 87 : }