diff options
author | Bruce Momjian <bruce@momjian.us> | 2002-08-15 02:51:27 +0000 |
---|---|---|
committer | Bruce Momjian <bruce@momjian.us> | 2002-08-15 02:51:27 +0000 |
commit | 45e25445846e98fe4aac23d1073566c08cd62f0b (patch) | |
tree | 7db989a91d752dca0a014eaaa6b160cb04b08b1c /src/backend | |
parent | 4c4854c4583f1d7c3d0a28b714304e433f5571e8 (diff) | |
download | postgresql-45e25445846e98fe4aac23d1073566c08cd62f0b.tar.gz postgresql-45e25445846e98fe4aac23d1073566c08cd62f0b.zip |
As discussed on several occasions previously, the new anonymous
composite type capability makes it possible to create a system view
based on a table function in a way that is hopefully palatable to
everyone. The attached patch takes advantage of this, moving
show_all_settings() from contrib/tablefunc into the backend (renamed
all_settings(). It is defined as a builtin returning type RECORD. During
initdb a system view is created to expose the same information presently
available through SHOW ALL. For example:
test=# select * from pg_settings where name like '%debug%';
name | setting
-----------------------+---------
debug_assertions | on
debug_pretty_print | off
debug_print_parse | off
debug_print_plan | off
debug_print_query | off
debug_print_rewritten | off
wal_debug | 0
(7 rows)
Additionally during initdb two rules are created which make it possible
to change settings by updating the system view -- a "virtual table" as
Tom put it. Here's an example:
Joe Conway
Diffstat (limited to 'src/backend')
-rw-r--r-- | src/backend/utils/misc/guc.c | 114 |
1 files changed, 113 insertions, 1 deletions
diff --git a/src/backend/utils/misc/guc.c b/src/backend/utils/misc/guc.c index 4e2764fc430..3cfa84191c7 100644 --- a/src/backend/utils/misc/guc.c +++ b/src/backend/utils/misc/guc.c @@ -5,7 +5,7 @@ * command, configuration file, and command line options. * See src/backend/utils/misc/README for more information. * - * $Header: /cvsroot/pgsql/src/backend/utils/misc/guc.c,v 1.81 2002/08/14 23:02:59 tgl Exp $ + * $Header: /cvsroot/pgsql/src/backend/utils/misc/guc.c,v 1.82 2002/08/15 02:51:26 momjian Exp $ * * Copyright 2000 by PostgreSQL Global Development Group * Written by Peter Eisentraut <peter_e@gmx.net>. @@ -29,6 +29,7 @@ #include "commands/vacuum.h" #include "executor/executor.h" #include "fmgr.h" +#include "funcapi.h" #include "libpq/auth.h" #include "libpq/pqcomm.h" #include "mb/pg_wchar.h" @@ -2403,6 +2404,117 @@ show_config_by_name(PG_FUNCTION_ARGS) PG_RETURN_TEXT_P(result_text); } +/* + * show_all_settings - equiv to SHOW ALL command but implemented as + * a Table Function. + */ +Datum +show_all_settings(PG_FUNCTION_ARGS) +{ + FuncCallContext *funcctx; + TupleDesc tupdesc; + int call_cntr; + int max_calls; + TupleTableSlot *slot; + AttInMetadata *attinmeta; + + /* stuff done only on the first call of the function */ + if(SRF_IS_FIRSTCALL()) + { + /* create a function context for cross-call persistence */ + funcctx = SRF_FIRSTCALL_INIT(); + + /* need a tuple descriptor representing two TEXT columns */ + tupdesc = CreateTemplateTupleDesc(2, WITHOUTOID); + TupleDescInitEntry(tupdesc, (AttrNumber) 1, "name", + TEXTOID, -1, 0, false); + TupleDescInitEntry(tupdesc, (AttrNumber) 2, "setting", + TEXTOID, -1, 0, false); + + /* allocate a slot for a tuple with this tupdesc */ + slot = TupleDescGetSlot(tupdesc); + + /* assign slot to function context */ + funcctx->slot = slot; + + /* + * Generate attribute metadata needed later to produce tuples from raw + * C strings + */ + attinmeta = TupleDescGetAttInMetadata(tupdesc); + funcctx->attinmeta = attinmeta; + + /* total number of tuples to be returned */ + funcctx->max_calls = GetNumConfigOptions(); + } + + /* stuff done on every call of the function */ + funcctx = SRF_PERCALL_SETUP(); + + call_cntr = funcctx->call_cntr; + max_calls = funcctx->max_calls; + slot = funcctx->slot; + attinmeta = funcctx->attinmeta; + + if (call_cntr < max_calls) /* do when there is more left to send */ + { + char **values; + char *varname; + char *varval; + bool noshow; + HeapTuple tuple; + Datum result; + + /* + * Get the next visible GUC variable name and value + */ + do + { + varval = GetConfigOptionByNum(call_cntr, (const char **) &varname, &noshow); + if (noshow) + { + /* varval is a palloc'd copy, so free it */ + if (varval != NULL) + pfree(varval); + + /* bump the counter and get the next config setting */ + call_cntr = ++funcctx->call_cntr; + + /* make sure we haven't gone too far now */ + if (call_cntr >= max_calls) + SRF_RETURN_DONE(funcctx); + } + } while (noshow); + + /* + * Prepare a values array for storage in our slot. + * This should be an array of C strings which will + * be processed later by the appropriate "in" functions. + */ + values = (char **) palloc(2 * sizeof(char *)); + values[0] = pstrdup(varname); + values[1] = varval; /* varval is already a palloc'd copy */ + + /* build a tuple */ + tuple = BuildTupleFromCStrings(attinmeta, values); + + /* make the tuple into a datum */ + result = TupleGetDatum(slot, tuple); + + /* Clean up */ + pfree(values[0]); + if (varval != NULL) + pfree(values[1]); + pfree(values); + + SRF_RETURN_NEXT(funcctx, result); + } + else /* do when there is no more left */ + { + SRF_RETURN_DONE(funcctx); + } +} + static char * _ShowOption(struct config_generic *record) { |