#include "fmgr.h"
Go to the source code of this file.
Data Structures | |
struct | VarBit |
Defines | |
#define | DatumGetVarBitP(X) ((VarBit *) PG_DETOAST_DATUM(X)) |
#define | DatumGetVarBitPCopy(X) ((VarBit *) PG_DETOAST_DATUM_COPY(X)) |
#define | VarBitPGetDatum(X) PointerGetDatum(X) |
#define | PG_GETARG_VARBIT_P(n) DatumGetVarBitP(PG_GETARG_DATUM(n)) |
#define | PG_GETARG_VARBIT_P_COPY(n) DatumGetVarBitPCopy(PG_GETARG_DATUM(n)) |
#define | PG_RETURN_VARBIT_P(x) return VarBitPGetDatum(x) |
#define | VARBITHDRSZ sizeof(int32) |
#define | VARBITLEN(PTR) (((VarBit *) (PTR))->bit_len) |
#define | VARBITS(PTR) (((VarBit *) (PTR))->bit_dat) |
#define | VARBITBYTES(PTR) (VARSIZE(PTR) - VARHDRSZ - VARBITHDRSZ) |
#define | VARBITPAD(PTR) (VARBITBYTES(PTR)*BITS_PER_BYTE - VARBITLEN(PTR)) |
#define | VARBITTOTALLEN(BITLEN) |
#define | VARBITEND(PTR) (((bits8 *) (PTR)) + VARSIZE(PTR)) |
#define | BITMASK 0xFF |
Functions | |
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 | 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 | varbittypmodin (PG_FUNCTION_ARGS) |
Datum | varbittypmodout (PG_FUNCTION_ARGS) |
Datum | bit (PG_FUNCTION_ARGS) |
Datum | varbit_transform (PG_FUNCTION_ARGS) |
Datum | varbit (PG_FUNCTION_ARGS) |
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 | 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 | 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 | 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 BITMASK 0xFF |
Definition at line 59 of file varbit.h.
Referenced by bit(), bit_catenate(), bit_or(), bit_recv(), bitfromint4(), bitfromint8(), bitnot(), bitposition(), bitshiftright(), bitsubstring(), bitxor(), varbit(), and varbit_recv().
#define DatumGetVarBitP | ( | X | ) | ((VarBit *) PG_DETOAST_DATUM(X)) |
#define DatumGetVarBitPCopy | ( | X | ) | ((VarBit *) PG_DETOAST_DATUM_COPY(X)) |
#define PG_GETARG_VARBIT_P | ( | n | ) | DatumGetVarBitP(PG_GETARG_DATUM(n)) |
Definition at line 39 of file varbit.h.
Referenced by bit(), bit_and(), bit_or(), bit_out(), bitcat(), bitcmp(), biteq(), bitge(), bitgetbit(), bitgt(), bitle(), bitlength(), bitlt(), bitne(), bitnot(), bitoctetlength(), bitoverlay(), bitoverlay_no_len(), bitposition(), bitsetbit(), bitshiftleft(), bitshiftright(), bitsubstr(), bitsubstr_no_len(), bittoint4(), bittoint8(), bitxor(), varbit(), varbit_out(), and varbit_send().
#define PG_GETARG_VARBIT_P_COPY | ( | n | ) | DatumGetVarBitPCopy(PG_GETARG_DATUM(n)) |
#define PG_RETURN_VARBIT_P | ( | x | ) | return VarBitPGetDatum(x) |
Definition at line 41 of file varbit.h.
Referenced by bit(), bit_and(), bit_in(), bit_or(), bit_recv(), bitcat(), bitfromint4(), bitfromint8(), bitnot(), bitoverlay(), bitoverlay_no_len(), bitsetbit(), bitshiftleft(), bitshiftright(), bitsubstr(), bitsubstr_no_len(), bitxor(), varbit(), varbit_in(), and varbit_recv().
#define VARBITBYTES | ( | PTR | ) | (VARSIZE(PTR) - VARHDRSZ - VARBITHDRSZ) |
Definition at line 50 of file varbit.h.
Referenced by bit(), bit_and(), bit_catenate(), bit_cmp(), bit_or(), bit_recv(), bitoctetlength(), bitposition(), bitsetbit(), bitshiftleft(), bitshiftright(), bitxor(), gbt_bit_xfrm(), varbit(), varbit_recv(), and varbit_send().
#define VARBITEND | ( | PTR | ) | (((bits8 *) (PTR)) + VARSIZE(PTR)) |
Definition at line 57 of file varbit.h.
Referenced by bit_catenate(), bitnot(), bitposition(), bitshiftleft(), bitshiftright(), bitsubstring(), bittoint4(), and bittoint8().
#define VARBITLEN | ( | PTR | ) | (((VarBit *) (PTR))->bit_len) |
Definition at line 46 of file varbit.h.
Referenced by bit(), bit_and(), bit_catenate(), bit_cmp(), bit_in(), bit_or(), bit_out(), bit_recv(), biteq(), bitfromint4(), bitfromint8(), bitgetbit(), bitlength(), bitne(), bitnot(), bitoverlay_no_len(), bitposition(), bitsetbit(), bitshiftleft(), bitshiftright(), bitsubstring(), bittoint4(), bittoint8(), bitxor(), varbit(), varbit_in(), varbit_out(), varbit_recv(), and varbit_send().
#define VARBITPAD | ( | PTR | ) | (VARBITBYTES(PTR)*BITS_PER_BYTE - VARBITLEN(PTR)) |
Definition at line 52 of file varbit.h.
Referenced by bit(), bit_catenate(), bit_or(), bit_recv(), bitnot(), bitposition(), bitsubstring(), bittoint4(), bittoint8(), bitxor(), varbit(), and varbit_recv().
#define VarBitPGetDatum | ( | X | ) | PointerGetDatum(X) |
Definition at line 38 of file varbit.h.
Referenced by bitshiftleft(), and bitshiftright().
#define VARBITS | ( | PTR | ) | (((VarBit *) (PTR))->bit_dat) |
Definition at line 48 of file varbit.h.
Referenced by bit(), bit_and(), bit_catenate(), bit_cmp(), bit_in(), bit_or(), bit_out(), bit_recv(), bitfromint4(), bitfromint8(), bitgetbit(), bitnot(), bitposition(), bitsetbit(), bitshiftleft(), bitshiftright(), bitsubstring(), bittoint4(), bittoint8(), bitxor(), gbt_bit_xfrm(), varbit(), varbit_in(), varbit_out(), varbit_recv(), and varbit_send().
#define VARBITTOTALLEN | ( | BITLEN | ) |
(((BITLEN) + BITS_PER_BYTE-1)/BITS_PER_BYTE + \ VARHDRSZ + VARBITHDRSZ)
Definition at line 54 of file varbit.h.
Referenced by bit(), bit_catenate(), bit_in(), bit_recv(), bitfromint4(), bitfromint8(), bitsubstring(), varbit(), varbit_in(), and varbit_recv().
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); }
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 }
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)); }
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)); }