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 : 320 : anybit_typmodin(ArrayType *ta, const char *typename)
91 : : {
92 : 320 : int32 typmod;
93 : 320 : int32 *tl;
94 : 320 : int n;
95 : :
96 : 320 : 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 [ + - ]: 320 : if (n != 1)
103 [ # # # # ]: 0 : ereport(ERROR,
104 : : (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
105 : : errmsg("invalid type modifier")));
106 : :
107 [ + - ]: 320 : 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 [ + - ]: 320 : 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 : 320 : typmod = *tl;
119 : :
120 : 640 : return typmod;
121 : 320 : }
122 : :
123 : : /*
124 : : * common code for bittypmodout and varbittypmodout
125 : : */
126 : : static char *
127 : 35 : anybit_typmodout(int32 typmod)
128 : : {
129 : 35 : char *res = (char *) palloc(64);
130 : :
131 [ + - ]: 35 : if (typmod >= 0)
132 : 35 : snprintf(res, 64, "(%d)", typmod);
133 : : else
134 : 0 : *res = '\0';
135 : :
136 : 70 : return res;
137 : 35 : }
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 : 733 : bit_in(PG_FUNCTION_ARGS)
148 : : {
149 : 733 : char *input_string = PG_GETARG_CSTRING(0);
150 : : #ifdef NOT_USED
151 : : Oid typelem = PG_GETARG_OID(1);
152 : : #endif
153 : 733 : int32 atttypmod = PG_GETARG_INT32(2);
154 : 733 : Node *escontext = fcinfo->context;
155 : 733 : VarBit *result; /* The resulting bit string */
156 : 733 : char *sp; /* pointer into the character string */
157 : 733 : bits8 *r; /* pointer into the result */
158 : 733 : 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 : 733 : bool bit_not_hex; /* false = hex string true = bit string */
162 : 733 : int bc;
163 : 733 : bits8 x = 0;
164 : :
165 : : /* Check that the first character is a b or an x */
166 [ + + + + ]: 733 : if (input_string[0] == 'b' || input_string[0] == 'B')
167 : : {
168 : 127 : bit_not_hex = true;
169 : 127 : sp = input_string + 1;
170 : 127 : }
171 [ + + + + ]: 606 : else if (input_string[0] == 'x' || input_string[0] == 'X')
172 : : {
173 : 567 : bit_not_hex = false;
174 : 567 : sp = input_string + 1;
175 : 567 : }
176 : : else
177 : : {
178 : : /*
179 : : * Otherwise it's binary. This allows things like cast('1001' as bit)
180 : : * to work transparently.
181 : : */
182 : 39 : bit_not_hex = true;
183 : 39 : 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 : 733 : slen = strlen(sp);
191 [ + + ]: 733 : if (bit_not_hex)
192 : 166 : bitlen = slen;
193 : : else
194 : : {
195 [ + - ]: 567 : 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 : 567 : 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 [ + + ]: 733 : if (atttypmod <= 0)
208 : 703 : atttypmod = bitlen;
209 [ + + ]: 30 : else if (bitlen != atttypmod)
210 [ + + ]: 3 : 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 : 730 : len = VARBITTOTALLEN(atttypmod);
216 : : /* set to 0 so that *r is always initialised and string is zero-padded */
217 : 730 : result = (VarBit *) palloc0(len);
218 : 730 : SET_VARSIZE(result, len);
219 : 730 : VARBITLEN(result) = atttypmod;
220 : :
221 : 730 : r = VARBITS(result);
222 [ + + ]: 730 : 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 : 163 : x = HIGHBIT;
227 [ + + ]: 3836 : for (; *sp; sp++)
228 : : {
229 [ + + ]: 3677 : if (*sp == '1')
230 : 1944 : *r |= x;
231 [ + + ]: 1733 : else if (*sp != '0')
232 [ + + ]: 4 : ereturn(escontext, (Datum) 0,
233 : : (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
234 : : errmsg("\"%.*s\" is not a valid binary digit",
235 : : pg_mblen(sp), sp)));
236 : :
237 : 3673 : x >>= 1;
238 [ + + ]: 3673 : if (x == 0)
239 : : {
240 : 408 : x = HIGHBIT;
241 : 408 : r++;
242 : 408 : }
243 : 3673 : }
244 : 159 : }
245 : : else
246 : : {
247 : : /* Parse the hex representation of the string */
248 [ + + ]: 6716 : for (bc = 0; *sp; sp++)
249 : : {
250 [ + + + + ]: 6153 : if (*sp >= '0' && *sp <= '9')
251 : 4234 : x = (bits8) (*sp - '0');
252 [ + + + + ]: 1919 : else if (*sp >= 'A' && *sp <= 'F')
253 : 23 : x = (bits8) (*sp - 'A') + 10;
254 [ + + + - ]: 1896 : else if (*sp >= 'a' && *sp <= 'f')
255 : 1892 : x = (bits8) (*sp - 'a') + 10;
256 : : else
257 [ + + ]: 4 : ereturn(escontext, (Datum) 0,
258 : : (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
259 : : errmsg("\"%.*s\" is not a valid hexadecimal digit",
260 : : pg_mblen(sp), sp)));
261 : :
262 [ + + ]: 6149 : if (bc)
263 : : {
264 : 3056 : *r++ |= x;
265 : 3056 : bc = 0;
266 : 3056 : }
267 : : else
268 : : {
269 : 3093 : *r = x << 4;
270 : 3093 : bc = 1;
271 : : }
272 : 6149 : }
273 : : }
274 : :
275 : 722 : PG_RETURN_VARBIT_P(result);
276 : 731 : }
277 : :
278 : :
279 : : Datum
280 : 539 : bit_out(PG_FUNCTION_ARGS)
281 : : {
282 : : #if 1
283 : : /* same as varbit output */
284 : 539 : 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 : : bits8 *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 : 0 : VarBit *result;
340 : 0 : 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 : 0 : }
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 : 158 : bit(PG_FUNCTION_ARGS)
392 : : {
393 : 158 : VarBit *arg = PG_GETARG_VARBIT_P(0);
394 : 158 : int32 len = PG_GETARG_INT32(1);
395 : 158 : bool isExplicit = PG_GETARG_BOOL(2);
396 : 158 : VarBit *result;
397 : 158 : int rlen;
398 : :
399 : : /* No work if typmod is invalid or supplied data matches it already */
400 [ + - + - : 158 : if (len <= 0 || len > VARBITMAXLEN || len == VARBITLEN(arg))
+ + ]
401 : 58 : PG_RETURN_VARBIT_P(arg);
402 : :
403 [ + + ]: 100 : if (!isExplicit)
404 [ + - + - ]: 3 : ereport(ERROR,
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 : 97 : rlen = VARBITTOTALLEN(len);
410 : : /* set to 0 so that string is zero-padded */
411 : 97 : result = (VarBit *) palloc0(rlen);
412 : 97 : SET_VARSIZE(result, rlen);
413 : 97 : VARBITLEN(result) = len;
414 : :
415 [ - + ]: 97 : memcpy(VARBITS(result), VARBITS(arg),
416 : : 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 [ + - - + ]: 97 : VARBIT_PAD(result);
424 : :
425 : 97 : PG_RETURN_VARBIT_P(result);
426 : 155 : }
427 : :
428 : : Datum
429 : 281 : bittypmodin(PG_FUNCTION_ARGS)
430 : : {
431 : 281 : ArrayType *ta = PG_GETARG_ARRAYTYPE_P(0);
432 : :
433 : 562 : PG_RETURN_INT32(anybit_typmodin(ta, "bit"));
434 : 281 : }
435 : :
436 : : Datum
437 : 18 : bittypmodout(PG_FUNCTION_ARGS)
438 : : {
439 : 18 : int32 typmod = PG_GETARG_INT32(0);
440 : :
441 : 36 : PG_RETURN_CSTRING(anybit_typmodout(typmod));
442 : 18 : }
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 : 101 : varbit_in(PG_FUNCTION_ARGS)
453 : : {
454 : 101 : char *input_string = PG_GETARG_CSTRING(0);
455 : : #ifdef NOT_USED
456 : : Oid typelem = PG_GETARG_OID(1);
457 : : #endif
458 : 101 : int32 atttypmod = PG_GETARG_INT32(2);
459 : 101 : Node *escontext = fcinfo->context;
460 : 101 : VarBit *result; /* The resulting bit string */
461 : 101 : char *sp; /* pointer into the character string */
462 : 101 : bits8 *r; /* pointer into the result */
463 : 101 : 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 : 101 : bool bit_not_hex; /* false = hex string true = bit string */
467 : 101 : int bc;
468 : 101 : bits8 x = 0;
469 : :
470 : : /* Check that the first character is a b or an x */
471 [ + - - + ]: 101 : if (input_string[0] == 'b' || input_string[0] == 'B')
472 : : {
473 : 0 : bit_not_hex = true;
474 : 0 : sp = input_string + 1;
475 : 0 : }
476 [ + + + + ]: 101 : else if (input_string[0] == 'x' || input_string[0] == 'X')
477 : : {
478 : 22 : bit_not_hex = false;
479 : 22 : sp = input_string + 1;
480 : 22 : }
481 : : else
482 : : {
483 : 79 : bit_not_hex = true;
484 : 79 : 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 : 101 : slen = strlen(sp);
492 [ + + ]: 101 : if (bit_not_hex)
493 : 79 : bitlen = slen;
494 : : else
495 : : {
496 [ + - ]: 22 : 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 : 22 : 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 [ + + ]: 101 : if (atttypmod <= 0)
509 : 79 : atttypmod = bitlen;
510 [ + + ]: 22 : else if (bitlen > atttypmod)
511 [ + - ]: 2 : 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 : 99 : len = VARBITTOTALLEN(bitlen);
517 : : /* set to 0 so that *r is always initialised and string is zero-padded */
518 : 99 : result = (VarBit *) palloc0(len);
519 : 99 : SET_VARSIZE(result, len);
520 [ + + ]: 99 : VARBITLEN(result) = Min(bitlen, atttypmod);
521 : :
522 : 99 : r = VARBITS(result);
523 [ + + ]: 99 : 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 : 77 : x = HIGHBIT;
528 [ + + ]: 545 : for (; *sp; sp++)
529 : : {
530 [ + + ]: 470 : if (*sp == '1')
531 : 225 : *r |= x;
532 [ + + ]: 245 : else if (*sp != '0')
533 [ + + ]: 2 : ereturn(escontext, (Datum) 0,
534 : : (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
535 : : errmsg("\"%.*s\" is not a valid binary digit",
536 : : pg_mblen(sp), sp)));
537 : :
538 : 468 : x >>= 1;
539 [ + + ]: 468 : if (x == 0)
540 : : {
541 : 43 : x = HIGHBIT;
542 : 43 : r++;
543 : 43 : }
544 : 468 : }
545 : 75 : }
546 : : else
547 : : {
548 : : /* Parse the hex representation of the string */
549 [ + + ]: 92 : for (bc = 0; *sp; sp++)
550 : : {
551 [ + - + + ]: 72 : if (*sp >= '0' && *sp <= '9')
552 : 53 : x = (bits8) (*sp - '0');
553 [ + - + + ]: 19 : else if (*sp >= 'A' && *sp <= 'F')
554 : 17 : x = (bits8) (*sp - 'A') + 10;
555 [ - + # # ]: 2 : else if (*sp >= 'a' && *sp <= 'f')
556 : 0 : x = (bits8) (*sp - 'a') + 10;
557 : : else
558 [ + + ]: 2 : ereturn(escontext, (Datum) 0,
559 : : (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
560 : : errmsg("\"%.*s\" is not a valid hexadecimal digit",
561 : : pg_mblen(sp), sp)));
562 : :
563 [ + + ]: 70 : if (bc)
564 : : {
565 : 34 : *r++ |= x;
566 : 34 : bc = 0;
567 : 34 : }
568 : : else
569 : : {
570 : 36 : *r = x << 4;
571 : 36 : bc = 1;
572 : : }
573 : 70 : }
574 : : }
575 : :
576 : 95 : PG_RETURN_VARBIT_P(result);
577 : 101 : }
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 : 715 : varbit_out(PG_FUNCTION_ARGS)
588 : : {
589 : 715 : VarBit *s = PG_GETARG_VARBIT_P(0);
590 : 715 : char *result,
591 : : *r;
592 : 715 : bits8 *sp;
593 : 715 : bits8 x;
594 : 715 : int i,
595 : : k,
596 : : len;
597 : :
598 : : /* Assertion to help catch any bit functions that don't pad correctly */
599 [ + - + + : 715 : VARBIT_CORRECTLY_PADDED(s);
+ - ]
600 : :
601 : 715 : len = VARBITLEN(s);
602 : 715 : result = (char *) palloc(len + 1);
603 : 715 : sp = VARBITS(s);
604 : 715 : r = result;
605 [ + + ]: 1679 : for (i = 0; i <= len - BITS_PER_BYTE; i += BITS_PER_BYTE, sp++)
606 : : {
607 : : /* print full bytes */
608 : 964 : x = *sp;
609 [ + + ]: 8676 : for (k = 0; k < BITS_PER_BYTE; k++)
610 : : {
611 : 7712 : *r++ = IS_HIGHBIT_SET(x) ? '1' : '0';
612 : 7712 : x <<= 1;
613 : 7712 : }
614 : 964 : }
615 [ + + ]: 715 : if (i < len)
616 : : {
617 : : /* print the last partial byte */
618 : 318 : x = *sp;
619 [ + + ]: 1794 : for (k = i; k < len; k++)
620 : : {
621 : 1476 : *r++ = IS_HIGHBIT_SET(x) ? '1' : '0';
622 : 1476 : x <<= 1;
623 : 1476 : }
624 : 318 : }
625 : 715 : *r = '\0';
626 : :
627 : 1430 : PG_RETURN_CSTRING(result);
628 : 715 : }
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 : 0 : VarBit *result;
645 : 0 : 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 : 0 : }
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 : 0 : 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 : 0 : }
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 : 20 : varbit_support(PG_FUNCTION_ARGS)
703 : : {
704 : 20 : Node *rawreq = (Node *) PG_GETARG_POINTER(0);
705 : 20 : Node *ret = NULL;
706 : :
707 [ + + ]: 20 : if (IsA(rawreq, SupportRequestSimplify))
708 : : {
709 : 10 : SupportRequestSimplify *req = (SupportRequestSimplify *) rawreq;
710 : 10 : FuncExpr *expr = req->fcall;
711 : 10 : Node *typmod;
712 : :
713 [ + - ]: 10 : Assert(list_length(expr->args) >= 2);
714 : :
715 : 10 : typmod = (Node *) lsecond(expr->args);
716 : :
717 [ + - - + ]: 10 : if (IsA(typmod, Const) && !((Const *) typmod)->constisnull)
718 : : {
719 : 10 : Node *source = (Node *) linitial(expr->args);
720 : 10 : int32 new_typmod = DatumGetInt32(((Const *) typmod)->constvalue);
721 : 10 : int32 old_max = exprTypmod(source);
722 : 10 : int32 new_max = new_typmod;
723 : :
724 : : /* Note: varbit() treats typmod 0 as invalid, so we do too */
725 [ + - - + : 10 : if (new_max <= 0 || (old_max > 0 && old_max <= new_max))
# # ]
726 : 0 : ret = relabel_to_typmod(source, new_typmod);
727 : 10 : }
728 : 10 : }
729 : :
730 : 40 : PG_RETURN_POINTER(ret);
731 : 20 : }
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 : 166 : varbit(PG_FUNCTION_ARGS)
743 : : {
744 : 166 : VarBit *arg = PG_GETARG_VARBIT_P(0);
745 : 166 : int32 len = PG_GETARG_INT32(1);
746 : 166 : bool isExplicit = PG_GETARG_BOOL(2);
747 : 166 : VarBit *result;
748 : 166 : int rlen;
749 : :
750 : : /* No work if typmod is invalid or supplied data matches it already */
751 [ + - + + ]: 166 : if (len <= 0 || len >= VARBITLEN(arg))
752 : 164 : PG_RETURN_VARBIT_P(arg);
753 : :
754 [ - + ]: 2 : if (!isExplicit)
755 [ + - + - ]: 2 : ereport(ERROR,
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 : 164 : }
772 : :
773 : : Datum
774 : 39 : varbittypmodin(PG_FUNCTION_ARGS)
775 : : {
776 : 39 : ArrayType *ta = PG_GETARG_ARRAYTYPE_P(0);
777 : :
778 : 78 : PG_RETURN_INT32(anybit_typmodin(ta, "varbit"));
779 : 39 : }
780 : :
781 : : Datum
782 : 17 : varbittypmodout(PG_FUNCTION_ARGS)
783 : : {
784 : 17 : int32 typmod = PG_GETARG_INT32(0);
785 : :
786 : 34 : PG_RETURN_CSTRING(anybit_typmodout(typmod));
787 : 17 : }
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 : 4232 : bit_cmp(VarBit *arg1, VarBit *arg2)
819 : : {
820 : 4232 : int bitlen1,
821 : : bytelen1,
822 : : bitlen2,
823 : : bytelen2;
824 : 4232 : int32 cmp;
825 : :
826 : 4232 : bytelen1 = VARBITBYTES(arg1);
827 : 4232 : bytelen2 = VARBITBYTES(arg2);
828 : :
829 [ + + ]: 4232 : cmp = memcmp(VARBITS(arg1), VARBITS(arg2), Min(bytelen1, bytelen2));
830 [ + + ]: 4232 : if (cmp == 0)
831 : : {
832 : 1019 : bitlen1 = VARBITLEN(arg1);
833 : 1019 : bitlen2 = VARBITLEN(arg2);
834 [ + + ]: 1019 : if (bitlen1 != bitlen2)
835 : 3 : cmp = (bitlen1 < bitlen2) ? -1 : 1;
836 : 1019 : }
837 : 8464 : return cmp;
838 : 4232 : }
839 : :
840 : : Datum
841 : 385 : biteq(PG_FUNCTION_ARGS)
842 : : {
843 : 385 : VarBit *arg1 = PG_GETARG_VARBIT_P(0);
844 : 385 : VarBit *arg2 = PG_GETARG_VARBIT_P(1);
845 : 385 : bool result;
846 : 385 : int bitlen1,
847 : : bitlen2;
848 : :
849 : 385 : bitlen1 = VARBITLEN(arg1);
850 : 385 : bitlen2 = VARBITLEN(arg2);
851 : :
852 : : /* fast path for different-length inputs */
853 [ - + ]: 385 : if (bitlen1 != bitlen2)
854 : 0 : result = false;
855 : : else
856 : 385 : result = (bit_cmp(arg1, arg2) == 0);
857 : :
858 [ + + ]: 385 : PG_FREE_IF_COPY(arg1, 0);
859 [ + + ]: 385 : PG_FREE_IF_COPY(arg2, 1);
860 : :
861 : 770 : PG_RETURN_BOOL(result);
862 : 385 : }
863 : :
864 : : Datum
865 : 162 : bitne(PG_FUNCTION_ARGS)
866 : : {
867 : 162 : VarBit *arg1 = PG_GETARG_VARBIT_P(0);
868 : 162 : VarBit *arg2 = PG_GETARG_VARBIT_P(1);
869 : 162 : bool result;
870 : 162 : int bitlen1,
871 : : bitlen2;
872 : :
873 : 162 : bitlen1 = VARBITLEN(arg1);
874 : 162 : bitlen2 = VARBITLEN(arg2);
875 : :
876 : : /* fast path for different-length inputs */
877 [ + + ]: 162 : if (bitlen1 != bitlen2)
878 : 1 : result = true;
879 : : else
880 : 161 : result = (bit_cmp(arg1, arg2) != 0);
881 : :
882 [ + + ]: 162 : PG_FREE_IF_COPY(arg1, 0);
883 [ + + ]: 162 : PG_FREE_IF_COPY(arg2, 1);
884 : :
885 : 324 : PG_RETURN_BOOL(result);
886 : 162 : }
887 : :
888 : : Datum
889 : 1040 : bitlt(PG_FUNCTION_ARGS)
890 : : {
891 : 1040 : VarBit *arg1 = PG_GETARG_VARBIT_P(0);
892 : 1040 : VarBit *arg2 = PG_GETARG_VARBIT_P(1);
893 : 1040 : bool result;
894 : :
895 : 1040 : result = (bit_cmp(arg1, arg2) < 0);
896 : :
897 [ - + ]: 1040 : PG_FREE_IF_COPY(arg1, 0);
898 [ + + ]: 1040 : PG_FREE_IF_COPY(arg2, 1);
899 : :
900 : 2080 : PG_RETURN_BOOL(result);
901 : 1040 : }
902 : :
903 : : Datum
904 : 820 : bitle(PG_FUNCTION_ARGS)
905 : : {
906 : 820 : VarBit *arg1 = PG_GETARG_VARBIT_P(0);
907 : 820 : VarBit *arg2 = PG_GETARG_VARBIT_P(1);
908 : 820 : bool result;
909 : :
910 : 820 : result = (bit_cmp(arg1, arg2) <= 0);
911 : :
912 [ - + ]: 820 : PG_FREE_IF_COPY(arg1, 0);
913 [ + + ]: 820 : PG_FREE_IF_COPY(arg2, 1);
914 : :
915 : 1640 : PG_RETURN_BOOL(result);
916 : 820 : }
917 : :
918 : : Datum
919 : 1040 : bitgt(PG_FUNCTION_ARGS)
920 : : {
921 : 1040 : VarBit *arg1 = PG_GETARG_VARBIT_P(0);
922 : 1040 : VarBit *arg2 = PG_GETARG_VARBIT_P(1);
923 : 1040 : bool result;
924 : :
925 : 1040 : result = (bit_cmp(arg1, arg2) > 0);
926 : :
927 [ - + ]: 1040 : PG_FREE_IF_COPY(arg1, 0);
928 [ + + ]: 1040 : PG_FREE_IF_COPY(arg2, 1);
929 : :
930 : 2080 : PG_RETURN_BOOL(result);
931 : 1040 : }
932 : :
933 : : Datum
934 : 696 : bitge(PG_FUNCTION_ARGS)
935 : : {
936 : 696 : VarBit *arg1 = PG_GETARG_VARBIT_P(0);
937 : 696 : VarBit *arg2 = PG_GETARG_VARBIT_P(1);
938 : 696 : bool result;
939 : :
940 : 696 : result = (bit_cmp(arg1, arg2) >= 0);
941 : :
942 [ - + ]: 696 : PG_FREE_IF_COPY(arg1, 0);
943 [ + + ]: 696 : PG_FREE_IF_COPY(arg2, 1);
944 : :
945 : 1392 : PG_RETURN_BOOL(result);
946 : 696 : }
947 : :
948 : : Datum
949 : 90 : bitcmp(PG_FUNCTION_ARGS)
950 : : {
951 : 90 : VarBit *arg1 = PG_GETARG_VARBIT_P(0);
952 : 90 : VarBit *arg2 = PG_GETARG_VARBIT_P(1);
953 : 90 : int32 result;
954 : :
955 : 90 : result = bit_cmp(arg1, arg2);
956 : :
957 [ + + ]: 90 : PG_FREE_IF_COPY(arg1, 0);
958 [ + + ]: 90 : PG_FREE_IF_COPY(arg2, 1);
959 : :
960 : 180 : PG_RETURN_INT32(result);
961 : 90 : }
962 : :
963 : : /*
964 : : * bitcat
965 : : * Concatenation of bit strings
966 : : */
967 : : Datum
968 : 27 : bitcat(PG_FUNCTION_ARGS)
969 : : {
970 : 27 : VarBit *arg1 = PG_GETARG_VARBIT_P(0);
971 : 27 : VarBit *arg2 = PG_GETARG_VARBIT_P(1);
972 : :
973 : 54 : PG_RETURN_VARBIT_P(bit_catenate(arg1, arg2));
974 : 27 : }
975 : :
976 : : static VarBit *
977 : 35 : bit_catenate(VarBit *arg1, VarBit *arg2)
978 : : {
979 : 35 : VarBit *result;
980 : 35 : int bitlen1,
981 : : bitlen2,
982 : : bytelen,
983 : : bit1pad,
984 : : bit2shift;
985 : 35 : bits8 *pr,
986 : : *pa;
987 : :
988 : 35 : bitlen1 = VARBITLEN(arg1);
989 : 35 : bitlen2 = VARBITLEN(arg2);
990 : :
991 [ + - ]: 35 : 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 : 35 : bytelen = VARBITTOTALLEN(bitlen1 + bitlen2);
997 : :
998 : 35 : result = (VarBit *) palloc(bytelen);
999 : 35 : SET_VARSIZE(result, bytelen);
1000 : 35 : VARBITLEN(result) = bitlen1 + bitlen2;
1001 : :
1002 : : /* Copy the first bitstring in */
1003 : 35 : memcpy(VARBITS(result), VARBITS(arg1), VARBITBYTES(arg1));
1004 : :
1005 : : /* Copy the second bit string */
1006 : 35 : bit1pad = VARBITPAD(arg1);
1007 [ + + ]: 35 : if (bit1pad == 0)
1008 : : {
1009 : 6 : memcpy(VARBITS(result) + VARBITBYTES(arg1), VARBITS(arg2),
1010 : : VARBITBYTES(arg2));
1011 : 6 : }
1012 [ + + ]: 29 : else if (bitlen2 > 0)
1013 : : {
1014 : : /* We need to shift all the bits to fit */
1015 : 27 : bit2shift = BITS_PER_BYTE - bit1pad;
1016 : 27 : pr = VARBITS(result) + VARBITBYTES(arg1) - 1;
1017 [ + + ]: 63 : for (pa = VARBITS(arg2); pa < VARBITEND(arg2); pa++)
1018 : : {
1019 : 36 : *pr |= ((*pa >> bit2shift) & BITMASK);
1020 : 36 : pr++;
1021 [ + + ]: 36 : if (pr < VARBITEND(result))
1022 : 23 : *pr = (*pa << bit1pad) & BITMASK;
1023 : 36 : }
1024 : 27 : }
1025 : :
1026 : : /* The pad bits should be already zero at this point */
1027 : :
1028 : 70 : return result;
1029 : 35 : }
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 : 20 : bitsubstr(PG_FUNCTION_ARGS)
1039 : : {
1040 : 20 : 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 : 7 : bitsubstr_no_len(PG_FUNCTION_ARGS)
1048 : : {
1049 : 7 : PG_RETURN_VARBIT_P(bitsubstring(PG_GETARG_VARBIT_P(0),
1050 : : PG_GETARG_INT32(1),
1051 : : -1, true));
1052 : : }
1053 : :
1054 : : static VarBit *
1055 : 35 : bitsubstring(VarBit *arg, int32 s, int32 l, bool length_not_specified)
1056 : : {
1057 : 35 : VarBit *result;
1058 : 35 : int bitlen,
1059 : : rbitlen,
1060 : : len,
1061 : : ishift,
1062 : : i;
1063 : 35 : int32 e,
1064 : : s1,
1065 : : e1;
1066 : 35 : bits8 *r,
1067 : : *ps;
1068 : :
1069 : 35 : bitlen = VARBITLEN(arg);
1070 [ + + ]: 35 : s1 = Max(s, 1);
1071 : : /* If we do not have an upper bound, use end of string */
1072 [ + + ]: 35 : if (length_not_specified)
1073 : : {
1074 : 11 : e1 = bitlen + 1;
1075 : 11 : }
1076 [ + + ]: 24 : else if (l < 0)
1077 : : {
1078 : : /* SQL99 says to throw an error for E < S, i.e., negative length */
1079 [ + - + - ]: 2 : ereport(ERROR,
1080 : : (errcode(ERRCODE_SUBSTRING_ERROR),
1081 : : errmsg("negative substring length not allowed")));
1082 : 0 : e1 = -1; /* silence stupider compilers */
1083 : 0 : }
1084 [ + + ]: 22 : 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 : 2 : e1 = bitlen + 1;
1091 : 2 : }
1092 : : else
1093 : : {
1094 [ + + ]: 20 : e1 = Min(e, bitlen + 1);
1095 : : }
1096 [ + + - + ]: 33 : if (s1 > bitlen || e1 <= s1)
1097 : : {
1098 : : /* Need to return a zero-length bitstring */
1099 : 9 : len = VARBITTOTALLEN(0);
1100 : 9 : result = (VarBit *) palloc(len);
1101 : 9 : SET_VARSIZE(result, len);
1102 : 9 : VARBITLEN(result) = 0;
1103 : 9 : }
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 : 24 : rbitlen = e1 - s1;
1111 : 24 : len = VARBITTOTALLEN(rbitlen);
1112 : 24 : result = (VarBit *) palloc(len);
1113 : 24 : SET_VARSIZE(result, len);
1114 : 24 : VARBITLEN(result) = rbitlen;
1115 : 24 : len -= VARHDRSZ + VARBITHDRSZ;
1116 : : /* Are we copying from a byte boundary? */
1117 [ + + ]: 24 : if ((s1 - 1) % BITS_PER_BYTE == 0)
1118 : : {
1119 : : /* Yep, we are copying bytes */
1120 : 7 : memcpy(VARBITS(result), VARBITS(arg) + (s1 - 1) / BITS_PER_BYTE,
1121 : : len);
1122 : 7 : }
1123 : : else
1124 : : {
1125 : : /* Figure out how much we need to shift the sequence by */
1126 : 17 : ishift = (s1 - 1) % BITS_PER_BYTE;
1127 : 17 : r = VARBITS(result);
1128 : 17 : ps = VARBITS(arg) + (s1 - 1) / BITS_PER_BYTE;
1129 [ + + ]: 34 : for (i = 0; i < len; i++)
1130 : : {
1131 : 17 : *r = (*ps << ishift) & BITMASK;
1132 [ + + ]: 17 : if ((++ps) < VARBITEND(arg))
1133 : 13 : *r |= *ps >> (BITS_PER_BYTE - ishift);
1134 : 17 : r++;
1135 : 17 : }
1136 : : }
1137 : :
1138 : : /* Make sure last byte is correctly zero-padded */
1139 [ + - + + ]: 24 : VARBIT_PAD(result);
1140 : : }
1141 : :
1142 : 66 : return result;
1143 : 33 : }
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 : 1 : bitoverlay(PG_FUNCTION_ARGS)
1154 : : {
1155 : 1 : VarBit *t1 = PG_GETARG_VARBIT_P(0);
1156 : 1 : VarBit *t2 = PG_GETARG_VARBIT_P(1);
1157 : 1 : int sp = PG_GETARG_INT32(2); /* substring start position */
1158 : 1 : int sl = PG_GETARG_INT32(3); /* substring length */
1159 : :
1160 : 2 : PG_RETURN_VARBIT_P(bit_overlay(t1, t2, sp, sl));
1161 : 1 : }
1162 : :
1163 : : Datum
1164 : 3 : bitoverlay_no_len(PG_FUNCTION_ARGS)
1165 : : {
1166 : 3 : VarBit *t1 = PG_GETARG_VARBIT_P(0);
1167 : 3 : VarBit *t2 = PG_GETARG_VARBIT_P(1);
1168 : 3 : int sp = PG_GETARG_INT32(2); /* substring start position */
1169 : 3 : int sl;
1170 : :
1171 : 3 : sl = VARBITLEN(t2); /* defaults to length(t2) */
1172 : 6 : PG_RETURN_VARBIT_P(bit_overlay(t1, t2, sp, sl));
1173 : 3 : }
1174 : :
1175 : : static VarBit *
1176 : 4 : bit_overlay(VarBit *t1, VarBit *t2, int sp, int sl)
1177 : : {
1178 : 4 : VarBit *result;
1179 : 4 : VarBit *s1;
1180 : 4 : VarBit *s2;
1181 : 4 : 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 [ + - ]: 4 : if (sp <= 0)
1189 [ # # # # ]: 0 : ereport(ERROR,
1190 : : (errcode(ERRCODE_SUBSTRING_ERROR),
1191 : : errmsg("negative substring length not allowed")));
1192 [ + - ]: 4 : 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 : 4 : s1 = bitsubstring(t1, 1, sp - 1, false);
1198 : 4 : s2 = bitsubstring(t1, sp_pl_sl, -1, true);
1199 : 4 : result = bit_catenate(s1, t2);
1200 : 4 : result = bit_catenate(result, s2);
1201 : :
1202 : 8 : return result;
1203 : 4 : }
1204 : :
1205 : : /*
1206 : : * bit_count
1207 : : *
1208 : : * Returns the number of bits set in a bit string.
1209 : : */
1210 : : Datum
1211 : 6 : bit_bit_count(PG_FUNCTION_ARGS)
1212 : : {
1213 : 6 : VarBit *arg = PG_GETARG_VARBIT_P(0);
1214 : :
1215 : 12 : PG_RETURN_INT64(pg_popcount((char *) VARBITS(arg), VARBITBYTES(arg)));
1216 : 6 : }
1217 : :
1218 : : /*
1219 : : * bitlength, bitoctetlength
1220 : : * Return the length of a bit string
1221 : : */
1222 : : Datum
1223 : 0 : bitlength(PG_FUNCTION_ARGS)
1224 : : {
1225 : 0 : VarBit *arg = PG_GETARG_VARBIT_P(0);
1226 : :
1227 : 0 : PG_RETURN_INT32(VARBITLEN(arg));
1228 : 0 : }
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 : 0 : }
1237 : :
1238 : : /*
1239 : : * bit_and
1240 : : * perform a logical AND on two bit strings.
1241 : : */
1242 : : Datum
1243 : 0 : bit_and(PG_FUNCTION_ARGS)
1244 : : {
1245 : 0 : VarBit *arg1 = PG_GETARG_VARBIT_P(0);
1246 : 0 : VarBit *arg2 = PG_GETARG_VARBIT_P(1);
1247 : 0 : VarBit *result;
1248 : 0 : int len,
1249 : : bitlen1,
1250 : : bitlen2,
1251 : : i;
1252 : 0 : bits8 *p1,
1253 : : *p2,
1254 : : *r;
1255 : :
1256 : 0 : bitlen1 = VARBITLEN(arg1);
1257 : 0 : bitlen2 = VARBITLEN(arg2);
1258 [ # # ]: 0 : if (bitlen1 != bitlen2)
1259 [ # # # # ]: 0 : ereport(ERROR,
1260 : : (errcode(ERRCODE_STRING_DATA_LENGTH_MISMATCH),
1261 : : errmsg("cannot AND bit strings of different sizes")));
1262 : :
1263 : 0 : len = VARSIZE(arg1);
1264 : 0 : result = (VarBit *) palloc(len);
1265 : 0 : SET_VARSIZE(result, len);
1266 : 0 : VARBITLEN(result) = bitlen1;
1267 : :
1268 : 0 : p1 = VARBITS(arg1);
1269 : 0 : p2 = VARBITS(arg2);
1270 : 0 : r = VARBITS(result);
1271 [ # # ]: 0 : for (i = 0; i < VARBITBYTES(arg1); i++)
1272 : 0 : *r++ = *p1++ & *p2++;
1273 : :
1274 : : /* Padding is not needed as & of 0 pads is 0 */
1275 : :
1276 : 0 : PG_RETURN_VARBIT_P(result);
1277 : 0 : }
1278 : :
1279 : : /*
1280 : : * bit_or
1281 : : * perform a logical OR on two bit strings.
1282 : : */
1283 : : Datum
1284 : 0 : bit_or(PG_FUNCTION_ARGS)
1285 : : {
1286 : 0 : VarBit *arg1 = PG_GETARG_VARBIT_P(0);
1287 : 0 : VarBit *arg2 = PG_GETARG_VARBIT_P(1);
1288 : 0 : VarBit *result;
1289 : 0 : int len,
1290 : : bitlen1,
1291 : : bitlen2,
1292 : : i;
1293 : 0 : bits8 *p1,
1294 : : *p2,
1295 : : *r;
1296 : :
1297 : 0 : bitlen1 = VARBITLEN(arg1);
1298 : 0 : bitlen2 = VARBITLEN(arg2);
1299 [ # # ]: 0 : if (bitlen1 != bitlen2)
1300 [ # # # # ]: 0 : ereport(ERROR,
1301 : : (errcode(ERRCODE_STRING_DATA_LENGTH_MISMATCH),
1302 : : errmsg("cannot OR bit strings of different sizes")));
1303 : 0 : len = VARSIZE(arg1);
1304 : 0 : result = (VarBit *) palloc(len);
1305 : 0 : SET_VARSIZE(result, len);
1306 : 0 : VARBITLEN(result) = bitlen1;
1307 : :
1308 : 0 : p1 = VARBITS(arg1);
1309 : 0 : p2 = VARBITS(arg2);
1310 : 0 : r = VARBITS(result);
1311 [ # # ]: 0 : for (i = 0; i < VARBITBYTES(arg1); i++)
1312 : 0 : *r++ = *p1++ | *p2++;
1313 : :
1314 : : /* Padding is not needed as | of 0 pads is 0 */
1315 : :
1316 : 0 : PG_RETURN_VARBIT_P(result);
1317 : 0 : }
1318 : :
1319 : : /*
1320 : : * bitxor
1321 : : * perform a logical XOR on two bit strings.
1322 : : */
1323 : : Datum
1324 : 0 : bitxor(PG_FUNCTION_ARGS)
1325 : : {
1326 : 0 : VarBit *arg1 = PG_GETARG_VARBIT_P(0);
1327 : 0 : VarBit *arg2 = PG_GETARG_VARBIT_P(1);
1328 : 0 : VarBit *result;
1329 : 0 : int len,
1330 : : bitlen1,
1331 : : bitlen2,
1332 : : i;
1333 : 0 : bits8 *p1,
1334 : : *p2,
1335 : : *r;
1336 : :
1337 : 0 : bitlen1 = VARBITLEN(arg1);
1338 : 0 : bitlen2 = VARBITLEN(arg2);
1339 [ # # ]: 0 : if (bitlen1 != bitlen2)
1340 [ # # # # ]: 0 : ereport(ERROR,
1341 : : (errcode(ERRCODE_STRING_DATA_LENGTH_MISMATCH),
1342 : : errmsg("cannot XOR bit strings of different sizes")));
1343 : :
1344 : 0 : len = VARSIZE(arg1);
1345 : 0 : result = (VarBit *) palloc(len);
1346 : 0 : SET_VARSIZE(result, len);
1347 : 0 : VARBITLEN(result) = bitlen1;
1348 : :
1349 : 0 : p1 = VARBITS(arg1);
1350 : 0 : p2 = VARBITS(arg2);
1351 : 0 : r = VARBITS(result);
1352 [ # # ]: 0 : for (i = 0; i < VARBITBYTES(arg1); i++)
1353 : 0 : *r++ = *p1++ ^ *p2++;
1354 : :
1355 : : /* Padding is not needed as ^ of 0 pads is 0 */
1356 : :
1357 : 0 : PG_RETURN_VARBIT_P(result);
1358 : 0 : }
1359 : :
1360 : : /*
1361 : : * bitnot
1362 : : * perform a logical NOT on a bit string.
1363 : : */
1364 : : Datum
1365 : 0 : bitnot(PG_FUNCTION_ARGS)
1366 : : {
1367 : 0 : VarBit *arg = PG_GETARG_VARBIT_P(0);
1368 : 0 : VarBit *result;
1369 : 0 : bits8 *p,
1370 : : *r;
1371 : :
1372 : 0 : result = (VarBit *) palloc(VARSIZE(arg));
1373 : 0 : SET_VARSIZE(result, VARSIZE(arg));
1374 : 0 : VARBITLEN(result) = VARBITLEN(arg);
1375 : :
1376 : 0 : p = VARBITS(arg);
1377 : 0 : r = VARBITS(result);
1378 [ # # ]: 0 : for (; p < VARBITEND(arg); p++)
1379 : 0 : *r++ = ~*p;
1380 : :
1381 : : /* Must zero-pad the result, because extra bits are surely 1's here */
1382 [ # # # # ]: 0 : VARBIT_PAD_LAST(result, r);
1383 : :
1384 : 0 : PG_RETURN_VARBIT_P(result);
1385 : 0 : }
1386 : :
1387 : : /*
1388 : : * bitshiftleft
1389 : : * do a left shift (i.e. towards the beginning of the string)
1390 : : */
1391 : : Datum
1392 : 0 : bitshiftleft(PG_FUNCTION_ARGS)
1393 : : {
1394 : 0 : VarBit *arg = PG_GETARG_VARBIT_P(0);
1395 : 0 : int32 shft = PG_GETARG_INT32(1);
1396 : 0 : VarBit *result;
1397 : 0 : int byte_shift,
1398 : : ishift,
1399 : : len;
1400 : 0 : bits8 *p,
1401 : : *r;
1402 : :
1403 : : /* Negative shift is a shift to the right */
1404 [ # # ]: 0 : if (shft < 0)
1405 : : {
1406 : : /* Prevent integer overflow in negation */
1407 [ # # ]: 0 : if (shft < -VARBITMAXLEN)
1408 : 0 : shft = -VARBITMAXLEN;
1409 : 0 : PG_RETURN_DATUM(DirectFunctionCall2(bitshiftright,
1410 : : VarBitPGetDatum(arg),
1411 : : Int32GetDatum(-shft)));
1412 : : }
1413 : :
1414 : 0 : result = (VarBit *) palloc(VARSIZE(arg));
1415 : 0 : SET_VARSIZE(result, VARSIZE(arg));
1416 : 0 : VARBITLEN(result) = VARBITLEN(arg);
1417 : 0 : r = VARBITS(result);
1418 : :
1419 : : /* If we shifted all the bits out, return an all-zero string */
1420 [ # # ]: 0 : if (shft >= VARBITLEN(arg))
1421 : : {
1422 [ # # # # : 0 : MemSet(r, 0, VARBITBYTES(arg));
# # # # #
# ]
1423 : 0 : PG_RETURN_VARBIT_P(result);
1424 : : }
1425 : :
1426 : 0 : byte_shift = shft / BITS_PER_BYTE;
1427 : 0 : ishift = shft % BITS_PER_BYTE;
1428 : 0 : p = VARBITS(arg) + byte_shift;
1429 : :
1430 [ # # ]: 0 : if (ishift == 0)
1431 : : {
1432 : : /* Special case: we can do a memcpy */
1433 : 0 : len = VARBITBYTES(arg) - byte_shift;
1434 : 0 : memcpy(r, p, len);
1435 [ # # # # : 0 : MemSet(r + len, 0, byte_shift);
# # # # #
# ]
1436 : 0 : }
1437 : : else
1438 : : {
1439 [ # # ]: 0 : for (; p < VARBITEND(arg); r++)
1440 : : {
1441 : 0 : *r = *p << ishift;
1442 [ # # ]: 0 : if ((++p) < VARBITEND(arg))
1443 : 0 : *r |= *p >> (BITS_PER_BYTE - ishift);
1444 : 0 : }
1445 [ # # ]: 0 : for (; r < VARBITEND(result); r++)
1446 : 0 : *r = 0;
1447 : : }
1448 : :
1449 : : /* The pad bits should be already zero at this point */
1450 : :
1451 : 0 : PG_RETURN_VARBIT_P(result);
1452 : 0 : }
1453 : :
1454 : : /*
1455 : : * bitshiftright
1456 : : * do a right shift (i.e. towards the end of the string)
1457 : : */
1458 : : Datum
1459 : 0 : bitshiftright(PG_FUNCTION_ARGS)
1460 : : {
1461 : 0 : VarBit *arg = PG_GETARG_VARBIT_P(0);
1462 : 0 : int32 shft = PG_GETARG_INT32(1);
1463 : 0 : VarBit *result;
1464 : 0 : int byte_shift,
1465 : : ishift,
1466 : : len;
1467 : 0 : bits8 *p,
1468 : : *r;
1469 : :
1470 : : /* Negative shift is a shift to the left */
1471 [ # # ]: 0 : if (shft < 0)
1472 : : {
1473 : : /* Prevent integer overflow in negation */
1474 [ # # ]: 0 : if (shft < -VARBITMAXLEN)
1475 : 0 : shft = -VARBITMAXLEN;
1476 : 0 : PG_RETURN_DATUM(DirectFunctionCall2(bitshiftleft,
1477 : : VarBitPGetDatum(arg),
1478 : : Int32GetDatum(-shft)));
1479 : : }
1480 : :
1481 : 0 : result = (VarBit *) palloc(VARSIZE(arg));
1482 : 0 : SET_VARSIZE(result, VARSIZE(arg));
1483 : 0 : VARBITLEN(result) = VARBITLEN(arg);
1484 : 0 : r = VARBITS(result);
1485 : :
1486 : : /* If we shifted all the bits out, return an all-zero string */
1487 [ # # ]: 0 : if (shft >= VARBITLEN(arg))
1488 : : {
1489 [ # # # # : 0 : MemSet(r, 0, VARBITBYTES(arg));
# # # # #
# ]
1490 : 0 : PG_RETURN_VARBIT_P(result);
1491 : : }
1492 : :
1493 : 0 : byte_shift = shft / BITS_PER_BYTE;
1494 : 0 : ishift = shft % BITS_PER_BYTE;
1495 : 0 : p = VARBITS(arg);
1496 : :
1497 : : /* Set the first part of the result to 0 */
1498 [ # # # # : 0 : MemSet(r, 0, byte_shift);
# # # # #
# ]
1499 : 0 : r += byte_shift;
1500 : :
1501 [ # # ]: 0 : if (ishift == 0)
1502 : : {
1503 : : /* Special case: we can do a memcpy */
1504 : 0 : len = VARBITBYTES(arg) - byte_shift;
1505 : 0 : memcpy(r, p, len);
1506 : 0 : r += len;
1507 : 0 : }
1508 : : else
1509 : : {
1510 [ # # ]: 0 : if (r < VARBITEND(result))
1511 : 0 : *r = 0; /* initialize first byte */
1512 [ # # ]: 0 : for (; r < VARBITEND(result); p++)
1513 : : {
1514 : 0 : *r |= *p >> ishift;
1515 [ # # ]: 0 : if ((++r) < VARBITEND(result))
1516 : 0 : *r = (*p << (BITS_PER_BYTE - ishift)) & BITMASK;
1517 : 0 : }
1518 : : }
1519 : :
1520 : : /* We may have shifted 1's into the pad bits, so fix that */
1521 [ # # # # ]: 0 : VARBIT_PAD_LAST(result, r);
1522 : :
1523 : 0 : PG_RETURN_VARBIT_P(result);
1524 : 0 : }
1525 : :
1526 : : /*
1527 : : * This is not defined in any standard. We retain the natural ordering of
1528 : : * bits here, as it just seems more intuitive.
1529 : : */
1530 : : Datum
1531 : 0 : bitfromint4(PG_FUNCTION_ARGS)
1532 : : {
1533 : 0 : int32 a = PG_GETARG_INT32(0);
1534 : 0 : int32 typmod = PG_GETARG_INT32(1);
1535 : 0 : VarBit *result;
1536 : 0 : bits8 *r;
1537 : 0 : int rlen;
1538 : 0 : int destbitsleft,
1539 : : srcbitsleft;
1540 : :
1541 [ # # # # ]: 0 : if (typmod <= 0 || typmod > VARBITMAXLEN)
1542 : 0 : typmod = 1; /* default bit length */
1543 : :
1544 : 0 : rlen = VARBITTOTALLEN(typmod);
1545 : 0 : result = (VarBit *) palloc(rlen);
1546 : 0 : SET_VARSIZE(result, rlen);
1547 : 0 : VARBITLEN(result) = typmod;
1548 : :
1549 : 0 : r = VARBITS(result);
1550 : 0 : destbitsleft = typmod;
1551 : 0 : srcbitsleft = 32;
1552 : : /* drop any input bits that don't fit */
1553 [ # # ]: 0 : srcbitsleft = Min(srcbitsleft, destbitsleft);
1554 : : /* sign-fill any excess bytes in output */
1555 [ # # ]: 0 : while (destbitsleft >= srcbitsleft + 8)
1556 : : {
1557 : 0 : *r++ = (bits8) ((a < 0) ? BITMASK : 0);
1558 : 0 : destbitsleft -= 8;
1559 : : }
1560 : : /* store first fractional byte */
1561 [ # # ]: 0 : if (destbitsleft > srcbitsleft)
1562 : : {
1563 : 0 : unsigned int val = (unsigned int) (a >> (destbitsleft - 8));
1564 : :
1565 : : /* Force sign-fill in case the compiler implements >> as zero-fill */
1566 [ # # ]: 0 : if (a < 0)
1567 : 0 : val |= ((unsigned int) -1) << (srcbitsleft + 8 - destbitsleft);
1568 : 0 : *r++ = (bits8) (val & BITMASK);
1569 : 0 : destbitsleft -= 8;
1570 : 0 : }
1571 : : /* Now srcbitsleft and destbitsleft are the same, need not track both */
1572 : : /* store whole bytes */
1573 [ # # ]: 0 : while (destbitsleft >= 8)
1574 : : {
1575 : 0 : *r++ = (bits8) ((a >> (destbitsleft - 8)) & BITMASK);
1576 : 0 : destbitsleft -= 8;
1577 : : }
1578 : : /* store last fractional byte */
1579 [ # # ]: 0 : if (destbitsleft > 0)
1580 : 0 : *r = (bits8) ((a << (8 - destbitsleft)) & BITMASK);
1581 : :
1582 : 0 : PG_RETURN_VARBIT_P(result);
1583 : 0 : }
1584 : :
1585 : : Datum
1586 : 0 : bittoint4(PG_FUNCTION_ARGS)
1587 : : {
1588 : 0 : VarBit *arg = PG_GETARG_VARBIT_P(0);
1589 : 0 : uint32 result;
1590 : 0 : bits8 *r;
1591 : :
1592 : : /* Check that the bit string is not too long */
1593 [ # # ]: 0 : if (VARBITLEN(arg) > sizeof(result) * BITS_PER_BYTE)
1594 [ # # # # ]: 0 : ereport(ERROR,
1595 : : (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
1596 : : errmsg("integer out of range")));
1597 : :
1598 : 0 : result = 0;
1599 [ # # ]: 0 : for (r = VARBITS(arg); r < VARBITEND(arg); r++)
1600 : : {
1601 : 0 : result <<= BITS_PER_BYTE;
1602 : 0 : result |= *r;
1603 : 0 : }
1604 : : /* Now shift the result to take account of the padding at the end */
1605 : 0 : result >>= VARBITPAD(arg);
1606 : :
1607 : 0 : PG_RETURN_INT32(result);
1608 : 0 : }
1609 : :
1610 : : Datum
1611 : 0 : bitfromint8(PG_FUNCTION_ARGS)
1612 : : {
1613 : 0 : int64 a = PG_GETARG_INT64(0);
1614 : 0 : int32 typmod = PG_GETARG_INT32(1);
1615 : 0 : VarBit *result;
1616 : 0 : bits8 *r;
1617 : 0 : int rlen;
1618 : 0 : int destbitsleft,
1619 : : srcbitsleft;
1620 : :
1621 [ # # # # ]: 0 : if (typmod <= 0 || typmod > VARBITMAXLEN)
1622 : 0 : typmod = 1; /* default bit length */
1623 : :
1624 : 0 : rlen = VARBITTOTALLEN(typmod);
1625 : 0 : result = (VarBit *) palloc(rlen);
1626 : 0 : SET_VARSIZE(result, rlen);
1627 : 0 : VARBITLEN(result) = typmod;
1628 : :
1629 : 0 : r = VARBITS(result);
1630 : 0 : destbitsleft = typmod;
1631 : 0 : srcbitsleft = 64;
1632 : : /* drop any input bits that don't fit */
1633 [ # # ]: 0 : srcbitsleft = Min(srcbitsleft, destbitsleft);
1634 : : /* sign-fill any excess bytes in output */
1635 [ # # ]: 0 : while (destbitsleft >= srcbitsleft + 8)
1636 : : {
1637 : 0 : *r++ = (bits8) ((a < 0) ? BITMASK : 0);
1638 : 0 : destbitsleft -= 8;
1639 : : }
1640 : : /* store first fractional byte */
1641 [ # # ]: 0 : if (destbitsleft > srcbitsleft)
1642 : : {
1643 : 0 : unsigned int val = (unsigned int) (a >> (destbitsleft - 8));
1644 : :
1645 : : /* Force sign-fill in case the compiler implements >> as zero-fill */
1646 [ # # ]: 0 : if (a < 0)
1647 : 0 : val |= ((unsigned int) -1) << (srcbitsleft + 8 - destbitsleft);
1648 : 0 : *r++ = (bits8) (val & BITMASK);
1649 : 0 : destbitsleft -= 8;
1650 : 0 : }
1651 : : /* Now srcbitsleft and destbitsleft are the same, need not track both */
1652 : : /* store whole bytes */
1653 [ # # ]: 0 : while (destbitsleft >= 8)
1654 : : {
1655 : 0 : *r++ = (bits8) ((a >> (destbitsleft - 8)) & BITMASK);
1656 : 0 : destbitsleft -= 8;
1657 : : }
1658 : : /* store last fractional byte */
1659 [ # # ]: 0 : if (destbitsleft > 0)
1660 : 0 : *r = (bits8) ((a << (8 - destbitsleft)) & BITMASK);
1661 : :
1662 : 0 : PG_RETURN_VARBIT_P(result);
1663 : 0 : }
1664 : :
1665 : : Datum
1666 : 0 : bittoint8(PG_FUNCTION_ARGS)
1667 : : {
1668 : 0 : VarBit *arg = PG_GETARG_VARBIT_P(0);
1669 : 0 : uint64 result;
1670 : 0 : bits8 *r;
1671 : :
1672 : : /* Check that the bit string is not too long */
1673 [ # # ]: 0 : if (VARBITLEN(arg) > sizeof(result) * BITS_PER_BYTE)
1674 [ # # # # ]: 0 : ereport(ERROR,
1675 : : (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
1676 : : errmsg("bigint out of range")));
1677 : :
1678 : 0 : result = 0;
1679 [ # # ]: 0 : for (r = VARBITS(arg); r < VARBITEND(arg); r++)
1680 : : {
1681 : 0 : result <<= BITS_PER_BYTE;
1682 : 0 : result |= *r;
1683 : 0 : }
1684 : : /* Now shift the result to take account of the padding at the end */
1685 : 0 : result >>= VARBITPAD(arg);
1686 : :
1687 : 0 : PG_RETURN_INT64(result);
1688 : 0 : }
1689 : :
1690 : :
1691 : : /*
1692 : : * Determines the position of S2 in the bitstring S1 (1-based string).
1693 : : * If S2 does not appear in S1 this function returns 0.
1694 : : * If S2 is of length 0 this function returns 1.
1695 : : * Compatible in usage with POSITION() functions for other data types.
1696 : : */
1697 : : Datum
1698 : 0 : bitposition(PG_FUNCTION_ARGS)
1699 : : {
1700 : 0 : VarBit *str = PG_GETARG_VARBIT_P(0);
1701 : 0 : VarBit *substr = PG_GETARG_VARBIT_P(1);
1702 : 0 : int substr_length,
1703 : : str_length,
1704 : : i,
1705 : : is;
1706 : 0 : bits8 *s, /* pointer into substring */
1707 : : *p; /* pointer into str */
1708 : 0 : bits8 cmp, /* shifted substring byte to compare */
1709 : : mask1, /* mask for substring byte shifted right */
1710 : : mask2, /* mask for substring byte shifted left */
1711 : : end_mask, /* pad mask for last substring byte */
1712 : : str_mask; /* pad mask for last string byte */
1713 : 0 : bool is_match;
1714 : :
1715 : : /* Get the substring length */
1716 : 0 : substr_length = VARBITLEN(substr);
1717 : 0 : str_length = VARBITLEN(str);
1718 : :
1719 : : /* String has zero length or substring longer than string, return 0 */
1720 [ # # # # ]: 0 : if ((str_length == 0) || (substr_length > str_length))
1721 : 0 : PG_RETURN_INT32(0);
1722 : :
1723 : : /* zero-length substring means return 1 */
1724 [ # # ]: 0 : if (substr_length == 0)
1725 : 0 : PG_RETURN_INT32(1);
1726 : :
1727 : : /* Initialise the padding masks */
1728 : 0 : end_mask = BITMASK << VARBITPAD(substr);
1729 : 0 : str_mask = BITMASK << VARBITPAD(str);
1730 [ # # ]: 0 : for (i = 0; i < VARBITBYTES(str) - VARBITBYTES(substr) + 1; i++)
1731 : : {
1732 [ # # ]: 0 : for (is = 0; is < BITS_PER_BYTE; is++)
1733 : : {
1734 : 0 : is_match = true;
1735 : 0 : p = VARBITS(str) + i;
1736 : 0 : mask1 = BITMASK >> is;
1737 : 0 : mask2 = ~mask1;
1738 [ # # ]: 0 : for (s = VARBITS(substr);
1739 [ # # ]: 0 : is_match && s < VARBITEND(substr); s++)
1740 : : {
1741 : 0 : cmp = *s >> is;
1742 [ # # ]: 0 : if (s == VARBITEND(substr) - 1)
1743 : : {
1744 : 0 : mask1 &= end_mask >> is;
1745 [ # # ]: 0 : if (p == VARBITEND(str) - 1)
1746 : : {
1747 : : /* Check that there is enough of str left */
1748 [ # # ]: 0 : if (mask1 & ~str_mask)
1749 : : {
1750 : 0 : is_match = false;
1751 : 0 : break;
1752 : : }
1753 : 0 : mask1 &= str_mask;
1754 : 0 : }
1755 : 0 : }
1756 : 0 : is_match = ((cmp ^ *p) & mask1) == 0;
1757 [ # # ]: 0 : if (!is_match)
1758 : 0 : break;
1759 : : /* Move on to the next byte */
1760 : 0 : p++;
1761 [ # # ]: 0 : if (p == VARBITEND(str))
1762 : : {
1763 : 0 : mask2 = end_mask << (BITS_PER_BYTE - is);
1764 : 0 : is_match = mask2 == 0;
1765 : : #if 0
1766 : : elog(DEBUG4, "S. %d %d em=%2x sm=%2x r=%d",
1767 : : i, is, end_mask, mask2, is_match);
1768 : : #endif
1769 : 0 : break;
1770 : : }
1771 : 0 : cmp = *s << (BITS_PER_BYTE - is);
1772 [ # # ]: 0 : if (s == VARBITEND(substr) - 1)
1773 : : {
1774 : 0 : mask2 &= end_mask << (BITS_PER_BYTE - is);
1775 [ # # ]: 0 : if (p == VARBITEND(str) - 1)
1776 : : {
1777 [ # # ]: 0 : if (mask2 & ~str_mask)
1778 : : {
1779 : 0 : is_match = false;
1780 : 0 : break;
1781 : : }
1782 : 0 : mask2 &= str_mask;
1783 : 0 : }
1784 : 0 : }
1785 : 0 : is_match = ((cmp ^ *p) & mask2) == 0;
1786 : 0 : }
1787 : : /* Have we found a match? */
1788 [ # # ]: 0 : if (is_match)
1789 : 0 : PG_RETURN_INT32(i * BITS_PER_BYTE + is + 1);
1790 : 0 : }
1791 : 0 : }
1792 : 0 : PG_RETURN_INT32(0);
1793 : 0 : }
1794 : :
1795 : :
1796 : : /*
1797 : : * bitsetbit
1798 : : *
1799 : : * Given an instance of type 'bit' creates a new one with
1800 : : * the Nth bit set to the given value.
1801 : : *
1802 : : * The bit location is specified left-to-right in a zero-based fashion
1803 : : * consistent with the other get_bit and set_bit functions, but
1804 : : * inconsistent with the standard substring, position, overlay functions
1805 : : */
1806 : : Datum
1807 : 0 : bitsetbit(PG_FUNCTION_ARGS)
1808 : : {
1809 : 0 : VarBit *arg1 = PG_GETARG_VARBIT_P(0);
1810 : 0 : int32 n = PG_GETARG_INT32(1);
1811 : 0 : int32 newBit = PG_GETARG_INT32(2);
1812 : 0 : VarBit *result;
1813 : 0 : int len,
1814 : : bitlen;
1815 : 0 : bits8 *r,
1816 : : *p;
1817 : 0 : int byteNo,
1818 : : bitNo;
1819 : :
1820 : 0 : bitlen = VARBITLEN(arg1);
1821 [ # # ]: 0 : if (n < 0 || n >= bitlen)
1822 [ # # # # ]: 0 : ereport(ERROR,
1823 : : (errcode(ERRCODE_ARRAY_SUBSCRIPT_ERROR),
1824 : : errmsg("bit index %d out of valid range (0..%d)",
1825 : : n, bitlen - 1)));
1826 : :
1827 : : /*
1828 : : * sanity check!
1829 : : */
1830 [ # # # # ]: 0 : if (newBit != 0 && newBit != 1)
1831 [ # # # # ]: 0 : ereport(ERROR,
1832 : : (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
1833 : : errmsg("new bit must be 0 or 1")));
1834 : :
1835 : 0 : len = VARSIZE(arg1);
1836 : 0 : result = (VarBit *) palloc(len);
1837 : 0 : SET_VARSIZE(result, len);
1838 : 0 : VARBITLEN(result) = bitlen;
1839 : :
1840 : 0 : p = VARBITS(arg1);
1841 : 0 : r = VARBITS(result);
1842 : :
1843 : 0 : memcpy(r, p, VARBITBYTES(arg1));
1844 : :
1845 : 0 : byteNo = n / BITS_PER_BYTE;
1846 : 0 : bitNo = BITS_PER_BYTE - 1 - (n % BITS_PER_BYTE);
1847 : :
1848 : : /*
1849 : : * Update the byte.
1850 : : */
1851 [ # # ]: 0 : if (newBit == 0)
1852 : 0 : r[byteNo] &= (~(1 << bitNo));
1853 : : else
1854 : 0 : r[byteNo] |= (1 << bitNo);
1855 : :
1856 : 0 : PG_RETURN_VARBIT_P(result);
1857 : 0 : }
1858 : :
1859 : : /*
1860 : : * bitgetbit
1861 : : *
1862 : : * returns the value of the Nth bit of a bit array (0 or 1).
1863 : : *
1864 : : * The bit location is specified left-to-right in a zero-based fashion
1865 : : * consistent with the other get_bit and set_bit functions, but
1866 : : * inconsistent with the standard substring, position, overlay functions
1867 : : */
1868 : : Datum
1869 : 0 : bitgetbit(PG_FUNCTION_ARGS)
1870 : : {
1871 : 0 : VarBit *arg1 = PG_GETARG_VARBIT_P(0);
1872 : 0 : int32 n = PG_GETARG_INT32(1);
1873 : 0 : int bitlen;
1874 : 0 : bits8 *p;
1875 : 0 : int byteNo,
1876 : : bitNo;
1877 : :
1878 : 0 : bitlen = VARBITLEN(arg1);
1879 [ # # ]: 0 : if (n < 0 || n >= bitlen)
1880 [ # # # # ]: 0 : ereport(ERROR,
1881 : : (errcode(ERRCODE_ARRAY_SUBSCRIPT_ERROR),
1882 : : errmsg("bit index %d out of valid range (0..%d)",
1883 : : n, bitlen - 1)));
1884 : :
1885 : 0 : p = VARBITS(arg1);
1886 : :
1887 : 0 : byteNo = n / BITS_PER_BYTE;
1888 : 0 : bitNo = BITS_PER_BYTE - 1 - (n % BITS_PER_BYTE);
1889 : :
1890 [ # # ]: 0 : if (p[byteNo] & (1 << bitNo))
1891 : 0 : PG_RETURN_INT32(1);
1892 : : else
1893 : 0 : PG_RETURN_INT32(0);
1894 : 0 : }
|