mirror of
https://github.com/postgres/postgres.git
synced 2025-11-06 07:49:08 +03:00
Add new system view, pg_config
Move and refactor the underlying code for the pg_config client application to src/common in support of sharing it with a new system information SRF called pg_config() which makes the same information available via SQL. Additionally wrap the SRF with a new system view, as called pg_config. Patch by me with extensive input and review by Michael Paquier and additional review by Alvaro Herrera.
This commit is contained in:
103
src/backend/utils/misc/pg_config.c
Normal file
103
src/backend/utils/misc/pg_config.c
Normal file
@@ -0,0 +1,103 @@
|
||||
/*-------------------------------------------------------------------------
|
||||
*
|
||||
* pg_config.c
|
||||
* Expose same output as pg_config except as an SRF
|
||||
*
|
||||
* Portions Copyright (c) 1996-2016, PostgreSQL Global Development Group
|
||||
* Portions Copyright (c) 1994, Regents of the University of California
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* src/backend/utils/misc/pg_config.c
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
#include "postgres.h"
|
||||
|
||||
#include "funcapi.h"
|
||||
#include "miscadmin.h"
|
||||
#include "catalog/pg_type.h"
|
||||
#include "common/config_info.h"
|
||||
#include "utils/builtins.h"
|
||||
#include "utils/elog.h"
|
||||
#include "port.h"
|
||||
|
||||
Datum
|
||||
pg_config(PG_FUNCTION_ARGS)
|
||||
{
|
||||
ReturnSetInfo *rsinfo = (ReturnSetInfo *) fcinfo->resultinfo;
|
||||
Tuplestorestate *tupstore;
|
||||
HeapTuple tuple;
|
||||
TupleDesc tupdesc;
|
||||
AttInMetadata *attinmeta;
|
||||
MemoryContext per_query_ctx;
|
||||
MemoryContext oldcontext;
|
||||
ConfigData *configdata;
|
||||
size_t configdata_len;
|
||||
char *values[2];
|
||||
int i = 0;
|
||||
|
||||
/* check to see if caller supports us returning a tuplestore */
|
||||
if (!rsinfo || !(rsinfo->allowedModes & SFRM_Materialize))
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_SYNTAX_ERROR),
|
||||
errmsg("materialize mode required, but it is not "
|
||||
"allowed in this context")));
|
||||
|
||||
per_query_ctx = rsinfo->econtext->ecxt_per_query_memory;
|
||||
oldcontext = MemoryContextSwitchTo(per_query_ctx);
|
||||
|
||||
/* get the requested return tuple description */
|
||||
tupdesc = CreateTupleDescCopy(rsinfo->expectedDesc);
|
||||
|
||||
/*
|
||||
* Check to make sure we have a reasonable tuple descriptor
|
||||
*/
|
||||
if (tupdesc->natts != 2 ||
|
||||
tupdesc->attrs[0]->atttypid != TEXTOID ||
|
||||
tupdesc->attrs[1]->atttypid != TEXTOID)
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_SYNTAX_ERROR),
|
||||
errmsg("query-specified return tuple and "
|
||||
"function return type are not compatible")));
|
||||
|
||||
/* OK to use it */
|
||||
attinmeta = TupleDescGetAttInMetadata(tupdesc);
|
||||
|
||||
/* let the caller know we're sending back a tuplestore */
|
||||
rsinfo->returnMode = SFRM_Materialize;
|
||||
|
||||
/* initialize our tuplestore */
|
||||
tupstore = tuplestore_begin_heap(true, false, work_mem);
|
||||
|
||||
configdata = get_configdata(my_exec_path, &configdata_len);
|
||||
for (i = 0; i < configdata_len; i++)
|
||||
{
|
||||
values[0] = configdata[i].name;
|
||||
values[1] = configdata[i].setting;
|
||||
|
||||
tuple = BuildTupleFromCStrings(attinmeta, values);
|
||||
tuplestore_puttuple(tupstore, tuple);
|
||||
}
|
||||
|
||||
/*
|
||||
* no longer need the tuple descriptor reference created by
|
||||
* TupleDescGetAttInMetadata()
|
||||
*/
|
||||
ReleaseTupleDesc(tupdesc);
|
||||
|
||||
tuplestore_donestoring(tupstore);
|
||||
rsinfo->setResult = tupstore;
|
||||
|
||||
/*
|
||||
* SFRM_Materialize mode expects us to return a NULL Datum. The actual
|
||||
* tuples are in our tuplestore and passed back through
|
||||
* rsinfo->setResult. rsinfo->setDesc is set to the tuple description
|
||||
* that we actually used to build our tuples with, so the caller can
|
||||
* verify we did what it was expecting.
|
||||
*/
|
||||
rsinfo->setDesc = tupdesc;
|
||||
MemoryContextSwitchTo(oldcontext);
|
||||
|
||||
return (Datum) 0;
|
||||
}
|
||||
Reference in New Issue
Block a user