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 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 : }