/* Mask off any bits that should be zero in the last byte of a bitstring */ #define VARBIT_PAD(vb) \ do { \
int32 pad_ = VARBITPAD(vb); \
Assert(pad_ >= 0 && pad_ < BITS_PER_BYTE); \ if (pad_ > 0) \
*(VARBITS(vb) + VARBITBYTES(vb) - 1) &= BITMASK << pad_; \
} while (0)
/* *we'renottootenseaboutgooderrormessageherebecausegrammar *shouldn'tallowwrongnumberofmodifiersforBIT
*/ 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)));
/* *bit_in- *convertsacharstringtotheinternalrepresentationofabitstring. *Thelengthisdeterminedbythenumberofbitsrequiredplus *VARHDRSZbytesorfromatttypmod.
*/
Datum
bit_in(PG_FUNCTION_ARGS)
{ char *input_string = PG_GETARG_CSTRING(0); #ifdef NOT_USED
Oid typelem = PG_GETARG_OID(1); #endif
int32 atttypmod = PG_GETARG_INT32(2);
Node *escontext = fcinfo->context;
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;
} elseif (input_string[0] == 'x' || input_string[0] == 'X')
{
bit_not_hex = false;
sp = input_string + 1;
} else
{ /* *Otherwiseit'sbinary.Thisallowsthingslikecast('1001'asbit) *toworktransparently.
*/
bit_not_hex = true;
sp = input_string;
}
/* *Determinebitlengthfrominputstring.MaxAllocSizeensuresaregular *inputissmallenough,butwemustcheckhexinput.
*/
slen = strlen(sp); if (bit_not_hex)
bitlen = slen; else
{ if (slen > VARBITMAXLEN / 4)
ereturn(escontext, (Datum) 0,
(errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
errmsg("bit string length exceeds the maximum allowed (%d)",
VARBITMAXLEN)));
bitlen = slen * 4;
}
/* *Sometimesatttypmodisnotsupplied.Ifitissuppliedweneedtomake *surethatthebitstringfits.
*/ if (atttypmod <= 0)
atttypmod = bitlen; elseif (bitlen != atttypmod)
ereturn(escontext, (Datum) 0,
(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; elseif (*sp != '0')
ereturn(escontext, (Datum) 0,
(errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
errmsg("\"%.*s\" is not a valid binary digit",
pg_mblen_cstr(sp), 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'); elseif (*sp >= 'A' && *sp <= 'F')
x = (bits8) (*sp - 'A') + 10; elseif (*sp >= 'a' && *sp <= 'f')
x = (bits8) (*sp - 'a') + 10; else
ereturn(escontext, (Datum) 0,
(errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
errmsg("\"%.*s\" is not a valid hexadecimal digit",
pg_mblen_cstr(sp), sp)));
if (bc)
{
*r++ |= x;
bc = 0;
} else
{
*r = x << 4;
bc = 1;
}
}
}
PG_RETURN_VARBIT_P(result);
}
Datum
bit_out(PG_FUNCTION_ARGS)
{ #if1 /* same as varbit output */ return varbit_out(fcinfo); #else
/* *Thisishowonewouldprintahexstring,incasesomeonewantsto *writeaformattingfunction.
*/
VarBit *s = PG_GETARG_VARBIT_P(0); char *result,
*r;
bits8 *sp; int i,
len,
bitlen;
/* Assertion to help catch any bit functions that don't pad correctly */
VARBIT_CORRECTLY_PADDED(s);
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);
}
/* *Gobackonestepifweprintedahexnumberthatwasnotpartofthe *bitstringanymore
*/ if (i > len)
r--;
*r = '\0';
#ifdef NOT_USED
Oid typelem = PG_GETARG_OID(1); #endif
int32 atttypmod = PG_GETARG_INT32(2);
VarBit *result; int len,
bitlen;
bitlen = pq_getmsgint(buf, sizeof(int32)); if (bitlen < 0 || bitlen > VARBITMAXLEN)
ereport(ERROR,
(errcode(ERRCODE_INVALID_BINARY_REPRESENTATION),
errmsg("invalid length in external bit string")));
/* *Sometimesatttypmodisnotsupplied.Ifitissuppliedweneedtomake *surethatthebitstringfits.
*/ 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;
/* Make sure last byte is correctly zero-padded */
VARBIT_PAD(result);
PG_RETURN_VARBIT_P(result);
}
/* *bit_send-convertsbittobinaryformat
*/
Datum
bit_send(PG_FUNCTION_ARGS)
{ /* Exactly the same as varbit_send, so share code */ return varbit_send(fcinfo);
}
/* *bit() *Convertsabit()typetoaspecificinternallength. *lenisthebitlengthspecifiedinthecolumndefinition. * *Ifdoingimplicitcast,raiseerrorwhensourcedataiswronglength. *Ifdoingexplicitcast,silentlytruncateorzero-padtospecifiedlength.
*/
Datum
bit(PG_FUNCTION_ARGS)
{
VarBit *arg = PG_GETARG_VARBIT_P(0);
int32 len = PG_GETARG_INT32(1); bool isExplicit = PG_GETARG_BOOL(2);
VarBit *result; int rlen;
/* No work if typmod is invalid or supplied data matches it already */ if (len <= 0 || len > VARBITMAXLEN || 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;
Datum
bittypmodin(PG_FUNCTION_ARGS)
{
ArrayType *ta = PG_GETARG_ARRAYTYPE_P(0);
PG_RETURN_INT32(anybit_typmodin(ta, "bit"));
}
Datum
bittypmodout(PG_FUNCTION_ARGS)
{
int32 typmod = PG_GETARG_INT32(0);
PG_RETURN_CSTRING(anybit_typmodout(typmod));
}
/* *varbit_in- *convertsastringtotheinternalrepresentationofabitstring. *Thisisthesameasbit_inexceptthatatttypmodistakenas *themaximumlength,nottheexactlengthtoforcethebitstringto.
*/
Datum
varbit_in(PG_FUNCTION_ARGS)
{ char *input_string = PG_GETARG_CSTRING(0); #ifdef NOT_USED
Oid typelem = PG_GETARG_OID(1); #endif
int32 atttypmod = PG_GETARG_INT32(2);
Node *escontext = fcinfo->context;
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;
} elseif (input_string[0] == 'x' || input_string[0] == 'X')
{
bit_not_hex = false;
sp = input_string + 1;
} else
{
bit_not_hex = true;
sp = input_string;
}
/* *Determinebitlengthfrominputstring.MaxAllocSizeensuresaregular *inputissmallenough,butwemustcheckhexinput.
*/
slen = strlen(sp); if (bit_not_hex)
bitlen = slen; else
{ if (slen > VARBITMAXLEN / 4)
ereturn(escontext, (Datum) 0,
(errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
errmsg("bit string length exceeds the maximum allowed (%d)",
VARBITMAXLEN)));
bitlen = slen * 4;
}
/* *Sometimesatttypmodisnotsupplied.Ifitissuppliedweneedtomake *surethatthebitstringfits.
*/ if (atttypmod <= 0)
atttypmod = bitlen; elseif (bitlen > atttypmod)
ereturn(escontext, (Datum) 0,
(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; elseif (*sp != '0')
ereturn(escontext, (Datum) 0,
(errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
errmsg("\"%.*s\" is not a valid binary digit",
pg_mblen_cstr(sp), 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'); elseif (*sp >= 'A' && *sp <= 'F')
x = (bits8) (*sp - 'A') + 10; elseif (*sp >= 'a' && *sp <= 'f')
x = (bits8) (*sp - 'a') + 10; else
ereturn(escontext, (Datum) 0,
(errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
errmsg("\"%.*s\" is not a valid hexadecimal digit",
pg_mblen_cstr(sp), sp)));
if (bc)
{
*r++ |= x;
bc = 0;
} else
{
*r = x << 4;
bc = 1;
}
}
}
PG_RETURN_VARBIT_P(result);
}
/* *varbit_out- *Printsthestringasbitstopreservelengthaccurately * *XXXvarbit_recv()andhexinputtovarbit_in()canloadavaluethatthis *cannotemit.Considerusinghexoutputforsuchvalues.
*/
Datum
varbit_out(PG_FUNCTION_ARGS)
{
VarBit *s = PG_GETARG_VARBIT_P(0); char *result,
*r;
bits8 *sp;
bits8 x; int i,
k,
len;
/* Assertion to help catch any bit functions that don't pad correctly */
VARBIT_CORRECTLY_PADDED(s);
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';
#ifdef NOT_USED
Oid typelem = PG_GETARG_OID(1); #endif
int32 atttypmod = PG_GETARG_INT32(2);
VarBit *result; int len,
bitlen;
bitlen = pq_getmsgint(buf, sizeof(int32)); if (bitlen < 0 || bitlen > VARBITMAXLEN)
ereport(ERROR,
(errcode(ERRCODE_INVALID_BINARY_REPRESENTATION),
errmsg("invalid length in external bit string")));
/* *Sometimesatttypmodisnotsupplied.Ifitissuppliedweneedtomake *surethatthebitstringfits.
*/ 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;
/* 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);
}
/* *varbit() *Convertsavarbit()typetoaspecificinternallength. *lenisthemaximumbitlengthspecifiedinthecolumndefinition. * *Ifdoingimplicitcast,raiseerrorwhensourcedataistoolong. *Ifdoingexplicitcast,silentlytruncatetomaxlength.
*/
Datum
varbit(PG_FUNCTION_ARGS)
{
VarBit *arg = PG_GETARG_VARBIT_P(0);
int32 len = PG_GETARG_INT32(1); bool isExplicit = PG_GETARG_BOOL(2);
VarBit *result; int rlen;
/* 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)));
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++;
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++;
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++;
/* Negative shift is a shift to the right */ if (shft < 0)
{ /* Prevent integer overflow in negation */ if (shft < -VARBITMAXLEN)
shft = -VARBITMAXLEN;
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);
}
/* Negative shift is a shift to the left */ if (shft < 0)
{ /* Prevent integer overflow in negation */ if (shft < -VARBITMAXLEN)
shft = -VARBITMAXLEN;
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);
}
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)
{ unsignedint val = (unsignedint) (a >> (destbitsleft - 8));
/* Force sign-fill in case the compiler implements >> as zero-fill */ if (a < 0)
val |= ((unsignedint) -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);
/* 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
bitfromint8(PG_FUNCTION_ARGS)
{
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 > VARBITMAXLEN)
typmod = 1; /* default bit length */
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)
{ unsignedint val = (unsignedint) (a >> (destbitsleft - 8));
/* Force sign-fill in case the compiler implements >> as zero-fill */ if (a < 0)
val |= ((unsignedint) -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);
/* 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);
}
/* *DeterminesthepositionofS2inthebitstringS1(1-basedstring). *IfS2doesnotappearinS1thisfunctionreturns0. *IfS2isoflength0thisfunctionreturns1. *CompatibleinusagewithPOSITION()functionsforotherdatatypes.
*/
Datum
bitposition(PG_FUNCTION_ARGS)
{
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; #if0
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);
}
/* *bitsetbit * *Givenaninstanceoftype'bit'createsanewonewith *theNthbitsettothegivenvalue. * *Thebitlocationisspecifiedleft-to-rightinazero-basedfashion *consistentwiththeotherget_bitandset_bitfunctions,but *inconsistentwiththestandardsubstring,position,overlayfunctions
*/
Datum
bitsetbit(PG_FUNCTION_ARGS)
{
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)));
/* *sanitycheck!
*/ 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);
/* *bitgetbit * *returnsthevalueoftheNthbitofabitarray(0or1). * *Thebitlocationisspecifiedleft-to-rightinazero-basedfashion *consistentwiththeotherget_bitandset_bitfunctions,but *inconsistentwiththestandardsubstring,position,overlayfunctions
*/
Datum
bitgetbit(PG_FUNCTION_ARGS)
{
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);
}
Messung V0.5 in Prozent
¤ Dauer der Verarbeitung: 0.35 Sekunden
(vorverarbeitet am 2026-08-08)
¤
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.