varbit.c 34.6 KB
Newer Older
1 2 3
/*-------------------------------------------------------------------------
 *
 * varbit.c
4 5 6 7
 *	  Functions for the SQL datatypes BIT() and BIT VARYING().
 *
 * Code originally contributed by Adriaan Joubert.
 *
8
 * Portions Copyright (c) 1996-2008, PostgreSQL Global Development Group
9
 * Portions Copyright (c) 1994, Regents of the University of California
10 11
 *
 * IDENTIFICATION
12
 *	  $PostgreSQL: pgsql/src/backend/utils/adt/varbit.c,v 1.57.2.1 2009/12/12 19:24:51 tgl Exp $
13 14 15 16
 *
 *-------------------------------------------------------------------------
 */

17 18
#include "postgres.h"

19
#include "access/htup.h"
20
#include "libpq/pqformat.h"
21
#include "utils/array.h"
B
Bruce Momjian 已提交
22
#include "utils/varbit.h"
23

24 25 26
#define HEXDIG(z)	 ((z)<10 ? ((z)+'0') : ((z)-10+'A'))


27 28 29 30
/* common code for bittypmodin and varbittypmodin */
static int32
anybit_typmodin(ArrayType *ta, const char *typename)
{
B
Bruce Momjian 已提交
31 32 33
	int32		typmod;
	int32	   *tl;
	int			n;
34

35
	tl = ArrayGetIntegerTypmods(ta, &n);
36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65

	/*
	 * we're not too tense about good error message here because grammar
	 * shouldn't allow wrong number of modifiers for BIT
	 */
	if (n != 1)
		ereport(ERROR,
				(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
				 errmsg("invalid type modifier")));

	if (*tl < 1)
		ereport(ERROR,
				(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
				 errmsg("length for type %s must be at least 1",
						typename)));
	if (*tl > (MaxAttrSize * BITS_PER_BYTE))
		ereport(ERROR,
				(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
				 errmsg("length for type %s cannot exceed %d",
						typename, MaxAttrSize * BITS_PER_BYTE)));

	typmod = *tl;

	return typmod;
}

/* common code for bittypmodout and varbittypmodout */
static char *
anybit_typmodout(int32 typmod)
{
B
Bruce Momjian 已提交
66
	char	   *res = (char *) palloc(64);
67 68 69 70 71 72 73 74 75 76

	if (typmod >= 0)
		snprintf(res, 64, "(%d)", typmod);
	else
		*res = '\0';

	return res;
}


77 78 79 80 81 82 83 84 85 86
/*----------
 *	attypmod -- contains the length of the bit string in bits, or for
 *			   varying bits the maximum length.
 *
 *	The data structure contains the following elements:
 *	  header  -- length of the whole data structure (incl header)
 *				 in bytes. (as with all varying length datatypes)
 *	  data section -- private data section for the bits data structures
 *		bitlength -- length of the bit string in bits
 *		bitdata   -- bit string, most significant byte first
87 88 89 90 91
 *
 *	The length of the bitdata vector should always be exactly as many
 *	bytes as are needed for the given bitlength.  If the bitlength is
 *	not a multiple of 8, the extra low-order padding bits of the last
 *	byte must be zeroes.
92 93
 *----------
 */
94 95

/*
96
 * bit_in -
97
 *	  converts a char string to the internal representation of a bitstring.
98 99
 *		  The length is determined by the number of bits required plus
 *		  VARHDRSZ bytes or from atttypmod.
100
 */
101
Datum
102
bit_in(PG_FUNCTION_ARGS)
103
{
104
	char	   *input_string = PG_GETARG_CSTRING(0);
B
Bruce Momjian 已提交
105

106 107 108 109 110
#ifdef NOT_USED
	Oid			typelem = PG_GETARG_OID(1);
#endif
	int32		atttypmod = PG_GETARG_INT32(2);
	VarBit	   *result;			/* The resulting bit string			  */
111
	char	   *sp;				/* pointer into the character string  */
112
	bits8	   *r;				/* pointer into the result */
113 114 115
	int			len,			/* Length of the whole data structure */
				bitlen,			/* Number of bits in the bit string   */
				slen;			/* Length of the input string		  */
116
	bool		bit_not_hex;	/* false = hex string  true = bit string */
117
	int			bc;
118 119 120
	bits8		x = 0;

	/* Check that the first character is a b or an x */
121 122
	if (input_string[0] == 'b' || input_string[0] == 'B')
	{
123
		bit_not_hex = true;
124 125 126 127
		sp = input_string + 1;
	}
	else if (input_string[0] == 'x' || input_string[0] == 'X')
	{
128
		bit_not_hex = false;
129 130
		sp = input_string + 1;
	}
131
	else
132
	{
133
		/*
B
Bruce Momjian 已提交
134 135
		 * Otherwise it's binary.  This allows things like cast('1001' as bit)
		 * to work transparently.
136 137 138
		 */
		bit_not_hex = true;
		sp = input_string;
139
	}
140

141
	slen = strlen(sp);
142
	/* Determine bitlength from input string */
143 144 145 146
	if (bit_not_hex)
		bitlen = slen;
	else
		bitlen = slen * 4;
147 148

	/*
B
Bruce Momjian 已提交
149 150
	 * Sometimes atttypmod is not supplied. If it is supplied we need to make
	 * sure that the bitstring fits.
151
	 */
152
	if (atttypmod <= 0)
153
		atttypmod = bitlen;
154
	else if (bitlen != atttypmod)
155 156
		ereport(ERROR,
				(errcode(ERRCODE_STRING_DATA_LENGTH_MISMATCH),
B
Bruce Momjian 已提交
157 158
				 errmsg("bit string length %d does not match type bit(%d)",
						bitlen, atttypmod)));
159

160 161
	len = VARBITTOTALLEN(atttypmod);
	/* set to 0 so that *r is always initialised and string is zero-padded */
162
	result = (VarBit *) palloc0(len);
163
	SET_VARSIZE(result, len);
164 165 166 167
	VARBITLEN(result) = atttypmod;

	r = VARBITS(result);
	if (bit_not_hex)
168
	{
169 170
		/* Parse the bit representation of the string */
		/* We know it fits, as bitlen was compared to atttypmod */
B
Bruce Momjian 已提交
171
		x = HIGHBIT;
172
		for (; *sp; sp++)
173 174 175
		{
			if (*sp == '1')
				*r |= x;
176
			else if (*sp != '0')
177 178 179 180 181
				ereport(ERROR,
						(errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
						 errmsg("\"%c\" is not a valid binary digit",
								*sp)));

182 183
			x >>= 1;
			if (x == 0)
184
			{
B
Bruce Momjian 已提交
185
				x = HIGHBIT;
186 187 188
				r++;
			}
		}
189
	}
190
	else
191
	{
192
		/* Parse the hex representation of the string */
193
		for (bc = 0; *sp; sp++)
194 195 196 197 198 199 200 201
		{
			if (*sp >= '0' && *sp <= '9')
				x = (bits8) (*sp - '0');
			else if (*sp >= 'A' && *sp <= 'F')
				x = (bits8) (*sp - 'A') + 10;
			else if (*sp >= 'a' && *sp <= 'f')
				x = (bits8) (*sp - 'a') + 10;
			else
202 203
				ereport(ERROR,
						(errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
204
						 errmsg("\"%c\" is not a valid hexadecimal digit",
205 206
								*sp)));

207 208 209
			if (bc)
			{
				*r++ |= x;
210
				bc = 0;
211 212 213 214
			}
			else
			{
				*r = x << 4;
215
				bc = 1;
216 217
			}
		}
218 219
	}

220
	PG_RETURN_VARBIT_P(result);
221 222
}

223

224
Datum
225
bit_out(PG_FUNCTION_ARGS)
226
{
227 228 229 230 231 232
#if 1
	/* same as varbit output */
	return varbit_out(fcinfo);
#else
/* This is how one would print a hex string, in case someone wants to
   write a formatting function. */
233
	VarBit	   *s = PG_GETARG_VARBIT_P(0);
234 235 236 237 238 239 240
	char	   *result,
			   *r;
	bits8	   *sp;
	int			i,
				len,
				bitlen;

241 242 243 244 245 246 247 248
	bitlen = VARBITLEN(s);
	len = (bitlen + 3) / 4;
	result = (char *) palloc(len + 2);
	sp = VARBITS(s);
	r = result;
	*r++ = 'X';
	/* we cheat by knowing that we store full bytes zero padded */
	for (i = 0; i < len; i += 2, sp++)
249
	{
250 251
		*r++ = HEXDIG((*sp) >> 4);
		*r++ = HEXDIG((*sp) & 0xF);
252 253
	}

254
	/*
B
Bruce Momjian 已提交
255 256
	 * Go back one step if we printed a hex number that was not part of the
	 * bitstring anymore
257 258 259 260 261 262
	 */
	if (i > len)
		r--;
	*r = '\0';

	PG_RETURN_CSTRING(result);
263
#endif
264 265
}

266 267 268 269 270 271
/*
 *		bit_recv			- converts external binary format to bit
 */
Datum
bit_recv(PG_FUNCTION_ARGS)
{
272
	StringInfo	buf = (StringInfo) PG_GETARG_POINTER(0);
B
Bruce Momjian 已提交
273

274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290
#ifdef NOT_USED
	Oid			typelem = PG_GETARG_OID(1);
#endif
	int32		atttypmod = PG_GETARG_INT32(2);
	VarBit	   *result;
	int			len,
				bitlen;
	int			ipad;
	bits8		mask;

	bitlen = pq_getmsgint(buf, sizeof(int32));
	if (bitlen < 0)
		ereport(ERROR,
				(errcode(ERRCODE_INVALID_BINARY_REPRESENTATION),
				 errmsg("invalid length in external bit string")));

	/*
B
Bruce Momjian 已提交
291 292
	 * Sometimes atttypmod is not supplied. If it is supplied we need to make
	 * sure that the bitstring fits.
293 294 295 296
	 */
	if (atttypmod > 0 && bitlen != atttypmod)
		ereport(ERROR,
				(errcode(ERRCODE_STRING_DATA_LENGTH_MISMATCH),
B
Bruce Momjian 已提交
297 298
				 errmsg("bit string length %d does not match type bit(%d)",
						bitlen, atttypmod)));
299 300 301

	len = VARBITTOTALLEN(bitlen);
	result = (VarBit *) palloc(len);
302
	SET_VARSIZE(result, len);
303 304 305 306 307 308 309 310 311 312 313 314 315
	VARBITLEN(result) = bitlen;

	pq_copymsgbytes(buf, (char *) VARBITS(result), VARBITBYTES(result));

	/* Make sure last byte is zero-padded if needed */
	ipad = VARBITPAD(result);
	if (ipad > 0)
	{
		mask = BITMASK << ipad;
		*(VARBITS(result) + VARBITBYTES(result) - 1) &= mask;
	}

	PG_RETURN_VARBIT_P(result);
316 317 318 319 320 321 322 323 324 325 326 327
}

/*
 *		bit_send			- converts bit to binary format
 */
Datum
bit_send(PG_FUNCTION_ARGS)
{
	/* Exactly the same as varbit_send, so share code */
	return varbit_send(fcinfo);
}

328
/* bit()
329 330
 * Converts a bit() type to a specific internal length.
 * len is the bitlength specified in the column definition.
331 332 333
 *
 * If doing implicit cast, raise error when source data is wrong length.
 * If doing explicit cast, silently truncate or zero-pad to specified length.
334
 */
335
Datum
336
bit(PG_FUNCTION_ARGS)
337
{
338 339
	VarBit	   *arg = PG_GETARG_VARBIT_P(0);
	int32		len = PG_GETARG_INT32(1);
340 341 342 343 344
	bool		isExplicit = PG_GETARG_BOOL(2);
	VarBit	   *result;
	int			rlen;
	int			ipad;
	bits8		mask;
345 346 347 348

	/* No work if typmod is invalid or supplied data matches it already */
	if (len <= 0 || len == VARBITLEN(arg))
		PG_RETURN_VARBIT_P(arg);
349 350

	if (!isExplicit)
351 352
		ereport(ERROR,
				(errcode(ERRCODE_STRING_DATA_LENGTH_MISMATCH),
B
Bruce Momjian 已提交
353 354
				 errmsg("bit string length %d does not match type bit(%d)",
						VARBITLEN(arg), len)));
355

356 357
	rlen = VARBITTOTALLEN(len);
	/* set to 0 so that string is zero-padded */
358
	result = (VarBit *) palloc0(rlen);
359
	SET_VARSIZE(result, rlen);
360 361 362 363
	VARBITLEN(result) = len;

	memcpy(VARBITS(result), VARBITS(arg),
		   Min(VARBITBYTES(result), VARBITBYTES(arg)));
B
Bruce Momjian 已提交
364

365
	/*
B
Bruce Momjian 已提交
366 367 368
	 * Make sure last byte is zero-padded if needed.  This is useless but safe
	 * if source data was shorter than target length (we assume the last byte
	 * of the source data was itself correctly zero-padded).
369
	 */
370 371 372 373 374 375
	ipad = VARBITPAD(result);
	if (ipad > 0)
	{
		mask = BITMASK << ipad;
		*(VARBITS(result) + VARBITBYTES(result) - 1) &= mask;
	}
376

377
	PG_RETURN_VARBIT_P(result);
378
}
379

380 381 382
Datum
bittypmodin(PG_FUNCTION_ARGS)
{
B
Bruce Momjian 已提交
383
	ArrayType  *ta = PG_GETARG_ARRAYTYPE_P(0);
384 385 386 387 388 389 390

	PG_RETURN_INT32(anybit_typmodin(ta, "bit"));
}

Datum
bittypmodout(PG_FUNCTION_ARGS)
{
B
Bruce Momjian 已提交
391
	int32		typmod = PG_GETARG_INT32(0);
392 393 394 395 396

	PG_RETURN_CSTRING(anybit_typmodout(typmod));
}


397 398 399
/*
 * varbit_in -
 *	  converts a string to the internal representation of a bitstring.
400
 *		This is the same as bit_in except that atttypmod is taken as
401 402 403 404
 *		the maximum length, not the exact length to force the bitstring to.
 */
Datum
varbit_in(PG_FUNCTION_ARGS)
405
{
406
	char	   *input_string = PG_GETARG_CSTRING(0);
B
Bruce Momjian 已提交
407

408 409 410 411 412
#ifdef NOT_USED
	Oid			typelem = PG_GETARG_OID(1);
#endif
	int32		atttypmod = PG_GETARG_INT32(2);
	VarBit	   *result;			/* The resulting bit string			  */
413
	char	   *sp;				/* pointer into the character string  */
414
	bits8	   *r;				/* pointer into the result */
415 416 417
	int			len,			/* Length of the whole data structure */
				bitlen,			/* Number of bits in the bit string   */
				slen;			/* Length of the input string		  */
418
	bool		bit_not_hex;	/* false = hex string  true = bit string */
419
	int			bc;
420 421 422
	bits8		x = 0;

	/* Check that the first character is a b or an x */
423 424
	if (input_string[0] == 'b' || input_string[0] == 'B')
	{
425
		bit_not_hex = true;
426 427 428 429
		sp = input_string + 1;
	}
	else if (input_string[0] == 'x' || input_string[0] == 'X')
	{
430
		bit_not_hex = false;
431 432
		sp = input_string + 1;
	}
433
	else
434
	{
435 436
		bit_not_hex = true;
		sp = input_string;
437
	}
438

439
	slen = strlen(sp);
440
	/* Determine bitlength from input string */
441 442 443 444
	if (bit_not_hex)
		bitlen = slen;
	else
		bitlen = slen * 4;
445 446

	/*
B
Bruce Momjian 已提交
447 448
	 * Sometimes atttypmod is not supplied. If it is supplied we need to make
	 * sure that the bitstring fits.
449
	 */
450 451
	if (atttypmod <= 0)
		atttypmod = bitlen;
452
	else if (bitlen > atttypmod)
453
		ereport(ERROR,
454
				(errcode(ERRCODE_STRING_DATA_RIGHT_TRUNCATION),
455
				 errmsg("bit string too long for type bit varying(%d)",
B
Bruce Momjian 已提交
456
						atttypmod)));
457

458 459
	len = VARBITTOTALLEN(bitlen);
	/* set to 0 so that *r is always initialised and string is zero-padded */
460
	result = (VarBit *) palloc0(len);
461
	SET_VARSIZE(result, len);
462
	VARBITLEN(result) = Min(bitlen, atttypmod);
463 464 465

	r = VARBITS(result);
	if (bit_not_hex)
466
	{
467
		/* Parse the bit representation of the string */
468
		/* We know it fits, as bitlen was compared to atttypmod */
B
Bruce Momjian 已提交
469
		x = HIGHBIT;
470
		for (; *sp; sp++)
471 472 473
		{
			if (*sp == '1')
				*r |= x;
474
			else if (*sp != '0')
475 476 477 478 479
				ereport(ERROR,
						(errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
						 errmsg("\"%c\" is not a valid binary digit",
								*sp)));

480 481
			x >>= 1;
			if (x == 0)
482
			{
B
Bruce Momjian 已提交
483
				x = HIGHBIT;
484 485 486
				r++;
			}
		}
487
	}
488
	else
489
	{
490 491
		/* Parse the hex representation of the string */
		for (bc = 0; *sp; sp++)
492 493 494 495 496 497 498 499
		{
			if (*sp >= '0' && *sp <= '9')
				x = (bits8) (*sp - '0');
			else if (*sp >= 'A' && *sp <= 'F')
				x = (bits8) (*sp - 'A') + 10;
			else if (*sp >= 'a' && *sp <= 'f')
				x = (bits8) (*sp - 'a') + 10;
			else
500 501
				ereport(ERROR,
						(errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
502
						 errmsg("\"%c\" is not a valid hexadecimal digit",
503 504
								*sp)));

505 506 507
			if (bc)
			{
				*r++ |= x;
508
				bc = 0;
509 510 511 512
			}
			else
			{
				*r = x << 4;
513
				bc = 1;
514 515
			}
		}
516 517
	}

518
	PG_RETURN_VARBIT_P(result);
519 520
}

521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536
/* varbit_out -
 *	  Prints the string as bits to preserve length accurately
 */
Datum
varbit_out(PG_FUNCTION_ARGS)
{
	VarBit	   *s = PG_GETARG_VARBIT_P(0);
	char	   *result,
			   *r;
	bits8	   *sp;
	bits8		x;
	int			i,
				k,
				len;

	len = VARBITLEN(s);
537
	result = (char *) palloc(len + 1);
538 539
	sp = VARBITS(s);
	r = result;
540
	for (i = 0; i <= len - BITS_PER_BYTE; i += BITS_PER_BYTE, sp++)
541
	{
542
		/* print full bytes */
543
		x = *sp;
544
		for (k = 0; k < BITS_PER_BYTE; k++)
545
		{
B
Bruce Momjian 已提交
546
			*r++ = IS_HIGHBIT_SET(x) ? '1' : '0';
547 548 549
			x <<= 1;
		}
	}
550
	if (i < len)
551
	{
552 553 554 555 556 557 558
		/* print the last partial byte */
		x = *sp;
		for (k = i; k < len; k++)
		{
			*r++ = IS_HIGHBIT_SET(x) ? '1' : '0';
			x <<= 1;
		}
559 560 561 562 563 564
	}
	*r = '\0';

	PG_RETURN_CSTRING(result);
}

565 566 567 568 569 570 571 572 573
/*
 *		varbit_recv			- converts external binary format to varbit
 *
 * External format is the bitlen as an int32, then the byte array.
 */
Datum
varbit_recv(PG_FUNCTION_ARGS)
{
	StringInfo	buf = (StringInfo) PG_GETARG_POINTER(0);
B
Bruce Momjian 已提交
574

575 576 577 578
#ifdef NOT_USED
	Oid			typelem = PG_GETARG_OID(1);
#endif
	int32		atttypmod = PG_GETARG_INT32(2);
579 580 581 582 583 584 585 586
	VarBit	   *result;
	int			len,
				bitlen;
	int			ipad;
	bits8		mask;

	bitlen = pq_getmsgint(buf, sizeof(int32));
	if (bitlen < 0)
587 588 589
		ereport(ERROR,
				(errcode(ERRCODE_INVALID_BINARY_REPRESENTATION),
				 errmsg("invalid length in external bit string")));
590

591
	/*
B
Bruce Momjian 已提交
592 593
	 * Sometimes atttypmod is not supplied. If it is supplied we need to make
	 * sure that the bitstring fits.
594 595 596 597 598 599 600
	 */
	if (atttypmod > 0 && bitlen > atttypmod)
		ereport(ERROR,
				(errcode(ERRCODE_STRING_DATA_RIGHT_TRUNCATION),
				 errmsg("bit string too long for type bit varying(%d)",
						atttypmod)));

601 602
	len = VARBITTOTALLEN(bitlen);
	result = (VarBit *) palloc(len);
603
	SET_VARSIZE(result, len);
604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629
	VARBITLEN(result) = bitlen;

	pq_copymsgbytes(buf, (char *) VARBITS(result), VARBITBYTES(result));

	/* Make sure last byte is zero-padded if needed */
	ipad = VARBITPAD(result);
	if (ipad > 0)
	{
		mask = BITMASK << ipad;
		*(VARBITS(result) + VARBITBYTES(result) - 1) &= mask;
	}

	PG_RETURN_VARBIT_P(result);
}

/*
 *		varbit_send			- converts varbit to binary format
 */
Datum
varbit_send(PG_FUNCTION_ARGS)
{
	VarBit	   *s = PG_GETARG_VARBIT_P(0);
	StringInfoData buf;

	pq_begintypsend(&buf);
	pq_sendint(&buf, VARBITLEN(s), sizeof(int32));
630
	pq_sendbytes(&buf, (char *) VARBITS(s), VARBITBYTES(s));
631 632 633
	PG_RETURN_BYTEA_P(pq_endtypsend(&buf));
}

634 635 636
/* varbit()
 * Converts a varbit() type to a specific internal length.
 * len is the maximum bitlength specified in the column definition.
637 638 639
 *
 * If doing implicit cast, raise error when source data is too long.
 * If doing explicit cast, silently truncate to max length.
640 641 642 643 644 645
 */
Datum
varbit(PG_FUNCTION_ARGS)
{
	VarBit	   *arg = PG_GETARG_VARBIT_P(0);
	int32		len = PG_GETARG_INT32(1);
646
	bool		isExplicit = PG_GETARG_BOOL(2);
647 648
	VarBit	   *result;
	int			rlen;
649 650
	int			ipad;
	bits8		mask;
651 652 653 654 655

	/* No work if typmod is invalid or supplied data matches it already */
	if (len <= 0 || len >= VARBITLEN(arg))
		PG_RETURN_VARBIT_P(arg);

656
	if (!isExplicit)
657
		ereport(ERROR,
658
				(errcode(ERRCODE_STRING_DATA_RIGHT_TRUNCATION),
659
				 errmsg("bit string too long for type bit varying(%d)",
B
Bruce Momjian 已提交
660
						len)));
661

662 663
	rlen = VARBITTOTALLEN(len);
	result = (VarBit *) palloc(rlen);
664
	SET_VARSIZE(result, rlen);
665 666 667 668
	VARBITLEN(result) = len;

	memcpy(VARBITS(result), VARBITS(arg), VARBITBYTES(result));

669 670 671 672 673 674 675
	/* Make sure last byte is zero-padded if needed */
	ipad = VARBITPAD(result);
	if (ipad > 0)
	{
		mask = BITMASK << ipad;
		*(VARBITS(result) + VARBITBYTES(result) - 1) &= mask;
	}
676

677
	PG_RETURN_VARBIT_P(result);
678
}
679

680 681 682
Datum
varbittypmodin(PG_FUNCTION_ARGS)
{
B
Bruce Momjian 已提交
683
	ArrayType  *ta = PG_GETARG_ARRAYTYPE_P(0);
684 685 686 687 688 689 690

	PG_RETURN_INT32(anybit_typmodin(ta, "varbit"));
}

Datum
varbittypmodout(PG_FUNCTION_ARGS)
{
B
Bruce Momjian 已提交
691
	int32		typmod = PG_GETARG_INT32(0);
692 693 694 695

	PG_RETURN_CSTRING(anybit_typmodout(typmod));
}

696 697 698 699 700

/*
 * Comparison operators
 *
 * We only need one set of comparison operators for bitstrings, as the lengths
701
 * are stored in the same way for zero-padded and varying bit strings.
702
 *
703
 * Note that the standard is not unambiguous about the comparison between
704
 * zero-padded bit strings and varying bitstrings. If the same value is written
705 706
 * into a zero padded bitstring as into a varying bitstring, but the zero
 * padded bitstring has greater length, it will be bigger.
707 708 709
 *
 * Zeros from the beginning of a bitstring cannot simply be ignored, as they
 * may be part of a bit string and may be significant.
710 711 712 713
 *
 * Note: btree indexes need these routines not to leak memory; therefore,
 * be careful to free working copies of toasted datums.  Most places don't
 * need to be so careful.
714 715
 */

716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745
/* bit_cmp
 *
 * Compares two bitstrings and returns <0, 0, >0 depending on whether the first
 * string is smaller, equal, or bigger than the second. All bits are considered
 * and additional zero bits may make one string smaller/larger than the other,
 * even if their zero-padded values would be the same.
 */
static int32
bit_cmp(VarBit *arg1, VarBit *arg2)
{
	int			bitlen1,
				bytelen1,
				bitlen2,
				bytelen2;
	int32		cmp;

	bytelen1 = VARBITBYTES(arg1);
	bytelen2 = VARBITBYTES(arg2);

	cmp = memcmp(VARBITS(arg1), VARBITS(arg2), Min(bytelen1, bytelen2));
	if (cmp == 0)
	{
		bitlen1 = VARBITLEN(arg1);
		bitlen2 = VARBITLEN(arg2);
		if (bitlen1 != bitlen2)
			cmp = (bitlen1 < bitlen2) ? -1 : 1;
	}
	return cmp;
}

746 747
Datum
biteq(PG_FUNCTION_ARGS)
748
{
749 750 751
	VarBit	   *arg1 = PG_GETARG_VARBIT_P(0);
	VarBit	   *arg2 = PG_GETARG_VARBIT_P(1);
	bool		result;
752 753 754 755 756
	int			bitlen1,
				bitlen2;

	bitlen1 = VARBITLEN(arg1);
	bitlen2 = VARBITLEN(arg2);
757 758

	/* fast path for different-length inputs */
759
	if (bitlen1 != bitlen2)
760 761
		result = false;
	else
762
		result = (bit_cmp(arg1, arg2) == 0);
763 764 765

	PG_FREE_IF_COPY(arg1, 0);
	PG_FREE_IF_COPY(arg2, 1);
766

767
	PG_RETURN_BOOL(result);
768 769
}

770 771
Datum
bitne(PG_FUNCTION_ARGS)
772
{
773 774 775
	VarBit	   *arg1 = PG_GETARG_VARBIT_P(0);
	VarBit	   *arg2 = PG_GETARG_VARBIT_P(1);
	bool		result;
776 777
	int			bitlen1,
				bitlen2;
778

779 780
	bitlen1 = VARBITLEN(arg1);
	bitlen2 = VARBITLEN(arg2);
781 782

	/* fast path for different-length inputs */
783
	if (bitlen1 != bitlen2)
784 785
		result = true;
	else
786
		result = (bit_cmp(arg1, arg2) != 0);
787 788 789

	PG_FREE_IF_COPY(arg1, 0);
	PG_FREE_IF_COPY(arg2, 1);
790

791
	PG_RETURN_BOOL(result);
792 793
}

794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810
Datum
bitlt(PG_FUNCTION_ARGS)
{
	VarBit	   *arg1 = PG_GETARG_VARBIT_P(0);
	VarBit	   *arg2 = PG_GETARG_VARBIT_P(1);
	bool		result;

	result = (bit_cmp(arg1, arg2) < 0);

	PG_FREE_IF_COPY(arg1, 0);
	PG_FREE_IF_COPY(arg2, 1);

	PG_RETURN_BOOL(result);
}

Datum
bitle(PG_FUNCTION_ARGS)
811
{
812 813 814 815 816 817 818 819 820 821
	VarBit	   *arg1 = PG_GETARG_VARBIT_P(0);
	VarBit	   *arg2 = PG_GETARG_VARBIT_P(1);
	bool		result;

	result = (bit_cmp(arg1, arg2) <= 0);

	PG_FREE_IF_COPY(arg1, 0);
	PG_FREE_IF_COPY(arg2, 1);

	PG_RETURN_BOOL(result);
822 823
}

824 825
Datum
bitgt(PG_FUNCTION_ARGS)
826
{
827 828 829 830 831 832 833 834 835 836
	VarBit	   *arg1 = PG_GETARG_VARBIT_P(0);
	VarBit	   *arg2 = PG_GETARG_VARBIT_P(1);
	bool		result;

	result = (bit_cmp(arg1, arg2) > 0);

	PG_FREE_IF_COPY(arg1, 0);
	PG_FREE_IF_COPY(arg2, 1);

	PG_RETURN_BOOL(result);
837 838
}

839 840
Datum
bitge(PG_FUNCTION_ARGS)
841
{
842 843 844 845 846 847 848 849 850 851
	VarBit	   *arg1 = PG_GETARG_VARBIT_P(0);
	VarBit	   *arg2 = PG_GETARG_VARBIT_P(1);
	bool		result;

	result = (bit_cmp(arg1, arg2) >= 0);

	PG_FREE_IF_COPY(arg1, 0);
	PG_FREE_IF_COPY(arg2, 1);

	PG_RETURN_BOOL(result);
852 853
}

854 855
Datum
bitcmp(PG_FUNCTION_ARGS)
856
{
857 858 859 860 861 862 863 864 865 866
	VarBit	   *arg1 = PG_GETARG_VARBIT_P(0);
	VarBit	   *arg2 = PG_GETARG_VARBIT_P(1);
	int32		result;

	result = bit_cmp(arg1, arg2);

	PG_FREE_IF_COPY(arg1, 0);
	PG_FREE_IF_COPY(arg2, 1);

	PG_RETURN_INT32(result);
867 868 869 870 871
}

/* bitcat
 * Concatenation of bit strings
 */
872 873
Datum
bitcat(PG_FUNCTION_ARGS)
874
{
875 876 877
	VarBit	   *arg1 = PG_GETARG_VARBIT_P(0);
	VarBit	   *arg2 = PG_GETARG_VARBIT_P(1);
	VarBit	   *result;
878 879 880 881 882 883 884 885 886 887 888
	int			bitlen1,
				bitlen2,
				bytelen,
				bit1pad,
				bit2shift;
	bits8	   *pr,
			   *pa;

	bitlen1 = VARBITLEN(arg1);
	bitlen2 = VARBITLEN(arg2);

889
	bytelen = VARBITTOTALLEN(bitlen1 + bitlen2);
890

891
	result = (VarBit *) palloc(bytelen);
892
	SET_VARSIZE(result, bytelen);
893
	VARBITLEN(result) = bitlen1 + bitlen2;
894

895 896
	/* Copy the first bitstring in */
	memcpy(VARBITS(result), VARBITS(arg1), VARBITBYTES(arg1));
897

898 899 900 901 902 903 904 905 906
	/* Copy the second bit string */
	bit1pad = VARBITPAD(arg1);
	if (bit1pad == 0)
	{
		memcpy(VARBITS(result) + VARBITBYTES(arg1), VARBITS(arg2),
			   VARBITBYTES(arg2));
	}
	else if (bitlen2 > 0)
	{
907
		/* We need to shift all the bits to fit */
908
		bit2shift = BITS_PER_BYTE - bit1pad;
909
		pr = VARBITS(result) + VARBITBYTES(arg1) - 1;
910
		for (pa = VARBITS(arg2); pa < VARBITEND(arg2); pa++)
911 912 913 914 915 916 917 918
		{
			*pr |= ((*pa >> bit2shift) & BITMASK);
			pr++;
			if (pr < VARBITEND(result))
				*pr = (*pa << bit1pad) & BITMASK;
		}
	}

919
	PG_RETURN_VARBIT_P(result);
920 921 922
}

/* bitsubstr
923
 * retrieve a substring from the bit string.
924 925 926
 * Note, s is 1-based.
 * SQL draft 6.10 9)
 */
927 928
Datum
bitsubstr(PG_FUNCTION_ARGS)
929
{
930 931 932 933
	VarBit	   *arg = PG_GETARG_VARBIT_P(0);
	int32		s = PG_GETARG_INT32(1);
	int32		l = PG_GETARG_INT32(2);
	VarBit	   *result;
934 935 936 937 938 939 940 941 942 943 944 945 946 947
	int			bitlen,
				rbitlen,
				len,
				ipad = 0,
				ishift,
				i;
	int			e,
				s1,
				e1;
	bits8		mask,
			   *r,
			   *ps;

	bitlen = VARBITLEN(arg);
948
	/* If we do not have an upper bound, set bitlen */
B
Bruce Momjian 已提交
949
	if (l == -1)
950
		l = bitlen;
951 952 953 954
	e = s + l;
	s1 = Max(s, 1);
	e1 = Min(e, bitlen + 1);
	if (s1 > bitlen || e1 < 1)
955
	{
956 957 958
		/* Need to return a zero-length bitstring */
		len = VARBITTOTALLEN(0);
		result = (VarBit *) palloc(len);
959
		SET_VARSIZE(result, len);
960
		VARBITLEN(result) = 0;
961
	}
962
	else
963
	{
964
		/*
B
Bruce Momjian 已提交
965 966
		 * OK, we've got a true substring starting at position s1-1 and ending
		 * at position e1-1
967 968
		 */
		rbitlen = e1 - s1;
969 970
		len = VARBITTOTALLEN(rbitlen);
		result = (VarBit *) palloc(len);
971
		SET_VARSIZE(result, len);
972
		VARBITLEN(result) = rbitlen;
973 974
		len -= VARHDRSZ + VARBITHDRSZ;
		/* Are we copying from a byte boundary? */
975
		if ((s1 - 1) % BITS_PER_BYTE == 0)
976 977
		{
			/* Yep, we are copying bytes */
978
			memcpy(VARBITS(result), VARBITS(arg) + (s1 - 1) / BITS_PER_BYTE,
979
				   len);
980 981 982 983
		}
		else
		{
			/* Figure out how much we need to shift the sequence by */
984
			ishift = (s1 - 1) % BITS_PER_BYTE;
985
			r = VARBITS(result);
986
			ps = VARBITS(arg) + (s1 - 1) / BITS_PER_BYTE;
987 988 989 990
			for (i = 0; i < len; i++)
			{
				*r = (*ps << ishift) & BITMASK;
				if ((++ps) < VARBITEND(arg))
991
					*r |= *ps >> (BITS_PER_BYTE - ishift);
992 993 994 995 996 997 998 999 1000 1001
				r++;
			}
		}
		/* Do we need to pad at the end? */
		ipad = VARBITPAD(result);
		if (ipad > 0)
		{
			mask = BITMASK << ipad;
			*(VARBITS(result) + len - 1) &= mask;
		}
1002 1003
	}

1004 1005 1006
	PG_RETURN_VARBIT_P(result);
}

B
Bruce Momjian 已提交
1007
/* bitlength, bitoctetlength
1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019 1020 1021 1022 1023
 * Return the length of a bit string
 */
Datum
bitlength(PG_FUNCTION_ARGS)
{
	VarBit	   *arg = PG_GETARG_VARBIT_P(0);

	PG_RETURN_INT32(VARBITLEN(arg));
}

Datum
bitoctetlength(PG_FUNCTION_ARGS)
{
	VarBit	   *arg = PG_GETARG_VARBIT_P(0);

	PG_RETURN_INT32(VARBITBYTES(arg));
1024 1025 1026
}

/* bitand
1027
 * perform a logical AND on two bit strings.
1028
 */
1029 1030
Datum
bitand(PG_FUNCTION_ARGS)
1031
{
1032 1033 1034
	VarBit	   *arg1 = PG_GETARG_VARBIT_P(0);
	VarBit	   *arg2 = PG_GETARG_VARBIT_P(1);
	VarBit	   *result;
1035
	int			len,
1036 1037
				bitlen1,
				bitlen2,
1038 1039 1040 1041 1042
				i;
	bits8	   *p1,
			   *p2,
			   *r;

1043 1044 1045
	bitlen1 = VARBITLEN(arg1);
	bitlen2 = VARBITLEN(arg2);
	if (bitlen1 != bitlen2)
1046
		ereport(ERROR,
1047
				(errcode(ERRCODE_STRING_DATA_LENGTH_MISMATCH),
1048 1049
				 errmsg("cannot AND bit strings of different sizes")));

1050 1051
	len = VARSIZE(arg1);
	result = (VarBit *) palloc(len);
1052
	SET_VARSIZE(result, len);
1053
	VARBITLEN(result) = bitlen1;
1054

1055 1056 1057 1058
	p1 = VARBITS(arg1);
	p2 = VARBITS(arg2);
	r = VARBITS(result);
	for (i = 0; i < VARBITBYTES(arg1); i++)
1059 1060 1061 1062
		*r++ = *p1++ & *p2++;

	/* Padding is not needed as & of 0 pad is 0 */

1063
	PG_RETURN_VARBIT_P(result);
1064 1065 1066
}

/* bitor
1067
 * perform a logical OR on two bit strings.
1068
 */
1069 1070
Datum
bitor(PG_FUNCTION_ARGS)
1071
{
1072 1073 1074
	VarBit	   *arg1 = PG_GETARG_VARBIT_P(0);
	VarBit	   *arg2 = PG_GETARG_VARBIT_P(1);
	VarBit	   *result;
1075
	int			len,
1076 1077
				bitlen1,
				bitlen2,
1078 1079 1080 1081 1082
				i;
	bits8	   *p1,
			   *p2,
			   *r;
	bits8		mask;
1083

1084 1085 1086
	bitlen1 = VARBITLEN(arg1);
	bitlen2 = VARBITLEN(arg2);
	if (bitlen1 != bitlen2)
1087
		ereport(ERROR,
1088
				(errcode(ERRCODE_STRING_DATA_LENGTH_MISMATCH),
1089
				 errmsg("cannot OR bit strings of different sizes")));
1090 1091
	len = VARSIZE(arg1);
	result = (VarBit *) palloc(len);
1092
	SET_VARSIZE(result, len);
1093
	VARBITLEN(result) = bitlen1;
1094

1095 1096 1097 1098
	p1 = VARBITS(arg1);
	p2 = VARBITS(arg2);
	r = VARBITS(result);
	for (i = 0; i < VARBITBYTES(arg1); i++)
1099
		*r++ = *p1++ | *p2++;
1100

1101 1102
	/* Pad the result */
	mask = BITMASK << VARBITPAD(result);
1103 1104 1105 1106 1107
	if (mask)
	{
		r--;
		*r &= mask;
	}
1108

1109
	PG_RETURN_VARBIT_P(result);
1110 1111 1112
}

/* bitxor
1113
 * perform a logical XOR on two bit strings.
1114
 */
1115 1116
Datum
bitxor(PG_FUNCTION_ARGS)
1117
{
1118 1119 1120
	VarBit	   *arg1 = PG_GETARG_VARBIT_P(0);
	VarBit	   *arg2 = PG_GETARG_VARBIT_P(1);
	VarBit	   *result;
1121
	int			len,
1122 1123
				bitlen1,
				bitlen2,
1124 1125 1126 1127 1128 1129
				i;
	bits8	   *p1,
			   *p2,
			   *r;
	bits8		mask;

1130 1131 1132
	bitlen1 = VARBITLEN(arg1);
	bitlen2 = VARBITLEN(arg2);
	if (bitlen1 != bitlen2)
1133
		ereport(ERROR,
1134
				(errcode(ERRCODE_STRING_DATA_LENGTH_MISMATCH),
1135 1136
				 errmsg("cannot XOR bit strings of different sizes")));

1137 1138
	len = VARSIZE(arg1);
	result = (VarBit *) palloc(len);
1139
	SET_VARSIZE(result, len);
1140
	VARBITLEN(result) = bitlen1;
1141

1142 1143 1144 1145
	p1 = VARBITS(arg1);
	p2 = VARBITS(arg2);
	r = VARBITS(result);
	for (i = 0; i < VARBITBYTES(arg1); i++)
1146 1147 1148 1149
		*r++ = *p1++ ^ *p2++;

	/* Pad the result */
	mask = BITMASK << VARBITPAD(result);
1150 1151 1152 1153 1154
	if (mask)
	{
		r--;
		*r &= mask;
	}
1155

1156
	PG_RETURN_VARBIT_P(result);
1157 1158 1159
}

/* bitnot
1160
 * perform a logical NOT on a bit string.
1161
 */
1162 1163
Datum
bitnot(PG_FUNCTION_ARGS)
1164
{
1165 1166
	VarBit	   *arg = PG_GETARG_VARBIT_P(0);
	VarBit	   *result;
1167 1168 1169 1170
	bits8	   *p,
			   *r;
	bits8		mask;

1171
	result = (VarBit *) palloc(VARSIZE(arg));
1172
	SET_VARSIZE(result, VARSIZE(arg));
1173
	VARBITLEN(result) = VARBITLEN(arg);
1174

1175 1176 1177
	p = VARBITS(arg);
	r = VARBITS(result);
	for (; p < VARBITEND(arg); p++)
B
Bruce Momjian 已提交
1178
		*r++ = ~*p;
1179

1180 1181
	/* Pad the result */
	mask = BITMASK << VARBITPAD(result);
1182 1183 1184 1185 1186
	if (mask)
	{
		r--;
		*r &= mask;
	}
1187

1188
	PG_RETURN_VARBIT_P(result);
1189 1190 1191
}

/* bitshiftleft
1192
 * do a left shift (i.e. towards the beginning of the string)
1193
 */
1194 1195
Datum
bitshiftleft(PG_FUNCTION_ARGS)
1196
{
1197 1198 1199
	VarBit	   *arg = PG_GETARG_VARBIT_P(0);
	int32		shft = PG_GETARG_INT32(1);
	VarBit	   *result;
1200 1201 1202 1203 1204 1205 1206 1207
	int			byte_shift,
				ishift,
				len;
	bits8	   *p,
			   *r;

	/* Negative shift is a shift to the right */
	if (shft < 0)
1208 1209 1210
		PG_RETURN_DATUM(DirectFunctionCall2(bitshiftright,
											VarBitPGetDatum(arg),
											Int32GetDatum(-shft)));
1211

1212
	result = (VarBit *) palloc(VARSIZE(arg));
1213
	SET_VARSIZE(result, VARSIZE(arg));
1214
	VARBITLEN(result) = VARBITLEN(arg);
1215 1216 1217 1218 1219
	r = VARBITS(result);

	/* If we shifted all the bits out, return an all-zero string */
	if (shft >= VARBITLEN(arg))
	{
1220
		MemSet(r, 0, VARBITBYTES(arg));
1221 1222
		PG_RETURN_VARBIT_P(result);
	}
1223

1224 1225
	byte_shift = shft / BITS_PER_BYTE;
	ishift = shft % BITS_PER_BYTE;
1226
	p = VARBITS(arg) + byte_shift;
1227 1228 1229 1230 1231 1232

	if (ishift == 0)
	{
		/* Special case: we can do a memcpy */
		len = VARBITBYTES(arg) - byte_shift;
		memcpy(r, p, len);
1233
		MemSet(r + len, 0, byte_shift);
1234 1235 1236 1237 1238 1239 1240
	}
	else
	{
		for (; p < VARBITEND(arg); r++)
		{
			*r = *p << ishift;
			if ((++p) < VARBITEND(arg))
1241
				*r |= *p >> (BITS_PER_BYTE - ishift);
1242 1243
		}
		for (; r < VARBITEND(result); r++)
1244
			*r = 0;
1245 1246
	}

1247
	PG_RETURN_VARBIT_P(result);
1248 1249 1250
}

/* bitshiftright
1251
 * do a right shift (i.e. towards the end of the string)
1252
 */
1253 1254
Datum
bitshiftright(PG_FUNCTION_ARGS)
1255
{
1256 1257 1258
	VarBit	   *arg = PG_GETARG_VARBIT_P(0);
	int32		shft = PG_GETARG_INT32(1);
	VarBit	   *result;
1259 1260 1261 1262 1263 1264 1265 1266
	int			byte_shift,
				ishift,
				len;
	bits8	   *p,
			   *r;

	/* Negative shift is a shift to the left */
	if (shft < 0)
1267
		PG_RETURN_DATUM(DirectFunctionCall2(bitshiftleft,
B
Bruce Momjian 已提交
1268 1269
											VarBitPGetDatum(arg),
											Int32GetDatum(-shft)));
1270

1271
	result = (VarBit *) palloc(VARSIZE(arg));
1272
	SET_VARSIZE(result, VARSIZE(arg));
1273
	VARBITLEN(result) = VARBITLEN(arg);
1274 1275 1276 1277 1278
	r = VARBITS(result);

	/* If we shifted all the bits out, return an all-zero string */
	if (shft >= VARBITLEN(arg))
	{
1279
		MemSet(r, 0, VARBITBYTES(arg));
1280 1281
		PG_RETURN_VARBIT_P(result);
	}
1282

1283 1284
	byte_shift = shft / BITS_PER_BYTE;
	ishift = shft % BITS_PER_BYTE;
1285
	p = VARBITS(arg);
1286 1287

	/* Set the first part of the result to 0 */
1288
	MemSet(r, 0, byte_shift);
1289
	r += byte_shift;
1290 1291 1292 1293 1294

	if (ishift == 0)
	{
		/* Special case: we can do a memcpy */
		len = VARBITBYTES(arg) - byte_shift;
1295
		memcpy(r, p, len);
1296 1297 1298
	}
	else
	{
1299 1300
		if (r < VARBITEND(result))
			*r = 0;				/* initialize first byte */
1301 1302 1303 1304
		for (; r < VARBITEND(result); p++)
		{
			*r |= *p >> ishift;
			if ((++r) < VARBITEND(result))
1305
				*r = (*p << (BITS_PER_BYTE - ishift)) & BITMASK;
1306 1307 1308
		}
	}

1309
	PG_RETURN_VARBIT_P(result);
1310 1311
}

1312 1313
/*
 * This is not defined in any standard. We retain the natural ordering of
B
Bruce Momjian 已提交
1314
 * bits here, as it just seems more intuitive.
1315 1316 1317
 */
Datum
bitfromint4(PG_FUNCTION_ARGS)
1318
{
1319
	int32		a = PG_GETARG_INT32(0);
1320
	int32		typmod = PG_GETARG_INT32(1);
1321 1322
	VarBit	   *result;
	bits8	   *r;
1323 1324 1325
	int			rlen;
	int			destbitsleft,
				srcbitsleft;
B
Bruce Momjian 已提交
1326

1327 1328 1329 1330 1331
	if (typmod <= 0)
		typmod = 1;				/* default bit length */

	rlen = VARBITTOTALLEN(typmod);
	result = (VarBit *) palloc(rlen);
1332
	SET_VARSIZE(result, rlen);
1333
	VARBITLEN(result) = typmod;
B
Bruce Momjian 已提交
1334

1335
	r = VARBITS(result);
1336 1337 1338 1339 1340 1341 1342 1343 1344 1345 1346 1347 1348
	destbitsleft = typmod;
	srcbitsleft = 32;
	/* drop any input bits that don't fit */
	srcbitsleft = Min(srcbitsleft, destbitsleft);
	/* sign-fill any excess bytes in output */
	while (destbitsleft >= srcbitsleft + 8)
	{
		*r++ = (bits8) ((a < 0) ? BITMASK : 0);
		destbitsleft -= 8;
	}
	/* store first fractional byte */
	if (destbitsleft > srcbitsleft)
	{
1349 1350 1351 1352 1353 1354
		int		val = (int) (a >> (destbitsleft - 8));

		/* Force sign-fill in case the compiler implements >> as zero-fill */
		if (a < 0)
			val |= (-1) << (srcbitsleft + 8 - destbitsleft);
		*r++ = (bits8) (val & BITMASK);
1355 1356 1357 1358 1359 1360 1361 1362 1363 1364 1365 1366
		destbitsleft -= 8;
	}
	/* Now srcbitsleft and destbitsleft are the same, need not track both */
	/* store whole bytes */
	while (destbitsleft >= 8)
	{
		*r++ = (bits8) ((a >> (destbitsleft - 8)) & BITMASK);
		destbitsleft -= 8;
	}
	/* store last fractional byte */
	if (destbitsleft > 0)
		*r = (bits8) ((a << (8 - destbitsleft)) & BITMASK);
1367

1368
	PG_RETURN_VARBIT_P(result);
1369 1370
}

1371 1372
Datum
bittoint4(PG_FUNCTION_ARGS)
1373
{
1374 1375 1376
	VarBit	   *arg = PG_GETARG_VARBIT_P(0);
	uint32		result;
	bits8	   *r;
1377

1378
	/* Check that the bit string is not too long */
1379
	if (VARBITLEN(arg) > sizeof(result) * BITS_PER_BYTE)
1380 1381 1382 1383
		ereport(ERROR,
				(errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
				 errmsg("integer out of range")));

1384 1385 1386
	result = 0;
	for (r = VARBITS(arg); r < VARBITEND(arg); r++)
	{
1387
		result <<= BITS_PER_BYTE;
1388 1389 1390 1391
		result |= *r;
	}
	/* Now shift the result to take account of the padding at the end */
	result >>= VARBITPAD(arg);
1392

1393
	PG_RETURN_INT32(result);
1394
}
1395

1396 1397 1398 1399
Datum
bitfromint8(PG_FUNCTION_ARGS)
{
	int64		a = PG_GETARG_INT64(0);
1400
	int32		typmod = PG_GETARG_INT32(1);
1401 1402
	VarBit	   *result;
	bits8	   *r;
1403 1404 1405
	int			rlen;
	int			destbitsleft,
				srcbitsleft;
1406

1407 1408
	if (typmod <= 0)
		typmod = 1;				/* default bit length */
1409

1410 1411
	rlen = VARBITTOTALLEN(typmod);
	result = (VarBit *) palloc(rlen);
1412
	SET_VARSIZE(result, rlen);
1413
	VARBITLEN(result) = typmod;
1414

1415 1416 1417 1418
	r = VARBITS(result);
	destbitsleft = typmod;
#ifndef INT64_IS_BUSTED
	srcbitsleft = 64;
1419
#else
1420
	srcbitsleft = 32;			/* don't try to shift more than 32 */
1421
#endif
1422 1423 1424 1425 1426 1427 1428 1429 1430 1431 1432
	/* drop any input bits that don't fit */
	srcbitsleft = Min(srcbitsleft, destbitsleft);
	/* sign-fill any excess bytes in output */
	while (destbitsleft >= srcbitsleft + 8)
	{
		*r++ = (bits8) ((a < 0) ? BITMASK : 0);
		destbitsleft -= 8;
	}
	/* store first fractional byte */
	if (destbitsleft > srcbitsleft)
	{
1433 1434 1435 1436 1437 1438
		int		val = (int) (a >> (destbitsleft - 8));

		/* Force sign-fill in case the compiler implements >> as zero-fill */
		if (a < 0)
			val |= (-1) << (srcbitsleft + 8 - destbitsleft);
		*r++ = (bits8) (val & BITMASK);
1439 1440 1441 1442 1443 1444 1445 1446 1447 1448 1449 1450 1451 1452
		destbitsleft -= 8;
	}
	/* Now srcbitsleft and destbitsleft are the same, need not track both */
	/* store whole bytes */
	while (destbitsleft >= 8)
	{
		*r++ = (bits8) ((a >> (destbitsleft - 8)) & BITMASK);
		destbitsleft -= 8;
	}
	/* store last fractional byte */
	if (destbitsleft > 0)
		*r = (bits8) ((a << (8 - destbitsleft)) & BITMASK);

	PG_RETURN_VARBIT_P(result);
1453 1454 1455 1456 1457 1458 1459 1460 1461 1462 1463
}

Datum
bittoint8(PG_FUNCTION_ARGS)
{
	VarBit	   *arg = PG_GETARG_VARBIT_P(0);
	uint64		result;
	bits8	   *r;

	/* Check that the bit string is not too long */
	if (VARBITLEN(arg) > sizeof(result) * BITS_PER_BYTE)
1464 1465
		ereport(ERROR,
				(errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
1466
				 errmsg("bigint out of range")));
1467

1468 1469 1470 1471 1472 1473 1474 1475 1476 1477 1478
	result = 0;
	for (r = VARBITS(arg); r < VARBITEND(arg); r++)
	{
		result <<= BITS_PER_BYTE;
		result |= *r;
	}
	/* Now shift the result to take account of the padding at the end */
	result >>= VARBITPAD(arg);

	PG_RETURN_INT64(result);
}
1479 1480 1481 1482 1483


/* Determines the position of S2 in the bitstring S1 (1-based string).
 * If S2 does not appear in S1 this function returns 0.
 * If S2 is of length 0 this function returns 1.
1484
 * Compatible in usage with POSITION() functions for other data types.
1485 1486 1487 1488
 */
Datum
bitposition(PG_FUNCTION_ARGS)
{
1489
	VarBit	   *str = PG_GETARG_VARBIT_P(0);
B
Bruce Momjian 已提交
1490 1491
	VarBit	   *substr = PG_GETARG_VARBIT_P(1);
	int			substr_length,
1492
				str_length,
1493 1494
				i,
				is;
B
Bruce Momjian 已提交
1495
	bits8	   *s,				/* pointer into substring */
1496
			   *p;				/* pointer into str */
B
Bruce Momjian 已提交
1497 1498 1499 1500
	bits8		cmp,			/* shifted substring byte to compare */
				mask1,			/* mask for substring byte shifted right */
				mask2,			/* mask for substring byte shifted left */
				end_mask,		/* pad mask for last substring byte */
1501
				str_mask;		/* pad mask for last string byte */
1502 1503 1504 1505
	bool		is_match;

	/* Get the substring length */
	substr_length = VARBITLEN(substr);
1506
	str_length = VARBITLEN(str);
1507

1508 1509
	/* String has zero length or substring longer than string, return 0 */
	if ((str_length == 0) || (substr_length > str_length))
B
Bruce Momjian 已提交
1510 1511
		PG_RETURN_INT32(0);

1512
	/* zero-length substring means return 1 */
1513 1514 1515 1516 1517
	if (substr_length == 0)
		PG_RETURN_INT32(1);

	/* Initialise the padding masks */
	end_mask = BITMASK << VARBITPAD(substr);
1518 1519
	str_mask = BITMASK << VARBITPAD(str);
	for (i = 0; i < VARBITBYTES(str) - VARBITBYTES(substr) + 1; i++)
1520
	{
B
Bruce Momjian 已提交
1521 1522
		for (is = 0; is < BITS_PER_BYTE; is++)
		{
1523
			is_match = true;
1524
			p = VARBITS(str) + i;
1525 1526
			mask1 = BITMASK >> is;
			mask2 = ~mask1;
B
Bruce Momjian 已提交
1527 1528
			for (s = VARBITS(substr);
				 is_match && s < VARBITEND(substr); s++)
1529 1530
			{
				cmp = *s >> is;
B
Bruce Momjian 已提交
1531
				if (s == VARBITEND(substr) - 1)
1532 1533
				{
					mask1 &= end_mask >> is;
1534
					if (p == VARBITEND(str) - 1)
B
Bruce Momjian 已提交
1535
					{
1536 1537
						/* Check that there is enough of str left */
						if (mask1 & ~str_mask)
B
Bruce Momjian 已提交
1538
						{
1539 1540 1541
							is_match = false;
							break;
						}
1542
						mask1 &= str_mask;
1543 1544 1545 1546 1547
					}
				}
				is_match = ((cmp ^ *p) & mask1) == 0;
				if (!is_match)
					break;
1548
				/* Move on to the next byte */
1549
				p++;
1550
				if (p == VARBITEND(str))
B
Bruce Momjian 已提交
1551
				{
1552 1553
					mask2 = end_mask << (BITS_PER_BYTE - is);
					is_match = mask2 == 0;
1554
#if 0
1555
					elog(DEBUG4, "S. %d %d em=%2x sm=%2x r=%d",
B
Bruce Momjian 已提交
1556
						 i, is, end_mask, mask2, is_match);
1557
#endif
1558 1559 1560
					break;
				}
				cmp = *s << (BITS_PER_BYTE - is);
B
Bruce Momjian 已提交
1561
				if (s == VARBITEND(substr) - 1)
1562 1563
				{
					mask2 &= end_mask << (BITS_PER_BYTE - is);
1564
					if (p == VARBITEND(str) - 1)
B
Bruce Momjian 已提交
1565
					{
1566
						if (mask2 & ~str_mask)
B
Bruce Momjian 已提交
1567
						{
1568 1569 1570
							is_match = false;
							break;
						}
1571
						mask2 &= str_mask;
1572 1573 1574 1575
					}
				}
				is_match = ((cmp ^ *p) & mask2) == 0;
			}
1576
			/* Have we found a match? */
1577
			if (is_match)
B
Bruce Momjian 已提交
1578
				PG_RETURN_INT32(i * BITS_PER_BYTE + is + 1);
1579 1580 1581 1582
		}
	}
	PG_RETURN_INT32(0);
}