Branch data Line data Source code
1 : : /*-------------------------------------------------------------------------
2 : : *
3 : : * varbit.c
4 : : * Functions for the SQL datatypes BIT() and BIT VARYING().
5 : : *
6 : : * The data structure contains the following elements:
7 : : * header -- length of the whole data structure (incl header)
8 : : * in bytes (as with all varying length datatypes)
9 : : * data section -- private data section for the bits data structures
10 : : * bitlength -- length of the bit string in bits
11 : : * bitdata -- bit string, most significant byte first
12 : : *
13 : : * The length of the bitdata vector should always be exactly as many
14 : : * bytes as are needed for the given bitlength. If the bitlength is
15 : : * not a multiple of 8, the extra low-order padding bits of the last
16 : : * byte must be zeroes.
17 : : *
18 : : * attypmod is defined as the length of the bit string in bits, or for
19 : : * varying bits the maximum length.
20 : : *
21 : : * Code originally contributed by Adriaan Joubert.
22 : : *
23 : : * Portions Copyright (c) 1996-2026, PostgreSQL Global Development Group
24 : : * Portions Copyright (c) 1994, Regents of the University of California
25 : : *
26 : : * IDENTIFICATION
27 : : * src/backend/utils/adt/varbit.c
28 : : *
29 : : *-------------------------------------------------------------------------
30 : : */
31 : :
32 : : #include "postgres.h"
33 : :
34 : : #include "access/htup_details.h"
35 : : #include "common/int.h"
36 : : #include "libpq/pqformat.h"
37 : : #include "nodes/nodeFuncs.h"
38 : : #include "nodes/supportnodes.h"
39 : : #include "port/pg_bitutils.h"
40 : : #include "utils/array.h"
41 : : #include "utils/fmgrprotos.h"
42 : : #include "utils/varbit.h"
43 : :
44 : : #define HEXDIG(z) ((z)<10 ? ((z)+'0') : ((z)-10+'A'))
45 : :
46 : : /* Mask off any bits that should be zero in the last byte of a bitstring */
47 : : #define VARBIT_PAD(vb) \
48 : : do { \
49 : : int32 pad_ = VARBITPAD(vb); \
50 : : Assert(pad_ >= 0 && pad_ < BITS_PER_BYTE); \
51 : : if (pad_ > 0) \
52 : : *(VARBITS(vb) + VARBITBYTES(vb) - 1) &= BITMASK << pad_; \
53 : : } while (0)
54 : :
55 : : /*
56 : : * Many functions work byte-by-byte, so they have a pointer handy to the
57 : : * last-plus-one byte, which saves a cycle or two.
58 : : */
59 : : #define VARBIT_PAD_LAST(vb, ptr) \
60 : : do { \
61 : : int32 pad_ = VARBITPAD(vb); \
62 : : Assert(pad_ >= 0 && pad_ < BITS_PER_BYTE); \
63 : : if (pad_ > 0) \
64 : : *((ptr) - 1) &= BITMASK << pad_; \
65 : : } while (0)
66 : :
67 : : /* Assert proper padding of a bitstring */
68 : : #ifdef USE_ASSERT_CHECKING
69 : : #define VARBIT_CORRECTLY_PADDED(vb) \
70 : : do { \
71 : : int32 pad_ = VARBITPAD(vb); \
72 : : Assert(pad_ >= 0 && pad_ < BITS_PER_BYTE); \
73 : : Assert(pad_ == 0 || \
74 : : (*(VARBITS(vb) + VARBITBYTES(vb) - 1) & ~(BITMASK << pad_)) == 0); \
75 : : } while (0)
76 : : #else
77 : : #define VARBIT_CORRECTLY_PADDED(vb) ((void) 0)
78 : : #endif
79 : :
80 : : static VarBit *bit_catenate(VarBit *arg1, VarBit *arg2);
81 : : static VarBit *bitsubstring(VarBit *arg, int32 s, int32 l,
82 : : bool length_not_specified);
83 : : static VarBit *bit_overlay(VarBit *t1, VarBit *t2, int sp, int sl);
84 : :
85 : :
86 : : /*
87 : : * common code for bittypmodin and varbittypmodin
88 : : */
89 : : static int32
90 : 1440 : anybit_typmodin(ArrayType *ta, const char *typename)
91 : : {
92 : : int32 typmod;
93 : : int32 *tl;
94 : : int n;
95 : :
96 : 1440 : tl = ArrayGetIntegerTypmods(ta, &n);
97 : :
98 : : /*
99 : : * we're not too tense about good error message here because grammar
100 : : * shouldn't allow wrong number of modifiers for BIT
101 : : */
102 [ - + ]: 1440 : if (n != 1)
103 [ # # ]: 0 : ereport(ERROR,
104 : : (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
105 : : errmsg("invalid type modifier")));
106 : :
107 [ - + ]: 1440 : if (*tl < 1)
108 [ # # ]: 0 : ereport(ERROR,
109 : : (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
110 : : errmsg("length for type %s must be at least 1",
111 : : typename)));
112 [ - + ]: 1440 : if (*tl > (MaxAttrSize * BITS_PER_BYTE))
113 [ # # ]: 0 : ereport(ERROR,
114 : : (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
115 : : errmsg("length for type %s cannot exceed %d",
116 : : typename, MaxAttrSize * BITS_PER_BYTE)));
117 : :
118 : 1440 : typmod = *tl;
119 : :
120 : 1440 : return typmod;
121 : : }
122 : :
123 : : /*
124 : : * common code for bittypmodout and varbittypmodout
125 : : */
126 : : static char *
127 : 216 : anybit_typmodout(int32 typmod)
128 : : {
129 : 216 : char *res = (char *) palloc(64);
130 : :
131 [ + - ]: 216 : if (typmod >= 0)
132 : 216 : snprintf(res, 64, "(%d)", typmod);
133 : : else
134 : 0 : *res = '\0';
135 : :
136 : 216 : return res;
137 : : }
138 : :
139 : :
140 : : /*
141 : : * bit_in -
142 : : * converts a char string to the internal representation of a bitstring.
143 : : * The length is determined by the number of bits required plus
144 : : * VARHDRSZ bytes or from atttypmod.
145 : : */
146 : : Datum
147 : 3626 : bit_in(PG_FUNCTION_ARGS)
148 : : {
149 : 3626 : char *input_string = PG_GETARG_CSTRING(0);
150 : : #ifdef NOT_USED
151 : : Oid typelem = PG_GETARG_OID(1);
152 : : #endif
153 : 3626 : int32 atttypmod = PG_GETARG_INT32(2);
154 : 3626 : Node *escontext = fcinfo->context;
155 : : VarBit *result; /* The resulting bit string */
156 : : char *sp; /* pointer into the character string */
157 : : uint8 *r; /* pointer into the result */
158 : : int len, /* Length of the whole data structure */
159 : : bitlen, /* Number of bits in the bit string */
160 : : slen; /* Length of the input string */
161 : : bool bit_not_hex; /* false = hex string true = bit string */
162 : : int bc;
163 : 3626 : uint8 x = 0;
164 : :
165 : : /* Check that the first character is a b or an x */
166 [ + + + + ]: 3626 : if (input_string[0] == 'b' || input_string[0] == 'B')
167 : : {
168 : 522 : bit_not_hex = true;
169 : 522 : sp = input_string + 1;
170 : : }
171 [ + + + + ]: 3104 : else if (input_string[0] == 'x' || input_string[0] == 'X')
172 : : {
173 : 2305 : bit_not_hex = false;
174 : 2305 : sp = input_string + 1;
175 : : }
176 : : else
177 : : {
178 : : /*
179 : : * Otherwise it's binary. This allows things like cast('1001' as bit)
180 : : * to work transparently.
181 : : */
182 : 799 : bit_not_hex = true;
183 : 799 : sp = input_string;
184 : : }
185 : :
186 : : /*
187 : : * Determine bitlength from input string. MaxAllocSize ensures a regular
188 : : * input is small enough, but we must check hex input.
189 : : */
190 : 3626 : slen = strlen(sp);
191 [ + + ]: 3626 : if (bit_not_hex)
192 : 1321 : bitlen = slen;
193 : : else
194 : : {
195 [ - + ]: 2305 : if (slen > VARBITMAXLEN / 4)
196 [ # # ]: 0 : ereturn(escontext, (Datum) 0,
197 : : (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
198 : : errmsg("bit string length exceeds the maximum allowed (%d)",
199 : : VARBITMAXLEN)));
200 : 2305 : bitlen = slen * 4;
201 : : }
202 : :
203 : : /*
204 : : * Sometimes atttypmod is not supplied. If it is supplied we need to make
205 : : * sure that the bitstring fits.
206 : : */
207 [ + + ]: 3626 : if (atttypmod <= 0)
208 : 2902 : atttypmod = bitlen;
209 [ + + ]: 724 : else if (bitlen != atttypmod)
210 [ + + ]: 16 : ereturn(escontext, (Datum) 0,
211 : : (errcode(ERRCODE_STRING_DATA_LENGTH_MISMATCH),
212 : : errmsg("bit string length %d does not match type bit(%d)",
213 : : bitlen, atttypmod)));
214 : :
215 : 3610 : len = VARBITTOTALLEN(atttypmod);
216 : : /* set to 0 so that *r is always initialised and string is zero-padded */
217 : 3610 : result = (VarBit *) palloc0(len);
218 : 3610 : SET_VARSIZE(result, len);
219 : 3610 : VARBITLEN(result) = atttypmod;
220 : :
221 : 3610 : r = VARBITS(result);
222 [ + + ]: 3610 : if (bit_not_hex)
223 : : {
224 : : /* Parse the bit representation of the string */
225 : : /* We know it fits, as bitlen was compared to atttypmod */
226 : 1305 : x = HIGHBIT;
227 [ + + ]: 38471 : for (; *sp; sp++)
228 : : {
229 [ + + ]: 37182 : if (*sp == '1')
230 : 19052 : *r |= x;
231 [ + + ]: 18130 : else if (*sp != '0')
232 [ + + ]: 16 : ereturn(escontext, (Datum) 0,
233 : : (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
234 : : errmsg("\"%.*s\" is not a valid binary digit",
235 : : pg_mblen_cstr(sp), sp)));
236 : :
237 : 37166 : x >>= 1;
238 [ + + ]: 37166 : if (x == 0)
239 : : {
240 : 4346 : x = HIGHBIT;
241 : 4346 : r++;
242 : : }
243 : : }
244 : : }
245 : : else
246 : : {
247 : : /* Parse the hex representation of the string */
248 [ + + ]: 27127 : for (bc = 0; *sp; sp++)
249 : : {
250 [ + + + + ]: 24838 : if (*sp >= '0' && *sp <= '9')
251 : 17086 : x = (uint8) (*sp - '0');
252 [ + + + + ]: 7752 : else if (*sp >= 'A' && *sp <= 'F')
253 : 162 : x = (uint8) (*sp - 'A') + 10;
254 [ + + + - ]: 7590 : else if (*sp >= 'a' && *sp <= 'f')
255 : 7574 : x = (uint8) (*sp - 'a') + 10;
256 : : else
257 [ + + ]: 16 : ereturn(escontext, (Datum) 0,
258 : : (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
259 : : errmsg("\"%.*s\" is not a valid hexadecimal digit",
260 : : pg_mblen_cstr(sp), sp)));
261 : :
262 [ + + ]: 24822 : if (bc)
263 : : {
264 : 12326 : *r++ |= x;
265 : 12326 : bc = 0;
266 : : }
267 : : else
268 : : {
269 : 12496 : *r = x << 4;
270 : 12496 : bc = 1;
271 : : }
272 : : }
273 : : }
274 : :
275 : 3578 : PG_RETURN_VARBIT_P(result);
276 : : }
277 : :
278 : :
279 : : Datum
280 : 2662 : bit_out(PG_FUNCTION_ARGS)
281 : : {
282 : : #if 1
283 : : /* same as varbit output */
284 : 2662 : return varbit_out(fcinfo);
285 : : #else
286 : :
287 : : /*
288 : : * This is how one would print a hex string, in case someone wants to
289 : : * write a formatting function.
290 : : */
291 : : VarBit *s = PG_GETARG_VARBIT_P(0);
292 : : char *result,
293 : : *r;
294 : : uint8 *sp;
295 : : int i,
296 : : len,
297 : : bitlen;
298 : :
299 : : /* Assertion to help catch any bit functions that don't pad correctly */
300 : : VARBIT_CORRECTLY_PADDED(s);
301 : :
302 : : bitlen = VARBITLEN(s);
303 : : len = (bitlen + 3) / 4;
304 : : result = (char *) palloc(len + 2);
305 : : sp = VARBITS(s);
306 : : r = result;
307 : : *r++ = 'X';
308 : : /* we cheat by knowing that we store full bytes zero padded */
309 : : for (i = 0; i < len; i += 2, sp++)
310 : : {
311 : : *r++ = HEXDIG((*sp) >> 4);
312 : : *r++ = HEXDIG((*sp) & 0xF);
313 : : }
314 : :
315 : : /*
316 : : * Go back one step if we printed a hex number that was not part of the
317 : : * bitstring anymore
318 : : */
319 : : if (i > len)
320 : : r--;
321 : : *r = '\0';
322 : :
323 : : PG_RETURN_CSTRING(result);
324 : : #endif
325 : : }
326 : :
327 : : /*
328 : : * bit_recv - converts external binary format to bit
329 : : */
330 : : Datum
331 : 0 : bit_recv(PG_FUNCTION_ARGS)
332 : : {
333 : 0 : StringInfo buf = (StringInfo) PG_GETARG_POINTER(0);
334 : :
335 : : #ifdef NOT_USED
336 : : Oid typelem = PG_GETARG_OID(1);
337 : : #endif
338 : 0 : int32 atttypmod = PG_GETARG_INT32(2);
339 : : VarBit *result;
340 : : int len,
341 : : bitlen;
342 : :
343 : 0 : bitlen = pq_getmsgint(buf, sizeof(int32));
344 [ # # # # ]: 0 : if (bitlen < 0 || bitlen > VARBITMAXLEN)
345 [ # # ]: 0 : ereport(ERROR,
346 : : (errcode(ERRCODE_INVALID_BINARY_REPRESENTATION),
347 : : errmsg("invalid length in external bit string")));
348 : :
349 : : /*
350 : : * Sometimes atttypmod is not supplied. If it is supplied we need to make
351 : : * sure that the bitstring fits.
352 : : */
353 [ # # # # ]: 0 : if (atttypmod > 0 && bitlen != atttypmod)
354 [ # # ]: 0 : ereport(ERROR,
355 : : (errcode(ERRCODE_STRING_DATA_LENGTH_MISMATCH),
356 : : errmsg("bit string length %d does not match type bit(%d)",
357 : : bitlen, atttypmod)));
358 : :
359 : 0 : len = VARBITTOTALLEN(bitlen);
360 : 0 : result = (VarBit *) palloc(len);
361 : 0 : SET_VARSIZE(result, len);
362 : 0 : VARBITLEN(result) = bitlen;
363 : :
364 : 0 : pq_copymsgbytes(buf, VARBITS(result), VARBITBYTES(result));
365 : :
366 : : /* Make sure last byte is correctly zero-padded */
367 [ # # ]: 0 : VARBIT_PAD(result);
368 : :
369 : 0 : PG_RETURN_VARBIT_P(result);
370 : : }
371 : :
372 : : /*
373 : : * bit_send - converts bit to binary format
374 : : */
375 : : Datum
376 : 0 : bit_send(PG_FUNCTION_ARGS)
377 : : {
378 : : /* Exactly the same as varbit_send, so share code */
379 : 0 : return varbit_send(fcinfo);
380 : : }
381 : :
382 : : /*
383 : : * bit()
384 : : * Converts a bit() type to a specific internal length.
385 : : * len is the bitlength specified in the column definition.
386 : : *
387 : : * If doing implicit cast, raise error when source data is wrong length.
388 : : * If doing explicit cast, silently truncate or zero-pad to specified length.
389 : : */
390 : : Datum
391 : 701 : bit(PG_FUNCTION_ARGS)
392 : : {
393 : 701 : VarBit *arg = PG_GETARG_VARBIT_P(0);
394 : 701 : int32 len = PG_GETARG_INT32(1);
395 : 701 : bool isExplicit = PG_GETARG_BOOL(2);
396 : : VarBit *result;
397 : : int rlen;
398 : :
399 : : /* No work if typmod is invalid or supplied data matches it already */
400 [ + - + - : 701 : if (len <= 0 || len > VARBITMAXLEN || len == VARBITLEN(arg))
+ + ]
401 : 286 : PG_RETURN_VARBIT_P(arg);
402 : :
403 [ + + ]: 415 : if (!isExplicit)
404 [ + - ]: 20 : ereturn(fcinfo->context, (Datum) 0,
405 : : (errcode(ERRCODE_STRING_DATA_LENGTH_MISMATCH),
406 : : errmsg("bit string length %d does not match type bit(%d)",
407 : : VARBITLEN(arg), len)));
408 : :
409 : 395 : rlen = VARBITTOTALLEN(len);
410 : : /* set to 0 so that string is zero-padded */
411 : 395 : result = (VarBit *) palloc0(rlen);
412 : 395 : SET_VARSIZE(result, rlen);
413 : 395 : VARBITLEN(result) = len;
414 : :
415 : 395 : memcpy(VARBITS(result), VARBITS(arg),
416 [ - + ]: 395 : Min(VARBITBYTES(result), VARBITBYTES(arg)));
417 : :
418 : : /*
419 : : * Make sure last byte is zero-padded if needed. This is useless but safe
420 : : * if source data was shorter than target length (we assume the last byte
421 : : * of the source data was itself correctly zero-padded).
422 : : */
423 [ + - ]: 395 : VARBIT_PAD(result);
424 : :
425 : 395 : PG_RETURN_VARBIT_P(result);
426 : : }
427 : :
428 : : Datum
429 : 1276 : bittypmodin(PG_FUNCTION_ARGS)
430 : : {
431 : 1276 : ArrayType *ta = PG_GETARG_ARRAYTYPE_P(0);
432 : :
433 : 1276 : PG_RETURN_INT32(anybit_typmodin(ta, "bit"));
434 : : }
435 : :
436 : : Datum
437 : 133 : bittypmodout(PG_FUNCTION_ARGS)
438 : : {
439 : 133 : int32 typmod = PG_GETARG_INT32(0);
440 : :
441 : 133 : PG_RETURN_CSTRING(anybit_typmodout(typmod));
442 : : }
443 : :
444 : :
445 : : /*
446 : : * varbit_in -
447 : : * converts a string to the internal representation of a bitstring.
448 : : * This is the same as bit_in except that atttypmod is taken as
449 : : * the maximum length, not the exact length to force the bitstring to.
450 : : */
451 : : Datum
452 : 1036 : varbit_in(PG_FUNCTION_ARGS)
453 : : {
454 : 1036 : char *input_string = PG_GETARG_CSTRING(0);
455 : : #ifdef NOT_USED
456 : : Oid typelem = PG_GETARG_OID(1);
457 : : #endif
458 : 1036 : int32 atttypmod = PG_GETARG_INT32(2);
459 : 1036 : Node *escontext = fcinfo->context;
460 : : VarBit *result; /* The resulting bit string */
461 : : char *sp; /* pointer into the character string */
462 : : uint8 *r; /* pointer into the result */
463 : : int len, /* Length of the whole data structure */
464 : : bitlen, /* Number of bits in the bit string */
465 : : slen; /* Length of the input string */
466 : : bool bit_not_hex; /* false = hex string true = bit string */
467 : : int bc;
468 : 1036 : uint8 x = 0;
469 : :
470 : : /* Check that the first character is a b or an x */
471 [ + - - + ]: 1036 : if (input_string[0] == 'b' || input_string[0] == 'B')
472 : : {
473 : 0 : bit_not_hex = true;
474 : 0 : sp = input_string + 1;
475 : : }
476 [ + + + + ]: 1036 : else if (input_string[0] == 'x' || input_string[0] == 'X')
477 : : {
478 : 88 : bit_not_hex = false;
479 : 88 : sp = input_string + 1;
480 : : }
481 : : else
482 : : {
483 : 948 : bit_not_hex = true;
484 : 948 : sp = input_string;
485 : : }
486 : :
487 : : /*
488 : : * Determine bitlength from input string. MaxAllocSize ensures a regular
489 : : * input is small enough, but we must check hex input.
490 : : */
491 : 1036 : slen = strlen(sp);
492 [ + + ]: 1036 : if (bit_not_hex)
493 : 948 : bitlen = slen;
494 : : else
495 : : {
496 [ - + ]: 88 : if (slen > VARBITMAXLEN / 4)
497 [ # # ]: 0 : ereturn(escontext, (Datum) 0,
498 : : (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
499 : : errmsg("bit string length exceeds the maximum allowed (%d)",
500 : : VARBITMAXLEN)));
501 : 88 : bitlen = slen * 4;
502 : : }
503 : :
504 : : /*
505 : : * Sometimes atttypmod is not supplied. If it is supplied we need to make
506 : : * sure that the bitstring fits.
507 : : */
508 [ + + ]: 1036 : if (atttypmod <= 0)
509 : 948 : atttypmod = bitlen;
510 [ + + ]: 88 : else if (bitlen > atttypmod)
511 [ - + ]: 8 : ereturn(escontext, (Datum) 0,
512 : : (errcode(ERRCODE_STRING_DATA_RIGHT_TRUNCATION),
513 : : errmsg("bit string too long for type bit varying(%d)",
514 : : atttypmod)));
515 : :
516 : 1028 : len = VARBITTOTALLEN(bitlen);
517 : : /* set to 0 so that *r is always initialised and string is zero-padded */
518 : 1028 : result = (VarBit *) palloc0(len);
519 : 1028 : SET_VARSIZE(result, len);
520 : 1028 : VARBITLEN(result) = Min(bitlen, atttypmod);
521 : :
522 : 1028 : r = VARBITS(result);
523 [ + + ]: 1028 : if (bit_not_hex)
524 : : {
525 : : /* Parse the bit representation of the string */
526 : : /* We know it fits, as bitlen was compared to atttypmod */
527 : 940 : x = HIGHBIT;
528 [ + + ]: 33989 : for (; *sp; sp++)
529 : : {
530 [ + + ]: 33057 : if (*sp == '1')
531 : 16479 : *r |= x;
532 [ + + ]: 16578 : else if (*sp != '0')
533 [ + + ]: 8 : ereturn(escontext, (Datum) 0,
534 : : (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
535 : : errmsg("\"%.*s\" is not a valid binary digit",
536 : : pg_mblen_cstr(sp), sp)));
537 : :
538 : 33049 : x >>= 1;
539 [ + + ]: 33049 : if (x == 0)
540 : : {
541 : 3793 : x = HIGHBIT;
542 : 3793 : r++;
543 : : }
544 : : }
545 : : }
546 : : else
547 : : {
548 : : /* Parse the hex representation of the string */
549 [ + + ]: 368 : for (bc = 0; *sp; sp++)
550 : : {
551 [ + - + + ]: 288 : if (*sp >= '0' && *sp <= '9')
552 : 212 : x = (uint8) (*sp - '0');
553 [ + - + + ]: 76 : else if (*sp >= 'A' && *sp <= 'F')
554 : 68 : x = (uint8) (*sp - 'A') + 10;
555 [ - + - - ]: 8 : else if (*sp >= 'a' && *sp <= 'f')
556 : 0 : x = (uint8) (*sp - 'a') + 10;
557 : : else
558 [ + + ]: 8 : ereturn(escontext, (Datum) 0,
559 : : (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
560 : : errmsg("\"%.*s\" is not a valid hexadecimal digit",
561 : : pg_mblen_cstr(sp), sp)));
562 : :
563 [ + + ]: 280 : if (bc)
564 : : {
565 : 136 : *r++ |= x;
566 : 136 : bc = 0;
567 : : }
568 : : else
569 : : {
570 : 144 : *r = x << 4;
571 : 144 : bc = 1;
572 : : }
573 : : }
574 : : }
575 : :
576 : 1012 : PG_RETURN_VARBIT_P(result);
577 : : }
578 : :
579 : : /*
580 : : * varbit_out -
581 : : * Prints the string as bits to preserve length accurately
582 : : *
583 : : * XXX varbit_recv() and hex input to varbit_in() can load a value that this
584 : : * cannot emit. Consider using hex output for such values.
585 : : */
586 : : Datum
587 : 3820 : varbit_out(PG_FUNCTION_ARGS)
588 : : {
589 : 3820 : VarBit *s = PG_GETARG_VARBIT_P(0);
590 : : char *result,
591 : : *r;
592 : : uint8 *sp;
593 : : uint8 x;
594 : : int i,
595 : : k,
596 : : len;
597 : :
598 : : /* Assertion to help catch any bit functions that don't pad correctly */
599 : : VARBIT_CORRECTLY_PADDED(s);
600 : :
601 : 3820 : len = VARBITLEN(s);
602 : 3820 : result = (char *) palloc(len + 1);
603 : 3820 : sp = VARBITS(s);
604 : 3820 : r = result;
605 [ + + ]: 8942 : for (i = 0; i <= len - BITS_PER_BYTE; i += BITS_PER_BYTE, sp++)
606 : : {
607 : : /* print full bytes */
608 : 5122 : x = *sp;
609 [ + + ]: 46098 : for (k = 0; k < BITS_PER_BYTE; k++)
610 : : {
611 [ + + ]: 40976 : *r++ = IS_HIGHBIT_SET(x) ? '1' : '0';
612 : 40976 : x <<= 1;
613 : : }
614 : : }
615 [ + + ]: 3820 : if (i < len)
616 : : {
617 : : /* print the last partial byte */
618 : 1812 : x = *sp;
619 [ + + ]: 9032 : for (k = i; k < len; k++)
620 : : {
621 [ + + ]: 7220 : *r++ = IS_HIGHBIT_SET(x) ? '1' : '0';
622 : 7220 : x <<= 1;
623 : : }
624 : : }
625 : 3820 : *r = '\0';
626 : :
627 : 3820 : PG_RETURN_CSTRING(result);
628 : : }
629 : :
630 : : /*
631 : : * varbit_recv - converts external binary format to varbit
632 : : *
633 : : * External format is the bitlen as an int32, then the byte array.
634 : : */
635 : : Datum
636 : 0 : varbit_recv(PG_FUNCTION_ARGS)
637 : : {
638 : 0 : StringInfo buf = (StringInfo) PG_GETARG_POINTER(0);
639 : :
640 : : #ifdef NOT_USED
641 : : Oid typelem = PG_GETARG_OID(1);
642 : : #endif
643 : 0 : int32 atttypmod = PG_GETARG_INT32(2);
644 : : VarBit *result;
645 : : int len,
646 : : bitlen;
647 : :
648 : 0 : bitlen = pq_getmsgint(buf, sizeof(int32));
649 [ # # # # ]: 0 : if (bitlen < 0 || bitlen > VARBITMAXLEN)
650 [ # # ]: 0 : ereport(ERROR,
651 : : (errcode(ERRCODE_INVALID_BINARY_REPRESENTATION),
652 : : errmsg("invalid length in external bit string")));
653 : :
654 : : /*
655 : : * Sometimes atttypmod is not supplied. If it is supplied we need to make
656 : : * sure that the bitstring fits.
657 : : */
658 [ # # # # ]: 0 : if (atttypmod > 0 && bitlen > atttypmod)
659 [ # # ]: 0 : ereport(ERROR,
660 : : (errcode(ERRCODE_STRING_DATA_RIGHT_TRUNCATION),
661 : : errmsg("bit string too long for type bit varying(%d)",
662 : : atttypmod)));
663 : :
664 : 0 : len = VARBITTOTALLEN(bitlen);
665 : 0 : result = (VarBit *) palloc(len);
666 : 0 : SET_VARSIZE(result, len);
667 : 0 : VARBITLEN(result) = bitlen;
668 : :
669 : 0 : pq_copymsgbytes(buf, VARBITS(result), VARBITBYTES(result));
670 : :
671 : : /* Make sure last byte is correctly zero-padded */
672 [ # # ]: 0 : VARBIT_PAD(result);
673 : :
674 : 0 : PG_RETURN_VARBIT_P(result);
675 : : }
676 : :
677 : : /*
678 : : * varbit_send - converts varbit to binary format
679 : : */
680 : : Datum
681 : 0 : varbit_send(PG_FUNCTION_ARGS)
682 : : {
683 : 0 : VarBit *s = PG_GETARG_VARBIT_P(0);
684 : : StringInfoData buf;
685 : :
686 : 0 : pq_begintypsend(&buf);
687 : 0 : pq_sendint32(&buf, VARBITLEN(s));
688 : 0 : pq_sendbytes(&buf, VARBITS(s), VARBITBYTES(s));
689 : 0 : PG_RETURN_BYTEA_P(pq_endtypsend(&buf));
690 : : }
691 : :
692 : : /*
693 : : * varbit_support()
694 : : *
695 : : * Planner support function for the varbit() length coercion function.
696 : : *
697 : : * Currently, the only interesting thing we can do is flatten calls that set
698 : : * the new maximum length >= the previous maximum length. We can ignore the
699 : : * isExplicit argument, since that only affects truncation cases.
700 : : */
701 : : Datum
702 : 100 : varbit_support(PG_FUNCTION_ARGS)
703 : : {
704 : 100 : Node *rawreq = (Node *) PG_GETARG_POINTER(0);
705 : 100 : Node *ret = NULL;
706 : :
707 [ + + ]: 100 : if (IsA(rawreq, SupportRequestSimplify))
708 : : {
709 : 50 : SupportRequestSimplify *req = (SupportRequestSimplify *) rawreq;
710 : 50 : FuncExpr *expr = req->fcall;
711 : : Node *typmod;
712 : :
713 : : Assert(list_length(expr->args) >= 2);
714 : :
715 : 50 : typmod = (Node *) lsecond(expr->args);
716 : :
717 [ + - + - ]: 50 : if (IsA(typmod, Const) && !((Const *) typmod)->constisnull)
718 : : {
719 : 50 : Node *source = (Node *) linitial(expr->args);
720 : 50 : int32 new_typmod = DatumGetInt32(((Const *) typmod)->constvalue);
721 : 50 : int32 old_max = exprTypmod(source);
722 : 50 : int32 new_max = new_typmod;
723 : :
724 : : /* Note: varbit() treats typmod 0 as invalid, so we do too */
725 [ + - - + : 50 : if (new_max <= 0 || (old_max > 0 && old_max <= new_max))
- - ]
726 : 0 : ret = relabel_to_typmod(source, new_typmod);
727 : : }
728 : : }
729 : :
730 : 100 : PG_RETURN_POINTER(ret);
731 : : }
732 : :
733 : : /*
734 : : * varbit()
735 : : * Converts a varbit() type to a specific internal length.
736 : : * len is the maximum bitlength specified in the column definition.
737 : : *
738 : : * If doing implicit cast, raise error when source data is too long.
739 : : * If doing explicit cast, silently truncate to max length.
740 : : */
741 : : Datum
742 : 693 : varbit(PG_FUNCTION_ARGS)
743 : : {
744 : 693 : VarBit *arg = PG_GETARG_VARBIT_P(0);
745 : 693 : int32 len = PG_GETARG_INT32(1);
746 : 693 : bool isExplicit = PG_GETARG_BOOL(2);
747 : : VarBit *result;
748 : : int rlen;
749 : :
750 : : /* No work if typmod is invalid or supplied data matches it already */
751 [ + - + + ]: 693 : if (len <= 0 || len >= VARBITLEN(arg))
752 : 685 : PG_RETURN_VARBIT_P(arg);
753 : :
754 [ + - ]: 8 : if (!isExplicit)
755 [ + - ]: 8 : ereturn(fcinfo->context, (Datum) 0,
756 : : (errcode(ERRCODE_STRING_DATA_RIGHT_TRUNCATION),
757 : : errmsg("bit string too long for type bit varying(%d)",
758 : : len)));
759 : :
760 : 0 : rlen = VARBITTOTALLEN(len);
761 : 0 : result = (VarBit *) palloc(rlen);
762 : 0 : SET_VARSIZE(result, rlen);
763 : 0 : VARBITLEN(result) = len;
764 : :
765 : 0 : memcpy(VARBITS(result), VARBITS(arg), VARBITBYTES(result));
766 : :
767 : : /* Make sure last byte is correctly zero-padded */
768 [ # # ]: 0 : VARBIT_PAD(result);
769 : :
770 : 0 : PG_RETURN_VARBIT_P(result);
771 : : }
772 : :
773 : : Datum
774 : 164 : varbittypmodin(PG_FUNCTION_ARGS)
775 : : {
776 : 164 : ArrayType *ta = PG_GETARG_ARRAYTYPE_P(0);
777 : :
778 : 164 : PG_RETURN_INT32(anybit_typmodin(ta, "varbit"));
779 : : }
780 : :
781 : : Datum
782 : 83 : varbittypmodout(PG_FUNCTION_ARGS)
783 : : {
784 : 83 : int32 typmod = PG_GETARG_INT32(0);
785 : :
786 : 83 : PG_RETURN_CSTRING(anybit_typmodout(typmod));
787 : : }
788 : :
789 : :
790 : : /*
791 : : * Comparison operators
792 : : *
793 : : * We only need one set of comparison operators for bitstrings, as the lengths
794 : : * are stored in the same way for zero-padded and varying bit strings.
795 : : *
796 : : * Note that the standard is not unambiguous about the comparison between
797 : : * zero-padded bit strings and varying bitstrings. If the same value is written
798 : : * into a zero padded bitstring as into a varying bitstring, but the zero
799 : : * padded bitstring has greater length, it will be bigger.
800 : : *
801 : : * Zeros from the beginning of a bitstring cannot simply be ignored, as they
802 : : * may be part of a bit string and may be significant.
803 : : *
804 : : * Note: btree indexes need these routines not to leak memory; therefore,
805 : : * be careful to free working copies of toasted datums. Most places don't
806 : : * need to be so careful.
807 : : */
808 : :
809 : : /*
810 : : * bit_cmp
811 : : *
812 : : * Compares two bitstrings and returns <0, 0, >0 depending on whether the first
813 : : * string is smaller, equal, or bigger than the second. All bits are considered
814 : : * and additional zero bits may make one string smaller/larger than the other,
815 : : * even if their zero-padded values would be the same.
816 : : */
817 : : static int32
818 : 36966 : bit_cmp(VarBit *arg1, VarBit *arg2)
819 : : {
820 : : int bitlen1,
821 : : bytelen1,
822 : : bitlen2,
823 : : bytelen2;
824 : : int32 cmp;
825 : :
826 : 36966 : bytelen1 = VARBITBYTES(arg1);
827 : 36966 : bytelen2 = VARBITBYTES(arg2);
828 : :
829 : 36966 : cmp = memcmp(VARBITS(arg1), VARBITS(arg2), Min(bytelen1, bytelen2));
830 [ + + ]: 36966 : if (cmp == 0)
831 : : {
832 : 4249 : bitlen1 = VARBITLEN(arg1);
833 : 4249 : bitlen2 = VARBITLEN(arg2);
834 [ + + ]: 4249 : if (bitlen1 != bitlen2)
835 [ + + ]: 107 : cmp = (bitlen1 < bitlen2) ? -1 : 1;
836 : : }
837 : 36966 : return cmp;
838 : : }
839 : :
840 : : Datum
841 : 3059 : biteq(PG_FUNCTION_ARGS)
842 : : {
843 : 3059 : VarBit *arg1 = PG_GETARG_VARBIT_P(0);
844 : 3059 : VarBit *arg2 = PG_GETARG_VARBIT_P(1);
845 : : bool result;
846 : : int bitlen1,
847 : : bitlen2;
848 : :
849 : 3059 : bitlen1 = VARBITLEN(arg1);
850 : 3059 : bitlen2 = VARBITLEN(arg2);
851 : :
852 : : /* fast path for different-length inputs */
853 [ + + ]: 3059 : if (bitlen1 != bitlen2)
854 : 743 : result = false;
855 : : else
856 : 2316 : result = (bit_cmp(arg1, arg2) == 0);
857 : :
858 [ + + ]: 3059 : PG_FREE_IF_COPY(arg1, 0);
859 [ + + ]: 3059 : PG_FREE_IF_COPY(arg2, 1);
860 : :
861 : 3059 : PG_RETURN_BOOL(result);
862 : : }
863 : :
864 : : Datum
865 : 665 : bitne(PG_FUNCTION_ARGS)
866 : : {
867 : 665 : VarBit *arg1 = PG_GETARG_VARBIT_P(0);
868 : 665 : VarBit *arg2 = PG_GETARG_VARBIT_P(1);
869 : : bool result;
870 : : int bitlen1,
871 : : bitlen2;
872 : :
873 : 665 : bitlen1 = VARBITLEN(arg1);
874 : 665 : bitlen2 = VARBITLEN(arg2);
875 : :
876 : : /* fast path for different-length inputs */
877 [ + + ]: 665 : if (bitlen1 != bitlen2)
878 : 4 : result = true;
879 : : else
880 : 661 : result = (bit_cmp(arg1, arg2) != 0);
881 : :
882 [ + + ]: 665 : PG_FREE_IF_COPY(arg1, 0);
883 [ + + ]: 665 : PG_FREE_IF_COPY(arg2, 1);
884 : :
885 : 665 : PG_RETURN_BOOL(result);
886 : : }
887 : :
888 : : Datum
889 : 6260 : bitlt(PG_FUNCTION_ARGS)
890 : : {
891 : 6260 : VarBit *arg1 = PG_GETARG_VARBIT_P(0);
892 : 6260 : VarBit *arg2 = PG_GETARG_VARBIT_P(1);
893 : : bool result;
894 : :
895 : 6260 : result = (bit_cmp(arg1, arg2) < 0);
896 : :
897 [ + + ]: 6260 : PG_FREE_IF_COPY(arg1, 0);
898 [ + + ]: 6260 : PG_FREE_IF_COPY(arg2, 1);
899 : :
900 : 6260 : PG_RETURN_BOOL(result);
901 : : }
902 : :
903 : : Datum
904 : 5380 : bitle(PG_FUNCTION_ARGS)
905 : : {
906 : 5380 : VarBit *arg1 = PG_GETARG_VARBIT_P(0);
907 : 5380 : VarBit *arg2 = PG_GETARG_VARBIT_P(1);
908 : : bool result;
909 : :
910 : 5380 : result = (bit_cmp(arg1, arg2) <= 0);
911 : :
912 [ + + ]: 5380 : PG_FREE_IF_COPY(arg1, 0);
913 [ + + ]: 5380 : PG_FREE_IF_COPY(arg2, 1);
914 : :
915 : 5380 : PG_RETURN_BOOL(result);
916 : : }
917 : :
918 : : Datum
919 : 5960 : bitgt(PG_FUNCTION_ARGS)
920 : : {
921 : 5960 : VarBit *arg1 = PG_GETARG_VARBIT_P(0);
922 : 5960 : VarBit *arg2 = PG_GETARG_VARBIT_P(1);
923 : : bool result;
924 : :
925 : 5960 : result = (bit_cmp(arg1, arg2) > 0);
926 : :
927 [ + + ]: 5960 : PG_FREE_IF_COPY(arg1, 0);
928 [ + + ]: 5960 : PG_FREE_IF_COPY(arg2, 1);
929 : :
930 : 5960 : PG_RETURN_BOOL(result);
931 : : }
932 : :
933 : : Datum
934 : 4584 : bitge(PG_FUNCTION_ARGS)
935 : : {
936 : 4584 : VarBit *arg1 = PG_GETARG_VARBIT_P(0);
937 : 4584 : VarBit *arg2 = PG_GETARG_VARBIT_P(1);
938 : : bool result;
939 : :
940 : 4584 : result = (bit_cmp(arg1, arg2) >= 0);
941 : :
942 [ + + ]: 4584 : PG_FREE_IF_COPY(arg1, 0);
943 [ + + ]: 4584 : PG_FREE_IF_COPY(arg2, 1);
944 : :
945 : 4584 : PG_RETURN_BOOL(result);
946 : : }
947 : :
948 : : Datum
949 : 11805 : bitcmp(PG_FUNCTION_ARGS)
950 : : {
951 : 11805 : VarBit *arg1 = PG_GETARG_VARBIT_P(0);
952 : 11805 : VarBit *arg2 = PG_GETARG_VARBIT_P(1);
953 : : int32 result;
954 : :
955 : 11805 : result = bit_cmp(arg1, arg2);
956 : :
957 [ + + ]: 11805 : PG_FREE_IF_COPY(arg1, 0);
958 [ + + ]: 11805 : PG_FREE_IF_COPY(arg2, 1);
959 : :
960 : 11805 : PG_RETURN_INT32(result);
961 : : }
962 : :
963 : : /*
964 : : * bitcat
965 : : * Concatenation of bit strings
966 : : */
967 : : Datum
968 : 108 : bitcat(PG_FUNCTION_ARGS)
969 : : {
970 : 108 : VarBit *arg1 = PG_GETARG_VARBIT_P(0);
971 : 108 : VarBit *arg2 = PG_GETARG_VARBIT_P(1);
972 : :
973 : 108 : PG_RETURN_VARBIT_P(bit_catenate(arg1, arg2));
974 : : }
975 : :
976 : : static VarBit *
977 : 148 : bit_catenate(VarBit *arg1, VarBit *arg2)
978 : : {
979 : : VarBit *result;
980 : : int bitlen1,
981 : : bitlen2,
982 : : bytelen,
983 : : bit1pad,
984 : : bit2shift;
985 : : uint8 *pr,
986 : : *pa;
987 : :
988 : 148 : bitlen1 = VARBITLEN(arg1);
989 : 148 : bitlen2 = VARBITLEN(arg2);
990 : :
991 [ - + ]: 148 : if (bitlen1 > VARBITMAXLEN - bitlen2)
992 [ # # ]: 0 : ereport(ERROR,
993 : : (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
994 : : errmsg("bit string length exceeds the maximum allowed (%d)",
995 : : VARBITMAXLEN)));
996 : 148 : bytelen = VARBITTOTALLEN(bitlen1 + bitlen2);
997 : :
998 : 148 : result = (VarBit *) palloc(bytelen);
999 : 148 : SET_VARSIZE(result, bytelen);
1000 : 148 : VARBITLEN(result) = bitlen1 + bitlen2;
1001 : :
1002 : : /* Copy the first bitstring in */
1003 : 148 : memcpy(VARBITS(result), VARBITS(arg1), VARBITBYTES(arg1));
1004 : :
1005 : : /* Copy the second bit string */
1006 : 148 : bit1pad = VARBITPAD(arg1);
1007 [ + + ]: 148 : if (bit1pad == 0)
1008 : : {
1009 : 25 : memcpy(VARBITS(result) + VARBITBYTES(arg1), VARBITS(arg2),
1010 : 25 : VARBITBYTES(arg2));
1011 : : }
1012 [ + + ]: 123 : else if (bitlen2 > 0)
1013 : : {
1014 : : /* We need to shift all the bits to fit */
1015 : 113 : bit2shift = BITS_PER_BYTE - bit1pad;
1016 : 113 : pr = VARBITS(result) + VARBITBYTES(arg1) - 1;
1017 [ + + ]: 262 : for (pa = VARBITS(arg2); pa < VARBITEND(arg2); pa++)
1018 : : {
1019 : 149 : *pr |= ((*pa >> bit2shift) & BITMASK);
1020 : 149 : pr++;
1021 [ + + ]: 149 : if (pr < VARBITEND(result))
1022 : 93 : *pr = (*pa << bit1pad) & BITMASK;
1023 : : }
1024 : : }
1025 : :
1026 : : /* The pad bits should be already zero at this point */
1027 : :
1028 : 148 : return result;
1029 : : }
1030 : :
1031 : : /*
1032 : : * bitsubstr
1033 : : * retrieve a substring from the bit string.
1034 : : * Note, s is 1-based.
1035 : : * SQL draft 6.10 9)
1036 : : */
1037 : : Datum
1038 : 84 : bitsubstr(PG_FUNCTION_ARGS)
1039 : : {
1040 : 84 : PG_RETURN_VARBIT_P(bitsubstring(PG_GETARG_VARBIT_P(0),
1041 : : PG_GETARG_INT32(1),
1042 : : PG_GETARG_INT32(2),
1043 : : false));
1044 : : }
1045 : :
1046 : : Datum
1047 : 28 : bitsubstr_no_len(PG_FUNCTION_ARGS)
1048 : : {
1049 : 28 : PG_RETURN_VARBIT_P(bitsubstring(PG_GETARG_VARBIT_P(0),
1050 : : PG_GETARG_INT32(1),
1051 : : -1, true));
1052 : : }
1053 : :
1054 : : static VarBit *
1055 : 152 : bitsubstring(VarBit *arg, int32 s, int32 l, bool length_not_specified)
1056 : : {
1057 : : VarBit *result;
1058 : : int bitlen,
1059 : : rbitlen,
1060 : : len,
1061 : : ishift,
1062 : : i;
1063 : : int32 e,
1064 : : s1,
1065 : : e1;
1066 : : uint8 *r,
1067 : : *ps;
1068 : :
1069 : 152 : bitlen = VARBITLEN(arg);
1070 : 152 : s1 = Max(s, 1);
1071 : : /* If we do not have an upper bound, use end of string */
1072 [ + + ]: 152 : if (length_not_specified)
1073 : : {
1074 : 48 : e1 = bitlen + 1;
1075 : : }
1076 [ + + ]: 104 : else if (l < 0)
1077 : : {
1078 : : /* SQL99 says to throw an error for E < S, i.e., negative length */
1079 [ + - ]: 8 : ereport(ERROR,
1080 : : (errcode(ERRCODE_SUBSTRING_ERROR),
1081 : : errmsg("negative substring length not allowed")));
1082 : : e1 = -1; /* silence stupider compilers */
1083 : : }
1084 [ + + ]: 96 : else if (pg_add_s32_overflow(s, l, &e))
1085 : : {
1086 : : /*
1087 : : * L could be large enough for S + L to overflow, in which case the
1088 : : * substring must run to end of string.
1089 : : */
1090 : 10 : e1 = bitlen + 1;
1091 : : }
1092 : : else
1093 : : {
1094 : 86 : e1 = Min(e, bitlen + 1);
1095 : : }
1096 [ + + - + ]: 144 : if (s1 > bitlen || e1 <= s1)
1097 : : {
1098 : : /* Need to return a zero-length bitstring */
1099 : 38 : len = VARBITTOTALLEN(0);
1100 : 38 : result = (VarBit *) palloc(len);
1101 : 38 : SET_VARSIZE(result, len);
1102 : 38 : VARBITLEN(result) = 0;
1103 : : }
1104 : : else
1105 : : {
1106 : : /*
1107 : : * OK, we've got a true substring starting at position s1-1 and ending
1108 : : * at position e1-1
1109 : : */
1110 : 106 : rbitlen = e1 - s1;
1111 : 106 : len = VARBITTOTALLEN(rbitlen);
1112 : 106 : result = (VarBit *) palloc(len);
1113 : 106 : SET_VARSIZE(result, len);
1114 : 106 : VARBITLEN(result) = rbitlen;
1115 : 106 : len -= VARHDRSZ + VARBITHDRSZ;
1116 : : /* Are we copying from a byte boundary? */
1117 [ + + ]: 106 : if ((s1 - 1) % BITS_PER_BYTE == 0)
1118 : : {
1119 : : /* Yep, we are copying bytes */
1120 : 35 : memcpy(VARBITS(result), VARBITS(arg) + (s1 - 1) / BITS_PER_BYTE,
1121 : : len);
1122 : : }
1123 : : else
1124 : : {
1125 : : /* Figure out how much we need to shift the sequence by */
1126 : 71 : ishift = (s1 - 1) % BITS_PER_BYTE;
1127 : 71 : r = VARBITS(result);
1128 : 71 : ps = VARBITS(arg) + (s1 - 1) / BITS_PER_BYTE;
1129 [ + + ]: 142 : for (i = 0; i < len; i++)
1130 : : {
1131 : 71 : *r = (*ps << ishift) & BITMASK;
1132 [ + + ]: 71 : if ((++ps) < VARBITEND(arg))
1133 : 53 : *r |= *ps >> (BITS_PER_BYTE - ishift);
1134 : 71 : r++;
1135 : : }
1136 : : }
1137 : :
1138 : : /* Make sure last byte is correctly zero-padded */
1139 [ + + ]: 106 : VARBIT_PAD(result);
1140 : : }
1141 : :
1142 : 144 : return result;
1143 : : }
1144 : :
1145 : : /*
1146 : : * bitoverlay
1147 : : * Replace specified substring of first string with second
1148 : : *
1149 : : * The SQL standard defines OVERLAY() in terms of substring and concatenation.
1150 : : * This code is a direct implementation of what the standard says.
1151 : : */
1152 : : Datum
1153 : 5 : bitoverlay(PG_FUNCTION_ARGS)
1154 : : {
1155 : 5 : VarBit *t1 = PG_GETARG_VARBIT_P(0);
1156 : 5 : VarBit *t2 = PG_GETARG_VARBIT_P(1);
1157 : 5 : int sp = PG_GETARG_INT32(2); /* substring start position */
1158 : 5 : int sl = PG_GETARG_INT32(3); /* substring length */
1159 : :
1160 : 5 : PG_RETURN_VARBIT_P(bit_overlay(t1, t2, sp, sl));
1161 : : }
1162 : :
1163 : : Datum
1164 : 15 : bitoverlay_no_len(PG_FUNCTION_ARGS)
1165 : : {
1166 : 15 : VarBit *t1 = PG_GETARG_VARBIT_P(0);
1167 : 15 : VarBit *t2 = PG_GETARG_VARBIT_P(1);
1168 : 15 : int sp = PG_GETARG_INT32(2); /* substring start position */
1169 : : int sl;
1170 : :
1171 : 15 : sl = VARBITLEN(t2); /* defaults to length(t2) */
1172 : 15 : PG_RETURN_VARBIT_P(bit_overlay(t1, t2, sp, sl));
1173 : : }
1174 : :
1175 : : static VarBit *
1176 : 20 : bit_overlay(VarBit *t1, VarBit *t2, int sp, int sl)
1177 : : {
1178 : : VarBit *result;
1179 : : VarBit *s1;
1180 : : VarBit *s2;
1181 : : int sp_pl_sl;
1182 : :
1183 : : /*
1184 : : * Check for possible integer-overflow cases. For negative sp, throw a
1185 : : * "substring length" error because that's what should be expected
1186 : : * according to the spec's definition of OVERLAY().
1187 : : */
1188 [ - + ]: 20 : if (sp <= 0)
1189 [ # # ]: 0 : ereport(ERROR,
1190 : : (errcode(ERRCODE_SUBSTRING_ERROR),
1191 : : errmsg("negative substring length not allowed")));
1192 [ - + ]: 20 : if (pg_add_s32_overflow(sp, sl, &sp_pl_sl))
1193 [ # # ]: 0 : ereport(ERROR,
1194 : : (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
1195 : : errmsg("integer out of range")));
1196 : :
1197 : 20 : s1 = bitsubstring(t1, 1, sp - 1, false);
1198 : 20 : s2 = bitsubstring(t1, sp_pl_sl, -1, true);
1199 : 20 : result = bit_catenate(s1, t2);
1200 : 20 : result = bit_catenate(result, s2);
1201 : :
1202 : 20 : return result;
1203 : : }
1204 : :
1205 : : /*
1206 : : * bit_count
1207 : : *
1208 : : * Returns the number of bits set in a bit string.
1209 : : */
1210 : : Datum
1211 : 30 : bit_bit_count(PG_FUNCTION_ARGS)
1212 : : {
1213 : 30 : VarBit *arg = PG_GETARG_VARBIT_P(0);
1214 : :
1215 : 30 : PG_RETURN_INT64(pg_popcount((char *) VARBITS(arg), VARBITBYTES(arg)));
1216 : : }
1217 : :
1218 : : /*
1219 : : * bitlength, bitoctetlength
1220 : : * Return the length of a bit string
1221 : : */
1222 : : Datum
1223 : 28 : bitlength(PG_FUNCTION_ARGS)
1224 : : {
1225 : 28 : VarBit *arg = PG_GETARG_VARBIT_P(0);
1226 : :
1227 : 28 : PG_RETURN_INT32(VARBITLEN(arg));
1228 : : }
1229 : :
1230 : : Datum
1231 : 0 : bitoctetlength(PG_FUNCTION_ARGS)
1232 : : {
1233 : 0 : VarBit *arg = PG_GETARG_VARBIT_P(0);
1234 : :
1235 : 0 : PG_RETURN_INT32(VARBITBYTES(arg));
1236 : : }
1237 : :
1238 : : /*
1239 : : * bit_and
1240 : : * perform a logical AND on two bit strings.
1241 : : */
1242 : : Datum
1243 : 92 : bit_and(PG_FUNCTION_ARGS)
1244 : : {
1245 : 92 : VarBit *arg1 = PG_GETARG_VARBIT_P(0);
1246 : 92 : VarBit *arg2 = PG_GETARG_VARBIT_P(1);
1247 : : VarBit *result;
1248 : : int len,
1249 : : bitlen1,
1250 : : bitlen2;
1251 : : uint8 *p1,
1252 : : *p2,
1253 : : *r;
1254 : :
1255 : 92 : bitlen1 = VARBITLEN(arg1);
1256 : 92 : bitlen2 = VARBITLEN(arg2);
1257 [ + + ]: 92 : if (bitlen1 != bitlen2)
1258 [ + - ]: 4 : ereport(ERROR,
1259 : : (errcode(ERRCODE_STRING_DATA_LENGTH_MISMATCH),
1260 : : errmsg("cannot AND bit strings of different sizes")));
1261 : :
1262 : 88 : len = VARSIZE(arg1);
1263 : 88 : result = (VarBit *) palloc(len);
1264 : 88 : SET_VARSIZE(result, len);
1265 : 88 : VARBITLEN(result) = bitlen1;
1266 : :
1267 : 88 : p1 = VARBITS(arg1);
1268 : 88 : p2 = VARBITS(arg2);
1269 : 88 : r = VARBITS(result);
1270 [ + + ]: 236 : for (size_t i = 0; i < VARBITBYTES(arg1); i++)
1271 : 148 : *r++ = *p1++ & *p2++;
1272 : :
1273 : : /* Padding is not needed as & of 0 pads is 0 */
1274 : :
1275 : 88 : PG_RETURN_VARBIT_P(result);
1276 : : }
1277 : :
1278 : : /*
1279 : : * bit_or
1280 : : * perform a logical OR on two bit strings.
1281 : : */
1282 : : Datum
1283 : 117 : bit_or(PG_FUNCTION_ARGS)
1284 : : {
1285 : 117 : VarBit *arg1 = PG_GETARG_VARBIT_P(0);
1286 : 117 : VarBit *arg2 = PG_GETARG_VARBIT_P(1);
1287 : : VarBit *result;
1288 : : int len,
1289 : : bitlen1,
1290 : : bitlen2;
1291 : : uint8 *p1,
1292 : : *p2,
1293 : : *r;
1294 : :
1295 : 117 : bitlen1 = VARBITLEN(arg1);
1296 : 117 : bitlen2 = VARBITLEN(arg2);
1297 [ + + ]: 117 : if (bitlen1 != bitlen2)
1298 [ + - ]: 4 : ereport(ERROR,
1299 : : (errcode(ERRCODE_STRING_DATA_LENGTH_MISMATCH),
1300 : : errmsg("cannot OR bit strings of different sizes")));
1301 : 113 : len = VARSIZE(arg1);
1302 : 113 : result = (VarBit *) palloc(len);
1303 : 113 : SET_VARSIZE(result, len);
1304 : 113 : VARBITLEN(result) = bitlen1;
1305 : :
1306 : 113 : p1 = VARBITS(arg1);
1307 : 113 : p2 = VARBITS(arg2);
1308 : 113 : r = VARBITS(result);
1309 [ + + ]: 336 : for (size_t i = 0; i < VARBITBYTES(arg1); i++)
1310 : 223 : *r++ = *p1++ | *p2++;
1311 : :
1312 : : /* Padding is not needed as | of 0 pads is 0 */
1313 : :
1314 : 113 : PG_RETURN_VARBIT_P(result);
1315 : : }
1316 : :
1317 : : /*
1318 : : * bitxor
1319 : : * perform a logical XOR on two bit strings.
1320 : : */
1321 : : Datum
1322 : 92 : bitxor(PG_FUNCTION_ARGS)
1323 : : {
1324 : 92 : VarBit *arg1 = PG_GETARG_VARBIT_P(0);
1325 : 92 : VarBit *arg2 = PG_GETARG_VARBIT_P(1);
1326 : : VarBit *result;
1327 : : int len,
1328 : : bitlen1,
1329 : : bitlen2;
1330 : : uint8 *p1,
1331 : : *p2,
1332 : : *r;
1333 : :
1334 : 92 : bitlen1 = VARBITLEN(arg1);
1335 : 92 : bitlen2 = VARBITLEN(arg2);
1336 [ + + ]: 92 : if (bitlen1 != bitlen2)
1337 [ + - ]: 4 : ereport(ERROR,
1338 : : (errcode(ERRCODE_STRING_DATA_LENGTH_MISMATCH),
1339 : : errmsg("cannot XOR bit strings of different sizes")));
1340 : :
1341 : 88 : len = VARSIZE(arg1);
1342 : 88 : result = (VarBit *) palloc(len);
1343 : 88 : SET_VARSIZE(result, len);
1344 : 88 : VARBITLEN(result) = bitlen1;
1345 : :
1346 : 88 : p1 = VARBITS(arg1);
1347 : 88 : p2 = VARBITS(arg2);
1348 : 88 : r = VARBITS(result);
1349 [ + + ]: 236 : for (size_t i = 0; i < VARBITBYTES(arg1); i++)
1350 : 148 : *r++ = *p1++ ^ *p2++;
1351 : :
1352 : : /* Padding is not needed as ^ of 0 pads is 0 */
1353 : :
1354 : 88 : PG_RETURN_VARBIT_P(result);
1355 : : }
1356 : :
1357 : : /*
1358 : : * bitnot
1359 : : * perform a logical NOT on a bit string.
1360 : : */
1361 : : Datum
1362 : 80 : bitnot(PG_FUNCTION_ARGS)
1363 : : {
1364 : 80 : VarBit *arg = PG_GETARG_VARBIT_P(0);
1365 : : VarBit *result;
1366 : : uint8 *p,
1367 : : *r;
1368 : :
1369 : 80 : result = (VarBit *) palloc(VARSIZE(arg));
1370 : 80 : SET_VARSIZE(result, VARSIZE(arg));
1371 : 80 : VARBITLEN(result) = VARBITLEN(arg);
1372 : :
1373 : 80 : p = VARBITS(arg);
1374 : 80 : r = VARBITS(result);
1375 [ + + ]: 220 : for (; p < VARBITEND(arg); p++)
1376 : 140 : *r++ = ~*p;
1377 : :
1378 : : /* Must zero-pad the result, because extra bits are surely 1's here */
1379 [ - + ]: 80 : VARBIT_PAD_LAST(result, r);
1380 : :
1381 : 80 : PG_RETURN_VARBIT_P(result);
1382 : : }
1383 : :
1384 : : /*
1385 : : * bitshiftleft
1386 : : * do a left shift (i.e. towards the beginning of the string)
1387 : : */
1388 : : Datum
1389 : 464 : bitshiftleft(PG_FUNCTION_ARGS)
1390 : : {
1391 : 464 : VarBit *arg = PG_GETARG_VARBIT_P(0);
1392 : 464 : int32 shft = PG_GETARG_INT32(1);
1393 : : VarBit *result;
1394 : : int byte_shift,
1395 : : ishift,
1396 : : len;
1397 : : uint8 *p,
1398 : : *r;
1399 : :
1400 : : /* Negative shift is a shift to the right */
1401 [ - + ]: 464 : if (shft < 0)
1402 : : {
1403 : : /* Prevent integer overflow in negation */
1404 [ # # ]: 0 : if (shft < -VARBITMAXLEN)
1405 : 0 : shft = -VARBITMAXLEN;
1406 : 0 : PG_RETURN_DATUM(DirectFunctionCall2(bitshiftright,
1407 : : VarBitPGetDatum(arg),
1408 : : Int32GetDatum(-shft)));
1409 : : }
1410 : :
1411 : 464 : result = (VarBit *) palloc(VARSIZE(arg));
1412 : 464 : SET_VARSIZE(result, VARSIZE(arg));
1413 : 464 : VARBITLEN(result) = VARBITLEN(arg);
1414 : 464 : r = VARBITS(result);
1415 : :
1416 : : /* If we shifted all the bits out, return an all-zero string */
1417 [ + + ]: 464 : if (shft >= VARBITLEN(arg))
1418 : : {
1419 [ + - - + : 16 : MemSet(r, 0, VARBITBYTES(arg));
- - - - -
- ]
1420 : 16 : PG_RETURN_VARBIT_P(result);
1421 : : }
1422 : :
1423 : 448 : byte_shift = shft / BITS_PER_BYTE;
1424 : 448 : ishift = shft % BITS_PER_BYTE;
1425 : 448 : p = VARBITS(arg) + byte_shift;
1426 : :
1427 [ + + ]: 448 : if (ishift == 0)
1428 : : {
1429 : : /* Special case: we can do a memcpy */
1430 : 176 : len = VARBITBYTES(arg) - byte_shift;
1431 : 176 : memcpy(r, p, len);
1432 [ - + - - : 176 : MemSet(r + len, 0, byte_shift);
- - - - -
- ]
1433 : : }
1434 : : else
1435 : : {
1436 [ + + ]: 796 : for (; p < VARBITEND(arg); r++)
1437 : : {
1438 : 524 : *r = *p << ishift;
1439 [ + + ]: 524 : if ((++p) < VARBITEND(arg))
1440 : 252 : *r |= *p >> (BITS_PER_BYTE - ishift);
1441 : : }
1442 [ - + ]: 272 : for (; r < VARBITEND(result); r++)
1443 : 0 : *r = 0;
1444 : : }
1445 : :
1446 : : /* The pad bits should be already zero at this point */
1447 : :
1448 : 448 : PG_RETURN_VARBIT_P(result);
1449 : : }
1450 : :
1451 : : /*
1452 : : * bitshiftright
1453 : : * do a right shift (i.e. towards the end of the string)
1454 : : */
1455 : : Datum
1456 : 584 : bitshiftright(PG_FUNCTION_ARGS)
1457 : : {
1458 : 584 : VarBit *arg = PG_GETARG_VARBIT_P(0);
1459 : 584 : int32 shft = PG_GETARG_INT32(1);
1460 : : VarBit *result;
1461 : : int byte_shift,
1462 : : ishift,
1463 : : len;
1464 : : uint8 *p,
1465 : : *r;
1466 : :
1467 : : /* Negative shift is a shift to the left */
1468 [ - + ]: 584 : if (shft < 0)
1469 : : {
1470 : : /* Prevent integer overflow in negation */
1471 [ # # ]: 0 : if (shft < -VARBITMAXLEN)
1472 : 0 : shft = -VARBITMAXLEN;
1473 : 0 : PG_RETURN_DATUM(DirectFunctionCall2(bitshiftleft,
1474 : : VarBitPGetDatum(arg),
1475 : : Int32GetDatum(-shft)));
1476 : : }
1477 : :
1478 : 584 : result = (VarBit *) palloc(VARSIZE(arg));
1479 : 584 : SET_VARSIZE(result, VARSIZE(arg));
1480 : 584 : VARBITLEN(result) = VARBITLEN(arg);
1481 : 584 : r = VARBITS(result);
1482 : :
1483 : : /* If we shifted all the bits out, return an all-zero string */
1484 [ + + ]: 584 : if (shft >= VARBITLEN(arg))
1485 : : {
1486 [ + - - + : 16 : MemSet(r, 0, VARBITBYTES(arg));
- - - - -
- ]
1487 : 16 : PG_RETURN_VARBIT_P(result);
1488 : : }
1489 : :
1490 : 568 : byte_shift = shft / BITS_PER_BYTE;
1491 : 568 : ishift = shft % BITS_PER_BYTE;
1492 : 568 : p = VARBITS(arg);
1493 : :
1494 : : /* Set the first part of the result to 0 */
1495 [ + - + + : 568 : MemSet(r, 0, byte_shift);
+ - + - -
+ ]
1496 : 568 : r += byte_shift;
1497 : :
1498 [ + + ]: 568 : if (ishift == 0)
1499 : : {
1500 : : /* Special case: we can do a memcpy */
1501 : 240 : len = VARBITBYTES(arg) - byte_shift;
1502 : 240 : memcpy(r, p, len);
1503 : 240 : r += len;
1504 : : }
1505 : : else
1506 : : {
1507 [ + - ]: 328 : if (r < VARBITEND(result))
1508 : 328 : *r = 0; /* initialize first byte */
1509 [ + + ]: 952 : for (; r < VARBITEND(result); p++)
1510 : : {
1511 : 624 : *r |= *p >> ishift;
1512 [ + + ]: 624 : if ((++r) < VARBITEND(result))
1513 : 296 : *r = (*p << (BITS_PER_BYTE - ishift)) & BITMASK;
1514 : : }
1515 : : }
1516 : :
1517 : : /* We may have shifted 1's into the pad bits, so fix that */
1518 [ + + ]: 568 : VARBIT_PAD_LAST(result, r);
1519 : :
1520 : 568 : PG_RETURN_VARBIT_P(result);
1521 : : }
1522 : :
1523 : : /*
1524 : : * This is not defined in any standard. We retain the natural ordering of
1525 : : * bits here, as it just seems more intuitive.
1526 : : */
1527 : : Datum
1528 : 2044 : bitfromint4(PG_FUNCTION_ARGS)
1529 : : {
1530 : 2044 : int32 a = PG_GETARG_INT32(0);
1531 : 2044 : int32 typmod = PG_GETARG_INT32(1);
1532 : : VarBit *result;
1533 : : uint8 *r;
1534 : : int rlen;
1535 : : int destbitsleft,
1536 : : srcbitsleft;
1537 : :
1538 [ + - - + ]: 2044 : if (typmod <= 0 || typmod > VARBITMAXLEN)
1539 : 0 : typmod = 1; /* default bit length */
1540 : :
1541 : 2044 : rlen = VARBITTOTALLEN(typmod);
1542 : 2044 : result = (VarBit *) palloc(rlen);
1543 : 2044 : SET_VARSIZE(result, rlen);
1544 : 2044 : VARBITLEN(result) = typmod;
1545 : :
1546 : 2044 : r = VARBITS(result);
1547 : 2044 : destbitsleft = typmod;
1548 : 2044 : srcbitsleft = 32;
1549 : : /* drop any input bits that don't fit */
1550 : 2044 : srcbitsleft = Min(srcbitsleft, destbitsleft);
1551 : : /* sign-fill any excess bytes in output */
1552 [ - + ]: 2044 : while (destbitsleft >= srcbitsleft + 8)
1553 : : {
1554 [ # # ]: 0 : *r++ = (uint8) ((a < 0) ? BITMASK : 0);
1555 : 0 : destbitsleft -= 8;
1556 : : }
1557 : : /* store first fractional byte */
1558 [ - + ]: 2044 : if (destbitsleft > srcbitsleft)
1559 : : {
1560 : 0 : unsigned int val = (unsigned int) (a >> (destbitsleft - 8));
1561 : :
1562 : : /* Force sign-fill in case the compiler implements >> as zero-fill */
1563 [ # # ]: 0 : if (a < 0)
1564 : 0 : val |= ((unsigned int) -1) << (srcbitsleft + 8 - destbitsleft);
1565 : 0 : *r++ = (uint8) (val & BITMASK);
1566 : 0 : destbitsleft -= 8;
1567 : : }
1568 : : /* Now srcbitsleft and destbitsleft are the same, need not track both */
1569 : : /* store whole bytes */
1570 [ + + ]: 8000 : while (destbitsleft >= 8)
1571 : : {
1572 : 5956 : *r++ = (uint8) ((a >> (destbitsleft - 8)) & BITMASK);
1573 : 5956 : destbitsleft -= 8;
1574 : : }
1575 : : /* store last fractional byte */
1576 [ + + ]: 2044 : if (destbitsleft > 0)
1577 : 445 : *r = (uint8) ((a << (8 - destbitsleft)) & BITMASK);
1578 : :
1579 : 2044 : PG_RETURN_VARBIT_P(result);
1580 : : }
1581 : :
1582 : : Datum
1583 : 1309 : bittoint4(PG_FUNCTION_ARGS)
1584 : : {
1585 : 1309 : VarBit *arg = PG_GETARG_VARBIT_P(0);
1586 : : uint32 result;
1587 : : uint8 *r;
1588 : :
1589 : : /* Check that the bit string is not too long */
1590 [ - + ]: 1309 : if (VARBITLEN(arg) > sizeof(result) * BITS_PER_BYTE)
1591 [ # # ]: 0 : ereturn(fcinfo->context, (Datum) 0,
1592 : : (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
1593 : : errmsg("integer out of range")));
1594 : :
1595 : 1309 : result = 0;
1596 [ + + ]: 6355 : for (r = VARBITS(arg); r < VARBITEND(arg); r++)
1597 : : {
1598 : 5046 : result <<= BITS_PER_BYTE;
1599 : 5046 : result |= *r;
1600 : : }
1601 : : /* Now shift the result to take account of the padding at the end */
1602 : 1309 : result >>= VARBITPAD(arg);
1603 : :
1604 : 1309 : PG_RETURN_INT32(result);
1605 : : }
1606 : :
1607 : : Datum
1608 : 1164 : bitfromint8(PG_FUNCTION_ARGS)
1609 : : {
1610 : 1164 : int64 a = PG_GETARG_INT64(0);
1611 : 1164 : int32 typmod = PG_GETARG_INT32(1);
1612 : : VarBit *result;
1613 : : uint8 *r;
1614 : : int rlen;
1615 : : int destbitsleft,
1616 : : srcbitsleft;
1617 : :
1618 [ + - - + ]: 1164 : if (typmod <= 0 || typmod > VARBITMAXLEN)
1619 : 0 : typmod = 1; /* default bit length */
1620 : :
1621 : 1164 : rlen = VARBITTOTALLEN(typmod);
1622 : 1164 : result = (VarBit *) palloc(rlen);
1623 : 1164 : SET_VARSIZE(result, rlen);
1624 : 1164 : VARBITLEN(result) = typmod;
1625 : :
1626 : 1164 : r = VARBITS(result);
1627 : 1164 : destbitsleft = typmod;
1628 : 1164 : srcbitsleft = 64;
1629 : : /* drop any input bits that don't fit */
1630 : 1164 : srcbitsleft = Min(srcbitsleft, destbitsleft);
1631 : : /* sign-fill any excess bytes in output */
1632 [ - + ]: 1164 : while (destbitsleft >= srcbitsleft + 8)
1633 : : {
1634 [ # # ]: 0 : *r++ = (uint8) ((a < 0) ? BITMASK : 0);
1635 : 0 : destbitsleft -= 8;
1636 : : }
1637 : : /* store first fractional byte */
1638 [ - + ]: 1164 : if (destbitsleft > srcbitsleft)
1639 : : {
1640 : 0 : unsigned int val = (unsigned int) (a >> (destbitsleft - 8));
1641 : :
1642 : : /* Force sign-fill in case the compiler implements >> as zero-fill */
1643 [ # # ]: 0 : if (a < 0)
1644 : 0 : val |= ((unsigned int) -1) << (srcbitsleft + 8 - destbitsleft);
1645 : 0 : *r++ = (uint8) (val & BITMASK);
1646 : 0 : destbitsleft -= 8;
1647 : : }
1648 : : /* Now srcbitsleft and destbitsleft are the same, need not track both */
1649 : : /* store whole bytes */
1650 [ + + ]: 5820 : while (destbitsleft >= 8)
1651 : : {
1652 : 4656 : *r++ = (uint8) ((a >> (destbitsleft - 8)) & BITMASK);
1653 : 4656 : destbitsleft -= 8;
1654 : : }
1655 : : /* store last fractional byte */
1656 [ - + ]: 1164 : if (destbitsleft > 0)
1657 : 0 : *r = (uint8) ((a << (8 - destbitsleft)) & BITMASK);
1658 : :
1659 : 1164 : PG_RETURN_VARBIT_P(result);
1660 : : }
1661 : :
1662 : : Datum
1663 : 912 : bittoint8(PG_FUNCTION_ARGS)
1664 : : {
1665 : 912 : VarBit *arg = PG_GETARG_VARBIT_P(0);
1666 : : uint64 result;
1667 : : uint8 *r;
1668 : :
1669 : : /* Check that the bit string is not too long */
1670 [ - + ]: 912 : if (VARBITLEN(arg) > sizeof(result) * BITS_PER_BYTE)
1671 [ # # ]: 0 : ereturn(fcinfo->context, (Datum) 0,
1672 : : (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
1673 : : errmsg("bigint out of range")));
1674 : :
1675 : 912 : result = 0;
1676 [ + + ]: 8208 : for (r = VARBITS(arg); r < VARBITEND(arg); r++)
1677 : : {
1678 : 7296 : result <<= BITS_PER_BYTE;
1679 : 7296 : result |= *r;
1680 : : }
1681 : : /* Now shift the result to take account of the padding at the end */
1682 : 912 : result >>= VARBITPAD(arg);
1683 : :
1684 : 912 : PG_RETURN_INT64(result);
1685 : : }
1686 : :
1687 : :
1688 : : /*
1689 : : * Determines the position of S2 in the bitstring S1 (1-based string).
1690 : : * If S2 does not appear in S1 this function returns 0.
1691 : : * If S2 is of length 0 this function returns 1.
1692 : : * Compatible in usage with POSITION() functions for other data types.
1693 : : */
1694 : : Datum
1695 : 446 : bitposition(PG_FUNCTION_ARGS)
1696 : : {
1697 : 446 : VarBit *str = PG_GETARG_VARBIT_P(0);
1698 : 446 : VarBit *substr = PG_GETARG_VARBIT_P(1);
1699 : : int substr_length,
1700 : : str_length,
1701 : : is;
1702 : : uint8 *s, /* pointer into substring */
1703 : : *p; /* pointer into str */
1704 : : uint8 cmp, /* shifted substring byte to compare */
1705 : : mask1, /* mask for substring byte shifted right */
1706 : : mask2, /* mask for substring byte shifted left */
1707 : : end_mask, /* pad mask for last substring byte */
1708 : : str_mask; /* pad mask for last string byte */
1709 : : bool is_match;
1710 : :
1711 : : /* Get the substring length */
1712 : 446 : substr_length = VARBITLEN(substr);
1713 : 446 : str_length = VARBITLEN(str);
1714 : :
1715 : : /* String has zero length or substring longer than string, return 0 */
1716 [ + + + + ]: 446 : if ((str_length == 0) || (substr_length > str_length))
1717 : 20 : PG_RETURN_INT32(0);
1718 : :
1719 : : /* zero-length substring means return 1 */
1720 [ + + ]: 426 : if (substr_length == 0)
1721 : 5 : PG_RETURN_INT32(1);
1722 : :
1723 : : /* Initialise the padding masks */
1724 : 421 : end_mask = BITMASK << VARBITPAD(substr);
1725 : 421 : str_mask = BITMASK << VARBITPAD(str);
1726 [ + + ]: 677 : for (size_t i = 0; i < VARBITBYTES(str) - VARBITBYTES(substr) + 1; i++)
1727 : : {
1728 [ + + ]: 3688 : for (is = 0; is < BITS_PER_BYTE; is++)
1729 : : {
1730 : 3432 : is_match = true;
1731 : 3432 : p = VARBITS(str) + i;
1732 : 3432 : mask1 = BITMASK >> is;
1733 : 3432 : mask2 = ~mask1;
1734 : 3432 : for (s = VARBITS(substr);
1735 [ + + + + ]: 3865 : is_match && s < VARBITEND(substr); s++)
1736 : : {
1737 : 3607 : cmp = *s >> is;
1738 [ + + ]: 3607 : if (s == VARBITEND(substr) - 1)
1739 : : {
1740 : 2592 : mask1 &= end_mask >> is;
1741 [ + + ]: 2592 : if (p == VARBITEND(str) - 1)
1742 : : {
1743 : : /* Check that there is enough of str left */
1744 [ + + ]: 704 : if (mask1 & ~str_mask)
1745 : : {
1746 : 50 : is_match = false;
1747 : 50 : break;
1748 : : }
1749 : 654 : mask1 &= str_mask;
1750 : : }
1751 : : }
1752 : 3557 : is_match = ((cmp ^ *p) & mask1) == 0;
1753 [ + + ]: 3557 : if (!is_match)
1754 : 2889 : break;
1755 : : /* Move on to the next byte */
1756 : 668 : p++;
1757 [ + + ]: 668 : if (p == VARBITEND(str))
1758 : : {
1759 : 235 : mask2 = end_mask << (BITS_PER_BYTE - is);
1760 : 235 : is_match = mask2 == 0;
1761 : : #if 0
1762 : : elog(DEBUG4, "S. %d %d em=%2x sm=%2x r=%d",
1763 : : i, is, end_mask, mask2, is_match);
1764 : : #endif
1765 : 235 : break;
1766 : : }
1767 : 433 : cmp = *s << (BITS_PER_BYTE - is);
1768 [ + + ]: 433 : if (s == VARBITEND(substr) - 1)
1769 : : {
1770 : 163 : mask2 &= end_mask << (BITS_PER_BYTE - is);
1771 [ + + ]: 163 : if (p == VARBITEND(str) - 1)
1772 : : {
1773 [ - + ]: 158 : if (mask2 & ~str_mask)
1774 : : {
1775 : 0 : is_match = false;
1776 : 0 : break;
1777 : : }
1778 : 158 : mask2 &= str_mask;
1779 : : }
1780 : : }
1781 : 433 : is_match = ((cmp ^ *p) & mask2) == 0;
1782 : : }
1783 : : /* Have we found a match? */
1784 [ + + ]: 3432 : if (is_match)
1785 : 348 : PG_RETURN_INT32(i * BITS_PER_BYTE + is + 1);
1786 : : }
1787 : : }
1788 : 73 : PG_RETURN_INT32(0);
1789 : : }
1790 : :
1791 : :
1792 : : /*
1793 : : * bitsetbit
1794 : : *
1795 : : * Given an instance of type 'bit' creates a new one with
1796 : : * the Nth bit set to the given value.
1797 : : *
1798 : : * The bit location is specified left-to-right in a zero-based fashion
1799 : : * consistent with the other get_bit and set_bit functions, but
1800 : : * inconsistent with the standard substring, position, overlay functions
1801 : : */
1802 : : Datum
1803 : 9 : bitsetbit(PG_FUNCTION_ARGS)
1804 : : {
1805 : 9 : VarBit *arg1 = PG_GETARG_VARBIT_P(0);
1806 : 9 : int32 n = PG_GETARG_INT32(1);
1807 : 9 : int32 newBit = PG_GETARG_INT32(2);
1808 : : VarBit *result;
1809 : : int len,
1810 : : bitlen;
1811 : : uint8 *r,
1812 : : *p;
1813 : : int byteNo,
1814 : : bitNo;
1815 : :
1816 : 9 : bitlen = VARBITLEN(arg1);
1817 [ + - + + ]: 9 : if (n < 0 || n >= bitlen)
1818 [ + - ]: 4 : ereport(ERROR,
1819 : : (errcode(ERRCODE_ARRAY_SUBSCRIPT_ERROR),
1820 : : errmsg("bit index %d out of valid range (0..%d)",
1821 : : n, bitlen - 1)));
1822 : :
1823 : : /*
1824 : : * sanity check!
1825 : : */
1826 [ + - - + ]: 5 : if (newBit != 0 && newBit != 1)
1827 [ # # ]: 0 : ereport(ERROR,
1828 : : (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
1829 : : errmsg("new bit must be 0 or 1")));
1830 : :
1831 : 5 : len = VARSIZE(arg1);
1832 : 5 : result = (VarBit *) palloc(len);
1833 : 5 : SET_VARSIZE(result, len);
1834 : 5 : VARBITLEN(result) = bitlen;
1835 : :
1836 : 5 : p = VARBITS(arg1);
1837 : 5 : r = VARBITS(result);
1838 : :
1839 : 5 : memcpy(r, p, VARBITBYTES(arg1));
1840 : :
1841 : 5 : byteNo = n / BITS_PER_BYTE;
1842 : 5 : bitNo = BITS_PER_BYTE - 1 - (n % BITS_PER_BYTE);
1843 : :
1844 : : /*
1845 : : * Update the byte.
1846 : : */
1847 [ - + ]: 5 : if (newBit == 0)
1848 : 0 : r[byteNo] &= (~(1 << bitNo));
1849 : : else
1850 : 5 : r[byteNo] |= (1 << bitNo);
1851 : :
1852 : 5 : PG_RETURN_VARBIT_P(result);
1853 : : }
1854 : :
1855 : : /*
1856 : : * bitgetbit
1857 : : *
1858 : : * returns the value of the Nth bit of a bit array (0 or 1).
1859 : : *
1860 : : * The bit location is specified left-to-right in a zero-based fashion
1861 : : * consistent with the other get_bit and set_bit functions, but
1862 : : * inconsistent with the standard substring, position, overlay functions
1863 : : */
1864 : : Datum
1865 : 5 : bitgetbit(PG_FUNCTION_ARGS)
1866 : : {
1867 : 5 : VarBit *arg1 = PG_GETARG_VARBIT_P(0);
1868 : 5 : int32 n = PG_GETARG_INT32(1);
1869 : : int bitlen;
1870 : : uint8 *p;
1871 : : int byteNo,
1872 : : bitNo;
1873 : :
1874 : 5 : bitlen = VARBITLEN(arg1);
1875 [ + - - + ]: 5 : if (n < 0 || n >= bitlen)
1876 [ # # ]: 0 : ereport(ERROR,
1877 : : (errcode(ERRCODE_ARRAY_SUBSCRIPT_ERROR),
1878 : : errmsg("bit index %d out of valid range (0..%d)",
1879 : : n, bitlen - 1)));
1880 : :
1881 : 5 : p = VARBITS(arg1);
1882 : :
1883 : 5 : byteNo = n / BITS_PER_BYTE;
1884 : 5 : bitNo = BITS_PER_BYTE - 1 - (n % BITS_PER_BYTE);
1885 : :
1886 [ + - ]: 5 : if (p[byteNo] & (1 << bitNo))
1887 : 5 : PG_RETURN_INT32(1);
1888 : : else
1889 : 0 : PG_RETURN_INT32(0);
1890 : : }
|