mirror of https://github.com/postgres/postgres
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 <nagnrik@gmail.com> Reviewed-by: Michael Paquier <michael@paquier.xyz> Reviewed-by: Ashutosh Bapat <ashutosh.bapat.oss@gmail.com> Discussion: https://postgr.es/m/CA+QeY+AAsYK6WvBW4qYzHz4bahHycDAY_q5ECmHkEV_eB9ckzg@mail.gmail.compull/239/head
parent
4a4038068b
commit
df9133fa63
@ -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); |
||||
} |
Loading…
Reference in new issue