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