1 /*-------------------------------------------------------------------------
4 * Functions for the built-in type "bool".
6 * Portions Copyright (c) 1996-2017, PostgreSQL Global Development Group
7 * Portions Copyright (c) 1994, Regents of the University of California
11 * src/backend/utils/adt/bool.c
13 *-------------------------------------------------------------------------
20 #include "libpq/pqformat.h"
21 #include "utils/builtins.h"
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.
30 parse_bool(const char *value, bool *result)
32 return parse_bool_with_len(value, strlen(value), result);
36 parse_bool_with_len(const char *value, size_t len, bool *result)
42 if (pg_strncasecmp(value, "true", len) == 0)
51 if (pg_strncasecmp(value, "false", len) == 0)
60 if (pg_strncasecmp(value, "yes", len) == 0)
69 if (pg_strncasecmp(value, "no", len) == 0)
78 /* 'o' is not unique enough */
79 if (pg_strncasecmp(value, "on", (len > 2 ? len : 2)) == 0)
85 else if (pg_strncasecmp(value, "off", (len > 2 ? len : 2)) == 0)
113 *result = false; /* suppress compiler warning */
117 /*****************************************************************************
118 * USER I/O ROUTINES *
119 *****************************************************************************/
122 * boolin - converts "t" or "f" to 1 or 0
124 * Check explicitly for "true/false" and TRUE/FALSE, 1/0, YES/NO, ON/OFF.
125 * Reject other values.
127 * In the switch statement, check the most-used possibilities first.
130 boolin(PG_FUNCTION_ARGS)
132 const char *in_str = PG_GETARG_CSTRING(0);
138 * Skip leading and trailing whitespace
141 while (isspace((unsigned char) *str))
145 while (len > 0 && isspace((unsigned char) str[len - 1]))
148 if (parse_bool_with_len(str, len, &result))
149 PG_RETURN_BOOL(result);
152 (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
153 errmsg("invalid input syntax for type boolean: \"%s\"", in_str)));
156 PG_RETURN_BOOL(false);
160 * boolout - converts 1 or 0 to "t" or "f"
163 boolout(PG_FUNCTION_ARGS)
165 bool b = PG_GETARG_BOOL(0);
166 char *result = (char *) palloc(2);
168 result[0] = (b) ? 't' : 'f';
170 PG_RETURN_CSTRING(result);
174 * boolrecv - converts external binary format to bool
176 * The external representation is one byte. Any nonzero value is taken
180 boolrecv(PG_FUNCTION_ARGS)
182 StringInfo buf = (StringInfo) PG_GETARG_POINTER(0);
185 ext = pq_getmsgbyte(buf);
186 PG_RETURN_BOOL((ext != 0) ? true : false);
190 * boolsend - converts bool to binary format
193 boolsend(PG_FUNCTION_ARGS)
195 bool arg1 = PG_GETARG_BOOL(0);
198 pq_begintypsend(&buf);
199 pq_sendbyte(&buf, arg1 ? 1 : 0);
200 PG_RETURN_BYTEA_P(pq_endtypsend(&buf));
204 * booltext - cast function for bool => text
206 * We need this because it's different from the behavior of boolout();
207 * this function follows the SQL-spec result (except for producing lower case)
210 booltext(PG_FUNCTION_ARGS)
212 bool arg1 = PG_GETARG_BOOL(0);
220 PG_RETURN_TEXT_P(cstring_to_text(str));
224 /*****************************************************************************
226 *****************************************************************************/
229 booleq(PG_FUNCTION_ARGS)
231 bool arg1 = PG_GETARG_BOOL(0);
232 bool arg2 = PG_GETARG_BOOL(1);
234 PG_RETURN_BOOL(arg1 == arg2);
238 boolne(PG_FUNCTION_ARGS)
240 bool arg1 = PG_GETARG_BOOL(0);
241 bool arg2 = PG_GETARG_BOOL(1);
243 PG_RETURN_BOOL(arg1 != arg2);
247 boollt(PG_FUNCTION_ARGS)
249 bool arg1 = PG_GETARG_BOOL(0);
250 bool arg2 = PG_GETARG_BOOL(1);
252 PG_RETURN_BOOL(arg1 < arg2);
256 boolgt(PG_FUNCTION_ARGS)
258 bool arg1 = PG_GETARG_BOOL(0);
259 bool arg2 = PG_GETARG_BOOL(1);
261 PG_RETURN_BOOL(arg1 > arg2);
265 boolle(PG_FUNCTION_ARGS)
267 bool arg1 = PG_GETARG_BOOL(0);
268 bool arg2 = PG_GETARG_BOOL(1);
270 PG_RETURN_BOOL(arg1 <= arg2);
274 boolge(PG_FUNCTION_ARGS)
276 bool arg1 = PG_GETARG_BOOL(0);
277 bool arg2 = PG_GETARG_BOOL(1);
279 PG_RETURN_BOOL(arg1 >= arg2);
283 * boolean-and and boolean-or aggregates.
287 * Function for standard EVERY aggregate conforming to SQL 2003.
288 * The aggregate is also named bool_and for consistency.
290 * Note: this is only used in plain aggregate mode, not moving-aggregate mode.
293 booland_statefunc(PG_FUNCTION_ARGS)
295 PG_RETURN_BOOL(PG_GETARG_BOOL(0) && PG_GETARG_BOOL(1));
299 * Function for standard ANY/SOME aggregate conforming to SQL 2003.
300 * The aggregate is named bool_or, because ANY/SOME have parsing conflicts.
302 * Note: this is only used in plain aggregate mode, not moving-aggregate mode.
305 boolor_statefunc(PG_FUNCTION_ARGS)
307 PG_RETURN_BOOL(PG_GETARG_BOOL(0) || PG_GETARG_BOOL(1));
310 typedef struct BoolAggState
312 int64 aggcount; /* number of non-null values aggregated */
313 int64 aggtrue; /* number of values aggregated that are true */
316 static BoolAggState *
317 makeBoolAggState(FunctionCallInfo fcinfo)
320 MemoryContext agg_context;
322 if (!AggCheckCallContext(fcinfo, &agg_context))
323 elog(ERROR, "aggregate function called in non-aggregate context");
325 state = (BoolAggState *) MemoryContextAlloc(agg_context,
326 sizeof(BoolAggState));
334 bool_accum(PG_FUNCTION_ARGS)
338 state = PG_ARGISNULL(0) ? NULL : (BoolAggState *) PG_GETARG_POINTER(0);
340 /* Create the state data on first call */
342 state = makeBoolAggState(fcinfo);
344 if (!PG_ARGISNULL(1))
347 if (PG_GETARG_BOOL(1))
351 PG_RETURN_POINTER(state);
355 bool_accum_inv(PG_FUNCTION_ARGS)
359 state = PG_ARGISNULL(0) ? NULL : (BoolAggState *) PG_GETARG_POINTER(0);
361 /* bool_accum should have created the state data */
363 elog(ERROR, "bool_accum_inv called with NULL state");
365 if (!PG_ARGISNULL(1))
368 if (PG_GETARG_BOOL(1))
372 PG_RETURN_POINTER(state);
376 bool_alltrue(PG_FUNCTION_ARGS)
380 state = PG_ARGISNULL(0) ? NULL : (BoolAggState *) PG_GETARG_POINTER(0);
382 /* if there were no non-null values, return NULL */
383 if (state == NULL || state->aggcount == 0)
386 /* true if all non-null values are true */
387 PG_RETURN_BOOL(state->aggtrue == state->aggcount);
391 bool_anytrue(PG_FUNCTION_ARGS)
395 state = PG_ARGISNULL(0) ? NULL : (BoolAggState *) PG_GETARG_POINTER(0);
397 /* if there were no non-null values, return NULL */
398 if (state == NULL || state->aggcount == 0)
401 /* true if any non-null value is true */
402 PG_RETURN_BOOL(state->aggtrue > 0);