diff -cpr head/src/backend/utils/adt/bool.c boolin_accepts_onoff/src/backend/utils/adt/bool.c
*** head/src/backend/utils/adt/bool.c	Mon Jan  5 00:22:25 2009
--- boolin_accepts_onoff/src/backend/utils/adt/bool.c	Fri Feb 20 17:46:15 2009
***************
*** 20,25 ****
--- 20,118 ----
  #include "libpq/pqformat.h"
  #include "utils/builtins.h"
  
+ /*
+  * Try to interpret value as boolean value.  Valid values are: true,
+  * false, yes, no, on, off, 1, 0; as well as unique prefixes thereof.
+  * If the string parses okay, return true, else false.
+  * If okay and result is not NULL, return the value in *result.
+  */
+ bool
+ parse_bool(const char *value, bool *result)
+ {
+ 	return parse_bool_with_len(value, strlen(value), result);
+ }
+ 
+ bool
+ parse_bool_with_len(const char *value, size_t len, bool *result)
+ {
+ 	switch (*value)
+ 	{
+ 		case 't':
+ 		case 'T':
+ 			if (pg_strncasecmp(value, "true", len) == 0)
+ 			{
+ 				if (result)
+ 					*result = true;
+ 				return true;
+ 			}
+ 			break;
+ 		case 'f':
+ 		case 'F':
+ 			if (pg_strncasecmp(value, "false", len) == 0)
+ 			{
+ 				if (result)
+ 					*result = false;
+ 				return true;
+ 			}
+ 			break;
+ 		case 'y':
+ 		case 'Y':
+ 			if (pg_strncasecmp(value, "yes", len) == 0)
+ 			{
+ 				if (result)
+ 					*result = true;
+ 				return true;
+ 			}
+ 			break;
+ 		case 'n':
+ 		case 'N':
+ 			if (pg_strncasecmp(value, "no", len) == 0)
+ 			{
+ 				if (result)
+ 					*result = false;
+ 				return true;
+ 			}
+ 			break;
+ 		case 'o':
+ 		case 'O':
+ 			/* 'o' is not unique enough */
+ 			if (pg_strncasecmp(value, "on", (len > 2 ? len : 2)) == 0)
+ 			{
+ 				if (result)
+ 					*result = true;
+ 				return true;
+ 			}
+ 			else if (pg_strncasecmp(value, "off", (len > 2 ? len : 2)) == 0)
+ 			{
+ 				if (result)
+ 					*result = false;
+ 				return true;
+ 			}
+ 			break;
+ 		case '1':
+ 			if (len == 1)
+ 			{
+ 				if (result)
+ 					*result = true;
+ 				return true;
+ 			}
+ 			break;
+ 		case '0':
+ 			if (len == 1)
+ 			{
+ 				if (result)
+ 					*result = false;
+ 				return true;
+ 			}
+ 			break;
+ 		default:
+ 			break;
+ 	}
+ 
+ 	*result = false;	/* suppress compiler warning */
+ 	return false;
+ }
+ 
  /*****************************************************************************
   *	 USER I/O ROUTINES														 *
   *****************************************************************************/
***************
*** 27,34 ****
  /*
   *		boolin			- converts "t" or "f" to 1 or 0
   *
!  * Check explicitly for "true/false" and TRUE/FALSE, 1/0, YES/NO.
!  * Reject other values. - thomas 1997-10-05
   *
   * In the switch statement, check the most-used possibilities first.
   */
--- 120,127 ----
  /*
   *		boolin			- converts "t" or "f" to 1 or 0
   *
!  * Check explicitly for "true/false" and TRUE/FALSE, 1/0, YES/NO, ON/OFF.
!  * Reject other values.
   *
   * In the switch statement, check the most-used possibilities first.
   */
*************** boolin(PG_FUNCTION_ARGS)
*** 38,43 ****
--- 131,137 ----
  	const char *in_str = PG_GETARG_CSTRING(0);
  	const char *str;
  	size_t		len;
+ 	bool		result;
  
  	/*
  	 * Skip leading and trailing whitespace
*************** boolin(PG_FUNCTION_ARGS)
*** 50,94 ****
  	while (len > 0 && isspace((unsigned char) str[len - 1]))
  		len--;
  
! 	switch (*str)
! 	{
! 		case 't':
! 		case 'T':
! 			if (pg_strncasecmp(str, "true", len) == 0)
! 				PG_RETURN_BOOL(true);
! 			break;
! 
! 		case 'f':
! 		case 'F':
! 			if (pg_strncasecmp(str, "false", len) == 0)
! 				PG_RETURN_BOOL(false);
! 			break;
! 
! 		case 'y':
! 		case 'Y':
! 			if (pg_strncasecmp(str, "yes", len) == 0)
! 				PG_RETURN_BOOL(true);
! 			break;
! 
! 		case '1':
! 			if (pg_strncasecmp(str, "1", len) == 0)
! 				PG_RETURN_BOOL(true);
! 			break;
! 
! 		case 'n':
! 		case 'N':
! 			if (pg_strncasecmp(str, "no", len) == 0)
! 				PG_RETURN_BOOL(false);
! 			break;
! 
! 		case '0':
! 			if (pg_strncasecmp(str, "0", len) == 0)
! 				PG_RETURN_BOOL(false);
! 			break;
! 
! 		default:
! 			break;
! 	}
  
  	ereport(ERROR,
  			(errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
--- 144,151 ----
  	while (len > 0 && isspace((unsigned char) str[len - 1]))
  		len--;
  
! 	if (parse_bool_with_len(str, len, &result))
! 		PG_RETURN_BOOL(result);
  
  	ereport(ERROR,
  			(errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
diff -cpr head/src/backend/utils/misc/guc.c boolin_accepts_onoff/src/backend/utils/misc/guc.c
*** head/src/backend/utils/misc/guc.c	Thu Jan 22 09:48:53 2009
--- boolin_accepts_onoff/src/backend/utils/misc/guc.c	Fri Feb 20 17:46:15 2009
*************** ReportGUCOption(struct config_generic * 
*** 4086,4159 ****
  	}
  }
  
- 
- /*
-  * Try to interpret value as boolean value.  Valid values are: true,
-  * false, yes, no, on, off, 1, 0; as well as unique prefixes thereof.
-  * If the string parses okay, return true, else false.
-  * If okay and result is not NULL, return the value in *result.
-  */
- bool
- parse_bool(const char *value, bool *result)
- {
- 	size_t		len = strlen(value);
- 
- 	if (pg_strncasecmp(value, "true", len) == 0)
- 	{
- 		if (result)
- 			*result = true;
- 	}
- 	else if (pg_strncasecmp(value, "false", len) == 0)
- 	{
- 		if (result)
- 			*result = false;
- 	}
- 
- 	else if (pg_strncasecmp(value, "yes", len) == 0)
- 	{
- 		if (result)
- 			*result = true;
- 	}
- 	else if (pg_strncasecmp(value, "no", len) == 0)
- 	{
- 		if (result)
- 			*result = false;
- 	}
- 
- 	/* 'o' is not unique enough */
- 	else if (pg_strncasecmp(value, "on", (len > 2 ? len : 2)) == 0)
- 	{
- 		if (result)
- 			*result = true;
- 	}
- 	else if (pg_strncasecmp(value, "off", (len > 2 ? len : 2)) == 0)
- 	{
- 		if (result)
- 			*result = false;
- 	}
- 
- 	else if (pg_strcasecmp(value, "1") == 0)
- 	{
- 		if (result)
- 			*result = true;
- 	}
- 	else if (pg_strcasecmp(value, "0") == 0)
- 	{
- 		if (result)
- 			*result = false;
- 	}
- 
- 	else
- 	{
- 		if (result)
- 			*result = false;	/* suppress compiler warning */
- 		return false;
- 	}
- 	return true;
- }
- 
- 
- 
  /*
   * Try to parse value as an integer.  The accepted formats are the
   * usual decimal, octal, or hexadecimal formats, optionally followed by
--- 4086,4091 ----
diff -cpr head/src/include/utils/builtins.h boolin_accepts_onoff/src/include/utils/builtins.h
*** head/src/include/utils/builtins.h	Mon Feb  9 09:25:51 2009
--- boolin_accepts_onoff/src/include/utils/builtins.h	Fri Feb 20 17:46:15 2009
*************** extern Datum boolle(PG_FUNCTION_ARGS);
*** 109,114 ****
--- 109,116 ----
  extern Datum boolge(PG_FUNCTION_ARGS);
  extern Datum booland_statefunc(PG_FUNCTION_ARGS);
  extern Datum boolor_statefunc(PG_FUNCTION_ARGS);
+ extern bool parse_bool(const char *value, bool *result);
+ extern bool parse_bool_with_len(const char *value, size_t len, bool *result);
  
  /* char.c */
  extern Datum charin(PG_FUNCTION_ARGS);
diff -cpr head/src/include/utils/guc.h boolin_accepts_onoff/src/include/utils/guc.h
*** head/src/include/utils/guc.h	Mon Jan  5 00:22:25 2009
--- boolin_accepts_onoff/src/include/utils/guc.h	Fri Feb 20 17:46:15 2009
*************** extern int	NewGUCNestLevel(void);
*** 257,263 ****
  extern void AtEOXact_GUC(bool isCommit, int nestLevel);
  extern void BeginReportingGUCOptions(void);
  extern void ParseLongOption(const char *string, char **name, char **value);
- extern bool parse_bool(const char *value, bool *result);
  extern bool parse_int(const char *value, int *result, int flags,
  					  const char **hintmsg);
  extern bool parse_real(const char *value, double *result);
--- 257,262 ----
diff -cpr head/src/test/regress/expected/boolean.out boolin_accepts_onoff/src/test/regress/expected/boolean.out
*** head/src/test/regress/expected/boolean.out	Tue Oct  7 09:40:59 2008
--- boolin_accepts_onoff/src/test/regress/expected/boolean.out	Fri Feb 20 17:46:15 2009
*************** SELECT bool 'nay' AS error;
*** 88,93 ****
--- 88,123 ----
  ERROR:  invalid input syntax for type boolean: "nay"
  LINE 1: SELECT bool 'nay' AS error;
                      ^
+ SELECT bool 'on' AS true;
+  true 
+ ------
+  t
+ (1 row)
+ 
+ SELECT bool 'off' AS false;
+  false 
+ -------
+  f
+ (1 row)
+ 
+ SELECT bool 'of' AS false;
+  false 
+ -------
+  f
+ (1 row)
+ 
+ SELECT bool 'o' AS error;
+ ERROR:  invalid input syntax for type boolean: "o"
+ LINE 1: SELECT bool 'o' AS error;
+                     ^
+ SELECT bool 'on_' AS error;
+ ERROR:  invalid input syntax for type boolean: "on_"
+ LINE 1: SELECT bool 'on_' AS error;
+                     ^
+ SELECT bool 'off_' AS error;
+ ERROR:  invalid input syntax for type boolean: "off_"
+ LINE 1: SELECT bool 'off_' AS error;
+                     ^
  SELECT bool '1' AS true;
   true 
  ------
diff -cpr head/src/test/regress/sql/boolean.sql boolin_accepts_onoff/src/test/regress/sql/boolean.sql
*** head/src/test/regress/sql/boolean.sql	Tue Oct  7 09:40:59 2008
--- boolin_accepts_onoff/src/test/regress/sql/boolean.sql	Fri Feb 20 17:46:15 2009
*************** SELECT bool 'no' AS false;
*** 40,45 ****
--- 40,57 ----
  
  SELECT bool 'nay' AS error;
  
+ SELECT bool 'on' AS true;
+ 
+ SELECT bool 'off' AS false;
+ 
+ SELECT bool 'of' AS false;
+ 
+ SELECT bool 'o' AS error;
+ 
+ SELECT bool 'on_' AS error;
+ 
+ SELECT bool 'off_' AS error;
+ 
  SELECT bool '1' AS true;
  
  SELECT bool '11' AS error;
