Header And Logo

PostgreSQL
| The world's most advanced open source database.

Data Structures | Defines | Functions

varbit.h File Reference

#include "fmgr.h"
Include dependency graph for varbit.h:
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Data Structures

struct  VarBit

Defines

#define DatumGetVarBitP(X)   ((VarBit *) PG_DETOAST_DATUM(X))
#define DatumGetVarBitPCopy(X)   ((VarBit *) PG_DETOAST_DATUM_COPY(X))
#define VarBitPGetDatum(X)   PointerGetDatum(X)
#define PG_GETARG_VARBIT_P(n)   DatumGetVarBitP(PG_GETARG_DATUM(n))
#define PG_GETARG_VARBIT_P_COPY(n)   DatumGetVarBitPCopy(PG_GETARG_DATUM(n))
#define PG_RETURN_VARBIT_P(x)   return VarBitPGetDatum(x)
#define VARBITHDRSZ   sizeof(int32)
#define VARBITLEN(PTR)   (((VarBit *) (PTR))->bit_len)
#define VARBITS(PTR)   (((VarBit *) (PTR))->bit_dat)
#define VARBITBYTES(PTR)   (VARSIZE(PTR) - VARHDRSZ - VARBITHDRSZ)
#define VARBITPAD(PTR)   (VARBITBYTES(PTR)*BITS_PER_BYTE - VARBITLEN(PTR))
#define VARBITTOTALLEN(BITLEN)
#define VARBITEND(PTR)   (((bits8 *) (PTR)) + VARSIZE(PTR))
#define BITMASK   0xFF

Functions

Datum bit_in (PG_FUNCTION_ARGS)
Datum bit_out (PG_FUNCTION_ARGS)
Datum bit_recv (PG_FUNCTION_ARGS)
Datum bit_send (PG_FUNCTION_ARGS)
Datum bittypmodin (PG_FUNCTION_ARGS)
Datum bittypmodout (PG_FUNCTION_ARGS)
Datum varbit_in (PG_FUNCTION_ARGS)
Datum varbit_out (PG_FUNCTION_ARGS)
Datum varbit_recv (PG_FUNCTION_ARGS)
Datum varbit_send (PG_FUNCTION_ARGS)
Datum varbittypmodin (PG_FUNCTION_ARGS)
Datum varbittypmodout (PG_FUNCTION_ARGS)
Datum bit (PG_FUNCTION_ARGS)
Datum varbit_transform (PG_FUNCTION_ARGS)
Datum varbit (PG_FUNCTION_ARGS)
Datum biteq (PG_FUNCTION_ARGS)
Datum bitne (PG_FUNCTION_ARGS)
Datum bitlt (PG_FUNCTION_ARGS)
Datum bitle (PG_FUNCTION_ARGS)
Datum bitgt (PG_FUNCTION_ARGS)
Datum bitge (PG_FUNCTION_ARGS)
Datum bitcmp (PG_FUNCTION_ARGS)
Datum bit_and (PG_FUNCTION_ARGS)
Datum bit_or (PG_FUNCTION_ARGS)
Datum bitxor (PG_FUNCTION_ARGS)
Datum bitnot (PG_FUNCTION_ARGS)
Datum bitshiftleft (PG_FUNCTION_ARGS)
Datum bitshiftright (PG_FUNCTION_ARGS)
Datum bitcat (PG_FUNCTION_ARGS)
Datum bitsubstr (PG_FUNCTION_ARGS)
Datum bitsubstr_no_len (PG_FUNCTION_ARGS)
Datum bitoverlay (PG_FUNCTION_ARGS)
Datum bitoverlay_no_len (PG_FUNCTION_ARGS)
Datum bitlength (PG_FUNCTION_ARGS)
Datum bitoctetlength (PG_FUNCTION_ARGS)
Datum bitfromint4 (PG_FUNCTION_ARGS)
Datum bittoint4 (PG_FUNCTION_ARGS)
Datum bitfromint8 (PG_FUNCTION_ARGS)
Datum bittoint8 (PG_FUNCTION_ARGS)
Datum bitposition (PG_FUNCTION_ARGS)
Datum bitsetbit (PG_FUNCTION_ARGS)
Datum bitgetbit (PG_FUNCTION_ARGS)

Define Documentation

#define BITMASK   0xFF
#define DatumGetVarBitP (   X  )     ((VarBit *) PG_DETOAST_DATUM(X))

Definition at line 36 of file varbit.h.

#define DatumGetVarBitPCopy (   X  )     ((VarBit *) PG_DETOAST_DATUM_COPY(X))

Definition at line 37 of file varbit.h.

#define PG_GETARG_VARBIT_P (   n  )     DatumGetVarBitP(PG_GETARG_DATUM(n))
#define PG_GETARG_VARBIT_P_COPY (   n  )     DatumGetVarBitPCopy(PG_GETARG_DATUM(n))

Definition at line 40 of file varbit.h.

#define PG_RETURN_VARBIT_P (   x  )     return VarBitPGetDatum(x)
#define VARBITBYTES (   PTR  )     (VARSIZE(PTR) - VARHDRSZ - VARBITHDRSZ)
#define VARBITEND (   PTR  )     (((bits8 *) (PTR)) + VARSIZE(PTR))
#define VARBITHDRSZ   sizeof(int32)

Definition at line 44 of file varbit.h.

#define VARBITLEN (   PTR  )     (((VarBit *) (PTR))->bit_len)
#define VARBITPAD (   PTR  )     (VARBITBYTES(PTR)*BITS_PER_BYTE - VARBITLEN(PTR))
#define VarBitPGetDatum (   X  )     PointerGetDatum(X)

Definition at line 38 of file varbit.h.

Referenced by bitshiftleft(), and bitshiftright().

#define VARBITS (   PTR  )     (((VarBit *) (PTR))->bit_dat)
#define VARBITTOTALLEN (   BITLEN  ) 
Value:
(((BITLEN) + BITS_PER_BYTE-1)/BITS_PER_BYTE + \
                                 VARHDRSZ + VARBITHDRSZ)

Definition at line 54 of file varbit.h.

Referenced by bit(), bit_catenate(), bit_in(), bit_recv(), bitfromint4(), bitfromint8(), bitsubstring(), varbit(), varbit_in(), and varbit_recv().


Function Documentation

Datum bit ( PG_FUNCTION_ARGS   ) 

Definition at line 350 of file varbit.c.

References arg, BITMASK, ereport, errcode(), errmsg(), ERROR, Min, palloc0(), PG_GETARG_BOOL, PG_GETARG_INT32, PG_GETARG_VARBIT_P, PG_RETURN_VARBIT_P, SET_VARSIZE, VARBITBYTES, VARBITLEN, VARBITPAD, VARBITS, and VARBITTOTALLEN.

{
    VarBit     *arg = PG_GETARG_VARBIT_P(0);
    int32       len = PG_GETARG_INT32(1);
    bool        isExplicit = PG_GETARG_BOOL(2);
    VarBit     *result;
    int         rlen;
    int         ipad;
    bits8       mask;

    /* No work if typmod is invalid or supplied data matches it already */
    if (len <= 0 || len == VARBITLEN(arg))
        PG_RETURN_VARBIT_P(arg);

    if (!isExplicit)
        ereport(ERROR,
                (errcode(ERRCODE_STRING_DATA_LENGTH_MISMATCH),
                 errmsg("bit string length %d does not match type bit(%d)",
                        VARBITLEN(arg), len)));

    rlen = VARBITTOTALLEN(len);
    /* set to 0 so that string is zero-padded */
    result = (VarBit *) palloc0(rlen);
    SET_VARSIZE(result, rlen);
    VARBITLEN(result) = len;

    memcpy(VARBITS(result), VARBITS(arg),
           Min(VARBITBYTES(result), VARBITBYTES(arg)));

    /*
     * Make sure last byte is zero-padded if needed.  This is useless but safe
     * if source data was shorter than target length (we assume the last byte
     * of the source data was itself correctly zero-padded).
     */
    ipad = VARBITPAD(result);
    if (ipad > 0)
    {
        mask = BITMASK << ipad;
        *(VARBITS(result) + VARBITBYTES(result) - 1) &= mask;
    }

    PG_RETURN_VARBIT_P(result);
}

Datum bit_and ( PG_FUNCTION_ARGS   ) 

Definition at line 1180 of file varbit.c.

References ereport, errcode(), errmsg(), ERROR, i, palloc(), PG_GETARG_VARBIT_P, PG_RETURN_VARBIT_P, SET_VARSIZE, VARBITBYTES, VARBITLEN, VARBITS, and VARSIZE.

{
    VarBit     *arg1 = PG_GETARG_VARBIT_P(0);
    VarBit     *arg2 = PG_GETARG_VARBIT_P(1);
    VarBit     *result;
    int         len,
                bitlen1,
                bitlen2,
                i;
    bits8      *p1,
               *p2,
               *r;

    bitlen1 = VARBITLEN(arg1);
    bitlen2 = VARBITLEN(arg2);
    if (bitlen1 != bitlen2)
        ereport(ERROR,
                (errcode(ERRCODE_STRING_DATA_LENGTH_MISMATCH),
                 errmsg("cannot AND bit strings of different sizes")));

    len = VARSIZE(arg1);
    result = (VarBit *) palloc(len);
    SET_VARSIZE(result, len);
    VARBITLEN(result) = bitlen1;

    p1 = VARBITS(arg1);
    p2 = VARBITS(arg2);
    r = VARBITS(result);
    for (i = 0; i < VARBITBYTES(arg1); i++)
        *r++ = *p1++ & *p2++;

    /* Padding is not needed as & of 0 pad is 0 */

    PG_RETURN_VARBIT_P(result);
}

Datum bit_in ( PG_FUNCTION_ARGS   ) 

Definition at line 112 of file varbit.c.

References ereport, errcode(), errmsg(), ERROR, palloc0(), PG_GETARG_CSTRING, PG_GETARG_INT32, PG_GETARG_OID, PG_RETURN_VARBIT_P, SET_VARSIZE, VARBITLEN, VARBITS, and VARBITTOTALLEN.

Referenced by leftmostvalue_bit(), and make_const().

{
    char       *input_string = PG_GETARG_CSTRING(0);

#ifdef NOT_USED
    Oid         typelem = PG_GETARG_OID(1);
#endif
    int32       atttypmod = PG_GETARG_INT32(2);
    VarBit     *result;         /* The resulting bit string           */
    char       *sp;             /* pointer into the character string  */
    bits8      *r;              /* pointer into the result */
    int         len,            /* Length of the whole data structure */
                bitlen,         /* Number of bits in the bit string   */
                slen;           /* Length of the input string         */
    bool        bit_not_hex;    /* false = hex string  true = bit string */
    int         bc;
    bits8       x = 0;

    /* Check that the first character is a b or an x */
    if (input_string[0] == 'b' || input_string[0] == 'B')
    {
        bit_not_hex = true;
        sp = input_string + 1;
    }
    else if (input_string[0] == 'x' || input_string[0] == 'X')
    {
        bit_not_hex = false;
        sp = input_string + 1;
    }
    else
    {
        /*
         * Otherwise it's binary.  This allows things like cast('1001' as bit)
         * to work transparently.
         */
        bit_not_hex = true;
        sp = input_string;
    }

    slen = strlen(sp);
    /* Determine bitlength from input string */
    if (bit_not_hex)
        bitlen = slen;
    else
        bitlen = slen * 4;

    /*
     * Sometimes atttypmod is not supplied. If it is supplied we need to make
     * sure that the bitstring fits.
     */
    if (atttypmod <= 0)
        atttypmod = bitlen;
    else if (bitlen != atttypmod)
        ereport(ERROR,
                (errcode(ERRCODE_STRING_DATA_LENGTH_MISMATCH),
                 errmsg("bit string length %d does not match type bit(%d)",
                        bitlen, atttypmod)));

    len = VARBITTOTALLEN(atttypmod);
    /* set to 0 so that *r is always initialised and string is zero-padded */
    result = (VarBit *) palloc0(len);
    SET_VARSIZE(result, len);
    VARBITLEN(result) = atttypmod;

    r = VARBITS(result);
    if (bit_not_hex)
    {
        /* Parse the bit representation of the string */
        /* We know it fits, as bitlen was compared to atttypmod */
        x = HIGHBIT;
        for (; *sp; sp++)
        {
            if (*sp == '1')
                *r |= x;
            else if (*sp != '0')
                ereport(ERROR,
                        (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
                         errmsg("\"%c\" is not a valid binary digit",
                                *sp)));

            x >>= 1;
            if (x == 0)
            {
                x = HIGHBIT;
                r++;
            }
        }
    }
    else
    {
        /* Parse the hex representation of the string */
        for (bc = 0; *sp; sp++)
        {
            if (*sp >= '0' && *sp <= '9')
                x = (bits8) (*sp - '0');
            else if (*sp >= 'A' && *sp <= 'F')
                x = (bits8) (*sp - 'A') + 10;
            else if (*sp >= 'a' && *sp <= 'f')
                x = (bits8) (*sp - 'a') + 10;
            else
                ereport(ERROR,
                        (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
                         errmsg("\"%c\" is not a valid hexadecimal digit",
                                *sp)));

            if (bc)
            {
                *r++ |= x;
                bc = 0;
            }
            else
            {
                *r = x << 4;
                bc = 1;
            }
        }
    }

    PG_RETURN_VARBIT_P(result);
}

Datum bit_or ( PG_FUNCTION_ARGS   ) 

Definition at line 1221 of file varbit.c.

References BITMASK, ereport, errcode(), errmsg(), ERROR, i, palloc(), PG_GETARG_VARBIT_P, PG_RETURN_VARBIT_P, SET_VARSIZE, VARBITBYTES, VARBITLEN, VARBITPAD, VARBITS, and VARSIZE.

{
    VarBit     *arg1 = PG_GETARG_VARBIT_P(0);
    VarBit     *arg2 = PG_GETARG_VARBIT_P(1);
    VarBit     *result;
    int         len,
                bitlen1,
                bitlen2,
                i;
    bits8      *p1,
               *p2,
               *r;
    bits8       mask;

    bitlen1 = VARBITLEN(arg1);
    bitlen2 = VARBITLEN(arg2);
    if (bitlen1 != bitlen2)
        ereport(ERROR,
                (errcode(ERRCODE_STRING_DATA_LENGTH_MISMATCH),
                 errmsg("cannot OR bit strings of different sizes")));
    len = VARSIZE(arg1);
    result = (VarBit *) palloc(len);
    SET_VARSIZE(result, len);
    VARBITLEN(result) = bitlen1;

    p1 = VARBITS(arg1);
    p2 = VARBITS(arg2);
    r = VARBITS(result);
    for (i = 0; i < VARBITBYTES(arg1); i++)
        *r++ = *p1++ | *p2++;

    /* Pad the result */
    mask = BITMASK << VARBITPAD(result);
    if (mask)
    {
        r--;
        *r &= mask;
    }

    PG_RETURN_VARBIT_P(result);
}

Datum bit_out ( PG_FUNCTION_ARGS   ) 

Definition at line 235 of file varbit.c.

References HEXDIG, i, palloc(), PG_GETARG_VARBIT_P, PG_RETURN_CSTRING, varbit_out(), VARBITLEN, and VARBITS.

{
#if 1
    /* same as varbit output */
    return varbit_out(fcinfo);
#else

    /*
     * This is how one would print a hex string, in case someone wants to
     * write a formatting function.
     */
    VarBit     *s = PG_GETARG_VARBIT_P(0);
    char       *result,
               *r;
    bits8      *sp;
    int         i,
                len,
                bitlen;

    bitlen = VARBITLEN(s);
    len = (bitlen + 3) / 4;
    result = (char *) palloc(len + 2);
    sp = VARBITS(s);
    r = result;
    *r++ = 'X';
    /* we cheat by knowing that we store full bytes zero padded */
    for (i = 0; i < len; i += 2, sp++)
    {
        *r++ = HEXDIG((*sp) >> 4);
        *r++ = HEXDIG((*sp) & 0xF);
    }

    /*
     * Go back one step if we printed a hex number that was not part of the
     * bitstring anymore
     */
    if (i > len)
        r--;
    *r = '\0';

    PG_RETURN_CSTRING(result);
#endif
}

Datum bit_recv ( PG_FUNCTION_ARGS   ) 

Definition at line 283 of file varbit.c.

References BITMASK, buf, ereport, errcode(), errmsg(), ERROR, palloc(), PG_GETARG_INT32, PG_GETARG_OID, PG_GETARG_POINTER, PG_RETURN_VARBIT_P, pq_copymsgbytes(), pq_getmsgint(), SET_VARSIZE, VARBITBYTES, VARBITLEN, VARBITPAD, VARBITS, and VARBITTOTALLEN.

{
    StringInfo  buf = (StringInfo) PG_GETARG_POINTER(0);

#ifdef NOT_USED
    Oid         typelem = PG_GETARG_OID(1);
#endif
    int32       atttypmod = PG_GETARG_INT32(2);
    VarBit     *result;
    int         len,
                bitlen;
    int         ipad;
    bits8       mask;

    bitlen = pq_getmsgint(buf, sizeof(int32));
    if (bitlen < 0)
        ereport(ERROR,
                (errcode(ERRCODE_INVALID_BINARY_REPRESENTATION),
                 errmsg("invalid length in external bit string")));

    /*
     * Sometimes atttypmod is not supplied. If it is supplied we need to make
     * sure that the bitstring fits.
     */
    if (atttypmod > 0 && bitlen != atttypmod)
        ereport(ERROR,
                (errcode(ERRCODE_STRING_DATA_LENGTH_MISMATCH),
                 errmsg("bit string length %d does not match type bit(%d)",
                        bitlen, atttypmod)));

    len = VARBITTOTALLEN(bitlen);
    result = (VarBit *) palloc(len);
    SET_VARSIZE(result, len);
    VARBITLEN(result) = bitlen;

    pq_copymsgbytes(buf, (char *) VARBITS(result), VARBITBYTES(result));

    /* Make sure last byte is zero-padded if needed */
    ipad = VARBITPAD(result);
    if (ipad > 0)
    {
        mask = BITMASK << ipad;
        *(VARBITS(result) + VARBITBYTES(result) - 1) &= mask;
    }

    PG_RETURN_VARBIT_P(result);
}

Datum bit_send ( PG_FUNCTION_ARGS   ) 

Definition at line 335 of file varbit.c.

References varbit_send().

{
    /* Exactly the same as varbit_send, so share code */
    return varbit_send(fcinfo);
}

Datum bitcat ( PG_FUNCTION_ARGS   ) 

Definition at line 924 of file varbit.c.

References bit_catenate(), PG_GETARG_VARBIT_P, and PG_RETURN_VARBIT_P.

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.

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.

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   ) 
Datum bitsubstr_no_len ( PG_FUNCTION_ARGS   ) 
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.

Datum bittypmodout ( PG_FUNCTION_ARGS   ) 

Definition at line 403 of file varbit.c.

References anybit_typmodout(), PG_GETARG_INT32, and PG_RETURN_CSTRING.

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   ) 
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.

Datum varbittypmodout ( PG_FUNCTION_ARGS   ) 

Definition at line 738 of file varbit.c.

References anybit_typmodout(), PG_GETARG_INT32, and PG_RETURN_CSTRING.