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