Header And Logo

PostgreSQL
| The world's most advanced open source database.

bool.c

Go to the documentation of this file.
00001 /*-------------------------------------------------------------------------
00002  *
00003  * bool.c
00004  *    Functions for the built-in type "bool".
00005  *
00006  * Portions Copyright (c) 1996-2013, PostgreSQL Global Development Group
00007  * Portions Copyright (c) 1994, Regents of the University of California
00008  *
00009  *
00010  * IDENTIFICATION
00011  *    src/backend/utils/adt/bool.c
00012  *
00013  *-------------------------------------------------------------------------
00014  */
00015 
00016 #include "postgres.h"
00017 
00018 #include <ctype.h>
00019 
00020 #include "libpq/pqformat.h"
00021 #include "utils/builtins.h"
00022 
00023 /*
00024  * Try to interpret value as boolean value.  Valid values are: true,
00025  * false, yes, no, on, off, 1, 0; as well as unique prefixes thereof.
00026  * If the string parses okay, return true, else false.
00027  * If okay and result is not NULL, return the value in *result.
00028  */
00029 bool
00030 parse_bool(const char *value, bool *result)
00031 {
00032     return parse_bool_with_len(value, strlen(value), result);
00033 }
00034 
00035 bool
00036 parse_bool_with_len(const char *value, size_t len, bool *result)
00037 {
00038     switch (*value)
00039     {
00040         case 't':
00041         case 'T':
00042             if (pg_strncasecmp(value, "true", len) == 0)
00043             {
00044                 if (result)
00045                     *result = true;
00046                 return true;
00047             }
00048             break;
00049         case 'f':
00050         case 'F':
00051             if (pg_strncasecmp(value, "false", len) == 0)
00052             {
00053                 if (result)
00054                     *result = false;
00055                 return true;
00056             }
00057             break;
00058         case 'y':
00059         case 'Y':
00060             if (pg_strncasecmp(value, "yes", len) == 0)
00061             {
00062                 if (result)
00063                     *result = true;
00064                 return true;
00065             }
00066             break;
00067         case 'n':
00068         case 'N':
00069             if (pg_strncasecmp(value, "no", len) == 0)
00070             {
00071                 if (result)
00072                     *result = false;
00073                 return true;
00074             }
00075             break;
00076         case 'o':
00077         case 'O':
00078             /* 'o' is not unique enough */
00079             if (pg_strncasecmp(value, "on", (len > 2 ? len : 2)) == 0)
00080             {
00081                 if (result)
00082                     *result = true;
00083                 return true;
00084             }
00085             else if (pg_strncasecmp(value, "off", (len > 2 ? len : 2)) == 0)
00086             {
00087                 if (result)
00088                     *result = false;
00089                 return true;
00090             }
00091             break;
00092         case '1':
00093             if (len == 1)
00094             {
00095                 if (result)
00096                     *result = true;
00097                 return true;
00098             }
00099             break;
00100         case '0':
00101             if (len == 1)
00102             {
00103                 if (result)
00104                     *result = false;
00105                 return true;
00106             }
00107             break;
00108         default:
00109             break;
00110     }
00111 
00112     if (result)
00113         *result = false;        /* suppress compiler warning */
00114     return false;
00115 }
00116 
00117 /*****************************************************************************
00118  *   USER I/O ROUTINES                                                       *
00119  *****************************************************************************/
00120 
00121 /*
00122  *      boolin          - converts "t" or "f" to 1 or 0
00123  *
00124  * Check explicitly for "true/false" and TRUE/FALSE, 1/0, YES/NO, ON/OFF.
00125  * Reject other values.
00126  *
00127  * In the switch statement, check the most-used possibilities first.
00128  */
00129 Datum
00130 boolin(PG_FUNCTION_ARGS)
00131 {
00132     const char *in_str = PG_GETARG_CSTRING(0);
00133     const char *str;
00134     size_t      len;
00135     bool        result;
00136 
00137     /*
00138      * Skip leading and trailing whitespace
00139      */
00140     str = in_str;
00141     while (isspace((unsigned char) *str))
00142         str++;
00143 
00144     len = strlen(str);
00145     while (len > 0 && isspace((unsigned char) str[len - 1]))
00146         len--;
00147 
00148     if (parse_bool_with_len(str, len, &result))
00149         PG_RETURN_BOOL(result);
00150 
00151     ereport(ERROR,
00152             (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
00153            errmsg("invalid input syntax for type boolean: \"%s\"", in_str)));
00154 
00155     /* not reached */
00156     PG_RETURN_BOOL(false);
00157 }
00158 
00159 /*
00160  *      boolout         - converts 1 or 0 to "t" or "f"
00161  */
00162 Datum
00163 boolout(PG_FUNCTION_ARGS)
00164 {
00165     bool        b = PG_GETARG_BOOL(0);
00166     char       *result = (char *) palloc(2);
00167 
00168     result[0] = (b) ? 't' : 'f';
00169     result[1] = '\0';
00170     PG_RETURN_CSTRING(result);
00171 }
00172 
00173 /*
00174  *      boolrecv            - converts external binary format to bool
00175  *
00176  * The external representation is one byte.  Any nonzero value is taken
00177  * as "true".
00178  */
00179 Datum
00180 boolrecv(PG_FUNCTION_ARGS)
00181 {
00182     StringInfo  buf = (StringInfo) PG_GETARG_POINTER(0);
00183     int         ext;
00184 
00185     ext = pq_getmsgbyte(buf);
00186     PG_RETURN_BOOL((ext != 0) ? true : false);
00187 }
00188 
00189 /*
00190  *      boolsend            - converts bool to binary format
00191  */
00192 Datum
00193 boolsend(PG_FUNCTION_ARGS)
00194 {
00195     bool        arg1 = PG_GETARG_BOOL(0);
00196     StringInfoData buf;
00197 
00198     pq_begintypsend(&buf);
00199     pq_sendbyte(&buf, arg1 ? 1 : 0);
00200     PG_RETURN_BYTEA_P(pq_endtypsend(&buf));
00201 }
00202 
00203 /*
00204  *      booltext            - cast function for bool => text
00205  *
00206  * We need this because it's different from the behavior of boolout();
00207  * this function follows the SQL-spec result (except for producing lower case)
00208  */
00209 Datum
00210 booltext(PG_FUNCTION_ARGS)
00211 {
00212     bool        arg1 = PG_GETARG_BOOL(0);
00213     const char *str;
00214 
00215     if (arg1)
00216         str = "true";
00217     else
00218         str = "false";
00219 
00220     PG_RETURN_TEXT_P(cstring_to_text(str));
00221 }
00222 
00223 
00224 /*****************************************************************************
00225  *   PUBLIC ROUTINES                                                         *
00226  *****************************************************************************/
00227 
00228 Datum
00229 booleq(PG_FUNCTION_ARGS)
00230 {
00231     bool        arg1 = PG_GETARG_BOOL(0);
00232     bool        arg2 = PG_GETARG_BOOL(1);
00233 
00234     PG_RETURN_BOOL(arg1 == arg2);
00235 }
00236 
00237 Datum
00238 boolne(PG_FUNCTION_ARGS)
00239 {
00240     bool        arg1 = PG_GETARG_BOOL(0);
00241     bool        arg2 = PG_GETARG_BOOL(1);
00242 
00243     PG_RETURN_BOOL(arg1 != arg2);
00244 }
00245 
00246 Datum
00247 boollt(PG_FUNCTION_ARGS)
00248 {
00249     bool        arg1 = PG_GETARG_BOOL(0);
00250     bool        arg2 = PG_GETARG_BOOL(1);
00251 
00252     PG_RETURN_BOOL(arg1 < arg2);
00253 }
00254 
00255 Datum
00256 boolgt(PG_FUNCTION_ARGS)
00257 {
00258     bool        arg1 = PG_GETARG_BOOL(0);
00259     bool        arg2 = PG_GETARG_BOOL(1);
00260 
00261     PG_RETURN_BOOL(arg1 > arg2);
00262 }
00263 
00264 Datum
00265 boolle(PG_FUNCTION_ARGS)
00266 {
00267     bool        arg1 = PG_GETARG_BOOL(0);
00268     bool        arg2 = PG_GETARG_BOOL(1);
00269 
00270     PG_RETURN_BOOL(arg1 <= arg2);
00271 }
00272 
00273 Datum
00274 boolge(PG_FUNCTION_ARGS)
00275 {
00276     bool        arg1 = PG_GETARG_BOOL(0);
00277     bool        arg2 = PG_GETARG_BOOL(1);
00278 
00279     PG_RETURN_BOOL(arg1 >= arg2);
00280 }
00281 
00282 /*
00283  * boolean-and and boolean-or aggregates.
00284  */
00285 
00286 /* function for standard EVERY aggregate implementation conforming to SQL 2003.
00287  * must be strict. It is also named bool_and for homogeneity.
00288  */
00289 Datum
00290 booland_statefunc(PG_FUNCTION_ARGS)
00291 {
00292     PG_RETURN_BOOL(PG_GETARG_BOOL(0) && PG_GETARG_BOOL(1));
00293 }
00294 
00295 /* function for standard ANY/SOME aggregate conforming to SQL 2003.
00296  * must be strict. The name of the aggregate is bool_or. See the doc.
00297  */
00298 Datum
00299 boolor_statefunc(PG_FUNCTION_ARGS)
00300 {
00301     PG_RETURN_BOOL(PG_GETARG_BOOL(0) || PG_GETARG_BOOL(1));
00302 }