* pg_resqueue_status - produce a view with one row per resource queue * showing internal information (counter values, waiters, holders). */
| 1980 | * showing internal information (counter values, waiters, holders). |
| 1981 | */ |
| 1982 | Datum |
| 1983 | pg_resqueue_status(PG_FUNCTION_ARGS) |
| 1984 | { |
| 1985 | FuncCallContext *funcctx = NULL; |
| 1986 | Datum result; |
| 1987 | MemoryContext oldcontext = NULL; |
| 1988 | QueueStatusContext *fctx = NULL; /* User function context. */ |
| 1989 | HeapTuple tuple = NULL; |
| 1990 | |
| 1991 | if (SRF_IS_FIRSTCALL()) |
| 1992 | { |
| 1993 | |
| 1994 | funcctx = SRF_FIRSTCALL_INIT(); |
| 1995 | |
| 1996 | /* Switch context when allocating stuff to be used in later calls */ |
| 1997 | oldcontext = MemoryContextSwitchTo(funcctx->multi_call_memory_ctx); |
| 1998 | |
| 1999 | fctx = (QueueStatusContext *) palloc(sizeof(QueueStatusContext)); |
| 2000 | |
| 2001 | /* |
| 2002 | * Allocate space for the per-call area - this overestimates, but |
| 2003 | * means we can take the resource rescheduler lock after our memory |
| 2004 | * context switching. |
| 2005 | */ |
| 2006 | fctx->record = (QueueStatusRec *) palloc(sizeof(QueueStatusRec) * MaxResourceQueues); |
| 2007 | |
| 2008 | funcctx->user_fctx = fctx; |
| 2009 | |
| 2010 | /* Construct a tuple descriptor for the result rows. */ |
| 2011 | TupleDesc tupledesc = CreateTemplateTupleDesc(PG_RESQUEUE_STATUS_COLUMNS); |
| 2012 | |
| 2013 | TupleDescInitEntry(tupledesc, (AttrNumber) 1, "queueid", OIDOID, -1, 0); |
| 2014 | TupleDescInitEntry(tupledesc, (AttrNumber) 2, "queuecountvalue", FLOAT4OID, -1, 0); |
| 2015 | TupleDescInitEntry(tupledesc, (AttrNumber) 3, "queuecostvalue", FLOAT4OID, -1, 0); |
| 2016 | TupleDescInitEntry(tupledesc, (AttrNumber) 4, "queuewaiters", INT4OID, -1, 0); |
| 2017 | TupleDescInitEntry(tupledesc, (AttrNumber) 5, "queueholders", INT4OID, -1, 0); |
| 2018 | |
| 2019 | funcctx->tuple_desc = BlessTupleDesc(tupledesc); |
| 2020 | |
| 2021 | /* Return to original context when allocating transient memory */ |
| 2022 | MemoryContextSwitchTo(oldcontext); |
| 2023 | |
| 2024 | if (IsResQueueEnabled()) |
| 2025 | { |
| 2026 | /* Get a snapshot of current state of resource queues */ |
| 2027 | BuildQueueStatusContext(fctx); |
| 2028 | |
| 2029 | funcctx->max_calls = fctx->numRecords; |
| 2030 | } |
| 2031 | else |
| 2032 | { |
| 2033 | funcctx->max_calls = fctx->numRecords = 0; |
| 2034 | } |
| 2035 | } |
| 2036 | |
| 2037 | funcctx = SRF_PERCALL_SETUP(); |
| 2038 | |
| 2039 | /* Get the saved state. */ |
nothing calls this directly
no test coverage detected