Commit 05a7db05 authored by Peter Eisentraut's avatar Peter Eisentraut

Accept 'on' and 'off' as input for boolean data type, unifying the syntax

that the data type and GUC accepts.

ITAGAKI Takahiro
parent fd497ab6
<!-- $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"> <chapter id="datatype">
<title id="datatype-title">Data Types</title> <title id="datatype-title">Data Types</title>
...@@ -2686,6 +2686,7 @@ P <optional> <replaceable>years</>-<replaceable>months</>-<replaceable>days</> < ...@@ -2686,6 +2686,7 @@ P <optional> <replaceable>years</>-<replaceable>months</>-<replaceable>days</> <
<member><literal>'true'</literal></member> <member><literal>'true'</literal></member>
<member><literal>'y'</literal></member> <member><literal>'y'</literal></member>
<member><literal>'yes'</literal></member> <member><literal>'yes'</literal></member>
<member><literal>'on'</literal></member>
<member><literal>'1'</literal></member> <member><literal>'1'</literal></member>
</simplelist> </simplelist>
For the <quote>false</quote> state, the following values can be For the <quote>false</quote> state, the following values can be
...@@ -2696,6 +2697,7 @@ P <optional> <replaceable>years</>-<replaceable>months</>-<replaceable>days</> < ...@@ -2696,6 +2697,7 @@ P <optional> <replaceable>years</>-<replaceable>months</>-<replaceable>days</> <
<member><literal>'false'</literal></member> <member><literal>'false'</literal></member>
<member><literal>'n'</literal></member> <member><literal>'n'</literal></member>
<member><literal>'no'</literal></member> <member><literal>'no'</literal></member>
<member><literal>'off'</literal></member>
<member><literal>'0'</literal></member> <member><literal>'0'</literal></member>
</simplelist> </simplelist>
Leading and trailing whitespace is ignored. Using the key words Leading and trailing whitespace is ignored. Using the key words
......
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * 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 $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -20,6 +20,99 @@ ...@@ -20,6 +20,99 @@
#include "libpq/pqformat.h" #include "libpq/pqformat.h"
#include "utils/builtins.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 * * USER I/O ROUTINES *
*****************************************************************************/ *****************************************************************************/
...@@ -27,8 +120,8 @@ ...@@ -27,8 +120,8 @@
/* /*
* boolin - converts "t" or "f" to 1 or 0 * boolin - converts "t" or "f" to 1 or 0
* *
* Check explicitly for "true/false" and TRUE/FALSE, 1/0, YES/NO. * Check explicitly for "true/false" and TRUE/FALSE, 1/0, YES/NO, ON/OFF.
* Reject other values. - thomas 1997-10-05 * Reject other values.
* *
* In the switch statement, check the most-used possibilities first. * In the switch statement, check the most-used possibilities first.
*/ */
...@@ -38,6 +131,7 @@ boolin(PG_FUNCTION_ARGS) ...@@ -38,6 +131,7 @@ boolin(PG_FUNCTION_ARGS)
const char *in_str = PG_GETARG_CSTRING(0); const char *in_str = PG_GETARG_CSTRING(0);
const char *str; const char *str;
size_t len; size_t len;
bool result;
/* /*
* Skip leading and trailing whitespace * Skip leading and trailing whitespace
...@@ -50,45 +144,8 @@ boolin(PG_FUNCTION_ARGS) ...@@ -50,45 +144,8 @@ boolin(PG_FUNCTION_ARGS)
while (len > 0 && isspace((unsigned char) str[len - 1])) while (len > 0 && isspace((unsigned char) str[len - 1]))
len--; len--;
switch (*str) if (parse_bool_with_len(str, len, &result))
{ PG_RETURN_BOOL(result);
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, ereport(ERROR,
(errcode(ERRCODE_INVALID_TEXT_REPRESENTATION), (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
......
...@@ -10,7 +10,7 @@ ...@@ -10,7 +10,7 @@
* Written by Peter Eisentraut <peter_e@gmx.net>. * Written by Peter Eisentraut <peter_e@gmx.net>.
* *
* IDENTIFICATION * 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) ...@@ -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 * Try to parse value as an integer. The accepted formats are the
* usual decimal, octal, or hexadecimal formats, optionally followed by * usual decimal, octal, or hexadecimal formats, optionally followed by
......
...@@ -7,7 +7,7 @@ ...@@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2009, PostgreSQL Global Development Group * Portions Copyright (c) 1996-2009, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California * 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); ...@@ -109,6 +109,8 @@ extern Datum boolle(PG_FUNCTION_ARGS);
extern Datum boolge(PG_FUNCTION_ARGS); extern Datum boolge(PG_FUNCTION_ARGS);
extern Datum booland_statefunc(PG_FUNCTION_ARGS); extern Datum booland_statefunc(PG_FUNCTION_ARGS);
extern Datum boolor_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 */ /* char.c */
extern Datum charin(PG_FUNCTION_ARGS); extern Datum charin(PG_FUNCTION_ARGS);
......
...@@ -7,7 +7,7 @@ ...@@ -7,7 +7,7 @@
* Copyright (c) 2000-2009, PostgreSQL Global Development Group * Copyright (c) 2000-2009, PostgreSQL Global Development Group
* Written by Peter Eisentraut <peter_e@gmx.net>. * 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 #ifndef GUC_H
...@@ -257,7 +257,6 @@ extern int NewGUCNestLevel(void); ...@@ -257,7 +257,6 @@ extern int NewGUCNestLevel(void);
extern void AtEOXact_GUC(bool isCommit, int nestLevel); extern void AtEOXact_GUC(bool isCommit, int nestLevel);
extern void BeginReportingGUCOptions(void); extern void BeginReportingGUCOptions(void);
extern void ParseLongOption(const char *string, char **name, char **value); 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, extern bool parse_int(const char *value, int *result, int flags,
const char **hintmsg); const char **hintmsg);
extern bool parse_real(const char *value, double *result); extern bool parse_real(const char *value, double *result);
......
...@@ -88,6 +88,36 @@ SELECT bool 'nay' AS error; ...@@ -88,6 +88,36 @@ SELECT bool 'nay' AS error;
ERROR: invalid input syntax for type boolean: "nay" ERROR: invalid input syntax for type boolean: "nay"
LINE 1: SELECT bool 'nay' AS error; 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; SELECT bool '1' AS true;
true true
------ ------
......
...@@ -40,6 +40,18 @@ SELECT bool 'no' AS false; ...@@ -40,6 +40,18 @@ SELECT bool 'no' AS false;
SELECT bool 'nay' AS error; 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 '1' AS true;
SELECT bool '11' AS error; SELECT bool '11' AS error;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment