PostgreSQL Source Code git master
All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Pages
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 "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 */
30bool
31parse_bool(const char *value, bool *result)
32{
33 return parse_bool_with_len(value, strlen(value), result);
34}
35
36bool
37parse_bool_with_len(const char *value, size_t len, bool *result)
38{
39 /* Check the most-used possibilities first. */
40 switch (*value)
41 {
42 case 't':
43 case 'T':
44 if (pg_strncasecmp(value, "true", len) == 0)
45 {
46 if (result)
47 *result = true;
48 return true;
49 }
50 break;
51 case 'f':
52 case 'F':
53 if (pg_strncasecmp(value, "false", len) == 0)
54 {
55 if (result)
56 *result = false;
57 return true;
58 }
59 break;
60 case 'y':
61 case 'Y':
62 if (pg_strncasecmp(value, "yes", len) == 0)
63 {
64 if (result)
65 *result = true;
66 return true;
67 }
68 break;
69 case 'n':
70 case 'N':
71 if (pg_strncasecmp(value, "no", len) == 0)
72 {
73 if (result)
74 *result = false;
75 return true;
76 }
77 break;
78 case 'o':
79 case 'O':
80 /* 'o' is not unique enough */
81 if (pg_strncasecmp(value, "on", (len > 2 ? len : 2)) == 0)
82 {
83 if (result)
84 *result = true;
85 return true;
86 }
87 else if (pg_strncasecmp(value, "off", (len > 2 ? len : 2)) == 0)
88 {
89 if (result)
90 *result = false;
91 return true;
92 }
93 break;
94 case '1':
95 if (len == 1)
96 {
97 if (result)
98 *result = true;
99 return true;
100 }
101 break;
102 case '0':
103 if (len == 1)
104 {
105 if (result)
106 *result = false;
107 return true;
108 }
109 break;
110 default:
111 break;
112 }
113
114 if (result)
115 *result = false; /* suppress compiler warning */
116 return false;
117}
118
119/*****************************************************************************
120 * USER I/O ROUTINES *
121 *****************************************************************************/
122
123/*
124 * boolin - input function for type boolean
125 */
126Datum
128{
129 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 str = in_str;
138 while (isspace((unsigned char) *str))
139 str++;
140
141 len = strlen(str);
142 while (len > 0 && isspace((unsigned char) str[len - 1]))
143 len--;
144
145 if (parse_bool_with_len(str, len, &result))
146 PG_RETURN_BOOL(result);
147
148 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 */
157Datum
159{
160 bool b = PG_GETARG_BOOL(0);
161 char *result = (char *) palloc(2);
162
163 result[0] = (b) ? 't' : 'f';
164 result[1] = '\0';
165 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 */
174Datum
176{
178 int ext;
179
180 ext = pq_getmsgbyte(buf);
181 PG_RETURN_BOOL(ext != 0);
182}
183
184/*
185 * boolsend - converts bool to binary format
186 */
187Datum
189{
190 bool arg1 = PG_GETARG_BOOL(0);
192
194 pq_sendbyte(&buf, arg1 ? 1 : 0);
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 */
204Datum
206{
207 bool arg1 = PG_GETARG_BOOL(0);
208 const char *str;
209
210 if (arg1)
211 str = "true";
212 else
213 str = "false";
214
216}
217
218
219/*****************************************************************************
220 * PUBLIC ROUTINES *
221 *****************************************************************************/
222
223Datum
225{
226 bool arg1 = PG_GETARG_BOOL(0);
227 bool arg2 = PG_GETARG_BOOL(1);
228
229 PG_RETURN_BOOL(arg1 == arg2);
230}
231
232Datum
234{
235 bool arg1 = PG_GETARG_BOOL(0);
236 bool arg2 = PG_GETARG_BOOL(1);
237
238 PG_RETURN_BOOL(arg1 != arg2);
239}
240
241Datum
243{
244 bool arg1 = PG_GETARG_BOOL(0);
245 bool arg2 = PG_GETARG_BOOL(1);
246
247 PG_RETURN_BOOL(arg1 < arg2);
248}
249
250Datum
252{
253 bool arg1 = PG_GETARG_BOOL(0);
254 bool arg2 = PG_GETARG_BOOL(1);
255
256 PG_RETURN_BOOL(arg1 > arg2);
257}
258
259Datum
261{
262 bool arg1 = PG_GETARG_BOOL(0);
263 bool arg2 = PG_GETARG_BOOL(1);
264
265 PG_RETURN_BOOL(arg1 <= arg2);
266}
267
268Datum
270{
271 bool arg1 = PG_GETARG_BOOL(0);
272 bool arg2 = PG_GETARG_BOOL(1);
273
274 PG_RETURN_BOOL(arg1 >= arg2);
275}
276
277Datum
279{
280 return hash_uint32((int32) PG_GETARG_BOOL(0));
281}
282
283Datum
285{
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 */
299Datum
301{
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 */
311Datum
313{
315}
316
317typedef struct BoolAggState
318{
319 int64 aggcount; /* number of non-null values aggregated */
320 int64 aggtrue; /* number of values aggregated that are true */
322
323static BoolAggState *
325{
327 MemoryContext agg_context;
328
329 if (!AggCheckCallContext(fcinfo, &agg_context))
330 elog(ERROR, "aggregate function called in non-aggregate context");
331
332 state = (BoolAggState *) MemoryContextAlloc(agg_context,
333 sizeof(BoolAggState));
334 state->aggcount = 0;
335 state->aggtrue = 0;
336
337 return state;
338}
339
340Datum
342{
344
346
347 /* Create the state data on first call */
348 if (state == NULL)
349 state = makeBoolAggState(fcinfo);
350
351 if (!PG_ARGISNULL(1))
352 {
353 state->aggcount++;
354 if (PG_GETARG_BOOL(1))
355 state->aggtrue++;
356 }
357
359}
360
361Datum
363{
365
367
368 /* bool_accum should have created the state data */
369 if (state == NULL)
370 elog(ERROR, "bool_accum_inv called with NULL state");
371
372 if (!PG_ARGISNULL(1))
373 {
374 state->aggcount--;
375 if (PG_GETARG_BOOL(1))
376 state->aggtrue--;
377 }
378
380}
381
382Datum
384{
386
388
389 /* if there were no non-null values, return NULL */
390 if (state == NULL || state->aggcount == 0)
392
393 /* true if all non-null values are true */
394 PG_RETURN_BOOL(state->aggtrue == state->aggcount);
395}
396
397Datum
399{
401
403
404 /* if there were no non-null values, return NULL */
405 if (state == NULL || state->aggcount == 0)
407
408 /* true if any non-null value is true */
409 PG_RETURN_BOOL(state->aggtrue > 0);
410}
Datum boolge(PG_FUNCTION_ARGS)
Definition: bool.c:269
Datum boolor_statefunc(PG_FUNCTION_ARGS)
Definition: bool.c:312
Datum boolle(PG_FUNCTION_ARGS)
Definition: bool.c:260
Datum boollt(PG_FUNCTION_ARGS)
Definition: bool.c:242
bool parse_bool(const char *value, bool *result)
Definition: bool.c:31
Datum boolin(PG_FUNCTION_ARGS)
Definition: bool.c:127
Datum hashbool(PG_FUNCTION_ARGS)
Definition: bool.c:278
Datum hashboolextended(PG_FUNCTION_ARGS)
Definition: bool.c:284
Datum boolgt(PG_FUNCTION_ARGS)
Definition: bool.c:251
Datum boolrecv(PG_FUNCTION_ARGS)
Definition: bool.c:175
Datum boolsend(PG_FUNCTION_ARGS)
Definition: bool.c:188
static BoolAggState * makeBoolAggState(FunctionCallInfo fcinfo)
Definition: bool.c:324
Datum boolout(PG_FUNCTION_ARGS)
Definition: bool.c:158
Datum booland_statefunc(PG_FUNCTION_ARGS)
Definition: bool.c:300
Datum bool_alltrue(PG_FUNCTION_ARGS)
Definition: bool.c:383
Datum booltext(PG_FUNCTION_ARGS)
Definition: bool.c:205
Datum booleq(PG_FUNCTION_ARGS)
Definition: bool.c:224
Datum bool_accum_inv(PG_FUNCTION_ARGS)
Definition: bool.c:362
Datum boolne(PG_FUNCTION_ARGS)
Definition: bool.c:233
Datum bool_anytrue(PG_FUNCTION_ARGS)
Definition: bool.c:398
Datum bool_accum(PG_FUNCTION_ARGS)
Definition: bool.c:341
bool parse_bool_with_len(const char *value, size_t len, bool *result)
Definition: bool.c:37
struct BoolAggState BoolAggState
int64_t int64
Definition: c.h:482
int32_t int32
Definition: c.h:481
int errcode(int sqlerrcode)
Definition: elog.c:853
int errmsg(const char *fmt,...)
Definition: elog.c:1070
#define ereturn(context, dummy_value,...)
Definition: elog.h:277
#define ERROR
Definition: elog.h:39
#define elog(elevel,...)
Definition: elog.h:225
#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_GETARG_INT64(n)
Definition: fmgr.h:283
#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 Datum hash_uint32(uint32 k)
Definition: hashfn.h:43
static Datum hash_uint32_extended(uint32 k, uint64 seed)
Definition: hashfn.h:49
const char * str
static struct @161 value
int b
Definition: isn.c:69
void * MemoryContextAlloc(MemoryContext context, Size size)
Definition: mcxt.c:1181
void * palloc(Size size)
Definition: mcxt.c:1317
int AggCheckCallContext(FunctionCallInfo fcinfo, MemoryContext *aggcontext)
Definition: nodeAgg.c:4511
const void size_t len
static char * buf
Definition: pg_test_fsync.c:72
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:319
int64 aggtrue
Definition: bool.c:320
Definition: regguts.h:323
text * cstring_to_text(const char *s)
Definition: varlena.c:184