LCOV - code coverage report
Current view: top level - src/backend/utils/adt - bool.c (source / functions) Coverage Total Hit
Test: PostgreSQL 19devel Lines: 90.3 % 154 139
Test Date: 2026-03-03 20:15:12 Functions: 86.4 % 22 19
Legend: Lines:     hit not hit

            Line data    Source code
       1              : /*-------------------------------------------------------------------------
       2              :  *
       3              :  * bool.c
       4              :  *    Functions for the built-in type "bool".
       5              :  *
       6              :  * Portions Copyright (c) 1996-2026, PostgreSQL Global Development Group
       7              :  * Portions Copyright (c) 1994, Regents of the University of California
       8              :  *
       9              :  *
      10              :  * IDENTIFICATION
      11              :  *    src/backend/utils/adt/bool.c
      12              :  *
      13              :  *-------------------------------------------------------------------------
      14              :  */
      15              : 
      16              : #include "postgres.h"
      17              : 
      18              : #include <ctype.h>
      19              : 
      20              : #include "common/hashfn.h"
      21              : #include "libpq/pqformat.h"
      22              : #include "utils/builtins.h"
      23              : 
      24              : /*
      25              :  * Try to interpret value as boolean value.  Valid values are: true,
      26              :  * false, yes, no, on, off, 1, 0; as well as unique prefixes thereof.
      27              :  * If the string parses okay, return true, else false.
      28              :  * If okay and result is not NULL, return the value in *result.
      29              :  */
      30              : bool
      31       102659 : parse_bool(const char *value, bool *result)
      32              : {
      33       102659 :     return parse_bool_with_len(value, strlen(value), result);
      34              : }
      35              : 
      36              : bool
      37      1752983 : parse_bool_with_len(const char *value, size_t len, bool *result)
      38              : {
      39              :     /* Check the most-used possibilities first. */
      40      1752983 :     switch (*value)
      41              :     {
      42       248322 :         case 't':
      43              :         case 'T':
      44       248322 :             if (pg_strncasecmp(value, "true", len) == 0)
      45              :             {
      46       248316 :                 if (result)
      47       248316 :                     *result = true;
      48       248316 :                 return true;
      49              :             }
      50            6 :             break;
      51      1432951 :         case 'f':
      52              :         case 'F':
      53      1432951 :             if (pg_strncasecmp(value, "false", len) == 0)
      54              :             {
      55      1432942 :                 if (result)
      56      1432942 :                     *result = false;
      57      1432942 :                 return true;
      58              :             }
      59            9 :             break;
      60         1296 :         case 'y':
      61              :         case 'Y':
      62         1296 :             if (pg_strncasecmp(value, "yes", len) == 0)
      63              :             {
      64         1293 :                 if (result)
      65         1293 :                     *result = true;
      66         1293 :                 return true;
      67              :             }
      68            3 :             break;
      69         2424 :         case 'n':
      70              :         case 'N':
      71         2424 :             if (pg_strncasecmp(value, "no", len) == 0)
      72              :             {
      73         2415 :                 if (result)
      74         2415 :                     *result = false;
      75         2415 :                 return true;
      76              :             }
      77            9 :             break;
      78        61353 :         case 'o':
      79              :         case 'O':
      80              :             /* 'o' is not unique enough */
      81        61353 :             if (pg_strncasecmp(value, "on", (len > 2 ? len : 2)) == 0)
      82              :             {
      83        44971 :                 if (result)
      84        44971 :                     *result = true;
      85        44971 :                 return true;
      86              :             }
      87        16382 :             else if (pg_strncasecmp(value, "off", (len > 2 ? len : 2)) == 0)
      88              :             {
      89        16373 :                 if (result)
      90        16373 :                     *result = false;
      91        16373 :                 return true;
      92              :             }
      93            9 :             break;
      94         3640 :         case '1':
      95         3640 :             if (len == 1)
      96              :             {
      97         3616 :                 if (result)
      98         3616 :                     *result = true;
      99         3616 :                 return true;
     100              :             }
     101           24 :             break;
     102         2943 :         case '0':
     103         2943 :             if (len == 1)
     104              :             {
     105         2940 :                 if (result)
     106         2940 :                     *result = false;
     107         2940 :                 return true;
     108              :             }
     109            3 :             break;
     110           54 :         default:
     111           54 :             break;
     112              :     }
     113              : 
     114          117 :     if (result)
     115          117 :         *result = false;        /* suppress compiler warning */
     116          117 :     return false;
     117              : }
     118              : 
     119              : /*****************************************************************************
     120              :  *   USER I/O ROUTINES                                                       *
     121              :  *****************************************************************************/
     122              : 
     123              : /*
     124              :  *      boolin          - input function for type boolean
     125              :  */
     126              : Datum
     127      1650324 : boolin(PG_FUNCTION_ARGS)
     128              : {
     129      1650324 :     const char *in_str = PG_GETARG_CSTRING(0);
     130              :     const char *str;
     131              :     size_t      len;
     132              :     bool        result;
     133              : 
     134              :     /*
     135              :      * Skip leading and trailing whitespace
     136              :      */
     137      1650324 :     str = in_str;
     138      1650366 :     while (isspace((unsigned char) *str))
     139           42 :         str++;
     140              : 
     141      1650324 :     len = strlen(str);
     142      1650369 :     while (len > 0 && isspace((unsigned char) str[len - 1]))
     143           45 :         len--;
     144              : 
     145      1650324 :     if (parse_bool_with_len(str, len, &result))
     146      1650258 :         PG_RETURN_BOOL(result);
     147              : 
     148           66 :     ereturn(fcinfo->context, (Datum) 0,
     149              :             (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
     150              :              errmsg("invalid input syntax for type %s: \"%s\"",
     151              :                     "boolean", in_str)));
     152              : }
     153              : 
     154              : /*
     155              :  *      boolout         - converts 1 or 0 to "t" or "f"
     156              :  */
     157              : Datum
     158      1651902 : boolout(PG_FUNCTION_ARGS)
     159              : {
     160      1651902 :     bool        b = PG_GETARG_BOOL(0);
     161      1651902 :     char       *result = (char *) palloc(2);
     162              : 
     163      1651902 :     result[0] = (b) ? 't' : 'f';
     164      1651902 :     result[1] = '\0';
     165      1651902 :     PG_RETURN_CSTRING(result);
     166              : }
     167              : 
     168              : /*
     169              :  *      boolrecv            - converts external binary format to bool
     170              :  *
     171              :  * The external representation is one byte.  Any nonzero value is taken
     172              :  * as "true".
     173              :  */
     174              : Datum
     175            0 : boolrecv(PG_FUNCTION_ARGS)
     176              : {
     177            0 :     StringInfo  buf = (StringInfo) PG_GETARG_POINTER(0);
     178              :     int         ext;
     179              : 
     180            0 :     ext = pq_getmsgbyte(buf);
     181            0 :     PG_RETURN_BOOL(ext != 0);
     182              : }
     183              : 
     184              : /*
     185              :  *      boolsend            - converts bool to binary format
     186              :  */
     187              : Datum
     188            0 : boolsend(PG_FUNCTION_ARGS)
     189              : {
     190            0 :     bool        arg1 = PG_GETARG_BOOL(0);
     191              :     StringInfoData buf;
     192              : 
     193            0 :     pq_begintypsend(&buf);
     194            0 :     pq_sendbyte(&buf, arg1 ? 1 : 0);
     195            0 :     PG_RETURN_BYTEA_P(pq_endtypsend(&buf));
     196              : }
     197              : 
     198              : /*
     199              :  *      booltext            - cast function for bool => text
     200              :  *
     201              :  * We need this because it's different from the behavior of boolout();
     202              :  * this function follows the SQL-spec result (except for producing lower case)
     203              :  */
     204              : Datum
     205           72 : booltext(PG_FUNCTION_ARGS)
     206              : {
     207           72 :     bool        arg1 = PG_GETARG_BOOL(0);
     208              :     const char *str;
     209              : 
     210           72 :     if (arg1)
     211           33 :         str = "true";
     212              :     else
     213           39 :         str = "false";
     214              : 
     215           72 :     PG_RETURN_TEXT_P(cstring_to_text(str));
     216              : }
     217              : 
     218              : 
     219              : /*****************************************************************************
     220              :  *   PUBLIC ROUTINES                                                         *
     221              :  *****************************************************************************/
     222              : 
     223              : Datum
     224       197991 : booleq(PG_FUNCTION_ARGS)
     225              : {
     226       197991 :     bool        arg1 = PG_GETARG_BOOL(0);
     227       197991 :     bool        arg2 = PG_GETARG_BOOL(1);
     228              : 
     229       197991 :     PG_RETURN_BOOL(arg1 == arg2);
     230              : }
     231              : 
     232              : Datum
     233        39574 : boolne(PG_FUNCTION_ARGS)
     234              : {
     235        39574 :     bool        arg1 = PG_GETARG_BOOL(0);
     236        39574 :     bool        arg2 = PG_GETARG_BOOL(1);
     237              : 
     238        39574 :     PG_RETURN_BOOL(arg1 != arg2);
     239              : }
     240              : 
     241              : Datum
     242            5 : boollt(PG_FUNCTION_ARGS)
     243              : {
     244            5 :     bool        arg1 = PG_GETARG_BOOL(0);
     245            5 :     bool        arg2 = PG_GETARG_BOOL(1);
     246              : 
     247            5 :     PG_RETURN_BOOL(arg1 < arg2);
     248              : }
     249              : 
     250              : Datum
     251            5 : boolgt(PG_FUNCTION_ARGS)
     252              : {
     253            5 :     bool        arg1 = PG_GETARG_BOOL(0);
     254            5 :     bool        arg2 = PG_GETARG_BOOL(1);
     255              : 
     256            5 :     PG_RETURN_BOOL(arg1 > arg2);
     257              : }
     258              : 
     259              : Datum
     260            8 : boolle(PG_FUNCTION_ARGS)
     261              : {
     262            8 :     bool        arg1 = PG_GETARG_BOOL(0);
     263            8 :     bool        arg2 = PG_GETARG_BOOL(1);
     264              : 
     265            8 :     PG_RETURN_BOOL(arg1 <= arg2);
     266              : }
     267              : 
     268              : Datum
     269            8 : boolge(PG_FUNCTION_ARGS)
     270              : {
     271            8 :     bool        arg1 = PG_GETARG_BOOL(0);
     272            8 :     bool        arg2 = PG_GETARG_BOOL(1);
     273              : 
     274            8 :     PG_RETURN_BOOL(arg1 >= arg2);
     275              : }
     276              : 
     277              : Datum
     278        46134 : hashbool(PG_FUNCTION_ARGS)
     279              : {
     280        46134 :     return hash_uint32((int32) PG_GETARG_BOOL(0));
     281              : }
     282              : 
     283              : Datum
     284            0 : hashboolextended(PG_FUNCTION_ARGS)
     285              : {
     286            0 :     return hash_uint32_extended((int32) PG_GETARG_BOOL(0), PG_GETARG_INT64(1));
     287              : }
     288              : 
     289              : /*
     290              :  * boolean-and and boolean-or aggregates.
     291              :  */
     292              : 
     293              : /*
     294              :  * Function for standard EVERY aggregate conforming to SQL 2003.
     295              :  * The aggregate is also named bool_and for consistency.
     296              :  *
     297              :  * Note: this is only used in plain aggregate mode, not moving-aggregate mode.
     298              :  */
     299              : Datum
     300        12054 : booland_statefunc(PG_FUNCTION_ARGS)
     301              : {
     302        12054 :     PG_RETURN_BOOL(PG_GETARG_BOOL(0) && PG_GETARG_BOOL(1));
     303              : }
     304              : 
     305              : /*
     306              :  * Function for standard ANY/SOME aggregate conforming to SQL 2003.
     307              :  * The aggregate is named bool_or, because ANY/SOME have parsing conflicts.
     308              :  *
     309              :  * Note: this is only used in plain aggregate mode, not moving-aggregate mode.
     310              :  */
     311              : Datum
     312           28 : boolor_statefunc(PG_FUNCTION_ARGS)
     313              : {
     314           28 :     PG_RETURN_BOOL(PG_GETARG_BOOL(0) || PG_GETARG_BOOL(1));
     315              : }
     316              : 
     317              : typedef struct BoolAggState
     318              : {
     319              :     int64       aggcount;       /* number of non-null values aggregated */
     320              :     int64       aggtrue;        /* number of values aggregated that are true */
     321              : } BoolAggState;
     322              : 
     323              : static BoolAggState *
     324            6 : makeBoolAggState(FunctionCallInfo fcinfo)
     325              : {
     326              :     BoolAggState *state;
     327              :     MemoryContext agg_context;
     328              : 
     329            6 :     if (!AggCheckCallContext(fcinfo, &agg_context))
     330            0 :         elog(ERROR, "aggregate function called in non-aggregate context");
     331              : 
     332            6 :     state = (BoolAggState *) MemoryContextAlloc(agg_context,
     333              :                                                 sizeof(BoolAggState));
     334            6 :     state->aggcount = 0;
     335            6 :     state->aggtrue = 0;
     336              : 
     337            6 :     return state;
     338              : }
     339              : 
     340              : Datum
     341           30 : bool_accum(PG_FUNCTION_ARGS)
     342              : {
     343              :     BoolAggState *state;
     344              : 
     345           30 :     state = PG_ARGISNULL(0) ? NULL : (BoolAggState *) PG_GETARG_POINTER(0);
     346              : 
     347              :     /* Create the state data on first call */
     348           30 :     if (state == NULL)
     349            6 :         state = makeBoolAggState(fcinfo);
     350              : 
     351           30 :     if (!PG_ARGISNULL(1))
     352              :     {
     353           30 :         state->aggcount++;
     354           30 :         if (PG_GETARG_BOOL(1))
     355           18 :             state->aggtrue++;
     356              :     }
     357              : 
     358           30 :     PG_RETURN_POINTER(state);
     359              : }
     360              : 
     361              : Datum
     362           24 : bool_accum_inv(PG_FUNCTION_ARGS)
     363              : {
     364              :     BoolAggState *state;
     365              : 
     366           24 :     state = PG_ARGISNULL(0) ? NULL : (BoolAggState *) PG_GETARG_POINTER(0);
     367              : 
     368              :     /* bool_accum should have created the state data */
     369           24 :     if (state == NULL)
     370            0 :         elog(ERROR, "bool_accum_inv called with NULL state");
     371              : 
     372           24 :     if (!PG_ARGISNULL(1))
     373              :     {
     374           24 :         state->aggcount--;
     375           24 :         if (PG_GETARG_BOOL(1))
     376           12 :             state->aggtrue--;
     377              :     }
     378              : 
     379           24 :     PG_RETURN_POINTER(state);
     380              : }
     381              : 
     382              : Datum
     383           15 : bool_alltrue(PG_FUNCTION_ARGS)
     384              : {
     385              :     BoolAggState *state;
     386              : 
     387           15 :     state = PG_ARGISNULL(0) ? NULL : (BoolAggState *) PG_GETARG_POINTER(0);
     388              : 
     389              :     /* if there were no non-null values, return NULL */
     390           15 :     if (state == NULL || state->aggcount == 0)
     391            0 :         PG_RETURN_NULL();
     392              : 
     393              :     /* true if all non-null values are true */
     394           15 :     PG_RETURN_BOOL(state->aggtrue == state->aggcount);
     395              : }
     396              : 
     397              : Datum
     398           15 : bool_anytrue(PG_FUNCTION_ARGS)
     399              : {
     400              :     BoolAggState *state;
     401              : 
     402           15 :     state = PG_ARGISNULL(0) ? NULL : (BoolAggState *) PG_GETARG_POINTER(0);
     403              : 
     404              :     /* if there were no non-null values, return NULL */
     405           15 :     if (state == NULL || state->aggcount == 0)
     406            0 :         PG_RETURN_NULL();
     407              : 
     408              :     /* true if any non-null value is true */
     409           15 :     PG_RETURN_BOOL(state->aggtrue > 0);
     410              : }
        

Generated by: LCOV version 2.0-1