#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)); }