#include "postgres.h"#include "access/htup_details.h"#include "libpq/pqformat.h"#include "nodes/nodeFuncs.h"#include "utils/array.h"#include "utils/varbit.h"
Go to the source code of this file.
Defines | |
| #define | HEXDIG(z) ((z)<10 ? ((z)+'0') : ((z)-10+'A')) |
Functions | |
| static VarBit * | bit_catenate (VarBit *arg1, VarBit *arg2) |
| static VarBit * | bitsubstring (VarBit *arg, int32 s, int32 l, bool length_not_specified) |
| static VarBit * | bit_overlay (VarBit *t1, VarBit *t2, int sp, int sl) |
| static int32 | anybit_typmodin (ArrayType *ta, const char *typename) |
| static char * | anybit_typmodout (int32 typmod) |
| Datum | bit_in (PG_FUNCTION_ARGS) |
| Datum | bit_out (PG_FUNCTION_ARGS) |
| Datum | bit_recv (PG_FUNCTION_ARGS) |
| Datum | bit_send (PG_FUNCTION_ARGS) |
| Datum | bit (PG_FUNCTION_ARGS) |
| Datum | bittypmodin (PG_FUNCTION_ARGS) |
| Datum | bittypmodout (PG_FUNCTION_ARGS) |
| Datum | varbit_in (PG_FUNCTION_ARGS) |
| Datum | varbit_out (PG_FUNCTION_ARGS) |
| Datum | varbit_recv (PG_FUNCTION_ARGS) |
| Datum | varbit_send (PG_FUNCTION_ARGS) |
| Datum | varbit_transform (PG_FUNCTION_ARGS) |
| Datum | varbit (PG_FUNCTION_ARGS) |
| Datum | varbittypmodin (PG_FUNCTION_ARGS) |
| Datum | varbittypmodout (PG_FUNCTION_ARGS) |
| static int32 | bit_cmp (VarBit *arg1, VarBit *arg2) |
| Datum | biteq (PG_FUNCTION_ARGS) |
| Datum | bitne (PG_FUNCTION_ARGS) |
| Datum | bitlt (PG_FUNCTION_ARGS) |
| Datum | bitle (PG_FUNCTION_ARGS) |
| Datum | bitgt (PG_FUNCTION_ARGS) |
| Datum | bitge (PG_FUNCTION_ARGS) |
| Datum | bitcmp (PG_FUNCTION_ARGS) |
| Datum | bitcat (PG_FUNCTION_ARGS) |
| Datum | bitsubstr (PG_FUNCTION_ARGS) |
| Datum | bitsubstr_no_len (PG_FUNCTION_ARGS) |
| Datum | bitoverlay (PG_FUNCTION_ARGS) |
| Datum | bitoverlay_no_len (PG_FUNCTION_ARGS) |
| Datum | bitlength (PG_FUNCTION_ARGS) |
| Datum | bitoctetlength (PG_FUNCTION_ARGS) |
| Datum | bit_and (PG_FUNCTION_ARGS) |
| Datum | bit_or (PG_FUNCTION_ARGS) |
| Datum | bitxor (PG_FUNCTION_ARGS) |
| Datum | bitnot (PG_FUNCTION_ARGS) |
| Datum | bitshiftleft (PG_FUNCTION_ARGS) |
| Datum | bitshiftright (PG_FUNCTION_ARGS) |
| Datum | bitfromint4 (PG_FUNCTION_ARGS) |
| Datum | bittoint4 (PG_FUNCTION_ARGS) |
| Datum | bitfromint8 (PG_FUNCTION_ARGS) |
| Datum | bittoint8 (PG_FUNCTION_ARGS) |
| Datum | bitposition (PG_FUNCTION_ARGS) |
| Datum | bitsetbit (PG_FUNCTION_ARGS) |
| Datum | bitgetbit (PG_FUNCTION_ARGS) |
| #define HEXDIG | ( | z | ) | ((z)<10 ? ((z)+'0') : ((z)-10+'A')) |
Definition at line 37 of file varbit.c.
References ArrayGetIntegerTypmods(), BITS_PER_BYTE, ereport, errcode(), errmsg(), ERROR, and MaxAttrSize.
Referenced by bittypmodin(), and varbittypmodin().
{
int32 typmod;
int32 *tl;
int n;
tl = ArrayGetIntegerTypmods(ta, &n);
/*
* 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;
}
| static char* anybit_typmodout | ( | int32 | typmod | ) | [static] |
Definition at line 74 of file varbit.c.
References palloc(), and snprintf().
Referenced by bittypmodout(), and varbittypmodout().
| Datum bit | ( | PG_FUNCTION_ARGS | ) |
Definition at line 350 of file varbit.c.
References arg, BITMASK, ereport, errcode(), errmsg(), ERROR, Min, palloc0(), PG_GETARG_BOOL, PG_GETARG_INT32, PG_GETARG_VARBIT_P, PG_RETURN_VARBIT_P, SET_VARSIZE, VARBITBYTES, VARBITLEN, VARBITPAD, VARBITS, and VARBITTOTALLEN.
{
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_LENGTH_MISMATCH),
errmsg("bit string length %d does not match type bit(%d)",
VARBITLEN(arg), len)));
rlen = VARBITTOTALLEN(len);
/* set to 0 so that string is zero-padded */
result = (VarBit *) palloc0(rlen);
SET_VARSIZE(result, rlen);
VARBITLEN(result) = len;
memcpy(VARBITS(result), VARBITS(arg),
Min(VARBITBYTES(result), VARBITBYTES(arg)));
/*
* 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).
*/
ipad = VARBITPAD(result);
if (ipad > 0)
{
mask = BITMASK << ipad;
*(VARBITS(result) + VARBITBYTES(result) - 1) &= mask;
}
PG_RETURN_VARBIT_P(result);
}
| Datum bit_and | ( | PG_FUNCTION_ARGS | ) |
Definition at line 1180 of file varbit.c.
References ereport, errcode(), errmsg(), ERROR, i, palloc(), PG_GETARG_VARBIT_P, PG_RETURN_VARBIT_P, SET_VARSIZE, VARBITBYTES, VARBITLEN, VARBITS, and VARSIZE.
{
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);
SET_VARSIZE(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);
}
Definition at line 933 of file varbit.c.
References BITMASK, BITS_PER_BYTE, palloc(), SET_VARSIZE, VARBITBYTES, VARBITEND, VARBITLEN, VARBITPAD, VARBITS, and VARBITTOTALLEN.
Referenced by bit_overlay(), and bitcat().
{
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);
SET_VARSIZE(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;
}
}
return result;
}
Definition at line 774 of file varbit.c.
References memcmp(), Min, VARBITBYTES, VARBITLEN, and VARBITS.
Referenced by bitcmp(), biteq(), bitge(), bitgt(), bitle(), bitlt(), and bitne().
{
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;
}
| Datum bit_in | ( | PG_FUNCTION_ARGS | ) |
Definition at line 112 of file varbit.c.
References ereport, errcode(), errmsg(), ERROR, palloc0(), PG_GETARG_CSTRING, PG_GETARG_INT32, PG_GETARG_OID, PG_RETURN_VARBIT_P, SET_VARSIZE, VARBITLEN, VARBITS, and VARBITTOTALLEN.
Referenced by leftmostvalue_bit(), and make_const().
{
char *input_string = PG_GETARG_CSTRING(0);
#ifdef NOT_USED
Oid typelem = PG_GETARG_OID(1);
#endif
int32 atttypmod = PG_GETARG_INT32(2);
VarBit *result; /* The resulting bit string */
char *sp; /* pointer into the character string */
bits8 *r; /* pointer into the result */
int len, /* Length of the whole data structure */
bitlen, /* Number of bits in the bit string */
slen; /* Length of the input string */
bool bit_not_hex; /* false = hex string true = bit string */
int bc;
bits8 x = 0;
/* Check that the first character is a b or an x */
if (input_string[0] == 'b' || input_string[0] == 'B')
{
bit_not_hex = true;
sp = input_string + 1;
}
else if (input_string[0] == 'x' || input_string[0] == 'X')
{
bit_not_hex = false;
sp = input_string + 1;
}
else
{
/*
* Otherwise it's binary. This allows things like cast('1001' as bit)
* to work transparently.
*/
bit_not_hex = true;
sp = input_string;
}
slen = strlen(sp);
/* Determine bitlength from input string */
if (bit_not_hex)
bitlen = slen;
else
bitlen = slen * 4;
/*
* Sometimes atttypmod is not supplied. If it is supplied we need to make
* sure that the bitstring fits.
*/
if (atttypmod <= 0)
atttypmod = bitlen;
else if (bitlen != atttypmod)
ereport(ERROR,
(errcode(ERRCODE_STRING_DATA_LENGTH_MISMATCH),
errmsg("bit string length %d does not match type bit(%d)",
bitlen, atttypmod)));
len = VARBITTOTALLEN(atttypmod);
/* set to 0 so that *r is always initialised and string is zero-padded */
result = (VarBit *) palloc0(len);
SET_VARSIZE(result, len);
VARBITLEN(result) = atttypmod;
r = VARBITS(result);
if (bit_not_hex)
{
/* Parse the bit representation of the string */
/* We know it fits, as bitlen was compared to atttypmod */
x = HIGHBIT;
for (; *sp; sp++)
{
if (*sp == '1')
*r |= x;
else if (*sp != '0')
ereport(ERROR,
(errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
errmsg("\"%c\" is not a valid binary digit",
*sp)));
x >>= 1;
if (x == 0)
{
x = HIGHBIT;
r++;
}
}
}
else
{
/* Parse the hex representation of the string */
for (bc = 0; *sp; sp++)
{
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
ereport(ERROR,
(errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
errmsg("\"%c\" is not a valid hexadecimal digit",
*sp)));
if (bc)
{
*r++ |= x;
bc = 0;
}
else
{
*r = x << 4;
bc = 1;
}
}
}
PG_RETURN_VARBIT_P(result);
}
| Datum bit_or | ( | PG_FUNCTION_ARGS | ) |
Definition at line 1221 of file varbit.c.
References BITMASK, ereport, errcode(), errmsg(), ERROR, i, palloc(), PG_GETARG_VARBIT_P, PG_RETURN_VARBIT_P, SET_VARSIZE, VARBITBYTES, VARBITLEN, VARBITPAD, VARBITS, and VARSIZE.
{
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;
bits8 mask;
bitlen1 = VARBITLEN(arg1);
bitlen2 = VARBITLEN(arg2);
if (bitlen1 != bitlen2)
ereport(ERROR,
(errcode(ERRCODE_STRING_DATA_LENGTH_MISMATCH),
errmsg("cannot OR bit strings of different sizes")));
len = VARSIZE(arg1);
result = (VarBit *) palloc(len);
SET_VARSIZE(result, len);
VARBITLEN(result) = bitlen1;
p1 = VARBITS(arg1);
p2 = VARBITS(arg2);
r = VARBITS(result);
for (i = 0; i < VARBITBYTES(arg1); i++)
*r++ = *p1++ | *p2++;
/* Pad the result */
mask = BITMASK << VARBITPAD(result);
if (mask)
{
r--;
*r &= mask;
}
PG_RETURN_VARBIT_P(result);
}
| Datum bit_out | ( | PG_FUNCTION_ARGS | ) |
Definition at line 235 of file varbit.c.
References HEXDIG, i, palloc(), PG_GETARG_VARBIT_P, PG_RETURN_CSTRING, varbit_out(), VARBITLEN, and VARBITS.
{
#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.
*/
VarBit *s = PG_GETARG_VARBIT_P(0);
char *result,
*r;
bits8 *sp;
int i,
len,
bitlen;
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++)
{
*r++ = HEXDIG((*sp) >> 4);
*r++ = HEXDIG((*sp) & 0xF);
}
/*
* Go back one step if we printed a hex number that was not part of the
* bitstring anymore
*/
if (i > len)
r--;
*r = '\0';
PG_RETURN_CSTRING(result);
#endif
}
Definition at line 1125 of file varbit.c.
References bit_catenate(), bitsubstring(), ereport, errcode(), errmsg(), ERROR, s1, and s2.
Referenced by bitoverlay(), and bitoverlay_no_len().
{
VarBit *result;
VarBit *s1;
VarBit *s2;
int sp_pl_sl;
/*
* Check for possible integer-overflow cases. For negative sp, throw a
* "substring length" error because that's what should be expected
* according to the spec's definition of OVERLAY().
*/
if (sp <= 0)
ereport(ERROR,
(errcode(ERRCODE_SUBSTRING_ERROR),
errmsg("negative substring length not allowed")));
sp_pl_sl = sp + sl;
if (sp_pl_sl <= sl)
ereport(ERROR,
(errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
errmsg("integer out of range")));
s1 = bitsubstring(t1, 1, sp - 1, false);
s2 = bitsubstring(t1, sp_pl_sl, -1, true);
result = bit_catenate(s1, t2);
result = bit_catenate(result, s2);
return result;
}
| Datum bit_recv | ( | PG_FUNCTION_ARGS | ) |
Definition at line 283 of file varbit.c.
References BITMASK, buf, ereport, errcode(), errmsg(), ERROR, palloc(), PG_GETARG_INT32, PG_GETARG_OID, PG_GETARG_POINTER, PG_RETURN_VARBIT_P, pq_copymsgbytes(), pq_getmsgint(), SET_VARSIZE, VARBITBYTES, VARBITLEN, VARBITPAD, VARBITS, and VARBITTOTALLEN.
{
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_LENGTH_MISMATCH),
errmsg("bit string length %d does not match type bit(%d)",
bitlen, atttypmod)));
len = VARBITTOTALLEN(bitlen);
result = (VarBit *) palloc(len);
SET_VARSIZE(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);
}
| Datum bit_send | ( | PG_FUNCTION_ARGS | ) |
Definition at line 335 of file varbit.c.
References varbit_send().
{
/* Exactly the same as varbit_send, so share code */
return varbit_send(fcinfo);
}
| Datum bitcat | ( | PG_FUNCTION_ARGS | ) |
Definition at line 924 of file varbit.c.
References bit_catenate(), PG_GETARG_VARBIT_P, and PG_RETURN_VARBIT_P.
{
VarBit *arg1 = PG_GETARG_VARBIT_P(0);
VarBit *arg2 = PG_GETARG_VARBIT_P(1);
PG_RETURN_VARBIT_P(bit_catenate(arg1, arg2));
}
| Datum bitcmp | ( | PG_FUNCTION_ARGS | ) |
Definition at line 905 of file varbit.c.
References bit_cmp(), PG_FREE_IF_COPY, PG_GETARG_VARBIT_P, and PG_RETURN_INT32.
{
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);
}
| Datum biteq | ( | PG_FUNCTION_ARGS | ) |
Definition at line 797 of file varbit.c.
References bit_cmp(), PG_FREE_IF_COPY, PG_GETARG_VARBIT_P, PG_RETURN_BOOL, and VARBITLEN.
Referenced by gbt_biteq().
{
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);
}
| Datum bitfromint4 | ( | PG_FUNCTION_ARGS | ) |
Definition at line 1472 of file varbit.c.
References BITMASK, Min, palloc(), PG_GETARG_INT32, PG_RETURN_VARBIT_P, SET_VARSIZE, val, VARBITLEN, VARBITS, and VARBITTOTALLEN.
{
int32 a = PG_GETARG_INT32(0);
int32 typmod = PG_GETARG_INT32(1);
VarBit *result;
bits8 *r;
int rlen;
int destbitsleft,
srcbitsleft;
if (typmod <= 0)
typmod = 1; /* default bit length */
rlen = VARBITTOTALLEN(typmod);
result = (VarBit *) palloc(rlen);
SET_VARSIZE(result, rlen);
VARBITLEN(result) = typmod;
r = VARBITS(result);
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)
{
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);
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);
}
| Datum bitfromint8 | ( | PG_FUNCTION_ARGS | ) |
Definition at line 1552 of file varbit.c.
References BITMASK, Min, palloc(), PG_GETARG_INT32, PG_GETARG_INT64, PG_RETURN_VARBIT_P, SET_VARSIZE, val, VARBITLEN, VARBITS, and VARBITTOTALLEN.
{
int64 a = PG_GETARG_INT64(0);
int32 typmod = PG_GETARG_INT32(1);
VarBit *result;
bits8 *r;
int rlen;
int destbitsleft,
srcbitsleft;
if (typmod <= 0)
typmod = 1; /* default bit length */
rlen = VARBITTOTALLEN(typmod);
result = (VarBit *) palloc(rlen);
SET_VARSIZE(result, rlen);
VARBITLEN(result) = typmod;
r = VARBITS(result);
destbitsleft = typmod;
srcbitsleft = 64;
/* 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)
{
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);
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);
}
| Datum bitge | ( | PG_FUNCTION_ARGS | ) |
Definition at line 890 of file varbit.c.
References bit_cmp(), PG_FREE_IF_COPY, PG_GETARG_VARBIT_P, and PG_RETURN_BOOL.
Referenced by gbt_bitge().
{
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 bitgetbit | ( | PG_FUNCTION_ARGS | ) |
Definition at line 1810 of file varbit.c.
References BITS_PER_BYTE, ereport, errcode(), errmsg(), ERROR, PG_GETARG_INT32, PG_GETARG_VARBIT_P, PG_RETURN_INT32, VARBITLEN, and VARBITS.
{
VarBit *arg1 = PG_GETARG_VARBIT_P(0);
int32 n = PG_GETARG_INT32(1);
int bitlen;
bits8 *p;
int byteNo,
bitNo;
bitlen = VARBITLEN(arg1);
if (n < 0 || n >= bitlen)
ereport(ERROR,
(errcode(ERRCODE_ARRAY_SUBSCRIPT_ERROR),
errmsg("bit index %d out of valid range (0..%d)",
n, bitlen - 1)));
p = VARBITS(arg1);
byteNo = n / BITS_PER_BYTE;
bitNo = BITS_PER_BYTE - 1 - (n % BITS_PER_BYTE);
if (p[byteNo] & (1 << bitNo))
PG_RETURN_INT32(1);
else
PG_RETURN_INT32(0);
}
| Datum bitgt | ( | PG_FUNCTION_ARGS | ) |
Definition at line 875 of file varbit.c.
References bit_cmp(), PG_FREE_IF_COPY, PG_GETARG_VARBIT_P, and PG_RETURN_BOOL.
Referenced by gbt_bitgt().
{
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 | ) |
Definition at line 860 of file varbit.c.
References bit_cmp(), PG_FREE_IF_COPY, PG_GETARG_VARBIT_P, and PG_RETURN_BOOL.
Referenced by gbt_bitle().
{
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 bitlength | ( | PG_FUNCTION_ARGS | ) |
Definition at line 1160 of file varbit.c.
References arg, PG_GETARG_VARBIT_P, PG_RETURN_INT32, and VARBITLEN.
{
VarBit *arg = PG_GETARG_VARBIT_P(0);
PG_RETURN_INT32(VARBITLEN(arg));
}
| Datum bitlt | ( | PG_FUNCTION_ARGS | ) |
Definition at line 845 of file varbit.c.
References bit_cmp(), PG_FREE_IF_COPY, PG_GETARG_VARBIT_P, and PG_RETURN_BOOL.
Referenced by gbt_bitlt().
{
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 bitne | ( | PG_FUNCTION_ARGS | ) |
Definition at line 821 of file varbit.c.
References bit_cmp(), PG_FREE_IF_COPY, PG_GETARG_VARBIT_P, PG_RETURN_BOOL, and VARBITLEN.
{
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);
}
| Datum bitnot | ( | PG_FUNCTION_ARGS | ) |
Definition at line 1316 of file varbit.c.
References arg, BITMASK, palloc(), PG_GETARG_VARBIT_P, PG_RETURN_VARBIT_P, SET_VARSIZE, VARBITEND, VARBITLEN, VARBITPAD, VARBITS, and VARSIZE.
{
VarBit *arg = PG_GETARG_VARBIT_P(0);
VarBit *result;
bits8 *p,
*r;
bits8 mask;
result = (VarBit *) palloc(VARSIZE(arg));
SET_VARSIZE(result, VARSIZE(arg));
VARBITLEN(result) = VARBITLEN(arg);
p = VARBITS(arg);
r = VARBITS(result);
for (; p < VARBITEND(arg); p++)
*r++ = ~*p;
/* Pad the result */
mask = BITMASK << VARBITPAD(result);
if (mask)
{
r--;
*r &= mask;
}
PG_RETURN_VARBIT_P(result);
}
| Datum bitoctetlength | ( | PG_FUNCTION_ARGS | ) |
Definition at line 1168 of file varbit.c.
References arg, PG_GETARG_VARBIT_P, PG_RETURN_INT32, and VARBITBYTES.
{
VarBit *arg = PG_GETARG_VARBIT_P(0);
PG_RETURN_INT32(VARBITBYTES(arg));
}
| Datum bitoverlay | ( | PG_FUNCTION_ARGS | ) |
Definition at line 1102 of file varbit.c.
References bit_overlay(), PG_GETARG_INT32, PG_GETARG_VARBIT_P, and PG_RETURN_VARBIT_P.
{
VarBit *t1 = PG_GETARG_VARBIT_P(0);
VarBit *t2 = PG_GETARG_VARBIT_P(1);
int sp = PG_GETARG_INT32(2); /* substring start position */
int sl = PG_GETARG_INT32(3); /* substring length */
PG_RETURN_VARBIT_P(bit_overlay(t1, t2, sp, sl));
}
| Datum bitoverlay_no_len | ( | PG_FUNCTION_ARGS | ) |
Definition at line 1113 of file varbit.c.
References bit_overlay(), PG_GETARG_INT32, PG_GETARG_VARBIT_P, PG_RETURN_VARBIT_P, and VARBITLEN.
{
VarBit *t1 = PG_GETARG_VARBIT_P(0);
VarBit *t2 = PG_GETARG_VARBIT_P(1);
int sp = PG_GETARG_INT32(2); /* substring start position */
int sl;
sl = VARBITLEN(t2); /* defaults to length(t2) */
PG_RETURN_VARBIT_P(bit_overlay(t1, t2, sp, sl));
}
| Datum bitposition | ( | PG_FUNCTION_ARGS | ) |
Definition at line 1639 of file varbit.c.
References BITMASK, DEBUG4, elog, i, PG_GETARG_VARBIT_P, PG_RETURN_INT32, VARBITBYTES, VARBITEND, VARBITLEN, VARBITPAD, and VARBITS.
{
VarBit *str = PG_GETARG_VARBIT_P(0);
VarBit *substr = PG_GETARG_VARBIT_P(1);
int substr_length,
str_length,
i,
is;
bits8 *s, /* pointer into substring */
*p; /* pointer into str */
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 */
str_mask; /* pad mask for last string byte */
bool is_match;
/* Get the substring length */
substr_length = VARBITLEN(substr);
str_length = VARBITLEN(str);
/* String has zero length or substring longer than string, return 0 */
if ((str_length == 0) || (substr_length > str_length))
PG_RETURN_INT32(0);
/* zero-length substring means return 1 */
if (substr_length == 0)
PG_RETURN_INT32(1);
/* Initialise the padding masks */
end_mask = BITMASK << VARBITPAD(substr);
str_mask = BITMASK << VARBITPAD(str);
for (i = 0; i < VARBITBYTES(str) - VARBITBYTES(substr) + 1; i++)
{
for (is = 0; is < BITS_PER_BYTE; is++)
{
is_match = true;
p = VARBITS(str) + i;
mask1 = BITMASK >> is;
mask2 = ~mask1;
for (s = VARBITS(substr);
is_match && s < VARBITEND(substr); s++)
{
cmp = *s >> is;
if (s == VARBITEND(substr) - 1)
{
mask1 &= end_mask >> is;
if (p == VARBITEND(str) - 1)
{
/* Check that there is enough of str left */
if (mask1 & ~str_mask)
{
is_match = false;
break;
}
mask1 &= str_mask;
}
}
is_match = ((cmp ^ *p) & mask1) == 0;
if (!is_match)
break;
/* Move on to the next byte */
p++;
if (p == VARBITEND(str))
{
mask2 = end_mask << (BITS_PER_BYTE - is);
is_match = mask2 == 0;
#if 0
elog(DEBUG4, "S. %d %d em=%2x sm=%2x r=%d",
i, is, end_mask, mask2, is_match);
#endif
break;
}
cmp = *s << (BITS_PER_BYTE - is);
if (s == VARBITEND(substr) - 1)
{
mask2 &= end_mask << (BITS_PER_BYTE - is);
if (p == VARBITEND(str) - 1)
{
if (mask2 & ~str_mask)
{
is_match = false;
break;
}
mask2 &= str_mask;
}
}
is_match = ((cmp ^ *p) & mask2) == 0;
}
/* Have we found a match? */
if (is_match)
PG_RETURN_INT32(i * BITS_PER_BYTE + is + 1);
}
}
PG_RETURN_INT32(0);
}
| Datum bitsetbit | ( | PG_FUNCTION_ARGS | ) |
Definition at line 1748 of file varbit.c.
References BITS_PER_BYTE, ereport, errcode(), errmsg(), ERROR, palloc(), PG_GETARG_INT32, PG_GETARG_VARBIT_P, PG_RETURN_VARBIT_P, SET_VARSIZE, VARBITBYTES, VARBITLEN, VARBITS, and VARSIZE.
{
VarBit *arg1 = PG_GETARG_VARBIT_P(0);
int32 n = PG_GETARG_INT32(1);
int32 newBit = PG_GETARG_INT32(2);
VarBit *result;
int len,
bitlen;
bits8 *r,
*p;
int byteNo,
bitNo;
bitlen = VARBITLEN(arg1);
if (n < 0 || n >= bitlen)
ereport(ERROR,
(errcode(ERRCODE_ARRAY_SUBSCRIPT_ERROR),
errmsg("bit index %d out of valid range (0..%d)",
n, bitlen - 1)));
/*
* sanity check!
*/
if (newBit != 0 && newBit != 1)
ereport(ERROR,
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
errmsg("new bit must be 0 or 1")));
len = VARSIZE(arg1);
result = (VarBit *) palloc(len);
SET_VARSIZE(result, len);
VARBITLEN(result) = bitlen;
p = VARBITS(arg1);
r = VARBITS(result);
memcpy(r, p, VARBITBYTES(arg1));
byteNo = n / BITS_PER_BYTE;
bitNo = BITS_PER_BYTE - 1 - (n % BITS_PER_BYTE);
/*
* Update the byte.
*/
if (newBit == 0)
r[byteNo] &= (~(1 << bitNo));
else
r[byteNo] |= (1 << bitNo);
PG_RETURN_VARBIT_P(result);
}
| Datum bitshiftleft | ( | PG_FUNCTION_ARGS | ) |
Definition at line 1349 of file varbit.c.
References arg, BITS_PER_BYTE, bitshiftright(), DirectFunctionCall2, Int32GetDatum, MemSet, palloc(), PG_GETARG_INT32, PG_GETARG_VARBIT_P, PG_RETURN_DATUM, PG_RETURN_VARBIT_P, SET_VARSIZE, VARBITBYTES, VARBITEND, VARBITLEN, VarBitPGetDatum, VARBITS, and VARSIZE.
Referenced by bitshiftright().
{
VarBit *arg = PG_GETARG_VARBIT_P(0);
int32 shft = PG_GETARG_INT32(1);
VarBit *result;
int byte_shift,
ishift,
len;
bits8 *p,
*r;
/* Negative shift is a shift to the right */
if (shft < 0)
PG_RETURN_DATUM(DirectFunctionCall2(bitshiftright,
VarBitPGetDatum(arg),
Int32GetDatum(-shft)));
result = (VarBit *) palloc(VARSIZE(arg));
SET_VARSIZE(result, VARSIZE(arg));
VARBITLEN(result) = VARBITLEN(arg);
r = VARBITS(result);
/* If we shifted all the bits out, return an all-zero string */
if (shft >= VARBITLEN(arg))
{
MemSet(r, 0, VARBITBYTES(arg));
PG_RETURN_VARBIT_P(result);
}
byte_shift = shft / BITS_PER_BYTE;
ishift = shft % BITS_PER_BYTE;
p = VARBITS(arg) + byte_shift;
if (ishift == 0)
{
/* Special case: we can do a memcpy */
len = VARBITBYTES(arg) - byte_shift;
memcpy(r, p, len);
MemSet(r + len, 0, byte_shift);
}
else
{
for (; p < VARBITEND(arg); r++)
{
*r = *p << ishift;
if ((++p) < VARBITEND(arg))
*r |= *p >> (BITS_PER_BYTE - ishift);
}
for (; r < VARBITEND(result); r++)
*r = 0;
}
PG_RETURN_VARBIT_P(result);
}
| Datum bitshiftright | ( | PG_FUNCTION_ARGS | ) |
Definition at line 1409 of file varbit.c.
References arg, BITMASK, BITS_PER_BYTE, bitshiftleft(), DirectFunctionCall2, Int32GetDatum, MemSet, palloc(), PG_GETARG_INT32, PG_GETARG_VARBIT_P, PG_RETURN_DATUM, PG_RETURN_VARBIT_P, SET_VARSIZE, VARBITBYTES, VARBITEND, VARBITLEN, VarBitPGetDatum, VARBITS, and VARSIZE.
Referenced by bitshiftleft().
{
VarBit *arg = PG_GETARG_VARBIT_P(0);
int32 shft = PG_GETARG_INT32(1);
VarBit *result;
int byte_shift,
ishift,
len;
bits8 *p,
*r;
/* Negative shift is a shift to the left */
if (shft < 0)
PG_RETURN_DATUM(DirectFunctionCall2(bitshiftleft,
VarBitPGetDatum(arg),
Int32GetDatum(-shft)));
result = (VarBit *) palloc(VARSIZE(arg));
SET_VARSIZE(result, VARSIZE(arg));
VARBITLEN(result) = VARBITLEN(arg);
r = VARBITS(result);
/* If we shifted all the bits out, return an all-zero string */
if (shft >= VARBITLEN(arg))
{
MemSet(r, 0, VARBITBYTES(arg));
PG_RETURN_VARBIT_P(result);
}
byte_shift = shft / BITS_PER_BYTE;
ishift = shft % BITS_PER_BYTE;
p = VARBITS(arg);
/* Set the first part of the result to 0 */
MemSet(r, 0, byte_shift);
r += byte_shift;
if (ishift == 0)
{
/* Special case: we can do a memcpy */
len = VARBITBYTES(arg) - byte_shift;
memcpy(r, p, len);
}
else
{
if (r < VARBITEND(result))
*r = 0; /* initialize first byte */
for (; r < VARBITEND(result); p++)
{
*r |= *p >> ishift;
if ((++r) < VARBITEND(result))
*r = (*p << (BITS_PER_BYTE - ishift)) & BITMASK;
}
}
PG_RETURN_VARBIT_P(result);
}
| Datum bitsubstr | ( | PG_FUNCTION_ARGS | ) |
Definition at line 987 of file varbit.c.
References bitsubstring(), PG_GETARG_INT32, PG_GETARG_VARBIT_P, and PG_RETURN_VARBIT_P.
{
PG_RETURN_VARBIT_P(bitsubstring(PG_GETARG_VARBIT_P(0),
PG_GETARG_INT32(1),
PG_GETARG_INT32(2),
false));
}
| Datum bitsubstr_no_len | ( | PG_FUNCTION_ARGS | ) |
Definition at line 996 of file varbit.c.
References bitsubstring(), PG_GETARG_INT32, PG_GETARG_VARBIT_P, and PG_RETURN_VARBIT_P.
{
PG_RETURN_VARBIT_P(bitsubstring(PG_GETARG_VARBIT_P(0),
PG_GETARG_INT32(1),
-1, true));
}
Definition at line 1004 of file varbit.c.
References BITMASK, BITS_PER_BYTE, ereport, errcode(), errmsg(), ERROR, i, Max, Min, palloc(), s1, SET_VARSIZE, VARBITEND, VARBITLEN, VARBITPAD, VARBITS, VARBITTOTALLEN, and VARHDRSZ.
Referenced by bit_overlay(), bitsubstr(), and bitsubstr_no_len().
{
VarBit *result;
int bitlen,
rbitlen,
len,
ipad = 0,
ishift,
i;
int e,
s1,
e1;
bits8 mask,
*r,
*ps;
bitlen = VARBITLEN(arg);
s1 = Max(s, 1);
/* If we do not have an upper bound, use end of string */
if (length_not_specified)
{
e1 = bitlen + 1;
}
else
{
e = s + l;
/*
* A negative value for L is the only way for the end position to be
* before the start. SQL99 says to throw an error.
*/
if (e < s)
ereport(ERROR,
(errcode(ERRCODE_SUBSTRING_ERROR),
errmsg("negative substring length not allowed")));
e1 = Min(e, bitlen + 1);
}
if (s1 > bitlen || e1 <= s1)
{
/* Need to return a zero-length bitstring */
len = VARBITTOTALLEN(0);
result = (VarBit *) palloc(len);
SET_VARSIZE(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);
SET_VARSIZE(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;
}
}
return result;
}
| Datum bittoint4 | ( | PG_FUNCTION_ARGS | ) |
Definition at line 1527 of file varbit.c.
References arg, BITS_PER_BYTE, ereport, errcode(), errmsg(), ERROR, PG_GETARG_VARBIT_P, PG_RETURN_INT32, VARBITEND, VARBITLEN, VARBITPAD, and VARBITS.
{
VarBit *arg = PG_GETARG_VARBIT_P(0);
uint32 result;
bits8 *r;
/* Check that the bit string is not too long */
if (VARBITLEN(arg) > sizeof(result) * BITS_PER_BYTE)
ereport(ERROR,
(errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
errmsg("integer out of range")));
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_INT32(result);
}
| Datum bittoint8 | ( | PG_FUNCTION_ARGS | ) |
Definition at line 1607 of file varbit.c.
References arg, BITS_PER_BYTE, ereport, errcode(), errmsg(), ERROR, PG_GETARG_VARBIT_P, PG_RETURN_INT64, VARBITEND, VARBITLEN, VARBITPAD, and VARBITS.
{
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)
ereport(ERROR,
(errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
errmsg("bigint out of range")));
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);
}
| Datum bittypmodin | ( | PG_FUNCTION_ARGS | ) |
Definition at line 395 of file varbit.c.
References anybit_typmodin(), PG_GETARG_ARRAYTYPE_P, and PG_RETURN_INT32.
{
ArrayType *ta = PG_GETARG_ARRAYTYPE_P(0);
PG_RETURN_INT32(anybit_typmodin(ta, "bit"));
}
| Datum bittypmodout | ( | PG_FUNCTION_ARGS | ) |
Definition at line 403 of file varbit.c.
References anybit_typmodout(), PG_GETARG_INT32, and PG_RETURN_CSTRING.
{
int32 typmod = PG_GETARG_INT32(0);
PG_RETURN_CSTRING(anybit_typmodout(typmod));
}
| Datum bitxor | ( | PG_FUNCTION_ARGS | ) |
Definition at line 1268 of file varbit.c.
References BITMASK, ereport, errcode(), errmsg(), ERROR, i, palloc(), PG_GETARG_VARBIT_P, PG_RETURN_VARBIT_P, SET_VARSIZE, VARBITBYTES, VARBITLEN, VARBITPAD, VARBITS, and VARSIZE.
{
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;
bits8 mask;
bitlen1 = VARBITLEN(arg1);
bitlen2 = VARBITLEN(arg2);
if (bitlen1 != bitlen2)
ereport(ERROR,
(errcode(ERRCODE_STRING_DATA_LENGTH_MISMATCH),
errmsg("cannot XOR bit strings of different sizes")));
len = VARSIZE(arg1);
result = (VarBit *) palloc(len);
SET_VARSIZE(result, len);
VARBITLEN(result) = bitlen1;
p1 = VARBITS(arg1);
p2 = VARBITS(arg2);
r = VARBITS(result);
for (i = 0; i < VARBITBYTES(arg1); i++)
*r++ = *p1++ ^ *p2++;
/* Pad the result */
mask = BITMASK << VARBITPAD(result);
if (mask)
{
r--;
*r &= mask;
}
PG_RETURN_VARBIT_P(result);
}
| Datum varbit | ( | PG_FUNCTION_ARGS | ) |
Definition at line 691 of file varbit.c.
References arg, BITMASK, ereport, errcode(), errmsg(), ERROR, palloc(), PG_GETARG_BOOL, PG_GETARG_INT32, PG_GETARG_VARBIT_P, PG_RETURN_VARBIT_P, SET_VARSIZE, VARBITBYTES, VARBITLEN, VARBITPAD, VARBITS, and VARBITTOTALLEN.
{
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);
SET_VARSIZE(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);
}
| Datum varbit_in | ( | PG_FUNCTION_ARGS | ) |
Definition at line 418 of file varbit.c.
References ereport, errcode(), errmsg(), ERROR, Min, palloc0(), PG_GETARG_CSTRING, PG_GETARG_INT32, PG_GETARG_OID, PG_RETURN_VARBIT_P, SET_VARSIZE, VARBITLEN, VARBITS, and VARBITTOTALLEN.
Referenced by leftmostvalue_varbit().
{
char *input_string = PG_GETARG_CSTRING(0);
#ifdef NOT_USED
Oid typelem = PG_GETARG_OID(1);
#endif
int32 atttypmod = PG_GETARG_INT32(2);
VarBit *result; /* The resulting bit string */
char *sp; /* pointer into the character string */
bits8 *r; /* pointer into the result */
int len, /* Length of the whole data structure */
bitlen, /* Number of bits in the bit string */
slen; /* Length of the input string */
bool bit_not_hex; /* false = hex string true = bit string */
int bc;
bits8 x = 0;
/* Check that the first character is a b or an x */
if (input_string[0] == 'b' || input_string[0] == 'B')
{
bit_not_hex = true;
sp = input_string + 1;
}
else if (input_string[0] == 'x' || input_string[0] == 'X')
{
bit_not_hex = false;
sp = input_string + 1;
}
else
{
bit_not_hex = true;
sp = input_string;
}
slen = strlen(sp);
/* Determine bitlength from input string */
if (bit_not_hex)
bitlen = slen;
else
bitlen = slen * 4;
/*
* Sometimes atttypmod is not supplied. If it is supplied we need to make
* sure that the bitstring fits.
*/
if (atttypmod <= 0)
atttypmod = bitlen;
else if (bitlen > atttypmod)
ereport(ERROR,
(errcode(ERRCODE_STRING_DATA_RIGHT_TRUNCATION),
errmsg("bit string too long for type bit varying(%d)",
atttypmod)));
len = VARBITTOTALLEN(bitlen);
/* set to 0 so that *r is always initialised and string is zero-padded */
result = (VarBit *) palloc0(len);
SET_VARSIZE(result, len);
VARBITLEN(result) = Min(bitlen, atttypmod);
r = VARBITS(result);
if (bit_not_hex)
{
/* Parse the bit representation of the string */
/* We know it fits, as bitlen was compared to atttypmod */
x = HIGHBIT;
for (; *sp; sp++)
{
if (*sp == '1')
*r |= x;
else if (*sp != '0')
ereport(ERROR,
(errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
errmsg("\"%c\" is not a valid binary digit",
*sp)));
x >>= 1;
if (x == 0)
{
x = HIGHBIT;
r++;
}
}
}
else
{
/* Parse the hex representation of the string */
for (bc = 0; *sp; sp++)
{
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
ereport(ERROR,
(errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
errmsg("\"%c\" is not a valid hexadecimal digit",
*sp)));
if (bc)
{
*r++ |= x;
bc = 0;
}
else
{
*r = x << 4;
bc = 1;
}
}
}
PG_RETURN_VARBIT_P(result);
}
| Datum varbit_out | ( | PG_FUNCTION_ARGS | ) |
Definition at line 540 of file varbit.c.
References i, IS_HIGHBIT_SET, palloc(), PG_GETARG_VARBIT_P, PG_RETURN_CSTRING, VARBITLEN, and VARBITS.
Referenced by bit_out().
{
VarBit *s = PG_GETARG_VARBIT_P(0);
char *result,
*r;
bits8 *sp;
bits8 x;
int i,
k,
len;
len = VARBITLEN(s);
result = (char *) palloc(len + 1);
sp = VARBITS(s);
r = result;
for (i = 0; i <= len - BITS_PER_BYTE; i += BITS_PER_BYTE, sp++)
{
/* print full bytes */
x = *sp;
for (k = 0; k < BITS_PER_BYTE; k++)
{
*r++ = IS_HIGHBIT_SET(x) ? '1' : '0';
x <<= 1;
}
}
if (i < len)
{
/* print the last partial byte */
x = *sp;
for (k = i; k < len; k++)
{
*r++ = IS_HIGHBIT_SET(x) ? '1' : '0';
x <<= 1;
}
}
*r = '\0';
PG_RETURN_CSTRING(result);
}
| Datum varbit_recv | ( | PG_FUNCTION_ARGS | ) |
Definition at line 586 of file varbit.c.
References BITMASK, buf, ereport, errcode(), errmsg(), ERROR, palloc(), PG_GETARG_INT32, PG_GETARG_OID, PG_GETARG_POINTER, PG_RETURN_VARBIT_P, pq_copymsgbytes(), pq_getmsgint(), SET_VARSIZE, VARBITBYTES, VARBITLEN, VARBITPAD, VARBITS, and VARBITTOTALLEN.
{
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);
SET_VARSIZE(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);
}
| Datum varbit_send | ( | PG_FUNCTION_ARGS | ) |
Definition at line 638 of file varbit.c.
References buf, PG_GETARG_VARBIT_P, PG_RETURN_BYTEA_P, pq_begintypsend(), pq_endtypsend(), pq_sendbytes(), pq_sendint(), VARBITBYTES, VARBITLEN, and VARBITS.
Referenced by bit_send().
{
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));
}
| Datum varbit_transform | ( | PG_FUNCTION_ARGS | ) |
Definition at line 656 of file varbit.c.
References FuncExpr::args, Assert, DatumGetInt32, exprTypmod(), IsA, linitial, list_length(), lsecond, PG_GETARG_POINTER, PG_RETURN_POINTER, and relabel_to_typmod().
{
FuncExpr *expr = (FuncExpr *) PG_GETARG_POINTER(0);
Node *ret = NULL;
Node *typmod;
Assert(IsA(expr, FuncExpr));
Assert(list_length(expr->args) >= 2);
typmod = (Node *) lsecond(expr->args);
if (IsA(typmod, Const) &&!((Const *) typmod)->constisnull)
{
Node *source = (Node *) linitial(expr->args);
int32 new_typmod = DatumGetInt32(((Const *) typmod)->constvalue);
int32 old_max = exprTypmod(source);
int32 new_max = new_typmod;
/* Note: varbit() treats typmod 0 as invalid, so we do too */
if (new_max <= 0 || (old_max > 0 && old_max <= new_max))
ret = relabel_to_typmod(source, new_typmod);
}
PG_RETURN_POINTER(ret);
}
| Datum varbittypmodin | ( | PG_FUNCTION_ARGS | ) |
Definition at line 730 of file varbit.c.
References anybit_typmodin(), PG_GETARG_ARRAYTYPE_P, and PG_RETURN_INT32.
{
ArrayType *ta = PG_GETARG_ARRAYTYPE_P(0);
PG_RETURN_INT32(anybit_typmodin(ta, "varbit"));
}
| Datum varbittypmodout | ( | PG_FUNCTION_ARGS | ) |
Definition at line 738 of file varbit.c.
References anybit_typmodout(), PG_GETARG_INT32, and PG_RETURN_CSTRING.
{
int32 typmod = PG_GETARG_INT32(0);
PG_RETURN_CSTRING(anybit_typmodout(typmod));
}
1.7.1