Accept 'on' and 'off' as input for boolean data type, unifying the syntax
authorPeter Eisentraut <peter_e@gmx.net>
Mon, 9 Mar 2009 14:34:35 +0000 (14:34 +0000)
committerPeter Eisentraut <peter_e@gmx.net>
Mon, 9 Mar 2009 14:34:35 +0000 (14:34 +0000)
that the data type and GUC accepts.

ITAGAKI Takahiro

doc/src/sgml/datatype.sgml
src/backend/utils/adt/bool.c
src/backend/utils/misc/guc.c
src/include/utils/builtins.h
src/include/utils/guc.h
src/test/regress/expected/boolean.out
src/test/regress/sql/boolean.sql

index 6a61c0c5bf532be0f921bd8209cdb3659087409b..fe7f95f08609bff59065af4a2905a73aa13d7343 100644 (file)
@@ -1,4 +1,4 @@
-<!-- $PostgreSQL: pgsql/doc/src/sgml/datatype.sgml,v 1.235 2008/12/19 01:34:19 tgl Exp $ -->
+<!-- $PostgreSQL: pgsql/doc/src/sgml/datatype.sgml,v 1.236 2009/03/09 14:34:34 petere Exp $ -->
 
  <chapter id="datatype">
   <title id="datatype-title">Data Types</title>
@@ -2686,6 +2686,7 @@ P <optional> <replaceable>years</>-<replaceable>months</>-<replaceable>days</> <
      <member><literal>'true'</literal></member>
      <member><literal>'y'</literal></member>
      <member><literal>'yes'</literal></member>
+     <member><literal>'on'</literal></member>
      <member><literal>'1'</literal></member>
     </simplelist>
     For the <quote>false</quote> state, the following values can be
@@ -2696,6 +2697,7 @@ P <optional> <replaceable>years</>-<replaceable>months</>-<replaceable>days</> <
      <member><literal>'false'</literal></member>
      <member><literal>'n'</literal></member>
      <member><literal>'no'</literal></member>
+     <member><literal>'off'</literal></member>
      <member><literal>'0'</literal></member>
     </simplelist>
     Leading and trailing whitespace is ignored. Using the key words
index 8584b3c290678a1465d746b138ce30398983ebc8..7d3f9e55a1c6213e07d7937625d4ebd8e81195dd 100644 (file)
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *   $PostgreSQL: pgsql/src/backend/utils/adt/bool.c,v 1.45 2009/01/01 17:23:49 momjian Exp $
+ *   $PostgreSQL: pgsql/src/backend/utils/adt/bool.c,v 1.46 2009/03/09 14:34:34 petere Exp $
  *
  *-------------------------------------------------------------------------
  */
 #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                                                       *
  *****************************************************************************/
 /*
  *     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
+ * 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.
  */
@@ -38,6 +131,7 @@ boolin(PG_FUNCTION_ARGS)
    const char *in_str = PG_GETARG_CSTRING(0);
    const char *str;
    size_t      len;
+   bool        result;
 
    /*
     * Skip leading and trailing whitespace
@@ -50,45 +144,8 @@ boolin(PG_FUNCTION_ARGS)
    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;
-   }
+   if (parse_bool_with_len(str, len, &result))
+       PG_RETURN_BOOL(result);
 
    ereport(ERROR,
            (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
index 5411840b2a087e1439c295602c0e7e96769518ce..8bf2305736c49a8a55f0a4076f343534fd34a2eb 100644 (file)
@@ -10,7 +10,7 @@
  * Written by Peter Eisentraut <peter_e@gmx.net>.
  *
  * IDENTIFICATION
- *   $PostgreSQL: pgsql/src/backend/utils/misc/guc.c,v 1.496 2009/02/28 00:10:51 tgl Exp $
+ *   $PostgreSQL: pgsql/src/backend/utils/misc/guc.c,v 1.497 2009/03/09 14:34:34 petere Exp $
  *
  *--------------------------------------------------------------------
  */
@@ -4086,74 +4086,6 @@ ReportGUCOption(struct config_generic * record)
    }
 }
 
-
-/*
- * 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
index 155abf456b55233c2c6e7aa08a5031770e0f65d1..06d8e04d1d6d4db319653002f6e7cd6971c14886 100644 (file)
@@ -7,7 +7,7 @@
  * Portions Copyright (c) 1996-2009, PostgreSQL Global Development Group
  * Portions Copyright (c) 1994, Regents of the University of California
  *
- * $PostgreSQL: pgsql/src/include/utils/builtins.h,v 1.331 2009/02/06 21:15:12 tgl Exp $
+ * $PostgreSQL: pgsql/src/include/utils/builtins.h,v 1.332 2009/03/09 14:34:34 petere Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -109,6 +109,8 @@ extern Datum boolle(PG_FUNCTION_ARGS);
 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);
index dcd00b97c35860de69ccb295a110fb97789d4bb2..cded751f92ca1d80aafcbb75818bf45b5e4924f1 100644 (file)
@@ -7,7 +7,7 @@
  * Copyright (c) 2000-2009, PostgreSQL Global Development Group
  * Written by Peter Eisentraut <peter_e@gmx.net>.
  *
- * $PostgreSQL: pgsql/src/include/utils/guc.h,v 1.100 2009/01/01 17:24:02 momjian Exp $
+ * $PostgreSQL: pgsql/src/include/utils/guc.h,v 1.101 2009/03/09 14:34:35 petere Exp $
  *--------------------------------------------------------------------
  */
 #ifndef GUC_H
@@ -257,7 +257,6 @@ extern int  NewGUCNestLevel(void);
 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);
index a3629f228272a2a1a70b2c984f1c4d65994be777..28d7cf952681f0339f1f481c2694fb094cfa3498 100644 (file)
@@ -88,6 +88,36 @@ SELECT bool 'nay' AS error;
 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 
 ------
index 63dd22f8771c292ce30cde12d9fb9a19a7108cf3..a605302e122c232a097e3debbde5f015c4b42e5b 100644 (file)
@@ -40,6 +40,18 @@ SELECT bool 'no' AS false;
 
 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;