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;