Here is a preliminary patch for units in postgresql.conf (and SET and so on, 
of course).  It currently supports memory units only.  Time units would be 
similar.  Let me know if you have comments.

(FWIW, work_mem is a good parameter to play with for trying this out.)

-- 
Peter Eisentraut
http://developer.postgresql.org/~petere/
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 */
---------------------------(end of broadcast)---------------------------
TIP 5: don't forget to increase your free space map settings

Reply via email to