Logo Search packages:      
Sourcecode: postgresql-8.4 version File versions

bool.c

/*-------------------------------------------------------------------------
 *
 * bool.c
 *      Functions for the built-in type "bool".
 *
 * Portions Copyright (c) 1996-2009, PostgreSQL Global Development Group
 * Portions Copyright (c) 1994, Regents of the University of California
 *
 *
 * IDENTIFICATION
 *      $PostgreSQL: pgsql/src/backend/utils/adt/bool.c,v 1.47 2009/03/09 16:49:12 petere Exp $
 *
 *-------------------------------------------------------------------------
 */

#include "postgres.h"

#include <ctype.h>

#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;
      }

      if (result)
            *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, ON/OFF.
 * Reject other values.
 *
 * In the switch statement, check the most-used possibilities first.
 */
Datum
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
       */
      str = in_str;
      while (isspace((unsigned char) *str))
            str++;

      len = strlen(str);
      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),
               errmsg("invalid input syntax for type boolean: \"%s\"", in_str)));

      /* not reached */
      PG_RETURN_BOOL(false);
}

/*
 *          boolout                 - converts 1 or 0 to "t" or "f"
 */
Datum
boolout(PG_FUNCTION_ARGS)
{
      bool        b = PG_GETARG_BOOL(0);
      char     *result = (char *) palloc(2);

      result[0] = (b) ? 't' : 'f';
      result[1] = '\0';
      PG_RETURN_CSTRING(result);
}

/*
 *          boolrecv                - converts external binary format to bool
 *
 * The external representation is one byte.  Any nonzero value is taken
 * as "true".
 */
Datum
boolrecv(PG_FUNCTION_ARGS)
{
      StringInfo  buf = (StringInfo) PG_GETARG_POINTER(0);
      int               ext;

      ext = pq_getmsgbyte(buf);
      PG_RETURN_BOOL((ext != 0) ? true : false);
}

/*
 *          boolsend                - converts bool to binary format
 */
Datum
boolsend(PG_FUNCTION_ARGS)
{
      bool        arg1 = PG_GETARG_BOOL(0);
      StringInfoData buf;

      pq_begintypsend(&buf);
      pq_sendbyte(&buf, arg1 ? 1 : 0);
      PG_RETURN_BYTEA_P(pq_endtypsend(&buf));
}

/*
 *          booltext                - cast function for bool => text
 *
 * We need this because it's different from the behavior of boolout();
 * this function follows the SQL-spec result (except for producing lower case)
 */
Datum
booltext(PG_FUNCTION_ARGS)
{
      bool        arg1 = PG_GETARG_BOOL(0);
      const char *str;

      if (arg1)
            str = "true";
      else
            str = "false";

      PG_RETURN_TEXT_P(cstring_to_text(str));
}


/*****************************************************************************
 *     PUBLIC ROUTINES                                                                                 *
 *****************************************************************************/

Datum
booleq(PG_FUNCTION_ARGS)
{
      bool        arg1 = PG_GETARG_BOOL(0);
      bool        arg2 = PG_GETARG_BOOL(1);

      PG_RETURN_BOOL(arg1 == arg2);
}

Datum
boolne(PG_FUNCTION_ARGS)
{
      bool        arg1 = PG_GETARG_BOOL(0);
      bool        arg2 = PG_GETARG_BOOL(1);

      PG_RETURN_BOOL(arg1 != arg2);
}

Datum
boollt(PG_FUNCTION_ARGS)
{
      bool        arg1 = PG_GETARG_BOOL(0);
      bool        arg2 = PG_GETARG_BOOL(1);

      PG_RETURN_BOOL(arg1 < arg2);
}

Datum
boolgt(PG_FUNCTION_ARGS)
{
      bool        arg1 = PG_GETARG_BOOL(0);
      bool        arg2 = PG_GETARG_BOOL(1);

      PG_RETURN_BOOL(arg1 > arg2);
}

Datum
boolle(PG_FUNCTION_ARGS)
{
      bool        arg1 = PG_GETARG_BOOL(0);
      bool        arg2 = PG_GETARG_BOOL(1);

      PG_RETURN_BOOL(arg1 <= arg2);
}

Datum
boolge(PG_FUNCTION_ARGS)
{
      bool        arg1 = PG_GETARG_BOOL(0);
      bool        arg2 = PG_GETARG_BOOL(1);

      PG_RETURN_BOOL(arg1 >= arg2);
}

/*
 * boolean-and and boolean-or aggregates.
 */

/* function for standard EVERY aggregate implementation conforming to SQL 2003.
 * must be strict. It is also named bool_and for homogeneity.
 */
Datum
booland_statefunc(PG_FUNCTION_ARGS)
{
      PG_RETURN_BOOL(PG_GETARG_BOOL(0) && PG_GETARG_BOOL(1));
}

/* function for standard ANY/SOME aggregate conforming to SQL 2003.
 * must be strict. The name of the aggregate is bool_or. See the doc.
 */
Datum
boolor_statefunc(PG_FUNCTION_ARGS)
{
      PG_RETURN_BOOL(PG_GETARG_BOOL(0) || PG_GETARG_BOOL(1));
}

Generated by  Doxygen 1.6.0   Back to index