Add zpbit and varbit data types from Adrian Joubert

<a.joubert@albourne.com>.
This commit is contained in:
Thomas G. Lockhart 2000-04-08 02:13:11 +00:00
parent 6a2d926933
commit 0337938fbf
7 changed files with 1155 additions and 13 deletions

View File

@ -4,7 +4,7 @@
# Makefile for utils/adt
#
# IDENTIFICATION
# $Header: /cvsroot/pgsql/src/backend/utils/adt/Makefile,v 1.35 2000/02/27 12:02:32 wieck Exp $
# $Header: /cvsroot/pgsql/src/backend/utils/adt/Makefile,v 1.36 2000/04/08 02:12:54 thomas Exp $
#
#-------------------------------------------------------------------------
@ -29,7 +29,7 @@ OBJS = acl.o arrayfuncs.o arrayutils.o bool.o cash.o char.o chunk.o \
misc.o nabstime.o name.o not_in.o numeric.o numutils.o \
oid.o oracle_compat.o \
regexp.o regproc.o ruleutils.o selfuncs.o sets.o \
tid.o timestamp.o varchar.o varlena.o version.o \
tid.o timestamp.o varbit.o varchar.o varlena.o version.o \
network.o mac.o inet_net_ntop.o inet_net_pton.o \
ri_triggers.o pg_lzcompress.o pg_locale.o formatting.o
@ -47,3 +47,6 @@ clean:
ifeq (depend,$(wildcard depend))
include depend
endif

View File

@ -0,0 +1,937 @@
/*-------------------------------------------------------------------------
*
* varbit.c
* Functions for the built-in type bit() and varying bit().
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/utils/adt/varbit.c,v 1.1 2000/04/08 02:12:54 thomas Exp $
*
*-------------------------------------------------------------------------
*/
/* Include file list stolen from float.c.
* Can probably get rid of some of these.
* - thomas 2000-04-07
*/
#include <ctype.h>
#include <errno.h>
#include <float.h> /* faked on sunos4 */
#include <math.h>
#include "postgres.h"
#ifdef HAVE_LIMITS_H
#include <limits.h>
#ifndef MAXINT
#define MAXINT INT_MAX
#endif
#else
#ifdef HAVE_VALUES_H
#include <values.h>
#endif
#endif
#include "fmgr.h"
#include "utils/builtins.h"
#include "access/htup.h"
/*
Prefixes:
zp -- zero-padded fixed length bit string
var -- varying bit string
attypmod -- contains the length of the bit string in bits, or for
varying bits the maximum length.
The data structure contains the following elements:
header -- length of the whole data structure (incl header)
in bytes. (as with all varying length datatypes)
data section -- private data section for the bits data structures
bitlength -- lenght of the bit string in bits
bitdata -- least significant byte first string
*/
char *
varbit_out (bits8 *s) {
return zpbits_out(s);
}
/*
* zpbit_in -
* converts a string to the internal representation of a bitstring.
* The length is determined by the number of bits required plus
* VARHDRSZ bytes or from atttypmod.
* (XXX dummy is here because we pass typelem as the second argument
* for array_in. copied this, no idea what it means??)
*/
bits8 *
zpbit_in(char *s, int dummy, int32 atttypmod)
{
bits8 *result; /* the bits string that was read in */
char *sp; /* pointer into the character string */
bits8 *r;
int len, /* Length of the whole data structure */
bitlen, /* Number of bits in the bit string */
slen; /* Length of the input string */
int bit_not_hex = 0; /* 0 = hex string 1=bit string */
int bc, ipad;
bits8 x = 0;
if (s == NULL)
return (bits8 *) NULL;
/* Check that the first character is a b or an x */
if (s[0]=='b' || s[0]=='B')
bit_not_hex = 1;
else if (s[0]=='x' || s[0]=='X')
bit_not_hex = 0;
else
elog(ERROR, "zpbit_in: %s is not a valid bitstring",s);
slen = strlen(s) - 1;
/* Determine bitlength from input string */
bitlen = slen;
if (!bit_not_hex)
bitlen *= 4;
/* Sometimes atttypmod is not supplied. If it is supplied we need to make
sure that the bitstring fits. Note that the number of infered bits can
be larger than the number of actual bits needed, but only if we are
reading a hex string and not by more than 3 bits, as a hex string gives
and accurate length upto 4 bits */
if (atttypmod == -1)
atttypmod = bitlen;
else
if ((bitlen>atttypmod && bit_not_hex) ||
(bitlen>atttypmod+3 && !bit_not_hex))
elog(ERROR, "zpbit_in: bit string of size %d cannot be written into bits(%d)",
bitlen,atttypmod);
len = VARBITDATALEN(atttypmod);
if (len > MaxAttrSize)
elog(ERROR, "zpbit_in: length of bit() must be less than %ld",
(MaxAttrSize-VARHDRSZ-VARBITHDRSZ)*BITSPERBYTE);
result = (bits8 *) palloc(len);
/* set to 0 so that *r is always initialised and strin is zero-padded */
memset(result, 0, len);
VARSIZE(result) = len;
VARBITLEN(result) = atttypmod;
/* We need to read the bitstring from the end, as we store it least
significant byte first. s points to the byte before the beginning
of the bitstring */
sp = s+1;
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 = BITHIGH;
for (bc = 0; sp != s+slen+1; sp++, bc++)
{
if (*sp=='1')
*r |= x;
if (bc==7) {
bc = 0;
x = BITHIGH;
r++;
} else
x >>= 1;
}
}
else
{
/* Parse the hex representation of the string */
for (bc = 0; sp != s+slen+1; 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
elog(ERROR,"Cannot parse %c as a hex digit",*sp);
if (bc) {
bc = 0;
*r++ |= x;
} else {
bc++;
*r = x<<4;
}
}
}
if (bitlen > atttypmod) {
/* Check that this fitted */
r = (bits8 *) (result + len - 1);
ipad = VARBITPAD(result);
/* The bottom ipad bits of the byte pointed to by r need to be zero */
if (((*r << (BITSPERBYTE-ipad)) & BITMASK) > 0)
elog(ERROR, "zpbit_in: bit string too large for bit(%d) data type",
atttypmod);
}
return result;
}
/* zpbit_out -
* for the time being we print everything as hex strings, as this is likely
* to be more compact than bit strings, and consequently much more efficient
* for long strings
*/
char *
zpbit_out(bits8 *s)
{
char *result, *r;
bits8 *sp;
int i, len, bitlen;
if (s == NULL)
{
result = (char *) palloc(2);
result[0] = '-';
result[1] = '\0';
}
else
{
bitlen = VARBITLEN(s);
len = bitlen/4 + (bitlen%4>0 ? 1 : 0);
result = (char *) palloc(len + 4);
sp = VARBITS(s);
r = result;
*r++ = 'X';
*r++ = '\'';
/* 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+1)
r--;
*r++ = '\'';
*r = '\0';
}
return result;
}
/* zpbits_out -
* Prints the string a bits
*/
char *
zpbits_out(bits8 *s)
{
char *result, *r;
bits8 *sp;
bits8 x;
int i, k, len;
if (s == NULL)
{
result = (char *) palloc(2);
result[0] = '-';
result[1] = '\0';
}
else
{
len = VARBITLEN(s);
result = (char *) palloc(len + 4);
sp = VARBITS(s);
r = result;
*r++ = 'B';
*r++ = '\'';
for (i=0; i<len-BITSPERBYTE; i+=BITSPERBYTE, sp++) {
x = *sp;
for (k=0; k<BITSPERBYTE; k++)
{
*r++ = (x & BITHIGH) ? '1' : '0';
x <<= 1;
}
}
x = *sp;
for (k=i; k<len; k++)
{
*r++ = (x & BITHIGH) ? '1' : '0';
x <<= 1;
}
*r++ = '\'';
*r = '\0';
}
return result;
}
/*
* varbit_in -
* converts a string to the internal representation of a bitstring.
*/
bits8 *
varbit_in(char *s, int dummy, int32 atttypmod)
{
bits8 *result; /* The resulting bit string */
char *sp; /* pointer into the character string */
bits8 *r;
int len, /* Length of the whole data structure */
bitlen, /* Number of bits in the bit string */
slen; /* Length of the input string */
int bit_not_hex = 0;
int bc, ipad;
bits8 x = 0;
if (s == NULL)
return (bits8 *) NULL;
/* Check that the first character is a b or an x */
if (s[0]=='b' || s[0]=='B')
bit_not_hex = 1;
else if (s[0]=='x' || s[0]=='X')
bit_not_hex = 0;
else
elog(ERROR, "zpbit_in: %s is not a valid bitstring",s);
slen = strlen(s) - 1;
/* Determine bitlength from input string */
bitlen = slen;
if (!bit_not_hex)
bitlen *= 4;
/* Sometimes atttypmod is not supplied. If it is supplied we need to make
sure that the bitstring fits. Note that the number of infered bits can
be larger than the number of actual bits needed, but only if we are
reading a hex string and not by more than 3 bits, as a hex string gives
and accurate length upto 4 bits */
if (atttypmod > -1)
if ((bitlen>atttypmod && bit_not_hex) ||
(bitlen>atttypmod+3 && !bit_not_hex))
elog(ERROR, "varbit_in: bit string of size %d cannot be written into varying bits(%d)",
bitlen,atttypmod);
len = VARBITDATALEN(bitlen);
if (len > MaxAttrSize)
elog(ERROR, "varbit_in: length of bit() must be less than %ld",
(MaxAttrSize-VARHDRSZ-VARBITHDRSZ)*BITSPERBYTE);
result = (bits8 *) palloc(len);
/* set to 0 so that *r is always initialised and strin is zero-padded */
memset(result, 0, len);
VARSIZE(result) = len;
VARBITLEN(result) = bitlen;
/* We need to read the bitstring from the end, as we store it least
significant byte first. s points to the byte before the beginning
of the bitstring */
sp = s + 1;
r = VARBITS(result);
if (bit_not_hex)
{
/* Parse the bit representation of the string */
x = BITHIGH;
for (bc = 0; sp != s+slen+1; sp++, bc++)
{
if (*sp=='1')
*r |= x;
if (bc==7) {
bc = 0;
x = BITHIGH;
r++;
} else
x >>= 1;
}
}
else
{
for (bc = 0; sp != s+slen+1; 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
elog(ERROR,"Cannot parse %c as a hex digit",*sp);
if (bc) {
bc = 0;
*r++ |= x;
} else {
bc++;
*r = x<<4;
}
}
}
if (bitlen > atttypmod) {
/* Check that this fitted */
r = (bits8 *) (result + len - 1);
ipad = VARBITPAD(result);
/* The bottom ipad bits of the byte pointed to by r need to be zero */
if (((*r << (BITSPERBYTE-ipad)) & BITMASK) > 0)
elog(ERROR, "varbit_in: bit string too large for varying bit(%d) data type",
atttypmod);
}
return result;
}
/*
the zpbit_out routines are fine for varying bits as well
*/
/*
* Comparison operators
*
* We only need one set of comparison operators for bitstrings, as the lengths
* are stored in the same way for zero-padded and varying bit strings.
*
* Note that the standard is not unambiguous about the comparison between
* zero-padded bit strings and varying bitstrings. If the same value is written
* into a zero padded bitstring as into a varying bitstring, but the zero
* padded bitstring has greater length, it will be bigger.
*
* Zeros from the beginning of a bitstring cannot simply be ignored, as they
* may be part of a bit string and may be significant.
*/
bool
biteq (bits8 *arg1, bits8 *arg2)
{
int bitlen1,
bitlen2;
if (!PointerIsValid(arg1) || !PointerIsValid(arg2))
return (bool) 0;
bitlen1 = VARBITLEN(arg1);
bitlen2 = VARBITLEN(arg2);
if (bitlen1 != bitlen2)
return (bool) 0;
/* bit strings are always stored in a full number of bytes */
return memcmp((void *)VARBITS(arg1),(void *)VARBITS(arg2),
VARBITBYTES(arg1)) == 0;
}
bool
bitne (bits8 *arg1, bits8 *arg2)
{
int bitlen1,
bitlen2;
if (!PointerIsValid(arg1) || !PointerIsValid(arg2))
return (bool) 0;
bitlen1 = VARBITLEN(arg1);
bitlen2 = VARBITLEN(arg2);
if (bitlen1 != bitlen2)
return (bool) 1;
/* bit strings are always stored in a full number of bytes */
return memcmp((void *)VARBITS(arg1),(void *)VARBITS(arg2),
VARBITBYTES(arg1)) != 0;
}
/* bitcmp
*
* Compares two bitstrings and returns -1, 0, 1 depending on whether the first
* string is smaller, equal, or bigger than the second. All bits are considered
* and additional zero bits may make one string smaller/larger than the other,
* even if their zero-padded values would be the same.
* Anything is equal to undefined.
*/
int
bitcmp (bits8 *arg1, bits8 *arg2)
{
int bitlen1, bytelen1,
bitlen2, bytelen2;
int cmp;
if (!PointerIsValid(arg1) || !PointerIsValid(arg2))
return (bool) 0;
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)
return bitlen1 < bitlen2 ? -1 : 1;
}
return cmp;
}
bool
bitlt (bits8 *arg1, bits8 *arg2)
{
return (bool) (bitcmp(arg1,arg2) == -1);
}
bool
bitle (bits8 *arg1, bits8 *arg2)
{
return (bool) (bitcmp(arg1,arg2) <= 0);
}
bool
bitge (bits8 *arg1, bits8 *arg2)
{
return (bool) (bitcmp(arg1,arg2) >= 0);
}
bool
bitgt (bits8 *arg1, bits8 *arg2)
{
return (bool) (bitcmp(arg1,arg2) == 1);
}
/* bitcat
* Concatenation of bit strings
*/
bits8 *
bitcat (bits8 *arg1, bits8 *arg2)
{
int bitlen1, bitlen2, bytelen, bit1pad, bit2shift;
bits8 *result;
bits8 *pr, *pa;
if (!PointerIsValid(arg1) || !PointerIsValid(arg2))
return NULL;
bitlen1 = VARBITLEN(arg1);
bitlen2 = VARBITLEN(arg2);
bytelen = VARBITDATALEN(bitlen1+bitlen2);
result = (bits8 *) palloc(bytelen*sizeof(bits8));
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 results to fit */
bit2shift = BITSPERBYTE - bit1pad;
pa = VARBITS(arg2);
pr = VARBITS(result)+VARBITBYTES(arg1)-1;
for ( ; pa < VARBITEND(arg2); pa++) {
*pr |= ((*pa >> bit2shift) & BITMASK);
pr++;
if (pr < VARBITEND(result))
*pr = (*pa << bit1pad) & BITMASK;
}
}
return result;
}
/* bitsubstr
* retrieve a substring from the bit string.
* Note, s is 1-based.
* SQL draft 6.10 9)
*/
bits8 *
bitsubstr (bits8 *arg, int32 s, int32 l)
{
int bitlen,
rbitlen,
len,
ipad = 0,
ishift,
i;
int e, s1, e1;
bits8 * result;
bits8 mask, *r, *ps;
if (!PointerIsValid(arg))
return NULL;
bitlen = VARBITLEN(arg);
e = s+l;
s1 = Max(s,1);
e1 = Min(e,bitlen+1);
if (s1>bitlen || e1<1)
{
/* Need to return a null string */
len = VARBITDATALEN(0);
result = (bits8 *) palloc(len);
VARBITLEN(result) = 0;
VARSIZE(result) = len;
}
else
{
/* OK, we've got a true substring starting at position s1-1 and
ending at position e1-1 */
rbitlen = e1-s1;
len = VARBITDATALEN(rbitlen);
result = (bits8 *) palloc(len);
VARBITLEN(result) = rbitlen;
VARSIZE(result) = len;
len -= VARHDRSZ + VARBITHDRSZ;
/* Are we copying from a byte boundary? */
if ((s1-1)%BITSPERBYTE==0)
{
/* Yep, we are copying bytes */
memcpy(VARBITS(result),VARBITS(arg)+(s1-1)/BITSPERBYTE,len);
}
else
{
/* Figure out how much we need to shift the sequence by */
ishift = (s1-1)%BITSPERBYTE;
r = VARBITS(result);
ps = VARBITS(arg) + (s1-1)/BITSPERBYTE;
for (i=0; i<len; i++)
{
*r = (*ps <<ishift) & BITMASK;
if ((++ps) < VARBITEND(arg))
*r |= *ps >>(BITSPERBYTE-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;
}
/* bitand
* perform a logical AND on two bit strings. The result is automatically
* truncated to the shorter bit string
*/
bits8 *
bitand (bits8 * arg1, bits8 * arg2)
{
int len,
i;
bits8 *result;
bits8 *p1,
*p2,
*r;
if (!PointerIsValid(arg1) || !PointerIsValid(arg2))
return (bool) 0;
len = Min(VARSIZE(arg1),VARSIZE(arg2));
result = (bits8 *) palloc(len);
VARSIZE(result) = len;
VARBITLEN(result) = Min(VARBITLEN(arg1),VARBITLEN(arg2));
p1 = (bits8 *) VARBITS(arg1);
p2 = (bits8 *) VARBITS(arg2);
r = (bits8 *) VARBITS(result);
for (i=0; i<Min(VARBITBYTES(arg1),VARBITBYTES(arg2)); i++)
*r++ = *p1++ & *p2++;
/* Padding is not needed as & of 0 pad is 0 */
return result;
}
/* bitor
* perform a logical OR on two bit strings. The result is automatically
* truncated to the shorter bit string.
*/
bits8 *
bitor (bits8 * arg1, bits8 * arg2)
{
int len,
i;
bits8 *result;
bits8 *p1,
*p2,
*r;
bits8 mask;
if (!PointerIsValid(arg1) || !PointerIsValid(arg2))
return (bool) 0;
len = Min(VARSIZE(arg1),VARSIZE(arg2));
result = (bits8 *) palloc(len);
VARSIZE(result) = len;
VARBITLEN(result) = Min(VARBITLEN(arg1),VARBITLEN(arg2));
p1 = (bits8 *) VARBITS(arg1);
p2 = (bits8 *) VARBITS(arg2);
r = (bits8 *) VARBITS(result);
for (i=0; i<Min(VARBITBYTES(arg1),VARBITBYTES(arg2)); i++)
*r++ = *p1++ | *p2++;
/* Pad the result */
mask = BITMASK << VARBITPAD(result);
*r &= mask;
return result;
}
/* bitxor
* perform a logical XOR on two bit strings. The result is automatically
* truncated to the shorter bit string.
*/
bits8 *
bitxor (bits8 * arg1, bits8 * arg2)
{
int len,
i;
bits8 *result;
bits8 *p1,
*p2,
*r;
bits8 mask;
if (!PointerIsValid(arg1) || !PointerIsValid(arg2))
return (bool) 0;
len = Min(VARSIZE(arg1),VARSIZE(arg2));
result = (bits8 *) palloc(len);
VARSIZE(result) = len;
VARBITLEN(result) = Min(VARBITLEN(arg1),VARBITLEN(arg2));
p1 = (bits8 *) VARBITS(arg1);
p2 = (bits8 *) VARBITS(arg2);
r = (bits8 *) VARBITS(result);
for (i=0; i<Min(VARBITBYTES(arg1),VARBITBYTES(arg2)); i++)
{
*r++ = *p1++ ^ *p2++;
}
/* Pad the result */
mask = BITMASK << VARBITPAD(result);
*r &= mask;
return result;
}
/* bitnot
* perform a logical NOT on a bit strings.
*/
bits8 *
bitnot (bits8 * arg)
{
bits8 *result;
bits8 *p,
*r;
bits8 mask;
if (!PointerIsValid(arg))
return (bool) 0;
result = (bits8 *) palloc(VARSIZE(arg));
VARSIZE(result) = VARSIZE(arg);
VARBITLEN(result) = VARBITLEN(arg);
p = (bits8 *) VARBITS(arg);
r = (bits8 *) VARBITS(result);
for ( ; p < VARBITEND(arg); p++, r++)
*r = ~*p;
/* Pad the result */
mask = BITMASK << VARBITPAD(result);
*r &= mask;
return result;
}
/* bitshiftleft
* do a left shift (i.e. to the beginning of the string) of the bit string
*/
bits8 *
bitshiftleft (bits8 * arg, int shft)
{
int byte_shift, ishift, len;
bits8 *result;
bits8 *p,
*r;
if (!PointerIsValid(arg))
return (bool) 0;
/* Negative shift is a shift to the right */
if (shft < 0)
return bitshiftright(arg, -shft);
result = (bits8 *) palloc(VARSIZE(arg));
VARSIZE(result) = VARSIZE(arg);
VARBITLEN(result) = VARBITLEN(arg);
r = (bits8 *) VARBITS(result);
byte_shift = shft/BITSPERBYTE;
ishift = shft % BITSPERBYTE;
p = ((bits8 *) 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 >>(BITSPERBYTE-ishift);
}
for ( ; r < VARBITEND(result) ; r++ )
*r = (bits8) 0;
}
return result;
}
/* bitshiftright
* do a right shift (i.e. to the beginning of the string) of the bit string
*/
bits8 *
bitshiftright (bits8 * arg, int shft)
{
int byte_shift, ishift, len;
bits8 *result;
bits8 *p,
*r;
if (!PointerIsValid(arg))
return (bits8 *) 0;
/* Negative shift is a shift to the left */
if (shft < 0)
return bitshiftleft(arg, -shft);
result = (bits8 *) palloc(VARSIZE(arg));
VARSIZE(result) = VARSIZE(arg);
VARBITLEN(result) = VARBITLEN(arg);
r = (bits8 *) VARBITS(result);
byte_shift = shft/BITSPERBYTE;
ishift = shft % BITSPERBYTE;
p = (bits8 *) VARBITS(arg);
/* Set the first part of the result to 0 */
memset(r, 0, byte_shift);
if (ishift == 0)
{
/* Special case: we can do a memcpy */
len = VARBITBYTES(arg) - byte_shift;
memcpy(r+byte_shift, p, len);
}
else
{
r += byte_shift;
*r = 0; /* Initialise first byte */
for ( ; r < VARBITEND(result); p++) {
*r |= *p >> ishift;
if ((++r) < VARBITEND(result))
*r = (*p <<(BITSPERBYTE-ishift)) & BITMASK;
}
}
return result;
}
bool
varbiteq (bits8 *arg1, bits8 *arg2)
{
return biteq(arg1, arg2);
}
bool
varbitne (bits8 *arg1, bits8 *arg2)
{
return bitne(arg1, arg2);
}
bool
varbitge (bits8 *arg1, bits8 *arg2)
{
return bitge(arg1, arg2);
}
bool
varbitgt (bits8 *arg1, bits8 *arg2)
{
return bitgt(arg1, arg2);
}
bool
varbitle (bits8 *arg1, bits8 *arg2)
{
return bitle(arg1, arg2);
}
bool
varbitlt (bits8 *arg1, bits8 *arg2)
{
return bitlt(arg1, arg2);
}
int
varbitcmp (bits8 *arg1, bits8 *arg2)
{
return bitcmp(arg1, arg2);
}
bits8 *
varbitand (bits8 * arg1, bits8 * arg2)
{
return bitand(arg1, arg2);
}
bits8 *
varbitor (bits8 * arg1, bits8 * arg2)
{
return bitor(arg1, arg2);
}
bits8 *
varbitxor (bits8 * arg1, bits8 * arg2)
{
return bitxor(arg1, arg2);
}
bits8 *
varbitnot (bits8 * arg)
{
return bitnot(arg);
}
bits8 *
varbitshiftright (bits8 * arg, int shft)
{
return bitshiftright(arg, shft);
}
bits8 *
varbitshiftleft (bits8 * arg, int shft)
{
return bitshiftleft(arg, shft);
}
bits8 *
varbitcat (bits8 *arg1, bits8 *arg2)
{
return bitcat(arg1, arg2);
}
bits8 *
varbitsubstr (bits8 *arg, int32 s, int32 l)
{
return bitsubstr(arg, s, l);
}

View File

@ -8,7 +8,7 @@
* Portions Copyright (c) 1996-2000, PostgreSQL, Inc
* Portions Copyright (c) 1994, Regents of the University of California
*
* $Id: pg_operator.h,v 1.73 2000/04/07 13:39:49 thomas Exp $
* $Id: pg_operator.h,v 1.74 2000/04/08 02:13:00 thomas Exp $
*
* NOTES
* the genbki.sh script reads this file and generates .bki
@ -716,6 +716,35 @@ DATA(insert OID = 1660 ( "<=" PGUID 0 b t f 1625 1625 16 1662 1661 0 0
DATA(insert OID = 1661 ( ">" PGUID 0 b t f 1625 1625 16 1659 1660 0 0 lztext_gt intgtsel intgtjoinsel ));
DATA(insert OID = 1662 ( ">=" PGUID 0 b t f 1625 1625 16 1660 1659 0 0 lztext_ge intgtsel intgtjoinsel ));
DATA(insert OID = 1784 ( "=" PGUID 0 b t f 1560 1560 16 1784 1785 1786 1786 biteq eqsel eqjoinsel ));
DATA(insert OID = 1785 ( "<>" PGUID 0 b t f 1560 1560 16 1785 1784 0 0 bitne neqsel neqjoinsel ));
DATA(insert OID = 1786 ( "<" PGUID 0 b t f 1560 1560 16 1787 1789 0 0 bitlt intltsel intltjoinsel ));
DATA(insert OID = 1787 ( ">" PGUID 0 b t f 1560 1560 16 1786 1788 0 0 bitgt intgtsel intgtjoinsel ));
DATA(insert OID = 1788 ( "<=" PGUID 0 b t f 1560 1560 16 1789 1787 0 0 bitle intltsel intltjoinsel ));
DATA(insert OID = 1789 ( ">=" PGUID 0 b t f 1560 1560 16 1788 1786 0 0 bitge intgtsel intgtjoinsel ));
DATA(insert OID = 1790 ( "<=>" PGUID 0 b t f 1560 1560 23 0 0 0 0 bitcmp - - ));
DATA(insert OID = 1791 ( "&" PGUID 0 b t f 1560 1560 1560 0 0 0 0 bitand - - ));
DATA(insert OID = 1792 ( "|" PGUID 0 b t f 1560 1560 1560 0 0 0 0 bitor - - ));
DATA(insert OID = 1793 ( "^" PGUID 0 b t f 1560 1560 1560 0 0 0 0 bitxor - - ));
DATA(insert OID = 1794 ( "~" PGUID 0 b t f 1560 1560 1560 0 0 0 0 bitnot - - ));
DATA(insert OID = 1795 ( "<<" PGUID 0 b t f 1560 1560 1560 0 0 0 0 bitshiftleft - - ));
DATA(insert OID = 1796 ( ">>" PGUID 0 b t f 1560 1560 1560 0 0 0 0 bitshiftright - - ));
DATA(insert OID = 1797 ( "||" PGUID 0 b t f 1560 1560 1560 0 0 0 0 bitcat - - ));
DATA(insert OID = 1804 ( "=" PGUID 0 b t f 1562 1562 16 1804 1805 1806 1806 varbiteq eqsel eqjoinsel ));
DATA(insert OID = 1805 ( "<>" PGUID 0 b t f 1562 1562 16 1805 1804 0 0 varbitne neqsel neqjoinsel ));
DATA(insert OID = 1806 ( "<" PGUID 0 b t f 1562 1562 16 1807 1809 0 0 varbitlt intltsel intltjoinsel ));
DATA(insert OID = 1807 ( ">" PGUID 0 b t f 1562 1562 16 1806 1808 0 0 varbitgt intgtsel intgtjoinsel ));
DATA(insert OID = 1808 ( "<=" PGUID 0 b t f 1562 1562 16 1809 1807 0 0 varbitle intltsel intltjoinsel ));
DATA(insert OID = 1809 ( ">=" PGUID 0 b t f 1562 1562 16 1808 1806 0 0 varbitge intgtsel intgtjoinsel ));
DATA(insert OID = 1810 ( "<=>" PGUID 0 b t f 1562 1562 23 0 0 0 0 varbitcmp - - ));
DATA(insert OID = 1811 ( "&" PGUID 0 b t f 1562 1562 1562 0 0 0 0 varbitand - - ));
DATA(insert OID = 1812 ( "|" PGUID 0 b t f 1562 1562 1562 0 0 0 0 varbitor - - ));
DATA(insert OID = 1813 ( "^" PGUID 0 b t f 1562 1562 1562 0 0 0 0 varbitxor - - ));
DATA(insert OID = 1814 ( "~" PGUID 0 b t f 1562 1562 1562 0 0 0 0 varbitnot - - ));
DATA(insert OID = 1815 ( "<<" PGUID 0 b t f 1562 1562 1562 0 0 0 0 varbitshiftleft - - ));
DATA(insert OID = 1816 ( ">>" PGUID 0 b t f 1562 1562 1562 0 0 0 0 varbitshiftright - - ));
DATA(insert OID = 1817 ( "||" PGUID 0 b t f 1562 1562 1562 0 0 0 0 varbitcat - - ));
/*
* function prototypes

View File

@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2000, PostgreSQL, Inc
* Portions Copyright (c) 1994, Regents of the University of California
*
* $Id: pg_proc.h,v 1.130 2000/04/07 13:39:49 thomas Exp $
* $Id: pg_proc.h,v 1.131 2000/04/08 02:13:00 thomas Exp $
*
* NOTES
* The script catalog/genbki.sh reads this file and generates .bki
@ -1979,8 +1979,11 @@ DATA(insert OID = 1545 ( npoints PGUID 11 f t t 1 f 23 "602" 100 0 0 100 pat
DESCR("# points in path");
DATA(insert OID = 1556 ( npoints PGUID 11 f t t 1 f 23 "604" 100 0 0 100 poly_npoints - ));
DESCR("number of points in polygon");
DATA(insert OID = 1573 ( int8 PGUID 14 f t t 1 f 20 "20" 100 0 0 100 "select $1" - ));
DESCR("convert int8 to int8 (no-op)");
DATA(insert OID = 1564 ( zpbit_in PGUID 11 f t t 1 f 1560 "0" 100 0 0 100 zpbit_in - ));
DESCR("(internal)");
DATA(insert OID = 1565 ( zpbit_out PGUID 11 f t t 1 f 23 "0" 100 0 0 100 zpbit_out - ));
DESCR("(internal)");
DATA(insert OID = 1569 ( like PGUID 11 f t t 2 f 16 "25 25" 100 0 1 0 textlike - ));
DESCR("matches LIKE expression");
@ -1990,6 +1993,9 @@ DATA(insert OID = 1571 ( like PGUID 11 f t t 2 f 16 "19 25" 100 0 0 100 nam
DESCR("matches LIKE expression");
DATA(insert OID = 1572 ( notlike PGUID 11 f t t 2 f 16 "19 25" 100 0 0 100 namenlike - ));
DESCR("does not match LIKE expression");
DATA(insert OID = 1573 ( int8 PGUID 14 f t t 1 f 20 "20" 100 0 0 100 "select $1" - ));
DESCR("convert int8 to int8 (no-op)");
/* SEQUENCEs nextval & currval functions */
DATA(insert OID = 1574 ( nextval PGUID 11 f t f 1 f 23 "25" 100 0 0 100 nextval - ));
@ -1999,6 +2005,26 @@ DESCR("sequence current value");
DATA(insert OID = 1576 ( setval PGUID 11 f t f 2 f 23 "25 23" 100 0 0 100 setval - ));
DESCR("sequence set value");
DATA(insert OID = 1579 ( varbit_in PGUID 11 f t t 1 f 1562 "0" 100 0 0 100 varbit_in - ));
DESCR("(internal)");
DATA(insert OID = 1580 ( varbit_out PGUID 11 f t t 1 f 23 "0" 100 0 0 100 varbit_out - ));
DESCR("(internal)");
DATA(insert OID = 1581 ( biteq PGUID 11 f t t 2 f 16 "1560 1560" 100 0 1 0 biteq - ));
DESCR("equal");
DATA(insert OID = 1582 ( bitne PGUID 11 f t t 2 f 16 "1560 1560" 100 0 1 0 bitne - ));
DESCR("not equal");
DATA(insert OID = 1592 ( bitge PGUID 11 f t t 2 f 16 "1560 1560" 100 0 1 0 bitge - ));
DESCR("greater than or equal");
DATA(insert OID = 1593 ( bitgt PGUID 11 f t t 2 f 16 "1560 1560" 100 0 1 0 bitgt - ));
DESCR("greater than");
DATA(insert OID = 1594 ( bitle PGUID 11 f t t 2 f 16 "1560 1560" 100 0 1 0 bitle - ));
DESCR("less than or equal");
DATA(insert OID = 1595 ( bitlt PGUID 11 f t t 2 f 16 "1560 1560" 100 0 1 0 bitlt - ));
DESCR("less than");
DATA(insert OID = 1596 ( bitcmp PGUID 11 f t t 2 f 23 "1560 1560" 100 0 1 0 bitcmp - ));
DESCR("compare");
DATA(insert OID = 1598 ( random PGUID 11 f t f 0 f 701 "0" 100 0 0 100 drandom - ));
DESCR("radians to degrees");
DATA(insert OID = 1599 ( setseed PGUID 11 f t t 1 f 23 "701" 100 0 0 100 setseed - ));
@ -2159,6 +2185,55 @@ DESCR("referential integrity ON DELETE NO ACTION");
DATA(insert OID = 1655 ( RI_FKey_noaction_upd PGUID 11 f t f 0 f 0 "" 100 0 0 100 RI_FKey_noaction_upd - ));
DESCR("referential integrity ON UPDATE NO ACTION");
DATA(insert OID = 1666 ( varbiteq PGUID 11 f t t 2 f 16 "1562 1562" 100 0 1 0 varbiteq - ));
DESCR("equal");
DATA(insert OID = 1667 ( varbitne PGUID 11 f t t 2 f 16 "1562 1562" 100 0 1 0 varbitne - ));
DESCR("not equal");
DATA(insert OID = 1668 ( varbitge PGUID 11 f t t 2 f 16 "1562 1562" 100 0 1 0 varbitge - ));
DESCR("greater than or equal");
DATA(insert OID = 1669 ( varbitgt PGUID 11 f t t 2 f 16 "1562 1562" 100 0 1 0 varbitgt - ));
DESCR("greater than");
DATA(insert OID = 1670 ( varbitle PGUID 11 f t t 2 f 16 "1562 1562" 100 0 1 0 varbitle - ));
DESCR("less than or equal");
DATA(insert OID = 1671 ( varbitlt PGUID 11 f t t 2 f 16 "1562 1562" 100 0 1 0 varbitlt - ));
DESCR("less than");
DATA(insert OID = 1672 ( varbitcmp PGUID 11 f t t 2 f 23 "1562 1562" 100 0 1 0 varbitcmp - ));
DESCR("compare");
DATA(insert OID = 1673 ( bitand PGUID 11 f t t 2 f 1560 "1560 1560" 100 0 1 0 bitand - ));
DESCR("bitwise and");
DATA(insert OID = 1674 ( bitor PGUID 11 f t t 2 f 1560 "1560 1560" 100 0 1 0 bitor - ));
DESCR("bitwise or");
DATA(insert OID = 1675 ( bitxor PGUID 11 f t t 2 f 1560 "1560 1560" 100 0 1 0 bitxor - ));
DESCR("bitwise exclusive or");
DATA(insert OID = 1676 ( bitnot PGUID 11 f t t 2 f 1560 "1560 1560" 100 0 1 0 bitnot - ));
DESCR("bitwise negation");
DATA(insert OID = 1677 ( bitshiftright PGUID 11 f t t 2 f 1560 "1560 1560" 100 0 1 0 bitshiftright - ));
DESCR("bitwise right shift");
DATA(insert OID = 1678 ( bitshiftleft PGUID 11 f t t 2 f 1560 "1560 1560" 100 0 1 0 bitshiftleft - ));
DESCR("bitwise left shift");
DATA(insert OID = 1679 ( bitcat PGUID 11 f t t 2 f 1560 "1560 1560" 100 0 1 0 bitcat - ));
DESCR("bitwise concatenation");
DATA(insert OID = 1680 ( bitsubstr PGUID 11 f t t 2 f 1560 "1560 1560" 100 0 1 0 bitsubstr - ));
DESCR("bitwise field");
DATA(insert OID = 1681 ( varbitand PGUID 11 f t t 2 f 1562 "1562 1562" 100 0 1 0 varbitand - ));
DESCR("bitwise and");
DATA(insert OID = 1682 ( varbitor PGUID 11 f t t 2 f 1562 "1562 1562" 100 0 1 0 varbitor - ));
DESCR("bitwise or");
DATA(insert OID = 1683 ( varbitxor PGUID 11 f t t 2 f 1562 "1562 1562" 100 0 1 0 varbitxor - ));
DESCR("bitwise exclusive or");
DATA(insert OID = 1684 ( varbitnot PGUID 11 f t t 2 f 1562 "1562 1562" 100 0 1 0 varbitnot - ));
DESCR("bitwise negation");
DATA(insert OID = 1685 ( varbitshiftright PGUID 11 f t t 2 f 1562 "1562 1562" 100 0 1 0 varbitshiftright - ));
DESCR("bitwise right shift");
DATA(insert OID = 1686 ( varbitshiftleft PGUID 11 f t t 2 f 1562 "1562 1562" 100 0 1 0 varbitshiftleft - ));
DESCR("bitwise left shift");
DATA(insert OID = 1687 ( varbitcat PGUID 11 f t t 2 f 1562 "1562 1562" 100 0 1 0 varbitcat - ));
DESCR("bitwise concatenation");
DATA(insert OID = 1688 ( varbitsubstr PGUID 11 f t t 2 f 1562 "1562 1562" 100 0 1 0 varbitsubstr - ));
DESCR("bitwise field");
/* for mac type support */
DATA(insert OID = 436 ( macaddr_in PGUID 11 f t t 1 f 829 "0" 100 0 0 100 macaddr_in - ));
DESCR("(internal)");

View File

@ -8,7 +8,7 @@
* Portions Copyright (c) 1996-2000, PostgreSQL, Inc
* Portions Copyright (c) 1994, Regents of the University of California
*
* $Id: pg_type.h,v 1.86 2000/03/18 20:50:10 momjian Exp $
* $Id: pg_type.h,v 1.87 2000/04/08 02:13:01 thomas Exp $
*
* NOTES
* the genbki.sh script reads this file and generates .bki
@ -382,16 +382,26 @@ DESCR("hh:mm:ss, ANSI SQL time");
#define TIMETZOID 1266
DATA(insert OID = 1270 ( _timetz PGUID -1 -1 f b t \054 0 1266 array_in array_out array_in array_out d _null_ ));
/* OIDS 1500 - 1599 */
DATA(insert OID = 1560 ( bit PGUID -1 -1 f b t \054 0 0 zpbit_in zpbit_out zpbit_in zpbit_out i _null_ ));
DESCR("fixed-length bit string");
#define ZPBITOID 1560
DATA(insert OID = 1561 ( _bit PGUID -1 -1 f b t \054 0 1560 array_in array_out array_in array_out i _null_ ));
DATA(insert OID = 1562 ( varbit PGUID -1 -1 f b t \054 0 0 varbit_in varbit_out varbit_in varbit_out i _null_ ));
DESCR("fixed-length bit string");
#define VARBITOID 1562
DATA(insert OID = 1563 ( _varbit PGUID -1 -1 f b t \054 0 1562 array_in array_out array_in array_out i _null_ ));
/* OIDS 1600 - 1699 */
DATA(insert OID = 1625 ( lztext PGUID -1 -1 f b t \054 0 0 lztextin lztextout lztextin lztextout i _null_ ));
DESCR("variable-length string, stored compressed");
#define LZTEXTOID 1625
/* OIDS 1700 - 1799 */
DATA(insert OID = 1700 ( numeric PGUID -1 -1 f b t \054 0 0 numeric_in numeric_out numeric_in numeric_out i _null_ ));
DESCR("numeric(precision, decimal), arbitrary precision number");
#define NUMERICOID 1700
/* OIDS 1625 - 1639 */
DATA(insert OID = 1625 ( lztext PGUID -1 -1 f b t \054 0 0 lztextin lztextout lztextin lztextout i _null_ ));
DESCR("variable-length string, stored compressed");
#define LZTEXTOID 1625
#define VARLENA_FIXED_SIZE(attr) ((attr)->atttypid == BPCHAROID && (attr)->atttypmod > 0)
/*

View File

@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2000, PostgreSQL, Inc
* Portions Copyright (c) 1994, Regents of the University of California
*
* $Id: builtins.h,v 1.108 2000/04/07 13:40:12 thomas Exp $
* $Id: builtins.h,v 1.109 2000/04/08 02:13:10 thomas Exp $
*
* NOTES
* This should normally only be included by fmgr.h.
@ -36,6 +36,7 @@
#include "utils/nabstime.h"
#include "utils/date.h"
#include "utils/lztext.h"
#include "utils/varbit.h"
/*
* Defined in adt/

View File

@ -0,0 +1,87 @@
#ifndef VARBIT_H
#define VARBIT_H
#include <math.h>
#include "postgres.h"
#ifdef HAVE_LIMITS_H
#include <limits.h>
#ifndef MAXINT
#define MAXINT INT_MAX
#endif
#else
#ifdef HAVE_VALUES_H
#include <values.h>
#endif
#endif
#include "utils/builtins.h"
#define HEXDIG(z) (z)<10 ? ((z)+'0') : ((z)-10+'A')
/* Modeled on struct varlena from postgres.h, bu data type is bits8 */
struct varbita
{
int32 vl_len;
bits8 vl_dat[1];
};
#define BITSPERBYTE 8
#define VARBITHDRSZ sizeof(int32)
/* Number of bits in this bit string */
#define VARBITLEN(PTR) (((struct varbita *)VARDATA(PTR))->vl_len)
/* Pointer tp the first byte containing bit string data */
#define VARBITS(PTR) (((struct varbita *)VARDATA(PTR))->vl_dat)
/* Number of bytes in the data section of a bit string */
#define VARBITBYTES(PTR) (VARSIZE(PTR) - VARHDRSZ - VARBITHDRSZ)
/* Padding of the bit string at the end */
#define VARBITPAD(PTR) (VARBITBYTES(PTR)*BITSPERBYTE - VARBITLEN(PTR))
/* Number of bytes needed to store a bit string of a given length */
#define VARBITDATALEN(BITLEN) ((BITLEN)/BITSPERBYTE + \
((BITLEN)%BITSPERBYTE > 0 ? 1 : 0) + \
VARHDRSZ + VARBITHDRSZ)
/* pointer beyond the end of the bit string (like end() in STL containers) */
#define VARBITEND(PTR) ((bits8 *) (PTR + VARSIZE(PTR)))
/* Mask that will cover exactly one byte, i.e. BITSPERBYTE bits */
#define BITMASK 0xFF
#define BITHIGH 0x80
bits8 * zpbit_in(char *s, int dummy, int32 atttypmod);
char * zpbit_out(bits8 *s);
char * zpbits_out(bits8 *s);
bits8 * varbit_in(char *s, int dummy, int32 atttypmod);
char * varbit_out (bits8 *s);
bool biteq (bits8 *arg1, bits8 *arg2);
bool bitne (bits8 *arg1, bits8 *arg2);
bool bitge (bits8 *arg1, bits8 *arg2);
bool bitgt (bits8 *arg1, bits8 *arg2);
bool bitle (bits8 *arg1, bits8 *arg2);
bool bitlt (bits8 *arg1, bits8 *arg2);
int bitcmp (bits8 *arg1, bits8 *arg2);
bits8 * bitand (bits8 * arg1, bits8 * arg2);
bits8 * bitor (bits8 * arg1, bits8 * arg2);
bits8 * bitxor (bits8 * arg1, bits8 * arg2);
bits8 * bitnot (bits8 * arg);
bits8 * bitshiftright (bits8 * arg, int shft);
bits8 * bitshiftleft (bits8 * arg, int shft);
bits8 * bitcat (bits8 *arg1, bits8 *arg2);
bits8 * bitsubstr (bits8 *arg, int32 s, int32 l);
bool varbiteq (bits8 *arg1, bits8 *arg2);
bool varbitne (bits8 *arg1, bits8 *arg2);
bool varbitge (bits8 *arg1, bits8 *arg2);
bool varbitgt (bits8 *arg1, bits8 *arg2);
bool varbitle (bits8 *arg1, bits8 *arg2);
bool varbitlt (bits8 *arg1, bits8 *arg2);
int varbitcmp (bits8 *arg1, bits8 *arg2);
bits8 * varbitand (bits8 * arg1, bits8 * arg2);
bits8 * varbitor (bits8 * arg1, bits8 * arg2);
bits8 * varbitxor (bits8 * arg1, bits8 * arg2);
bits8 * varbitnot (bits8 * arg);
bits8 * varbitshiftright (bits8 * arg, int shft);
bits8 * varbitshiftleft (bits8 * arg, int shft);
bits8 * varbitcat (bits8 *arg1, bits8 *arg2);
bits8 * varbitsubstr (bits8 *arg, int32 s, int32 l);
#endif