⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 varbit.c

📁 PostgreSQL 8.1.4的源码 适用于Linux下的开源数据库系统
💻 C
📖 第 1 页 / 共 3 页
字号:
 * * External format is the bitlen as an int32, then the byte array. */Datumvarbit_recv(PG_FUNCTION_ARGS){	StringInfo	buf = (StringInfo) PG_GETARG_POINTER(0);#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")));	/*	 * Sometimes atttypmod is not supplied. If it is supplied we need to make	 * sure that the bitstring fits.	 */	if (atttypmod > 0 && bitlen > atttypmod)		ereport(ERROR,				(errcode(ERRCODE_STRING_DATA_RIGHT_TRUNCATION),				 errmsg("bit string too long for type bit varying(%d)",						atttypmod)));	len = VARBITTOTALLEN(bitlen);	result = (VarBit *) palloc(len);	VARATT_SIZEP(result) = len;	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 */Datumvarbit_send(PG_FUNCTION_ARGS){	VarBit	   *s = PG_GETARG_VARBIT_P(0);	StringInfoData buf;	pq_begintypsend(&buf);	pq_sendint(&buf, VARBITLEN(s), sizeof(int32));	pq_sendbytes(&buf, (char *) VARBITS(s), VARBITBYTES(s));	PG_RETURN_BYTEA_P(pq_endtypsend(&buf));}/* varbit() * Converts a varbit() type to a specific internal length. * len is the maximum bitlength specified in the column definition. * * If doing implicit cast, raise error when source data is too long. * If doing explicit cast, silently truncate to max length. */Datumvarbit(PG_FUNCTION_ARGS){	VarBit	   *arg = PG_GETARG_VARBIT_P(0);	int32		len = PG_GETARG_INT32(1);	bool		isExplicit = PG_GETARG_BOOL(2);	VarBit	   *result;	int			rlen;	int			ipad;	bits8		mask;	/* No work if typmod is invalid or supplied data matches it already */	if (len <= 0 || len >= VARBITLEN(arg))		PG_RETURN_VARBIT_P(arg);	if (!isExplicit)		ereport(ERROR,				(errcode(ERRCODE_STRING_DATA_RIGHT_TRUNCATION),				 errmsg("bit string too long for type bit varying(%d)",						len)));	rlen = VARBITTOTALLEN(len);	result = (VarBit *) palloc(rlen);	VARATT_SIZEP(result) = rlen;	VARBITLEN(result) = len;	memcpy(VARBITS(result), VARBITS(arg), 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);}/* * Comparison operators * * We only need one set of comparison operators for bitstrings, as the lengths * are stored in the same way for zero-padded and varying bit strings. * * Note that the standard is not unambiguous about the comparison between * zero-padded bit strings and varying bitstrings. If the same value is written * into a zero padded bitstring as into a varying bitstring, but the zero * padded bitstring has greater length, it will be bigger. * * Zeros from the beginning of a bitstring cannot simply be ignored, as they * may be part of a bit string and may be significant. * * 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. *//* 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 int32bit_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;}Datumbiteq(PG_FUNCTION_ARGS){	VarBit	   *arg1 = PG_GETARG_VARBIT_P(0);	VarBit	   *arg2 = PG_GETARG_VARBIT_P(1);	bool		result;	int			bitlen1,				bitlen2;	bitlen1 = VARBITLEN(arg1);	bitlen2 = VARBITLEN(arg2);	/* fast path for different-length inputs */	if (bitlen1 != bitlen2)		result = false;	else		result = (bit_cmp(arg1, arg2) == 0);	PG_FREE_IF_COPY(arg1, 0);	PG_FREE_IF_COPY(arg2, 1);	PG_RETURN_BOOL(result);}Datumbitne(PG_FUNCTION_ARGS){	VarBit	   *arg1 = PG_GETARG_VARBIT_P(0);	VarBit	   *arg2 = PG_GETARG_VARBIT_P(1);	bool		result;	int			bitlen1,				bitlen2;	bitlen1 = VARBITLEN(arg1);	bitlen2 = VARBITLEN(arg2);	/* fast path for different-length inputs */	if (bitlen1 != bitlen2)		result = true;	else		result = (bit_cmp(arg1, arg2) != 0);	PG_FREE_IF_COPY(arg1, 0);	PG_FREE_IF_COPY(arg2, 1);	PG_RETURN_BOOL(result);}Datumbitlt(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);}Datumbitle(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);}Datumbitgt(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);}Datumbitge(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);}Datumbitcmp(PG_FUNCTION_ARGS){	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);}/* bitcat * Concatenation of bit strings */Datumbitcat(PG_FUNCTION_ARGS){	VarBit	   *arg1 = PG_GETARG_VARBIT_P(0);	VarBit	   *arg2 = PG_GETARG_VARBIT_P(1);	VarBit	   *result;	int			bitlen1,				bitlen2,				bytelen,				bit1pad,				bit2shift;	bits8	   *pr,			   *pa;	bitlen1 = VARBITLEN(arg1);	bitlen2 = VARBITLEN(arg2);	bytelen = VARBITTOTALLEN(bitlen1 + bitlen2);	result = (VarBit *) palloc(bytelen);	VARATT_SIZEP(result) = bytelen;	VARBITLEN(result) = bitlen1 + bitlen2;	/* Copy the first bitstring in */	memcpy(VARBITS(result), VARBITS(arg1), VARBITBYTES(arg1));	/* Copy the second bit string */	bit1pad = VARBITPAD(arg1);	if (bit1pad == 0)	{		memcpy(VARBITS(result) + VARBITBYTES(arg1), VARBITS(arg2),			   VARBITBYTES(arg2));	}	else if (bitlen2 > 0)	{		/* We need to shift all the bits to fit */		bit2shift = BITS_PER_BYTE - bit1pad;		pr = VARBITS(result) + VARBITBYTES(arg1) - 1;		for (pa = VARBITS(arg2); pa < VARBITEND(arg2); pa++)		{			*pr |= ((*pa >> bit2shift) & BITMASK);			pr++;			if (pr < VARBITEND(result))				*pr = (*pa << bit1pad) & BITMASK;		}	}	PG_RETURN_VARBIT_P(result);}/* bitsubstr * retrieve a substring from the bit string. * Note, s is 1-based. * SQL draft 6.10 9) */Datumbitsubstr(PG_FUNCTION_ARGS){	VarBit	   *arg = PG_GETARG_VARBIT_P(0);	int32		s = PG_GETARG_INT32(1);	int32		l = PG_GETARG_INT32(2);	VarBit	   *result;	int			bitlen,				rbitlen,				len,				ipad = 0,				ishift,				i;	int			e,				s1,				e1;	bits8		mask,			   *r,			   *ps;	bitlen = VARBITLEN(arg);	/* If we do not have an upper bound, set bitlen */	if (l == -1)		l = bitlen;	e = s + l;	s1 = Max(s, 1);	e1 = Min(e, bitlen + 1);	if (s1 > bitlen || e1 < 1)	{		/* Need to return a zero-length bitstring */		len = VARBITTOTALLEN(0);		result = (VarBit *) palloc(len);		VARATT_SIZEP(result) = len;		VARBITLEN(result) = 0;	}	else	{		/*		 * OK, we've got a true substring starting at position s1-1 and ending		 * at position e1-1		 */		rbitlen = e1 - s1;		len = VARBITTOTALLEN(rbitlen);		result = (VarBit *) palloc(len);		VARATT_SIZEP(result) = len;		VARBITLEN(result) = rbitlen;		len -= VARHDRSZ + VARBITHDRSZ;		/* Are we copying from a byte boundary? */		if ((s1 - 1) % BITS_PER_BYTE == 0)		{			/* Yep, we are copying bytes */			memcpy(VARBITS(result), VARBITS(arg) + (s1 - 1) / BITS_PER_BYTE,				   len);		}		else		{			/* Figure out how much we need to shift the sequence by */			ishift = (s1 - 1) % BITS_PER_BYTE;			r = VARBITS(result);			ps = VARBITS(arg) + (s1 - 1) / BITS_PER_BYTE;			for (i = 0; i < len; i++)			{				*r = (*ps << ishift) & BITMASK;				if ((++ps) < VARBITEND(arg))					*r |= *ps >> (BITS_PER_BYTE - ishift);				r++;			}		}		/* Do we need to pad at the end? */		ipad = VARBITPAD(result);		if (ipad > 0)		{			mask = BITMASK << ipad;			*(VARBITS(result) + len - 1) &= mask;		}	}	PG_RETURN_VARBIT_P(result);}/* bitlength, bitoctetlength * Return the length of a bit string */Datumbitlength(PG_FUNCTION_ARGS){	VarBit	   *arg = PG_GETARG_VARBIT_P(0);	PG_RETURN_INT32(VARBITLEN(arg));}Datumbitoctetlength(PG_FUNCTION_ARGS){	VarBit	   *arg = PG_GETARG_VARBIT_P(0);	PG_RETURN_INT32(VARBITBYTES(arg));}/* bitand * perform a logical AND on two bit strings. */Datumbitand(PG_FUNCTION_ARGS){	VarBit	   *arg1 = PG_GETARG_VARBIT_P(0);	VarBit	   *arg2 = PG_GETARG_VARBIT_P(1);	VarBit	   *result;	int			len,				bitlen1,				bitlen2,				i;	bits8	   *p1,			   *p2,			   *r;	bitlen1 = VARBITLEN(arg1);	bitlen2 = VARBITLEN(arg2);	if (bitlen1 != bitlen2)		ereport(ERROR,				(errcode(ERRCODE_STRING_DATA_LENGTH_MISMATCH),				 errmsg("cannot AND bit strings of different sizes")));	len = VARSIZE(arg1);	result = (VarBit *) palloc(len);	VARATT_SIZEP(result) = len;	VARBITLEN(result) = bitlen1;	p1 = VARBITS(arg1);	p2 = VARBITS(arg2);	r = VARBITS(result);	for (i = 0; i < VARBITBYTES(arg1); i++)		*r++ = *p1++ & *p2++;	/* Padding is not needed as & of 0 pad is 0 */	PG_RETURN_VARBIT_P(result);}/* bitor * perform a logical OR on two bit strings. */Datumbitor(PG_FUNCTION_ARGS){	VarBit	   *arg1 = PG_GETARG_VARBIT_P(0);	VarBit	   *arg2 = PG_GETARG_VARBIT_P(1);	VarBit	   *result;	int			len,				bitlen1,				bitlen2,				i;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -