PostgreSQL Source Code  git master
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros
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-2017, 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  ereport(ERROR,
152  (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
153  errmsg("invalid input syntax for type %s: \"%s\"",
154  "boolean", in_str)));
155 
156  /* not reached */
157  PG_RETURN_BOOL(false);
158 }
159 
160 /*
161  * boolout - converts 1 or 0 to "t" or "f"
162  */
163 Datum
165 {
166  bool b = PG_GETARG_BOOL(0);
167  char *result = (char *) palloc(2);
168 
169  result[0] = (b) ? 't' : 'f';
170  result[1] = '\0';
171  PG_RETURN_CSTRING(result);
172 }
173 
174 /*
175  * boolrecv - converts external binary format to bool
176  *
177  * The external representation is one byte. Any nonzero value is taken
178  * as "true".
179  */
180 Datum
182 {
184  int ext;
185 
186  ext = pq_getmsgbyte(buf);
187  PG_RETURN_BOOL((ext != 0) ? true : false);
188 }
189 
190 /*
191  * boolsend - converts bool to binary format
192  */
193 Datum
195 {
196  bool arg1 = PG_GETARG_BOOL(0);
198 
199  pq_begintypsend(&buf);
200  pq_sendbyte(&buf, arg1 ? 1 : 0);
202 }
203 
204 /*
205  * booltext - cast function for bool => text
206  *
207  * We need this because it's different from the behavior of boolout();
208  * this function follows the SQL-spec result (except for producing lower case)
209  */
210 Datum
212 {
213  bool arg1 = PG_GETARG_BOOL(0);
214  const char *str;
215 
216  if (arg1)
217  str = "true";
218  else
219  str = "false";
220 
222 }
223 
224 
225 /*****************************************************************************
226  * PUBLIC ROUTINES *
227  *****************************************************************************/
228 
229 Datum
231 {
232  bool arg1 = PG_GETARG_BOOL(0);
233  bool arg2 = PG_GETARG_BOOL(1);
234 
235  PG_RETURN_BOOL(arg1 == arg2);
236 }
237 
238 Datum
240 {
241  bool arg1 = PG_GETARG_BOOL(0);
242  bool arg2 = PG_GETARG_BOOL(1);
243 
244  PG_RETURN_BOOL(arg1 != arg2);
245 }
246 
247 Datum
249 {
250  bool arg1 = PG_GETARG_BOOL(0);
251  bool arg2 = PG_GETARG_BOOL(1);
252 
253  PG_RETURN_BOOL(arg1 < arg2);
254 }
255 
256 Datum
258 {
259  bool arg1 = PG_GETARG_BOOL(0);
260  bool arg2 = PG_GETARG_BOOL(1);
261 
262  PG_RETURN_BOOL(arg1 > arg2);
263 }
264 
265 Datum
267 {
268  bool arg1 = PG_GETARG_BOOL(0);
269  bool arg2 = PG_GETARG_BOOL(1);
270 
271  PG_RETURN_BOOL(arg1 <= arg2);
272 }
273 
274 Datum
276 {
277  bool arg1 = PG_GETARG_BOOL(0);
278  bool arg2 = PG_GETARG_BOOL(1);
279 
280  PG_RETURN_BOOL(arg1 >= arg2);
281 }
282 
283 /*
284  * boolean-and and boolean-or aggregates.
285  */
286 
287 /*
288  * Function for standard EVERY aggregate conforming to SQL 2003.
289  * The aggregate is also named bool_and for consistency.
290  *
291  * Note: this is only used in plain aggregate mode, not moving-aggregate mode.
292  */
293 Datum
295 {
297 }
298 
299 /*
300  * Function for standard ANY/SOME aggregate conforming to SQL 2003.
301  * The aggregate is named bool_or, because ANY/SOME have parsing conflicts.
302  *
303  * Note: this is only used in plain aggregate mode, not moving-aggregate mode.
304  */
305 Datum
307 {
309 }
310 
311 typedef struct BoolAggState
312 {
313  int64 aggcount; /* number of non-null values aggregated */
314  int64 aggtrue; /* number of values aggregated that are true */
315 } BoolAggState;
316 
317 static BoolAggState *
319 {
321  MemoryContext agg_context;
322 
323  if (!AggCheckCallContext(fcinfo, &agg_context))
324  elog(ERROR, "aggregate function called in non-aggregate context");
325 
326  state = (BoolAggState *) MemoryContextAlloc(agg_context,
327  sizeof(BoolAggState));
328  state->aggcount = 0;
329  state->aggtrue = 0;
330 
331  return state;
332 }
333 
334 Datum
336 {
338 
339  state = PG_ARGISNULL(0) ? NULL : (BoolAggState *) PG_GETARG_POINTER(0);
340 
341  /* Create the state data on first call */
342  if (state == NULL)
343  state = makeBoolAggState(fcinfo);
344 
345  if (!PG_ARGISNULL(1))
346  {
347  state->aggcount++;
348  if (PG_GETARG_BOOL(1))
349  state->aggtrue++;
350  }
351 
352  PG_RETURN_POINTER(state);
353 }
354 
355 Datum
357 {
359 
360  state = PG_ARGISNULL(0) ? NULL : (BoolAggState *) PG_GETARG_POINTER(0);
361 
362  /* bool_accum should have created the state data */
363  if (state == NULL)
364  elog(ERROR, "bool_accum_inv called with NULL state");
365 
366  if (!PG_ARGISNULL(1))
367  {
368  state->aggcount--;
369  if (PG_GETARG_BOOL(1))
370  state->aggtrue--;
371  }
372 
373  PG_RETURN_POINTER(state);
374 }
375 
376 Datum
378 {
380 
381  state = PG_ARGISNULL(0) ? NULL : (BoolAggState *) PG_GETARG_POINTER(0);
382 
383  /* if there were no non-null values, return NULL */
384  if (state == NULL || state->aggcount == 0)
385  PG_RETURN_NULL();
386 
387  /* true if all non-null values are true */
388  PG_RETURN_BOOL(state->aggtrue == state->aggcount);
389 }
390 
391 Datum
393 {
395 
396  state = PG_ARGISNULL(0) ? NULL : (BoolAggState *) PG_GETARG_POINTER(0);
397 
398  /* if there were no non-null values, return NULL */
399  if (state == NULL || state->aggcount == 0)
400  PG_RETURN_NULL();
401 
402  /* true if any non-null value is true */
403  PG_RETURN_BOOL(state->aggtrue > 0);
404 }
#define PG_RETURN_POINTER(x)
Definition: fmgr.h:321
static BoolAggState * makeBoolAggState(FunctionCallInfo fcinfo)
Definition: bool.c:318
Datum boolsend(PG_FUNCTION_ARGS)
Definition: bool.c:194
void pq_sendbyte(StringInfo buf, int byt)
Definition: pqformat.c:105
Datum bool_anytrue(PG_FUNCTION_ARGS)
Definition: bool.c:392
void pq_begintypsend(StringInfo buf)
Definition: pqformat.c:359
Datum boolin(PG_FUNCTION_ARGS)
Definition: bool.c:130
Datum boollt(PG_FUNCTION_ARGS)
Definition: bool.c:248
StringInfoData * StringInfo
Definition: stringinfo.h:46
int errcode(int sqlerrcode)
Definition: elog.c:575
int64 aggcount
Definition: bool.c:313
return result
Definition: formatting.c:1618
#define PG_GETARG_POINTER(n)
Definition: fmgr.h:241
bool parse_bool(const char *value, bool *result)
Definition: bool.c:30
#define PG_GETARG_BOOL(n)
Definition: fmgr.h:239
#define PG_RETURN_BYTEA_P(x)
Definition: fmgr.h:329
bytea * pq_endtypsend(StringInfo buf)
Definition: pqformat.c:379
Datum boolne(PG_FUNCTION_ARGS)
Definition: bool.c:239
Datum booltext(PG_FUNCTION_ARGS)
Definition: bool.c:211
int pg_strncasecmp(const char *s1, const char *s2, size_t n)
Definition: pgstrcasecmp.c:69
struct BoolAggState BoolAggState
#define ERROR
Definition: elog.h:43
static char * buf
Definition: pg_test_fsync.c:66
Datum boolgt(PG_FUNCTION_ARGS)
Definition: bool.c:257
#define ereport(elevel, rest)
Definition: elog.h:122
Datum bool_accum(PG_FUNCTION_ARGS)
Definition: bool.c:335
#define PG_RETURN_BOOL(x)
Definition: fmgr.h:319
uintptr_t Datum
Definition: postgres.h:372
bool parse_bool_with_len(const char *value, size_t len, bool *result)
Definition: bool.c:36
Datum boolle(PG_FUNCTION_ARGS)
Definition: bool.c:266
Datum boolout(PG_FUNCTION_ARGS)
Definition: bool.c:164
int pq_getmsgbyte(StringInfo msg)
Definition: pqformat.c:432
Datum boolge(PG_FUNCTION_ARGS)
Definition: bool.c:275
#define PG_RETURN_TEXT_P(x)
Definition: fmgr.h:330
text * cstring_to_text(const char *s)
Definition: varlena.c:149
#define PG_ARGISNULL(n)
Definition: fmgr.h:174
Datum boolor_statefunc(PG_FUNCTION_ARGS)
Definition: bool.c:306
#define NULL
Definition: c.h:229
Definition: regguts.h:298
#define PG_RETURN_CSTRING(x)
Definition: fmgr.h:322
int AggCheckCallContext(FunctionCallInfo fcinfo, MemoryContext *aggcontext)
Definition: nodeAgg.c:4018
Datum bool_accum_inv(PG_FUNCTION_ARGS)
Definition: bool.c:356
void * palloc(Size size)
Definition: mcxt.c:849
int errmsg(const char *fmt,...)
Definition: elog.c:797
void * MemoryContextAlloc(MemoryContext context, Size size)
Definition: mcxt.c:707
#define PG_GETARG_CSTRING(n)
Definition: fmgr.h:242
Datum boolrecv(PG_FUNCTION_ARGS)
Definition: bool.c:181
#define PG_FUNCTION_ARGS
Definition: fmgr.h:158
#define elog
Definition: elog.h:219
static struct @121 value
int64 aggtrue
Definition: bool.c:314
#define PG_RETURN_NULL()
Definition: fmgr.h:305
Datum bool_alltrue(PG_FUNCTION_ARGS)
Definition: bool.c:377
Datum booleq(PG_FUNCTION_ARGS)
Definition: bool.c:230
Datum booland_statefunc(PG_FUNCTION_ARGS)
Definition: bool.c:294