diff options
author | Joe Conway <mail@joeconway.com> | 2016-02-17 09:12:06 -0800 |
---|---|---|
committer | Joe Conway <mail@joeconway.com> | 2016-02-17 09:12:06 -0800 |
commit | a5c43b886942e96ec5c745041f2d6a50c3205147 (patch) | |
tree | b7d1967286366131bc65d34457fb0ba91ec710b8 /src/backend | |
parent | f1f5ec1efafe74ca45e24e0bf3371b1d6985c8ee (diff) | |
download | postgresql-a5c43b886942e96ec5c745041f2d6a50c3205147.tar.gz postgresql-a5c43b886942e96ec5c745041f2d6a50c3205147.zip |
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.
Diffstat (limited to 'src/backend')
-rw-r--r-- | src/backend/catalog/system_views.sql | 6 | ||||
-rw-r--r-- | src/backend/utils/misc/Makefile | 4 | ||||
-rw-r--r-- | src/backend/utils/misc/pg_config.c | 103 |
3 files changed, 111 insertions, 2 deletions
diff --git a/src/backend/catalog/system_views.sql b/src/backend/catalog/system_views.sql index 923fe589d5e..abf9a7007c5 100644 --- a/src/backend/catalog/system_views.sql +++ b/src/backend/catalog/system_views.sql @@ -433,6 +433,12 @@ CREATE VIEW pg_timezone_abbrevs AS CREATE VIEW pg_timezone_names AS SELECT * FROM pg_timezone_names(); +CREATE VIEW pg_config AS + SELECT * FROM pg_config(); + +REVOKE ALL on pg_config FROM PUBLIC; +REVOKE EXECUTE ON FUNCTION pg_config() FROM PUBLIC; + -- Statistics views CREATE VIEW pg_stat_all_tables AS diff --git a/src/backend/utils/misc/Makefile b/src/backend/utils/misc/Makefile index 788910157de..a0c82c17438 100644 --- a/src/backend/utils/misc/Makefile +++ b/src/backend/utils/misc/Makefile @@ -14,8 +14,8 @@ include $(top_builddir)/src/Makefile.global override CPPFLAGS := -I. -I$(srcdir) $(CPPFLAGS) -OBJS = guc.o help_config.o pg_rusage.o ps_status.o rls.o \ - sampling.o superuser.o timeout.o tzparser.o +OBJS = guc.o help_config.o pg_config.o pg_rusage.o \ + ps_status.o rls.o sampling.o superuser.o timeout.o tzparser.o # This location might depend on the installation directories. Therefore # we can't subsitute it into pg_config.h. diff --git a/src/backend/utils/misc/pg_config.c b/src/backend/utils/misc/pg_config.c new file mode 100644 index 00000000000..3d6b9f27c08 --- /dev/null +++ b/src/backend/utils/misc/pg_config.c @@ -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; +} |