diff -ur ../cvs-pgsql/src/backend/utils/misc/guc.c ./src/backend/utils/misc/guc.c
--- ../cvs-pgsql/src/backend/utils/misc/guc.c	2006-07-25 10:45:29.000000000 +0200
+++ ./src/backend/utils/misc/guc.c	2006-07-25 13:47:27.000000000 +0200
@@ -83,6 +83,10 @@
 #define MAX_KILOBYTES	(INT_MAX / 1024)
 #endif
 
+#define KILOBYTE 1024
+#define MEGABYTE (1024*1024)
+#define GIGABYTE (1024*1024*1024)
+
 /* XXX these should appear in other modules' header files */
 extern bool Log_disconnections;
 extern bool check_function_bodies;
@@ -1125,7 +1129,8 @@
 	{
 		{"shared_buffers", PGC_POSTMASTER, RESOURCES_MEM,
 			gettext_noop("Sets the number of shared memory buffers used by the server."),
-			NULL
+			NULL,
+			GUC_UNIT_BLOCKS
 		},
 		&NBuffers,
 		1000, 16, INT_MAX / 2, NULL, NULL
@@ -1134,7 +1139,8 @@
 	{
 		{"temp_buffers", PGC_USERSET, RESOURCES_MEM,
 			gettext_noop("Sets the maximum number of temporary buffers used by each session."),
-			NULL
+			NULL,
+			GUC_UNIT_BLOCKS
 		},
 		&num_temp_buffers,
 		1000, 100, INT_MAX / 2, NULL, show_num_temp_buffers
@@ -1167,7 +1173,8 @@
 			gettext_noop("Sets the maximum memory to be used for query workspaces."),
 			gettext_noop("This much memory may be used by each internal "
 						 "sort operation and hash table before switching to "
-						 "temporary disk files.")
+						 "temporary disk files."),
+			GUC_UNIT_KB
 		},
 		&work_mem,
 		1024, 8 * BLCKSZ / 1024, MAX_KILOBYTES, NULL, NULL
@@ -1185,7 +1192,8 @@
 	{
 		{"max_stack_depth", PGC_SUSET, RESOURCES_MEM,
 			gettext_noop("Sets the maximum stack depth, in kilobytes."),
-			NULL
+			NULL,
+			GUC_UNIT_KB
 		},
 		&max_stack_depth,
 		2048, 100, MAX_KILOBYTES, assign_max_stack_depth, NULL
@@ -1469,7 +1477,8 @@
 	{
 		{"log_rotation_size", PGC_SIGHUP, LOGGING_WHERE,
 			gettext_noop("Automatic log file rotation will occur after N kilobytes"),
-			NULL
+			NULL,
+			GUC_UNIT_KB
 		},
 		&Log_RotationSize,
 		10 * 1024, 0, INT_MAX / 1024, NULL, NULL
@@ -3513,13 +3522,46 @@
  * value there.
  */
 static bool
-parse_int(const char *value, int *result)
+parse_int(const char *value, int *result, int flags)
 {
 	long		val;
 	char	   *endptr;
 
 	errno = 0;
 	val = strtol(value, &endptr, 0);
+
+	if ((flags & (GUC_UNIT_KB|GUC_UNIT_BLOCKS)) && endptr != value)
+	{
+		bool used = false;
+
+		while (*endptr == ' ')
+			endptr++;
+
+		if (strcmp(endptr, "kB") == 0)
+		{
+			val *= KILOBYTE;
+			used = true;
+			endptr += 2;
+		}
+		else if (strcmp(endptr, "MB") == 0)
+		{
+			val *= MEGABYTE;
+			used = true;
+			endptr += 2;
+		}
+		else if (strcmp(endptr, "GB") == 0)
+		{
+			val *= GIGABYTE;
+			used = true;
+			endptr += 2;
+		}
+
+		if (used && (flags & GUC_UNIT_KB))
+			val /= 1024;
+		else if (used && (flags & GUC_UNIT_BLOCKS))
+			val /= BLCKSZ;
+	}
+
 	if (endptr == value || *endptr != '\0' || errno == ERANGE
 #ifdef HAVE_LONG_INT_64
 	/* if long > 32 bits, check for overflow of int4 */
@@ -3850,7 +3892,7 @@
 
 				if (value)
 				{
-					if (!parse_int(value, &newval))
+					if (!parse_int(value, &newval, conf->gen.flags))
 					{
 						ereport(elevel,
 								(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
@@ -5082,8 +5124,34 @@
 					val = (*conf->show_hook) ();
 				else
 				{
-					snprintf(buffer, sizeof(buffer), "%d",
-							 *conf->variable);
+					char unit[3];
+					int result = *conf->variable;
+
+					if (record->flags & (GUC_UNIT_KB|GUC_UNIT_BLOCKS))
+					{
+						if (record->flags & GUC_UNIT_BLOCKS)
+							result *= BLCKSZ/1024;
+
+						if (result % (GIGABYTE/1024) == 0)
+						{
+							result /= (GIGABYTE/1024);
+							strcpy(unit, "GB");
+						}
+						else if (result % (MEGABYTE/1024) == 0)
+						{
+							result /= (MEGABYTE/1024);
+							strcpy(unit, "MB");
+						}
+						else
+						{
+							strcpy(unit, "kB");
+						}
+					}
+					else
+						strcpy(unit, "");
+
+					snprintf(buffer, sizeof(buffer), "%d%s",
+							 result, unit);
 					val = buffer;
 				}
 			}
@@ -5144,7 +5212,7 @@
 			struct config_int *conf = (struct config_int *) record;
 			int newval;
 
-			return parse_int(newvalue, &newval) && *conf->variable == newval;
+			return parse_int(newvalue, &newval, record->flags) && *conf->variable == newval;
 		}
 		case PGC_REAL:
 		{
diff -ur ../cvs-pgsql/src/include/utils/guc_tables.h ./src/include/utils/guc_tables.h
--- ../cvs-pgsql/src/include/utils/guc_tables.h	2006-07-20 10:42:11.000000000 +0200
+++ ./src/include/utils/guc_tables.h	2006-07-25 12:37:19.000000000 +0200
@@ -129,6 +129,8 @@
 #define GUC_CUSTOM_PLACEHOLDER	0x0080	/* placeholder for custom variable */
 #define GUC_SUPERUSER_ONLY		0x0100	/* show only to superusers */
 #define GUC_IS_NAME				0x0200	/* limit string to NAMEDATALEN-1 */
+#define GUC_UNIT_KB				0x0400	/* value is in 1 kB */
+#define GUC_UNIT_BLOCKS			0x0800	/* value is in blocks */
 
 /* bit values in status field */
 #define GUC_HAVE_TENTATIVE	0x0001		/* tentative value is defined */
