diff --git a/doc/src/sgml/runtime.sgml b/doc/src/sgml/runtime.sgml
index 1f28e21559f283dfa5e8c36188276f55ef5f488f..d5598cd0b967674bf91a6bc1708ae41a2b2e2c68 100644
--- a/doc/src/sgml/runtime.sgml
+++ b/doc/src/sgml/runtime.sgml
@@ -1,5 +1,5 @@
 <!--
-$Header: /cvsroot/pgsql/doc/src/sgml/runtime.sgml,v 1.195 2003/07/23 20:30:35 momjian Exp $
+$Header: /cvsroot/pgsql/doc/src/sgml/runtime.sgml,v 1.196 2003/07/27 04:35:53 momjian Exp $
 -->
 
 <Chapter Id="runtime">
@@ -571,14 +571,45 @@ SET ENABLE_SEQSCAN TO OFF;
       <row>
        <entry><literal>name</literal></entry>
        <entry><type>text</type></entry>
-       <entry>The name of the run-time configuration parameter</entry>
+       <entry>run-time configuration parameter name</entry>
       </row>
  
       <row>
        <entry><literal>setting</literal></entry>
        <entry><type>text</type></entry>
-       <entry>The current value of the run-time configuration parameter</entry>
+       <entry>current value of the parameter</entry>
       </row>
+
+      <row>
+       <entry><literal>context</literal></entry>
+       <entry><type>text</type></entry>
+       <entry>context required to set the parameter's value</entry>
+      </row>
+
+      <row>
+       <entry><literal>vartype</literal></entry>
+       <entry><type>text</type></entry>
+       <entry>parameter type</entry>
+      </row>
+
+      <row>
+       <entry><literal>source</literal></entry>
+       <entry><type>text</type></entry>
+       <entry>source of the current parameter value</entry>
+      </row>
+
+      <row>
+       <entry><literal>min_val</literal></entry>
+       <entry><type>text</type></entry>
+       <entry>minimum allowed value of the parameter</entry>
+      </row>
+
+      <row>
+       <entry><literal>max_val</literal></entry>
+       <entry><type>text</type></entry>
+       <entry>maximum allowed value of the parameter</entry>
+      </row>
+
      </tbody>
     </tgroup>
     </table>
diff --git a/src/backend/utils/misc/guc.c b/src/backend/utils/misc/guc.c
index de1fd50d20379a081b01229e5dbbb21571d990c9..ef6053f3286ec4ee204f79576f4a9e6925300d57 100644
--- a/src/backend/utils/misc/guc.c
+++ b/src/backend/utils/misc/guc.c
@@ -10,7 +10,7 @@
  * Written by Peter Eisentraut <peter_e@gmx.net>.
  *
  * 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 $
  *
  *--------------------------------------------------------------------
  */
@@ -155,6 +155,47 @@ static char *timezone_string;
 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) \
@@ -3323,23 +3364,102 @@ GetConfigOptionByName(const char *name, const char **varname)
  * 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;
+	}
 }
 
 /*
@@ -3379,6 +3499,8 @@ show_config_by_name(PG_FUNCTION_ARGS)
  * 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)
 {
@@ -3402,12 +3524,25 @@ 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);
@@ -3438,9 +3573,7 @@ show_all_settings(PG_FUNCTION_ARGS)
 
 	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;
@@ -3450,15 +3583,9 @@ show_all_settings(PG_FUNCTION_ARGS)
 		 */
 		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;
 
@@ -3468,24 +3595,12 @@ show_all_settings(PG_FUNCTION_ARGS)
 			}
 		} 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
diff --git a/src/bin/initdb/initdb.sh b/src/bin/initdb/initdb.sh
index 62d1a8039ac46d81df70f030cf7a462640d8b83c..5908416ce40dc1bb620b45bd527fe860bd736479 100644
--- a/src/bin/initdb/initdb.sh
+++ b/src/bin/initdb/initdb.sh
@@ -27,7 +27,7 @@
 # Portions Copyright (c) 1996-2002, PostgreSQL Global Development Group
 # Portions Copyright (c) 1994, Regents of the University of California
 #
-# $Header: /cvsroot/pgsql/src/bin/initdb/Attic/initdb.sh,v 1.198 2003/07/23 08:46:54 petere Exp $
+# $Header: /cvsroot/pgsql/src/bin/initdb/Attic/initdb.sh,v 1.199 2003/07/27 04:35:53 momjian Exp $
 #
 #-------------------------------------------------------------------------
 
@@ -1000,7 +1000,9 @@ CREATE VIEW pg_locks AS \
 
 CREATE VIEW pg_settings AS \
     SELECT * \
-    FROM pg_show_all_settings() AS A(name text, setting text);
+    FROM pg_show_all_settings() AS A \
+    (name text, setting text, context text, vartype text, \
+     source text, min_val text, max_val text);
 
 CREATE RULE pg_settings_u AS \
     ON UPDATE TO pg_settings \
diff --git a/src/include/utils/guc.h b/src/include/utils/guc.h
index 7199a6e2ea2eae479ccbb9dc4a7b0ae00218a1f0..02d2a01d8bf9a20907369021170a049e422d6cab 100644
--- a/src/include/utils/guc.h
+++ b/src/include/utils/guc.h
@@ -7,7 +7,7 @@
  * Copyright 2000-2003 by PostgreSQL Global Development Group
  * Written by Peter Eisentraut <peter_e@gmx.net>.
  *
- * $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
@@ -55,13 +55,13 @@
  */
 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;
 
 /*
@@ -73,6 +73,8 @@ typedef enum
  * 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
 {
@@ -92,7 +94,6 @@ 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;
@@ -132,7 +133,7 @@ extern bool set_config_option(const char *name, const char *value,
 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);
diff --git a/src/include/utils/guc_tables.h b/src/include/utils/guc_tables.h
index e8ccfeefd00fd7d59ae76cb6dd0ddd7868a984d6..0eb9376dd573857cf04c345bf8f98f0d429af4fa 100644
--- a/src/include/utils/guc_tables.h
+++ b/src/include/utils/guc_tables.h
@@ -7,7 +7,7 @@
  *
  * Portions Copyright (c) 1996-2002, PostgreSQL Global Development Group
  *
- *	  $Id: guc_tables.h,v 1.1 2003/07/04 16:41:22 tgl Exp $
+ *	  $Id: guc_tables.h,v 1.2 2003/07/27 04:35:54 momjian Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -61,10 +61,10 @@ enum config_group
  */
 enum config_type
 {
-	PGC_BOOL,
-	PGC_INT,
-	PGC_REAL,
-	PGC_STRING
+	PGC_BOOL = 0,
+	PGC_INT = 1,
+	PGC_REAL = 2,
+	PGC_STRING = 3
 };
 
 /*
diff --git a/src/test/regress/expected/rangefuncs.out b/src/test/regress/expected/rangefuncs.out
index 2790790717aeb1844738f2ee0c8924581d44d59f..7acbbe9bc608d3e6093cd47c4bc7f7baf43c6d19 100644
--- a/src/test/regress/expected/rangefuncs.out
+++ b/src/test/regress/expected/rangefuncs.out
@@ -1,4 +1,4 @@
-SELECT * FROM pg_settings WHERE name LIKE 'enable%';
+SELECT name, setting FROM pg_settings WHERE name LIKE 'enable%';
        name       | setting 
 ------------------+---------
  enable_hashagg   | on
diff --git a/src/test/regress/expected/rules.out b/src/test/regress/expected/rules.out
index 75e8a676d316b588582e982abb8ad02a130abcfc..a00959e0f70b0ca6109eecb8f6dc306d3ccf3e4b 100644
--- a/src/test/regress/expected/rules.out
+++ b/src/test/regress/expected/rules.out
@@ -1273,7 +1273,7 @@ SELECT viewname, definition FROM pg_views WHERE schemaname <> 'information_schem
  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;
diff --git a/src/test/regress/sql/rangefuncs.sql b/src/test/regress/sql/rangefuncs.sql
index 6522fdda10d96ea651d63a5caf166c8e06edf688..2f1c8e75130b07dc7207691c28da659a63981869 100644
--- a/src/test/regress/sql/rangefuncs.sql
+++ b/src/test/regress/sql/rangefuncs.sql
@@ -1,4 +1,4 @@
-SELECT * FROM pg_settings WHERE name LIKE 'enable%';
+SELECT name, setting FROM pg_settings WHERE name LIKE 'enable%';
 
 CREATE TABLE foo2(fooid int, f2 int);
 INSERT INTO foo2 VALUES(1, 11);