diff --git a/src/backend/utils/adt/Makefile b/src/backend/utils/adt/Makefile index b6b02082e0..8ed27fe893 100644 --- a/src/backend/utils/adt/Makefile +++ b/src/backend/utils/adt/Makefile @@ -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 + + + diff --git a/src/backend/utils/adt/varbit.c b/src/backend/utils/adt/varbit.c new file mode 100644 index 0000000000..47946faccc --- /dev/null +++ b/src/backend/utils/adt/varbit.c @@ -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 +#include + +#include /* faked on sunos4 */ + +#include + +#include "postgres.h" +#ifdef HAVE_LIMITS_H +#include +#ifndef MAXINT +#define MAXINT INT_MAX +#endif +#else +#ifdef HAVE_VALUES_H +#include +#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>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 -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>(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>(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); +} diff --git a/src/include/catalog/pg_operator.h b/src/include/catalog/pg_operator.h index 0189184cfc..2150bac98d 100644 --- a/src/include/catalog/pg_operator.h +++ b/src/include/catalog/pg_operator.h @@ -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 diff --git a/src/include/catalog/pg_proc.h b/src/include/catalog/pg_proc.h index 24fa3f7325..c38c1c84a4 100644 --- a/src/include/catalog/pg_proc.h +++ b/src/include/catalog/pg_proc.h @@ -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)"); diff --git a/src/include/catalog/pg_type.h b/src/include/catalog/pg_type.h index d49ee9047e..61bbfeab85 100644 --- a/src/include/catalog/pg_type.h +++ b/src/include/catalog/pg_type.h @@ -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) /* diff --git a/src/include/utils/builtins.h b/src/include/utils/builtins.h index 4e6cbaaace..270187e917 100644 --- a/src/include/utils/builtins.h +++ b/src/include/utils/builtins.h @@ -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/ diff --git a/src/include/utils/varbit.h b/src/include/utils/varbit.h new file mode 100644 index 0000000000..9ee0724b01 --- /dev/null +++ b/src/include/utils/varbit.h @@ -0,0 +1,87 @@ +#ifndef VARBIT_H +#define VARBIT_H + +#include + +#include "postgres.h" +#ifdef HAVE_LIMITS_H +#include +#ifndef MAXINT +#define MAXINT INT_MAX +#endif +#else +#ifdef HAVE_VALUES_H +#include +#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