* Written by Peter Eisentraut
.
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/utils/misc/guc.c,v 1.139 2003/07/25 20:17:56 tgl Exp $
+ * $Header: /cvsroot/pgsql/src/backend/utils/misc/guc.c,v 1.140 2003/07/27 04:35:53 momjian Exp $
*
*--------------------------------------------------------------------
*/
static char *XactIsoLevel_string;
+/*
+ * Used for pg_settings. Keep in sync with config_type enum above
+ */
+static char *config_type_name[] =
+{
+ "bool",
+ "integer",
+ "real",
+ "string"
+};
+
+/*
+ * Used for pg_settings. Keep in sync with GucContext enum in guc.h
+ */
+static char *GucContextName[] =
+{
+ "internal",
+ "postmaster",
+ "sighup",
+ "backend",
+ "super-user",
+ "user"
+};
+
+/*
+ * Used for pg_settings. Keep in sync with GucSource enum in guc.h
+ */
+static char *GucSourceName[] =
+{
+ "default",
+ "environment variable",
+ "configuration file",
+ "command line",
+ "database",
+ "user",
+ "client",
+ "override",
+ "session"
+};
+
+
/* Macros for freeing malloc'd pointers only if appropriate to do so */
/* Some of these tests are probably redundant, but be safe ... */
#define SET_STRING_VARIABLE(rec, newval) \
* Return GUC variable value by variable number; optionally return canonical
* form of name. Return value is palloc'd.
*/
-char *
-GetConfigOptionByNum(int varnum, const char **varname, bool *noshow)
+void
+GetConfigOptionByNum(int varnum, const char **values, bool *noshow)
{
- struct config_generic *conf;
+ char buffer[256];
+ struct config_generic *conf;
/* check requested variable number valid */
Assert((varnum >= 0) && (varnum < num_guc_variables));
conf = guc_variables[varnum];
- if (varname)
- *varname = conf->name;
-
if (noshow)
*noshow = (conf->flags & GUC_NO_SHOW_ALL) ? true : false;
- return _ShowOption(conf);
+ /* first get the generic attributes */
+
+ /* name */
+ values[0] = conf->name;
+
+ /* setting : use _ShowOption in order to avoid duplicating the logic */
+ values[1] = _ShowOption(conf);
+
+ /* context */
+ values[2] = GucContextName[conf->context];
+
+ /* vartype */
+ values[3] = config_type_name[conf->vartype];
+
+ /* source */
+ values[4] = GucSourceName[conf->source];
+
+ /* now get the type specifc attributes */
+ switch (conf->vartype)
+ {
+ case PGC_BOOL:
+ {
+ /* min_val */
+ values[5] = NULL;
+
+ /* max_val */
+ values[6] = NULL;
+ }
+ break;
+
+ case PGC_INT:
+ {
+ struct config_int *lconf = (struct config_int *) conf;
+
+ /* min_val */
+ snprintf(buffer, sizeof(buffer), "%d", lconf->min);
+ values[5] = pstrdup(buffer);
+
+ /* max_val */
+ snprintf(buffer, sizeof(buffer), "%d", lconf->max);
+ values[6] = pstrdup(buffer);
+ }
+ break;
+
+ case PGC_REAL:
+ {
+ struct config_real *lconf = (struct config_real *) conf;
+
+ /* min_val */
+ snprintf(buffer, sizeof(buffer), "%g", lconf->min);
+ values[5] = pstrdup(buffer);
+
+ /* max_val */
+ snprintf(buffer, sizeof(buffer), "%g", lconf->max);
+ values[6] = pstrdup(buffer);
+ }
+ break;
+
+ case PGC_STRING:
+ {
+ /* min_val */
+ values[5] = NULL;
+
+ /* max_val */
+ values[6] = NULL;
+ }
+ break;
+
+ default:
+ {
+ /*
+ * should never get here, but in case we do, set 'em to NULL
+ */
+
+ /* min_val */
+ values[5] = NULL;
+
+ /* max_val */
+ values[6] = NULL;
+ }
+ break;
+ }
}
/*
* show_all_settings - equiv to SHOW ALL command but implemented as
* a Table Function.
*/
+#define NUM_PG_SETTINGS_ATTS 7
+
Datum
show_all_settings(PG_FUNCTION_ARGS)
{
*/
oldcontext = MemoryContextSwitchTo(funcctx->multi_call_memory_ctx);
- /* need a tuple descriptor representing two TEXT columns */
- tupdesc = CreateTemplateTupleDesc(2, false);
+ /*
+ * need a tuple descriptor representing NUM_PG_SETTINGS_ATTS columns
+ * of the appropriate types
+ */
+ tupdesc = CreateTemplateTupleDesc(NUM_PG_SETTINGS_ATTS, false);
TupleDescInitEntry(tupdesc, (AttrNumber) 1, "name",
TEXTOID, -1, 0, false);
TupleDescInitEntry(tupdesc, (AttrNumber) 2, "setting",
TEXTOID, -1, 0, false);
+ TupleDescInitEntry(tupdesc, (AttrNumber) 3, "context",
+ TEXTOID, -1, 0, false);
+ TupleDescInitEntry(tupdesc, (AttrNumber) 4, "vartype",
+ TEXTOID, -1, 0, false);
+ TupleDescInitEntry(tupdesc, (AttrNumber) 5, "source",
+ TEXTOID, -1, 0, false);
+ TupleDescInitEntry(tupdesc, (AttrNumber) 6, "min_val",
+ TEXTOID, -1, 0, false);
+ TupleDescInitEntry(tupdesc, (AttrNumber) 7, "max_val",
+ TEXTOID, -1, 0, false);
/* allocate a slot for a tuple with this tupdesc */
slot = TupleDescGetSlot(tupdesc);
if (call_cntr < max_calls) /* do when there is more left to send */
{
- char *values[2];
- char *varname;
- char *varval;
+ char *values[NUM_PG_SETTINGS_ATTS];
bool noshow;
HeapTuple tuple;
Datum result;
*/
do
{
- varval = GetConfigOptionByNum(call_cntr,
- (const char **) &varname,
- &noshow);
+ GetConfigOptionByNum(call_cntr, (const char **) values, &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;
}
} 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[0] = varname;
- values[1] = varval;
-
/* build a tuple */
tuple = BuildTupleFromCStrings(attinmeta, values);
/* make the tuple into a datum */
result = TupleGetDatum(slot, tuple);
- /* Clean up */
- if (varval != NULL)
- pfree(varval);
-
SRF_RETURN_NEXT(funcctx, result);
}
else
* Copyright 2000-2003 by PostgreSQL Global Development Group
* Written by Peter Eisentraut
.
*
- * $Id: guc.h,v 1.35 2003/07/21 21:02:12 momjian Exp $
+ * $Id: guc.h,v 1.36 2003/07/27 04:35:54 momjian Exp $
*--------------------------------------------------------------------
*/
#ifndef GUC_H
*/
typedef enum
{
- PGC_INTERNAL,
- PGC_POSTMASTER,
- PGC_SIGHUP,
- PGC_BACKEND,
- PGC_SUSET,
- PGC_USERLIMIT,
- PGC_USERSET
+ PGC_INTERNAL = 0,
+ PGC_POSTMASTER = 1,
+ PGC_SIGHUP = 2,
+ PGC_BACKEND = 3,
+ PGC_SUSET = 4,
+ PGC_USERLIMIT = 5,
+ PGC_USERSET = 6
} GucContext;
/*
* Sources <= PGC_S_OVERRIDE will set the default used by RESET, as well
* as the current value. Note that source == PGC_S_OVERRIDE should be
* used when setting a PGC_INTERNAL option.
+ *
+ * Keep in sync with GucSourceName in guc.c
*/
typedef enum
{
PGC_S_SESSION = 9 /* SET command */
} GucSource;
-
/* GUC vars that are actually declared in guc.c, rather than elsewhere */
extern bool log_statement;
extern bool log_duration;
extern void ShowGUCConfigOption(const char *name, DestReceiver *dest);
extern void ShowAllGUCConfig(DestReceiver *dest);
extern char *GetConfigOptionByName(const char *name, const char **varname);
-extern char *GetConfigOptionByNum(int varnum, const char **varname, bool *noshow);
+extern void GetConfigOptionByNum(int varnum, const char **values, bool *noshow);
extern int GetNumConfigOptions(void);
extern void SetPGVariable(const char *name, List *args, bool is_local);
pg_indexes | SELECT n.nspname AS schemaname, c.relname AS tablename, i.relname AS indexname, pg_get_indexdef(i.oid) AS indexdef FROM (((pg_index x JOIN pg_class c ON ((c.oid = x.indrelid))) JOIN pg_class i ON ((i.oid = x.indexrelid))) LEFT JOIN pg_namespace n ON ((n.oid = c.relnamespace))) WHERE ((c.relkind = 'r'::"char") AND (i.relkind = 'i'::"char"));
pg_locks | SELECT l.relation, l."database", l."transaction", l.pid, l."mode", l.granted FROM pg_lock_status() l(relation oid, "database" oid, "transaction" xid, pid integer, "mode" text, granted boolean);
pg_rules | SELECT n.nspname AS schemaname, c.relname AS tablename, r.rulename, pg_get_ruledef(r.oid) AS definition FROM ((pg_rewrite r JOIN pg_class c ON ((c.oid = r.ev_class))) LEFT JOIN pg_namespace n ON ((n.oid = c.relnamespace))) WHERE (r.rulename <> '_RETURN'::name);
- pg_settings | SELECT a.name, a.setting FROM pg_show_all_settings() a(name text, setting text);
+ pg_settings | SELECT a.name, a.setting, a.context, a.vartype, a.source, a.min_val, a.max_val FROM pg_show_all_settings() a(name text, setting text, context text, vartype text, source text, min_val text, max_val text);
pg_stat_activity | SELECT d.oid AS datid, d.datname, pg_stat_get_backend_pid(s.backendid) AS procpid, pg_stat_get_backend_userid(s.backendid) AS usesysid, u.usename, pg_stat_get_backend_activity(s.backendid) AS current_query, pg_stat_get_backend_activity_start(s.backendid) AS query_start FROM pg_database d, (SELECT pg_stat_get_backend_idset() AS backendid) s, pg_shadow u WHERE ((pg_stat_get_backend_dbid(s.backendid) = d.oid) AND (pg_stat_get_backend_userid(s.backendid) = u.usesysid));
pg_stat_all_indexes | SELECT c.oid AS relid, i.oid AS indexrelid, n.nspname AS schemaname, c.relname, i.relname AS indexrelname, pg_stat_get_numscans(i.oid) AS idx_scan, pg_stat_get_tuples_returned(i.oid) AS idx_tup_read, pg_stat_get_tuples_fetched(i.oid) AS idx_tup_fetch FROM (((pg_class c JOIN pg_index x ON ((c.oid = x.indrelid))) JOIN pg_class i ON ((i.oid = x.indexrelid))) LEFT JOIN pg_namespace n ON ((n.oid = c.relnamespace))) WHERE (c.relkind = 'r'::"char");
pg_stat_all_tables | SELECT c.oid AS relid, n.nspname AS schemaname, c.relname, pg_stat_get_numscans(c.oid) AS seq_scan, pg_stat_get_tuples_returned(c.oid) AS seq_tup_read, sum(pg_stat_get_numscans(i.indexrelid)) AS idx_scan, sum(pg_stat_get_tuples_fetched(i.indexrelid)) AS idx_tup_fetch, pg_stat_get_tuples_inserted(c.oid) AS n_tup_ins, pg_stat_get_tuples_updated(c.oid) AS n_tup_upd, pg_stat_get_tuples_deleted(c.oid) AS n_tup_del FROM ((pg_class c LEFT JOIN pg_index i ON ((c.oid = i.indrelid))) LEFT JOIN pg_namespace n ON ((n.oid = c.relnamespace))) WHERE (c.relkind = 'r'::"char") GROUP BY c.oid, n.nspname, c.relname;