LCOV - differential code coverage report
Current view: top level - src/backend/utils/adt - varbit.c (source / functions) Coverage Total Hit UBC CBC
Current: Differential Code Coverage 16@8cea358b128 vs 17@8cea358b128 Lines: 86.0 % 680 585 95 585
Current Date: 2024-04-14 14:21:10 Functions: 89.8 % 49 44 5 44
Baseline: 16@8cea358b128 Branches: 63.0 % 494 311 183 311
Baseline Date: 2024-04-14 14:21:09 Line coverage date bins:
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed (240..) days: 86.0 % 680 585 95 585
Function coverage date bins:
(240..) days: 89.8 % 49 44 5 44
Branch coverage date bins:
(240..) days: 63.0 % 494 311 183 311

 Age         Owner                    Branch data    TLA  Line data    Source code
                                  1                 :                : /*-------------------------------------------------------------------------
                                  2                 :                :  *
                                  3                 :                :  * varbit.c
                                  4                 :                :  *    Functions for the SQL datatypes BIT() and BIT VARYING().
                                  5                 :                :  *
                                  6                 :                :  * The data structure contains the following elements:
                                  7                 :                :  *   header  -- length of the whole data structure (incl header)
                                  8                 :                :  *              in bytes (as with all varying length datatypes)
                                  9                 :                :  *   data section -- private data section for the bits data structures
                                 10                 :                :  *     bitlength -- length of the bit string in bits
                                 11                 :                :  *     bitdata   -- bit string, most significant byte first
                                 12                 :                :  *
                                 13                 :                :  * The length of the bitdata vector should always be exactly as many
                                 14                 :                :  * bytes as are needed for the given bitlength.  If the bitlength is
                                 15                 :                :  * not a multiple of 8, the extra low-order padding bits of the last
                                 16                 :                :  * byte must be zeroes.
                                 17                 :                :  *
                                 18                 :                :  * attypmod is defined as the length of the bit string in bits, or for
                                 19                 :                :  * varying bits the maximum length.
                                 20                 :                :  *
                                 21                 :                :  * Code originally contributed by Adriaan Joubert.
                                 22                 :                :  *
                                 23                 :                :  * Portions Copyright (c) 1996-2024, PostgreSQL Global Development Group
                                 24                 :                :  * Portions Copyright (c) 1994, Regents of the University of California
                                 25                 :                :  *
                                 26                 :                :  * IDENTIFICATION
                                 27                 :                :  *    src/backend/utils/adt/varbit.c
                                 28                 :                :  *
                                 29                 :                :  *-------------------------------------------------------------------------
                                 30                 :                :  */
                                 31                 :                : 
                                 32                 :                : #include "postgres.h"
                                 33                 :                : 
                                 34                 :                : #include "access/htup_details.h"
                                 35                 :                : #include "common/int.h"
                                 36                 :                : #include "libpq/pqformat.h"
                                 37                 :                : #include "nodes/nodeFuncs.h"
                                 38                 :                : #include "nodes/supportnodes.h"
                                 39                 :                : #include "port/pg_bitutils.h"
                                 40                 :                : #include "utils/array.h"
                                 41                 :                : #include "utils/fmgrprotos.h"
                                 42                 :                : #include "utils/varbit.h"
                                 43                 :                : 
                                 44                 :                : #define HEXDIG(z)    ((z)<10 ? ((z)+'0') : ((z)-10+'A'))
                                 45                 :                : 
                                 46                 :                : /* Mask off any bits that should be zero in the last byte of a bitstring */
                                 47                 :                : #define VARBIT_PAD(vb) \
                                 48                 :                :     do { \
                                 49                 :                :         int32   pad_ = VARBITPAD(vb); \
                                 50                 :                :         Assert(pad_ >= 0 && pad_ < BITS_PER_BYTE); \
                                 51                 :                :         if (pad_ > 0) \
                                 52                 :                :             *(VARBITS(vb) + VARBITBYTES(vb) - 1) &= BITMASK << pad_; \
                                 53                 :                :     } while (0)
                                 54                 :                : 
                                 55                 :                : /*
                                 56                 :                :  * Many functions work byte-by-byte, so they have a pointer handy to the
                                 57                 :                :  * last-plus-one byte, which saves a cycle or two.
                                 58                 :                :  */
                                 59                 :                : #define VARBIT_PAD_LAST(vb, ptr) \
                                 60                 :                :     do { \
                                 61                 :                :         int32   pad_ = VARBITPAD(vb); \
                                 62                 :                :         Assert(pad_ >= 0 && pad_ < BITS_PER_BYTE); \
                                 63                 :                :         if (pad_ > 0) \
                                 64                 :                :             *((ptr) - 1) &= BITMASK << pad_; \
                                 65                 :                :     } while (0)
                                 66                 :                : 
                                 67                 :                : /* Assert proper padding of a bitstring */
                                 68                 :                : #ifdef USE_ASSERT_CHECKING
                                 69                 :                : #define VARBIT_CORRECTLY_PADDED(vb) \
                                 70                 :                :     do { \
                                 71                 :                :         int32   pad_ = VARBITPAD(vb); \
                                 72                 :                :         Assert(pad_ >= 0 && pad_ < BITS_PER_BYTE); \
                                 73                 :                :         Assert(pad_ == 0 || \
                                 74                 :                :                (*(VARBITS(vb) + VARBITBYTES(vb) - 1) & ~(BITMASK << pad_)) == 0); \
                                 75                 :                :     } while (0)
                                 76                 :                : #else
                                 77                 :                : #define VARBIT_CORRECTLY_PADDED(vb) ((void) 0)
                                 78                 :                : #endif
                                 79                 :                : 
                                 80                 :                : static VarBit *bit_catenate(VarBit *arg1, VarBit *arg2);
                                 81                 :                : static VarBit *bitsubstring(VarBit *arg, int32 s, int32 l,
                                 82                 :                :                             bool length_not_specified);
                                 83                 :                : static VarBit *bit_overlay(VarBit *t1, VarBit *t2, int sp, int sl);
                                 84                 :                : 
                                 85                 :                : 
                                 86                 :                : /*
                                 87                 :                :  * common code for bittypmodin and varbittypmodin
                                 88                 :                :  */
                                 89                 :                : static int32
 6315 tgl@sss.pgh.pa.us          90                 :CBC        1062 : anybit_typmodin(ArrayType *ta, const char *typename)
                                 91                 :                : {
                                 92                 :                :     int32       typmod;
                                 93                 :                :     int32      *tl;
                                 94                 :                :     int         n;
                                 95                 :                : 
 6148                            96                 :           1062 :     tl = ArrayGetIntegerTypmods(ta, &n);
                                 97                 :                : 
                                 98                 :                :     /*
                                 99                 :                :      * we're not too tense about good error message here because grammar
                                100                 :                :      * shouldn't allow wrong number of modifiers for BIT
                                101                 :                :      */
 6315                           102         [ -  + ]:           1062 :     if (n != 1)
 6315 tgl@sss.pgh.pa.us         103         [ #  # ]:UBC           0 :         ereport(ERROR,
                                104                 :                :                 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
                                105                 :                :                  errmsg("invalid type modifier")));
                                106                 :                : 
 6315 tgl@sss.pgh.pa.us         107         [ -  + ]:CBC        1062 :     if (*tl < 1)
 6315 tgl@sss.pgh.pa.us         108         [ #  # ]:UBC           0 :         ereport(ERROR,
                                109                 :                :                 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
                                110                 :                :                  errmsg("length for type %s must be at least 1",
                                111                 :                :                         typename)));
 6315 tgl@sss.pgh.pa.us         112         [ -  + ]:CBC        1062 :     if (*tl > (MaxAttrSize * BITS_PER_BYTE))
 6315 tgl@sss.pgh.pa.us         113         [ #  # ]:UBC           0 :         ereport(ERROR,
                                114                 :                :                 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
                                115                 :                :                  errmsg("length for type %s cannot exceed %d",
                                116                 :                :                         typename, MaxAttrSize * BITS_PER_BYTE)));
                                117                 :                : 
 6315 tgl@sss.pgh.pa.us         118                 :CBC        1062 :     typmod = *tl;
                                119                 :                : 
                                120                 :           1062 :     return typmod;
                                121                 :                : }
                                122                 :                : 
                                123                 :                : /*
                                124                 :                :  * common code for bittypmodout and varbittypmodout
                                125                 :                :  */
                                126                 :                : static char *
                                127                 :            179 : anybit_typmodout(int32 typmod)
                                128                 :                : {
 5995 bruce@momjian.us          129                 :            179 :     char       *res = (char *) palloc(64);
                                130                 :                : 
 6315 tgl@sss.pgh.pa.us         131         [ +  - ]:            179 :     if (typmod >= 0)
                                132                 :            179 :         snprintf(res, 64, "(%d)", typmod);
                                133                 :                :     else
 6315 tgl@sss.pgh.pa.us         134                 :UBC           0 :         *res = '\0';
                                135                 :                : 
 6315 tgl@sss.pgh.pa.us         136                 :CBC         179 :     return res;
                                137                 :                : }
                                138                 :                : 
                                139                 :                : 
                                140                 :                : /*
                                141                 :                :  * bit_in -
                                142                 :                :  *    converts a char string to the internal representation of a bitstring.
                                143                 :                :  *        The length is determined by the number of bits required plus
                                144                 :                :  *        VARHDRSZ bytes or from atttypmod.
                                145                 :                :  */
                                146                 :                : Datum
 8363 peter_e@gmx.net           147                 :           2890 : bit_in(PG_FUNCTION_ARGS)
                                148                 :                : {
 8548                           149                 :           2890 :     char       *input_string = PG_GETARG_CSTRING(0);
                                150                 :                : #ifdef NOT_USED
                                151                 :                :     Oid         typelem = PG_GETARG_OID(1);
                                152                 :                : #endif
 8637 tgl@sss.pgh.pa.us         153                 :           2890 :     int32       atttypmod = PG_GETARG_INT32(2);
  487                           154                 :           2890 :     Node       *escontext = fcinfo->context;
                                155                 :                :     VarBit     *result;         /* The resulting bit string           */
                                156                 :                :     char       *sp;             /* pointer into the character string  */
                                157                 :                :     bits8      *r;              /* pointer into the result */
                                158                 :                :     int         len,            /* Length of the whole data structure */
                                159                 :                :                 bitlen,         /* Number of bits in the bit string   */
                                160                 :                :                 slen;           /* Length of the input string         */
                                161                 :                :     bool        bit_not_hex;    /* false = hex string  true = bit string */
                                162                 :                :     int         bc;
 8768 bruce@momjian.us          163                 :           2890 :     bits8       x = 0;
                                164                 :                : 
                                165                 :                :     /* Check that the first character is a b or an x */
 8548 peter_e@gmx.net           166   [ +  +  +  + ]:           2890 :     if (input_string[0] == 'b' || input_string[0] == 'B')
                                167                 :                :     {
 8637 tgl@sss.pgh.pa.us         168                 :            385 :         bit_not_hex = true;
 8548 peter_e@gmx.net           169                 :            385 :         sp = input_string + 1;
                                170                 :                :     }
                                171   [ +  +  +  + ]:           2505 :     else if (input_string[0] == 'x' || input_string[0] == 'X')
                                172                 :                :     {
 8637 tgl@sss.pgh.pa.us         173                 :           1738 :         bit_not_hex = false;
 8548 peter_e@gmx.net           174                 :           1738 :         sp = input_string + 1;
                                175                 :                :     }
                                176                 :                :     else
                                177                 :                :     {
                                178                 :                :         /*
                                179                 :                :          * Otherwise it's binary.  This allows things like cast('1001' as bit)
                                180                 :                :          * to work transparently.
                                181                 :                :          */
                                182                 :            767 :         bit_not_hex = true;
                                183                 :            767 :         sp = input_string;
                                184                 :                :     }
                                185                 :                : 
                                186                 :                :     /*
                                187                 :                :      * Determine bitlength from input string.  MaxAllocSize ensures a regular
                                188                 :                :      * input is small enough, but we must check hex input.
                                189                 :                :      */
                                190                 :           2890 :     slen = strlen(sp);
 8637 tgl@sss.pgh.pa.us         191         [ +  + ]:           2890 :     if (bit_not_hex)
                                192                 :           1152 :         bitlen = slen;
                                193                 :                :     else
                                194                 :                :     {
 3709 noah@leadboat.com         195         [ -  + ]:           1738 :         if (slen > VARBITMAXLEN / 4)
  487 tgl@sss.pgh.pa.us         196         [ #  # ]:UBC           0 :             ereturn(escontext, (Datum) 0,
                                197                 :                :                     (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
                                198                 :                :                      errmsg("bit string length exceeds the maximum allowed (%d)",
                                199                 :                :                             VARBITMAXLEN)));
 8637 tgl@sss.pgh.pa.us         200                 :CBC        1738 :         bitlen = slen * 4;
                                201                 :                :     }
                                202                 :                : 
                                203                 :                :     /*
                                204                 :                :      * Sometimes atttypmod is not supplied. If it is supplied we need to make
                                205                 :                :      * sure that the bitstring fits.
                                206                 :                :      */
                                207         [ +  + ]:           2890 :     if (atttypmod <= 0)
 8768 bruce@momjian.us          208                 :           2203 :         atttypmod = bitlen;
 8363 peter_e@gmx.net           209         [ +  + ]:            687 :     else if (bitlen != atttypmod)
  487 tgl@sss.pgh.pa.us         210         [ +  + ]:              6 :         ereturn(escontext, (Datum) 0,
                                211                 :                :                 (errcode(ERRCODE_STRING_DATA_LENGTH_MISMATCH),
                                212                 :                :                  errmsg("bit string length %d does not match type bit(%d)",
                                213                 :                :                         bitlen, atttypmod)));
                                214                 :                : 
 8637                           215                 :           2884 :     len = VARBITTOTALLEN(atttypmod);
                                216                 :                :     /* set to 0 so that *r is always initialised and string is zero-padded */
 7823 bruce@momjian.us          217                 :           2884 :     result = (VarBit *) palloc0(len);
 6256 tgl@sss.pgh.pa.us         218                 :           2884 :     SET_VARSIZE(result, len);
 8768 bruce@momjian.us          219                 :           2884 :     VARBITLEN(result) = atttypmod;
                                220                 :                : 
                                221                 :           2884 :     r = VARBITS(result);
                                222         [ +  + ]:           2884 :     if (bit_not_hex)
                                223                 :                :     {
                                224                 :                :         /* Parse the bit representation of the string */
                                225                 :                :         /* We know it fits, as bitlen was compared to atttypmod */
 6685                           226                 :           1146 :         x = HIGHBIT;
 8637 tgl@sss.pgh.pa.us         227         [ +  + ]:          32543 :         for (; *sp; sp++)
                                228                 :                :         {
 8768 bruce@momjian.us          229         [ +  + ]:          31409 :             if (*sp == '1')
                                230                 :          15901 :                 *r |= x;
 8637 tgl@sss.pgh.pa.us         231         [ +  + ]:          15508 :             else if (*sp != '0')
  487                           232         [ +  + ]:             12 :                 ereturn(escontext, (Datum) 0,
                                233                 :                :                         (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
                                234                 :                :                          errmsg("\"%.*s\" is not a valid binary digit",
                                235                 :                :                                 pg_mblen(sp), sp)));
                                236                 :                : 
 8637                           237                 :          31397 :             x >>= 1;
                                238         [ +  + ]:          31397 :             if (x == 0)
                                239                 :                :             {
 6685 bruce@momjian.us          240                 :           3684 :                 x = HIGHBIT;
 8768                           241                 :           3684 :                 r++;
                                242                 :                :             }
                                243                 :                :         }
                                244                 :                :     }
                                245                 :                :     else
                                246                 :                :     {
                                247                 :                :         /* Parse the hex representation of the string */
 8637 tgl@sss.pgh.pa.us         248         [ +  + ]:          20578 :         for (bc = 0; *sp; sp++)
                                249                 :                :         {
 8768 bruce@momjian.us          250   [ +  +  +  + ]:          18852 :             if (*sp >= '0' && *sp <= '9')
                                251                 :          12824 :                 x = (bits8) (*sp - '0');
                                252   [ +  +  +  + ]:           6028 :             else if (*sp >= 'A' && *sp <= 'F')
                                253                 :            299 :                 x = (bits8) (*sp - 'A') + 10;
                                254   [ +  +  +  - ]:           5729 :             else if (*sp >= 'a' && *sp <= 'f')
                                255                 :           5717 :                 x = (bits8) (*sp - 'a') + 10;
                                256                 :                :             else
  487 tgl@sss.pgh.pa.us         257         [ +  + ]:             12 :                 ereturn(escontext, (Datum) 0,
                                258                 :                :                         (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
                                259                 :                :                          errmsg("\"%.*s\" is not a valid hexadecimal digit",
                                260                 :                :                                 pg_mblen(sp), sp)));
                                261                 :                : 
 8768 bruce@momjian.us          262         [ +  + ]:          18840 :             if (bc)
                                263                 :                :             {
                                264                 :           9364 :                 *r++ |= x;
 8637 tgl@sss.pgh.pa.us         265                 :           9364 :                 bc = 0;
                                266                 :                :             }
                                267                 :                :             else
                                268                 :                :             {
 8768 bruce@momjian.us          269                 :           9476 :                 *r = x << 4;
 8637 tgl@sss.pgh.pa.us         270                 :           9476 :                 bc = 1;
                                271                 :                :             }
                                272                 :                :         }
                                273                 :                :     }
                                274                 :                : 
                                275                 :           2860 :     PG_RETURN_VARBIT_P(result);
                                276                 :                : }
                                277                 :                : 
                                278                 :                : 
                                279                 :                : Datum
 8363 peter_e@gmx.net           280                 :           2119 : bit_out(PG_FUNCTION_ARGS)
                                281                 :                : {
                                282                 :                : #if 1
                                283                 :                :     /* same as varbit output */
 8550                           284                 :           2119 :     return varbit_out(fcinfo);
                                285                 :                : #else
                                286                 :                : 
                                287                 :                :     /*
                                288                 :                :      * This is how one would print a hex string, in case someone wants to
                                289                 :                :      * write a formatting function.
                                290                 :                :      */
                                291                 :                :     VarBit     *s = PG_GETARG_VARBIT_P(0);
                                292                 :                :     char       *result,
                                293                 :                :                *r;
                                294                 :                :     bits8      *sp;
                                295                 :                :     int         i,
                                296                 :                :                 len,
                                297                 :                :                 bitlen;
                                298                 :                : 
                                299                 :                :     /* Assertion to help catch any bit functions that don't pad correctly */
                                300                 :                :     VARBIT_CORRECTLY_PADDED(s);
                                301                 :                : 
                                302                 :                :     bitlen = VARBITLEN(s);
                                303                 :                :     len = (bitlen + 3) / 4;
                                304                 :                :     result = (char *) palloc(len + 2);
                                305                 :                :     sp = VARBITS(s);
                                306                 :                :     r = result;
                                307                 :                :     *r++ = 'X';
                                308                 :                :     /* we cheat by knowing that we store full bytes zero padded */
                                309                 :                :     for (i = 0; i < len; i += 2, sp++)
                                310                 :                :     {
                                311                 :                :         *r++ = HEXDIG((*sp) >> 4);
                                312                 :                :         *r++ = HEXDIG((*sp) & 0xF);
                                313                 :                :     }
                                314                 :                : 
                                315                 :                :     /*
                                316                 :                :      * Go back one step if we printed a hex number that was not part of the
                                317                 :                :      * bitstring anymore
                                318                 :                :      */
                                319                 :                :     if (i > len)
                                320                 :                :         r--;
                                321                 :                :     *r = '\0';
                                322                 :                : 
                                323                 :                :     PG_RETURN_CSTRING(result);
                                324                 :                : #endif
                                325                 :                : }
                                326                 :                : 
                                327                 :                : /*
                                328                 :                :  *      bit_recv            - converts external binary format to bit
                                329                 :                :  */
                                330                 :                : Datum
 7643 tgl@sss.pgh.pa.us         331                 :UBC           0 : bit_recv(PG_FUNCTION_ARGS)
                                332                 :                : {
 6853                           333                 :              0 :     StringInfo  buf = (StringInfo) PG_GETARG_POINTER(0);
                                334                 :                : 
                                335                 :                : #ifdef NOT_USED
                                336                 :                :     Oid         typelem = PG_GETARG_OID(1);
                                337                 :                : #endif
                                338                 :              0 :     int32       atttypmod = PG_GETARG_INT32(2);
                                339                 :                :     VarBit     *result;
                                340                 :                :     int         len,
                                341                 :                :                 bitlen;
                                342                 :                : 
                                343                 :              0 :     bitlen = pq_getmsgint(buf, sizeof(int32));
 2739                           344   [ #  #  #  # ]:              0 :     if (bitlen < 0 || bitlen > VARBITMAXLEN)
 6853                           345         [ #  # ]:              0 :         ereport(ERROR,
                                346                 :                :                 (errcode(ERRCODE_INVALID_BINARY_REPRESENTATION),
                                347                 :                :                  errmsg("invalid length in external bit string")));
                                348                 :                : 
                                349                 :                :     /*
                                350                 :                :      * Sometimes atttypmod is not supplied. If it is supplied we need to make
                                351                 :                :      * sure that the bitstring fits.
                                352                 :                :      */
                                353   [ #  #  #  # ]:              0 :     if (atttypmod > 0 && bitlen != atttypmod)
                                354         [ #  # ]:              0 :         ereport(ERROR,
                                355                 :                :                 (errcode(ERRCODE_STRING_DATA_LENGTH_MISMATCH),
                                356                 :                :                  errmsg("bit string length %d does not match type bit(%d)",
                                357                 :                :                         bitlen, atttypmod)));
                                358                 :                : 
                                359                 :              0 :     len = VARBITTOTALLEN(bitlen);
                                360                 :              0 :     result = (VarBit *) palloc(len);
 6256                           361                 :              0 :     SET_VARSIZE(result, len);
 6853                           362                 :              0 :     VARBITLEN(result) = bitlen;
                                363                 :                : 
                                364                 :              0 :     pq_copymsgbytes(buf, (char *) VARBITS(result), VARBITBYTES(result));
                                365                 :                : 
                                366                 :                :     /* Make sure last byte is correctly zero-padded */
 1666                           367   [ #  #  #  #  :              0 :     VARBIT_PAD(result);
                                              #  # ]
                                368                 :                : 
 6853                           369                 :              0 :     PG_RETURN_VARBIT_P(result);
                                370                 :                : }
                                371                 :                : 
                                372                 :                : /*
                                373                 :                :  *      bit_send            - converts bit to binary format
                                374                 :                :  */
                                375                 :                : Datum
 7643                           376                 :              0 : bit_send(PG_FUNCTION_ARGS)
                                377                 :                : {
                                378                 :                :     /* Exactly the same as varbit_send, so share code */
                                379                 :              0 :     return varbit_send(fcinfo);
                                380                 :                : }
                                381                 :                : 
                                382                 :                : /*
                                383                 :                :  * bit()
                                384                 :                :  * Converts a bit() type to a specific internal length.
                                385                 :                :  * len is the bitlength specified in the column definition.
                                386                 :                :  *
                                387                 :                :  * If doing implicit cast, raise error when source data is wrong length.
                                388                 :                :  * If doing explicit cast, silently truncate or zero-pad to specified length.
                                389                 :                :  */
                                390                 :                : Datum
 8363 peter_e@gmx.net           391                 :CBC         502 : bit(PG_FUNCTION_ARGS)
                                392                 :                : {
 8637 tgl@sss.pgh.pa.us         393                 :            502 :     VarBit     *arg = PG_GETARG_VARBIT_P(0);
                                394                 :            502 :     int32       len = PG_GETARG_INT32(1);
 7879                           395                 :            502 :     bool        isExplicit = PG_GETARG_BOOL(2);
                                396                 :                :     VarBit     *result;
                                397                 :                :     int         rlen;
                                398                 :                : 
                                399                 :                :     /* No work if typmod is invalid or supplied data matches it already */
 2739                           400   [ +  -  +  -  :            502 :     if (len <= 0 || len > VARBITMAXLEN || len == VARBITLEN(arg))
                                              +  + ]
 8637                           401                 :            199 :         PG_RETURN_VARBIT_P(arg);
                                402                 :                : 
 7879                           403         [ +  + ]:            303 :     if (!isExplicit)
 7567                           404         [ +  - ]:              6 :         ereport(ERROR,
                                405                 :                :                 (errcode(ERRCODE_STRING_DATA_LENGTH_MISMATCH),
                                406                 :                :                  errmsg("bit string length %d does not match type bit(%d)",
                                407                 :                :                         VARBITLEN(arg), len)));
                                408                 :                : 
 7879                           409                 :            297 :     rlen = VARBITTOTALLEN(len);
                                410                 :                :     /* set to 0 so that string is zero-padded */
 7823 bruce@momjian.us          411                 :            297 :     result = (VarBit *) palloc0(rlen);
 6256 tgl@sss.pgh.pa.us         412                 :            297 :     SET_VARSIZE(result, rlen);
 7879                           413                 :            297 :     VARBITLEN(result) = len;
                                414                 :                : 
                                415                 :            297 :     memcpy(VARBITS(result), VARBITS(arg),
                                416                 :            297 :            Min(VARBITBYTES(result), VARBITBYTES(arg)));
                                417                 :                : 
                                418                 :                :     /*
                                419                 :                :      * Make sure last byte is zero-padded if needed.  This is useless but safe
                                420                 :                :      * if source data was shorter than target length (we assume the last byte
                                421                 :                :      * of the source data was itself correctly zero-padded).
                                422                 :                :      */
 1666                           423   [ +  -  -  +  :            297 :     VARBIT_PAD(result);
                                              +  - ]
                                424                 :                : 
 7879                           425                 :            297 :     PG_RETURN_VARBIT_P(result);
                                426                 :                : }
                                427                 :                : 
                                428                 :                : Datum
 6315                           429                 :            940 : bittypmodin(PG_FUNCTION_ARGS)
                                430                 :                : {
 5995 bruce@momjian.us          431                 :            940 :     ArrayType  *ta = PG_GETARG_ARRAYTYPE_P(0);
                                432                 :                : 
 6315 tgl@sss.pgh.pa.us         433                 :            940 :     PG_RETURN_INT32(anybit_typmodin(ta, "bit"));
                                434                 :                : }
                                435                 :                : 
                                436                 :                : Datum
                                437                 :            113 : bittypmodout(PG_FUNCTION_ARGS)
                                438                 :                : {
 5995 bruce@momjian.us          439                 :            113 :     int32       typmod = PG_GETARG_INT32(0);
                                440                 :                : 
 6315 tgl@sss.pgh.pa.us         441                 :            113 :     PG_RETURN_CSTRING(anybit_typmodout(typmod));
                                442                 :                : }
                                443                 :                : 
                                444                 :                : 
                                445                 :                : /*
                                446                 :                :  * varbit_in -
                                447                 :                :  *    converts a string to the internal representation of a bitstring.
                                448                 :                :  *      This is the same as bit_in except that atttypmod is taken as
                                449                 :                :  *      the maximum length, not the exact length to force the bitstring to.
                                450                 :                :  */
                                451                 :                : Datum
 8637                           452                 :            917 : varbit_in(PG_FUNCTION_ARGS)
                                453                 :                : {
 8548 peter_e@gmx.net           454                 :            917 :     char       *input_string = PG_GETARG_CSTRING(0);
                                455                 :                : #ifdef NOT_USED
                                456                 :                :     Oid         typelem = PG_GETARG_OID(1);
                                457                 :                : #endif
 8637 tgl@sss.pgh.pa.us         458                 :            917 :     int32       atttypmod = PG_GETARG_INT32(2);
  487                           459                 :            917 :     Node       *escontext = fcinfo->context;
                                460                 :                :     VarBit     *result;         /* The resulting bit string           */
                                461                 :                :     char       *sp;             /* pointer into the character string  */
                                462                 :                :     bits8      *r;              /* pointer into the result */
                                463                 :                :     int         len,            /* Length of the whole data structure */
                                464                 :                :                 bitlen,         /* Number of bits in the bit string   */
                                465                 :                :                 slen;           /* Length of the input string         */
                                466                 :                :     bool        bit_not_hex;    /* false = hex string  true = bit string */
                                467                 :                :     int         bc;
 8768 bruce@momjian.us          468                 :            917 :     bits8       x = 0;
                                469                 :                : 
                                470                 :                :     /* Check that the first character is a b or an x */
 8548 peter_e@gmx.net           471   [ +  -  -  + ]:            917 :     if (input_string[0] == 'b' || input_string[0] == 'B')
                                472                 :                :     {
 8637 tgl@sss.pgh.pa.us         473                 :UBC           0 :         bit_not_hex = true;
 8548 peter_e@gmx.net           474                 :              0 :         sp = input_string + 1;
                                475                 :                :     }
 8548 peter_e@gmx.net           476   [ +  +  +  + ]:CBC         917 :     else if (input_string[0] == 'x' || input_string[0] == 'X')
                                477                 :                :     {
 8637 tgl@sss.pgh.pa.us         478                 :             66 :         bit_not_hex = false;
 8548 peter_e@gmx.net           479                 :             66 :         sp = input_string + 1;
                                480                 :                :     }
                                481                 :                :     else
                                482                 :                :     {
                                483                 :            851 :         bit_not_hex = true;
                                484                 :            851 :         sp = input_string;
                                485                 :                :     }
                                486                 :                : 
                                487                 :                :     /*
                                488                 :                :      * Determine bitlength from input string.  MaxAllocSize ensures a regular
                                489                 :                :      * input is small enough, but we must check hex input.
                                490                 :                :      */
                                491                 :            917 :     slen = strlen(sp);
 8637 tgl@sss.pgh.pa.us         492         [ +  + ]:            917 :     if (bit_not_hex)
                                493                 :            851 :         bitlen = slen;
                                494                 :                :     else
                                495                 :                :     {
 3709 noah@leadboat.com         496         [ -  + ]:             66 :         if (slen > VARBITMAXLEN / 4)
  487 tgl@sss.pgh.pa.us         497         [ #  # ]:UBC           0 :             ereturn(escontext, (Datum) 0,
                                498                 :                :                     (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
                                499                 :                :                      errmsg("bit string length exceeds the maximum allowed (%d)",
                                500                 :                :                             VARBITMAXLEN)));
 8637 tgl@sss.pgh.pa.us         501                 :CBC          66 :         bitlen = slen * 4;
                                502                 :                :     }
                                503                 :                : 
                                504                 :                :     /*
                                505                 :                :      * Sometimes atttypmod is not supplied. If it is supplied we need to make
                                506                 :                :      * sure that the bitstring fits.
                                507                 :                :      */
                                508         [ +  + ]:            917 :     if (atttypmod <= 0)
                                509                 :            857 :         atttypmod = bitlen;
 8363 peter_e@gmx.net           510         [ -  + ]:             60 :     else if (bitlen > atttypmod)
  487 tgl@sss.pgh.pa.us         511         [ #  # ]:UBC           0 :         ereturn(escontext, (Datum) 0,
                                512                 :                :                 (errcode(ERRCODE_STRING_DATA_RIGHT_TRUNCATION),
                                513                 :                :                  errmsg("bit string too long for type bit varying(%d)",
                                514                 :                :                         atttypmod)));
                                515                 :                : 
 8637 tgl@sss.pgh.pa.us         516                 :CBC         917 :     len = VARBITTOTALLEN(bitlen);
                                517                 :                :     /* set to 0 so that *r is always initialised and string is zero-padded */
 7823 bruce@momjian.us          518                 :            917 :     result = (VarBit *) palloc0(len);
 6256 tgl@sss.pgh.pa.us         519                 :            917 :     SET_VARSIZE(result, len);
 8637                           520                 :            917 :     VARBITLEN(result) = Min(bitlen, atttypmod);
                                521                 :                : 
 8768 bruce@momjian.us          522                 :            917 :     r = VARBITS(result);
                                523         [ +  + ]:            917 :     if (bit_not_hex)
                                524                 :                :     {
                                525                 :                :         /* Parse the bit representation of the string */
                                526                 :                :         /* We know it fits, as bitlen was compared to atttypmod */
 6685                           527                 :            851 :         x = HIGHBIT;
 8637 tgl@sss.pgh.pa.us         528         [ +  + ]:          33393 :         for (; *sp; sp++)
                                529                 :                :         {
 8768 bruce@momjian.us          530         [ +  + ]:          32548 :             if (*sp == '1')
                                531                 :          16227 :                 *r |= x;
 8637 tgl@sss.pgh.pa.us         532         [ +  + ]:          16321 :             else if (*sp != '0')
  487                           533         [ +  + ]:              6 :                 ereturn(escontext, (Datum) 0,
                                534                 :                :                         (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
                                535                 :                :                          errmsg("\"%.*s\" is not a valid binary digit",
                                536                 :                :                                 pg_mblen(sp), sp)));
                                537                 :                : 
 8637                           538                 :          32542 :             x >>= 1;
                                539         [ +  + ]:          32542 :             if (x == 0)
                                540                 :                :             {
 6685 bruce@momjian.us          541                 :           3750 :                 x = HIGHBIT;
 8768                           542                 :           3750 :                 r++;
                                543                 :                :             }
                                544                 :                :         }
                                545                 :                :     }
                                546                 :                :     else
                                547                 :                :     {
                                548                 :                :         /* Parse the hex representation of the string */
 8637 tgl@sss.pgh.pa.us         549         [ +  + ]:            276 :         for (bc = 0; *sp; sp++)
                                550                 :                :         {
 8768 bruce@momjian.us          551   [ +  -  +  + ]:            216 :             if (*sp >= '0' && *sp <= '9')
                                552                 :            159 :                 x = (bits8) (*sp - '0');
                                553   [ +  -  +  + ]:             57 :             else if (*sp >= 'A' && *sp <= 'F')
                                554                 :             51 :                 x = (bits8) (*sp - 'A') + 10;
                                555   [ -  +  -  - ]:              6 :             else if (*sp >= 'a' && *sp <= 'f')
 8768 bruce@momjian.us          556                 :UBC           0 :                 x = (bits8) (*sp - 'a') + 10;
                                557                 :                :             else
  487 tgl@sss.pgh.pa.us         558         [ +  + ]:CBC           6 :                 ereturn(escontext, (Datum) 0,
                                559                 :                :                         (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
                                560                 :                :                          errmsg("\"%.*s\" is not a valid hexadecimal digit",
                                561                 :                :                                 pg_mblen(sp), sp)));
                                562                 :                : 
 8768 bruce@momjian.us          563         [ +  + ]:            210 :             if (bc)
                                564                 :                :             {
                                565                 :            102 :                 *r++ |= x;
 8637 tgl@sss.pgh.pa.us         566                 :            102 :                 bc = 0;
                                567                 :                :             }
                                568                 :                :             else
                                569                 :                :             {
 8768 bruce@momjian.us          570                 :            108 :                 *r = x << 4;
 8637 tgl@sss.pgh.pa.us         571                 :            108 :                 bc = 1;
                                572                 :                :             }
                                573                 :                :         }
                                574                 :                :     }
                                575                 :                : 
                                576                 :            905 :     PG_RETURN_VARBIT_P(result);
                                577                 :                : }
                                578                 :                : 
                                579                 :                : /*
                                580                 :                :  * varbit_out -
                                581                 :                :  *    Prints the string as bits to preserve length accurately
                                582                 :                :  *
                                583                 :                :  * XXX varbit_recv() and hex input to varbit_in() can load a value that this
                                584                 :                :  * cannot emit.  Consider using hex output for such values.
                                585                 :                :  */
                                586                 :                : Datum
                                587                 :           3104 : varbit_out(PG_FUNCTION_ARGS)
                                588                 :                : {
                                589                 :           3104 :     VarBit     *s = PG_GETARG_VARBIT_P(0);
                                590                 :                :     char       *result,
                                591                 :                :                *r;
                                592                 :                :     bits8      *sp;
                                593                 :                :     bits8       x;
                                594                 :                :     int         i,
                                595                 :                :                 k,
                                596                 :                :                 len;
                                597                 :                : 
                                598                 :                :     /* Assertion to help catch any bit functions that don't pad correctly */
 1666                           599   [ +  -  -  +  :           3104 :     VARBIT_CORRECTLY_PADDED(s);
                                        +  +  -  + ]
                                600                 :                : 
 8637                           601                 :           3104 :     len = VARBITLEN(s);
 8548 peter_e@gmx.net           602                 :           3104 :     result = (char *) palloc(len + 1);
 8637 tgl@sss.pgh.pa.us         603                 :           3104 :     sp = VARBITS(s);
                                604                 :           3104 :     r = result;
 6081                           605         [ +  + ]:           7265 :     for (i = 0; i <= len - BITS_PER_BYTE; i += BITS_PER_BYTE, sp++)
                                606                 :                :     {
                                607                 :                :         /* print full bytes */
 8637                           608                 :           4161 :         x = *sp;
 8632                           609         [ +  + ]:          37449 :         for (k = 0; k < BITS_PER_BYTE; k++)
                                610                 :                :         {
 6685 bruce@momjian.us          611         [ +  + ]:          33288 :             *r++ = IS_HIGHBIT_SET(x) ? '1' : '0';
 8637 tgl@sss.pgh.pa.us         612                 :          33288 :             x <<= 1;
                                613                 :                :         }
                                614                 :                :     }
 6081                           615         [ +  + ]:           3104 :     if (i < len)
                                616                 :                :     {
                                617                 :                :         /* print the last partial byte */
                                618                 :           1487 :         x = *sp;
                                619         [ +  + ]:           7210 :         for (k = i; k < len; k++)
                                620                 :                :         {
                                621         [ +  + ]:           5723 :             *r++ = IS_HIGHBIT_SET(x) ? '1' : '0';
                                622                 :           5723 :             x <<= 1;
                                623                 :                :         }
                                624                 :                :     }
 8637                           625                 :           3104 :     *r = '\0';
                                626                 :                : 
                                627                 :           3104 :     PG_RETURN_CSTRING(result);
                                628                 :                : }
                                629                 :                : 
                                630                 :                : /*
                                631                 :                :  *      varbit_recv         - converts external binary format to varbit
                                632                 :                :  *
                                633                 :                :  * External format is the bitlen as an int32, then the byte array.
                                634                 :                :  */
                                635                 :                : Datum
 7643 tgl@sss.pgh.pa.us         636                 :UBC           0 : varbit_recv(PG_FUNCTION_ARGS)
                                637                 :                : {
                                638                 :              0 :     StringInfo  buf = (StringInfo) PG_GETARG_POINTER(0);
                                639                 :                : 
                                640                 :                : #ifdef NOT_USED
                                641                 :                :     Oid         typelem = PG_GETARG_OID(1);
                                642                 :                : #endif
 6853                           643                 :              0 :     int32       atttypmod = PG_GETARG_INT32(2);
                                644                 :                :     VarBit     *result;
                                645                 :                :     int         len,
                                646                 :                :                 bitlen;
                                647                 :                : 
 7643                           648                 :              0 :     bitlen = pq_getmsgint(buf, sizeof(int32));
 2739                           649   [ #  #  #  # ]:              0 :     if (bitlen < 0 || bitlen > VARBITMAXLEN)
 7567                           650         [ #  # ]:              0 :         ereport(ERROR,
                                651                 :                :                 (errcode(ERRCODE_INVALID_BINARY_REPRESENTATION),
                                652                 :                :                  errmsg("invalid length in external bit string")));
                                653                 :                : 
                                654                 :                :     /*
                                655                 :                :      * Sometimes atttypmod is not supplied. If it is supplied we need to make
                                656                 :                :      * sure that the bitstring fits.
                                657                 :                :      */
 6853                           658   [ #  #  #  # ]:              0 :     if (atttypmod > 0 && bitlen > atttypmod)
                                659         [ #  # ]:              0 :         ereport(ERROR,
                                660                 :                :                 (errcode(ERRCODE_STRING_DATA_RIGHT_TRUNCATION),
                                661                 :                :                  errmsg("bit string too long for type bit varying(%d)",
                                662                 :                :                         atttypmod)));
                                663                 :                : 
 7643                           664                 :              0 :     len = VARBITTOTALLEN(bitlen);
                                665                 :              0 :     result = (VarBit *) palloc(len);
 6256                           666                 :              0 :     SET_VARSIZE(result, len);
 7643                           667                 :              0 :     VARBITLEN(result) = bitlen;
                                668                 :                : 
                                669                 :              0 :     pq_copymsgbytes(buf, (char *) VARBITS(result), VARBITBYTES(result));
                                670                 :                : 
                                671                 :                :     /* Make sure last byte is correctly zero-padded */
 1666                           672   [ #  #  #  #  :              0 :     VARBIT_PAD(result);
                                              #  # ]
                                673                 :                : 
 7643                           674                 :              0 :     PG_RETURN_VARBIT_P(result);
                                675                 :                : }
                                676                 :                : 
                                677                 :                : /*
                                678                 :                :  *      varbit_send         - converts varbit to binary format
                                679                 :                :  */
                                680                 :                : Datum
                                681                 :              0 : varbit_send(PG_FUNCTION_ARGS)
                                682                 :                : {
                                683                 :              0 :     VarBit     *s = PG_GETARG_VARBIT_P(0);
                                684                 :                :     StringInfoData buf;
                                685                 :                : 
                                686                 :              0 :     pq_begintypsend(&buf);
 2377 andres@anarazel.de        687                 :              0 :     pq_sendint32(&buf, VARBITLEN(s));
  425 peter@eisentraut.org      688                 :              0 :     pq_sendbytes(&buf, VARBITS(s), VARBITBYTES(s));
 7643 tgl@sss.pgh.pa.us         689                 :              0 :     PG_RETURN_BYTEA_P(pq_endtypsend(&buf));
                                690                 :                : }
                                691                 :                : 
                                692                 :                : /*
                                693                 :                :  * varbit_support()
                                694                 :                :  *
                                695                 :                :  * Planner support function for the varbit() length coercion function.
                                696                 :                :  *
                                697                 :                :  * Currently, the only interesting thing we can do is flatten calls that set
                                698                 :                :  * the new maximum length >= the previous maximum length.  We can ignore the
                                699                 :                :  * isExplicit argument, since that only affects truncation cases.
                                700                 :                :  */
                                701                 :                : Datum
 1891 tgl@sss.pgh.pa.us         702                 :CBC          60 : varbit_support(PG_FUNCTION_ARGS)
                                703                 :                : {
                                704                 :             60 :     Node       *rawreq = (Node *) PG_GETARG_POINTER(0);
 4450 rhaas@postgresql.org      705                 :             60 :     Node       *ret = NULL;
                                706                 :                : 
 1891 tgl@sss.pgh.pa.us         707         [ +  + ]:             60 :     if (IsA(rawreq, SupportRequestSimplify))
                                708                 :                :     {
                                709                 :             30 :         SupportRequestSimplify *req = (SupportRequestSimplify *) rawreq;
                                710                 :             30 :         FuncExpr   *expr = req->fcall;
                                711                 :                :         Node       *typmod;
                                712                 :                : 
                                713         [ -  + ]:             30 :         Assert(list_length(expr->args) >= 2);
                                714                 :                : 
                                715                 :             30 :         typmod = (Node *) lsecond(expr->args);
                                716                 :                : 
 1429                           717   [ +  -  +  - ]:             30 :         if (IsA(typmod, Const) && !((Const *) typmod)->constisnull)
                                718                 :                :         {
 1891                           719                 :             30 :             Node       *source = (Node *) linitial(expr->args);
                                720                 :             30 :             int32       new_typmod = DatumGetInt32(((Const *) typmod)->constvalue);
                                721                 :             30 :             int32       old_max = exprTypmod(source);
                                722                 :             30 :             int32       new_max = new_typmod;
                                723                 :                : 
                                724                 :                :             /* Note: varbit() treats typmod 0 as invalid, so we do too */
                                725   [ +  -  -  +  :             30 :             if (new_max <= 0 || (old_max > 0 && old_max <= new_max))
                                              -  - ]
 1891 tgl@sss.pgh.pa.us         726                 :UBC           0 :                 ret = relabel_to_typmod(source, new_typmod);
                                727                 :                :         }
                                728                 :                :     }
                                729                 :                : 
 4450 rhaas@postgresql.org      730                 :CBC          60 :     PG_RETURN_POINTER(ret);
                                731                 :                : }
                                732                 :                : 
                                733                 :                : /*
                                734                 :                :  * varbit()
                                735                 :                :  * Converts a varbit() type to a specific internal length.
                                736                 :                :  * len is the maximum bitlength specified in the column definition.
                                737                 :                :  *
                                738                 :                :  * If doing implicit cast, raise error when source data is too long.
                                739                 :                :  * If doing explicit cast, silently truncate to max length.
                                740                 :                :  */
                                741                 :                : Datum
 8637 tgl@sss.pgh.pa.us         742                 :            489 : varbit(PG_FUNCTION_ARGS)
                                743                 :                : {
                                744                 :            489 :     VarBit     *arg = PG_GETARG_VARBIT_P(0);
                                745                 :            489 :     int32       len = PG_GETARG_INT32(1);
 7879                           746                 :            489 :     bool        isExplicit = PG_GETARG_BOOL(2);
                                747                 :                :     VarBit     *result;
                                748                 :                :     int         rlen;
                                749                 :                : 
                                750                 :                :     /* No work if typmod is invalid or supplied data matches it already */
 8637                           751   [ +  -  +  + ]:            489 :     if (len <= 0 || len >= VARBITLEN(arg))
                                752                 :            486 :         PG_RETURN_VARBIT_P(arg);
                                753                 :                : 
 7879                           754         [ +  - ]:              3 :     if (!isExplicit)
 7567                           755         [ +  - ]:              3 :         ereport(ERROR,
                                756                 :                :                 (errcode(ERRCODE_STRING_DATA_RIGHT_TRUNCATION),
                                757                 :                :                  errmsg("bit string too long for type bit varying(%d)",
                                758                 :                :                         len)));
                                759                 :                : 
 8637 tgl@sss.pgh.pa.us         760                 :UBC           0 :     rlen = VARBITTOTALLEN(len);
                                761                 :              0 :     result = (VarBit *) palloc(rlen);
 6256                           762                 :              0 :     SET_VARSIZE(result, rlen);
 8637                           763                 :              0 :     VARBITLEN(result) = len;
                                764                 :                : 
                                765                 :              0 :     memcpy(VARBITS(result), VARBITS(arg), VARBITBYTES(result));
                                766                 :                : 
                                767                 :                :     /* Make sure last byte is correctly zero-padded */
 1666                           768   [ #  #  #  #  :              0 :     VARBIT_PAD(result);
                                              #  # ]
                                769                 :                : 
 7879                           770                 :              0 :     PG_RETURN_VARBIT_P(result);
                                771                 :                : }
                                772                 :                : 
                                773                 :                : Datum
 6315 tgl@sss.pgh.pa.us         774                 :CBC         122 : varbittypmodin(PG_FUNCTION_ARGS)
                                775                 :                : {
 5995 bruce@momjian.us          776                 :            122 :     ArrayType  *ta = PG_GETARG_ARRAYTYPE_P(0);
                                777                 :                : 
 6315 tgl@sss.pgh.pa.us         778                 :            122 :     PG_RETURN_INT32(anybit_typmodin(ta, "varbit"));
                                779                 :                : }
                                780                 :                : 
                                781                 :                : Datum
                                782                 :             66 : varbittypmodout(PG_FUNCTION_ARGS)
                                783                 :                : {
 5995 bruce@momjian.us          784                 :             66 :     int32       typmod = PG_GETARG_INT32(0);
                                785                 :                : 
 6315 tgl@sss.pgh.pa.us         786                 :             66 :     PG_RETURN_CSTRING(anybit_typmodout(typmod));
                                787                 :                : }
                                788                 :                : 
                                789                 :                : 
                                790                 :                : /*
                                791                 :                :  * Comparison operators
                                792                 :                :  *
                                793                 :                :  * We only need one set of comparison operators for bitstrings, as the lengths
                                794                 :                :  * are stored in the same way for zero-padded and varying bit strings.
                                795                 :                :  *
                                796                 :                :  * Note that the standard is not unambiguous about the comparison between
                                797                 :                :  * zero-padded bit strings and varying bitstrings. If the same value is written
                                798                 :                :  * into a zero padded bitstring as into a varying bitstring, but the zero
                                799                 :                :  * padded bitstring has greater length, it will be bigger.
                                800                 :                :  *
                                801                 :                :  * Zeros from the beginning of a bitstring cannot simply be ignored, as they
                                802                 :                :  * may be part of a bit string and may be significant.
                                803                 :                :  *
                                804                 :                :  * Note: btree indexes need these routines not to leak memory; therefore,
                                805                 :                :  * be careful to free working copies of toasted datums.  Most places don't
                                806                 :                :  * need to be so careful.
                                807                 :                :  */
                                808                 :                : 
                                809                 :                : /*
                                810                 :                :  * bit_cmp
                                811                 :                :  *
                                812                 :                :  * Compares two bitstrings and returns <0, 0, >0 depending on whether the first
                                813                 :                :  * string is smaller, equal, or bigger than the second. All bits are considered
                                814                 :                :  * and additional zero bits may make one string smaller/larger than the other,
                                815                 :                :  * even if their zero-padded values would be the same.
                                816                 :                :  */
                                817                 :                : static int32
 8382                           818                 :          21353 : bit_cmp(VarBit *arg1, VarBit *arg2)
                                819                 :                : {
                                820                 :                :     int         bitlen1,
                                821                 :                :                 bytelen1,
                                822                 :                :                 bitlen2,
                                823                 :                :                 bytelen2;
                                824                 :                :     int32       cmp;
                                825                 :                : 
                                826                 :          21353 :     bytelen1 = VARBITBYTES(arg1);
                                827                 :          21353 :     bytelen2 = VARBITBYTES(arg2);
                                828                 :                : 
                                829                 :          21353 :     cmp = memcmp(VARBITS(arg1), VARBITS(arg2), Min(bytelen1, bytelen2));
                                830         [ +  + ]:          21353 :     if (cmp == 0)
                                831                 :                :     {
                                832                 :           3104 :         bitlen1 = VARBITLEN(arg1);
                                833                 :           3104 :         bitlen2 = VARBITLEN(arg2);
                                834         [ +  + ]:           3104 :         if (bitlen1 != bitlen2)
                                835         [ +  + ]:             21 :             cmp = (bitlen1 < bitlen2) ? -1 : 1;
                                836                 :                :     }
                                837                 :          21353 :     return cmp;
                                838                 :                : }
                                839                 :                : 
                                840                 :                : Datum
 8637                           841                 :           2656 : biteq(PG_FUNCTION_ARGS)
                                842                 :                : {
                                843                 :           2656 :     VarBit     *arg1 = PG_GETARG_VARBIT_P(0);
                                844                 :           2656 :     VarBit     *arg2 = PG_GETARG_VARBIT_P(1);
                                845                 :                :     bool        result;
                                846                 :                :     int         bitlen1,
                                847                 :                :                 bitlen2;
                                848                 :                : 
 8768 bruce@momjian.us          849                 :           2656 :     bitlen1 = VARBITLEN(arg1);
                                850                 :           2656 :     bitlen2 = VARBITLEN(arg2);
                                851                 :                : 
                                852                 :                :     /* fast path for different-length inputs */
                                853         [ +  + ]:           2656 :     if (bitlen1 != bitlen2)
 8637 tgl@sss.pgh.pa.us         854                 :            751 :         result = false;
                                855                 :                :     else
 8382                           856                 :           1905 :         result = (bit_cmp(arg1, arg2) == 0);
                                857                 :                : 
 8637                           858         [ +  + ]:           2656 :     PG_FREE_IF_COPY(arg1, 0);
                                859         [ +  + ]:           2656 :     PG_FREE_IF_COPY(arg2, 1);
                                860                 :                : 
                                861                 :           2656 :     PG_RETURN_BOOL(result);
                                862                 :                : }
                                863                 :                : 
                                864                 :                : Datum
                                865                 :            484 : bitne(PG_FUNCTION_ARGS)
                                866                 :                : {
                                867                 :            484 :     VarBit     *arg1 = PG_GETARG_VARBIT_P(0);
                                868                 :            484 :     VarBit     *arg2 = PG_GETARG_VARBIT_P(1);
                                869                 :                :     bool        result;
                                870                 :                :     int         bitlen1,
                                871                 :                :                 bitlen2;
                                872                 :                : 
 8768 bruce@momjian.us          873                 :            484 :     bitlen1 = VARBITLEN(arg1);
                                874                 :            484 :     bitlen2 = VARBITLEN(arg2);
                                875                 :                : 
                                876                 :                :     /* fast path for different-length inputs */
                                877         [ -  + ]:            484 :     if (bitlen1 != bitlen2)
 8637 tgl@sss.pgh.pa.us         878                 :UBC           0 :         result = true;
                                879                 :                :     else
 8382 tgl@sss.pgh.pa.us         880                 :CBC         484 :         result = (bit_cmp(arg1, arg2) != 0);
                                881                 :                : 
 8637                           882         [ +  + ]:            484 :     PG_FREE_IF_COPY(arg1, 0);
                                883         [ +  + ]:            484 :     PG_FREE_IF_COPY(arg2, 1);
                                884                 :                : 
                                885                 :            484 :     PG_RETURN_BOOL(result);
                                886                 :                : }
                                887                 :                : 
                                888                 :                : Datum
                                889                 :           4940 : bitlt(PG_FUNCTION_ARGS)
                                890                 :                : {
                                891                 :           4940 :     VarBit     *arg1 = PG_GETARG_VARBIT_P(0);
                                892                 :           4940 :     VarBit     *arg2 = PG_GETARG_VARBIT_P(1);
                                893                 :                :     bool        result;
                                894                 :                : 
                                895                 :           4940 :     result = (bit_cmp(arg1, arg2) < 0);
                                896                 :                : 
                                897         [ +  + ]:           4940 :     PG_FREE_IF_COPY(arg1, 0);
                                898         [ +  + ]:           4940 :     PG_FREE_IF_COPY(arg2, 1);
                                899                 :                : 
                                900                 :           4940 :     PG_RETURN_BOOL(result);
                                901                 :                : }
                                902                 :                : 
                                903                 :                : Datum
                                904                 :           4278 : bitle(PG_FUNCTION_ARGS)
                                905                 :                : {
                                906                 :           4278 :     VarBit     *arg1 = PG_GETARG_VARBIT_P(0);
                                907                 :           4278 :     VarBit     *arg2 = PG_GETARG_VARBIT_P(1);
                                908                 :                :     bool        result;
                                909                 :                : 
                                910                 :           4278 :     result = (bit_cmp(arg1, arg2) <= 0);
                                911                 :                : 
                                912         [ +  + ]:           4278 :     PG_FREE_IF_COPY(arg1, 0);
                                913         [ +  + ]:           4278 :     PG_FREE_IF_COPY(arg2, 1);
                                914                 :                : 
                                915                 :           4278 :     PG_RETURN_BOOL(result);
                                916                 :                : }
                                917                 :                : 
                                918                 :                : Datum
                                919                 :           5200 : bitgt(PG_FUNCTION_ARGS)
                                920                 :                : {
                                921                 :           5200 :     VarBit     *arg1 = PG_GETARG_VARBIT_P(0);
                                922                 :           5200 :     VarBit     *arg2 = PG_GETARG_VARBIT_P(1);
                                923                 :                :     bool        result;
                                924                 :                : 
                                925                 :           5200 :     result = (bit_cmp(arg1, arg2) > 0);
                                926                 :                : 
                                927         [ +  + ]:           5200 :     PG_FREE_IF_COPY(arg1, 0);
                                928         [ +  + ]:           5200 :     PG_FREE_IF_COPY(arg2, 1);
                                929                 :                : 
                                930                 :           5200 :     PG_RETURN_BOOL(result);
                                931                 :                : }
                                932                 :                : 
                                933                 :                : Datum
                                934                 :           4168 : bitge(PG_FUNCTION_ARGS)
                                935                 :                : {
                                936                 :           4168 :     VarBit     *arg1 = PG_GETARG_VARBIT_P(0);
                                937                 :           4168 :     VarBit     *arg2 = PG_GETARG_VARBIT_P(1);
                                938                 :                :     bool        result;
                                939                 :                : 
                                940                 :           4168 :     result = (bit_cmp(arg1, arg2) >= 0);
                                941                 :                : 
                                942         [ +  + ]:           4168 :     PG_FREE_IF_COPY(arg1, 0);
                                943         [ +  + ]:           4168 :     PG_FREE_IF_COPY(arg2, 1);
                                944                 :                : 
                                945                 :           4168 :     PG_RETURN_BOOL(result);
                                946                 :                : }
                                947                 :                : 
                                948                 :                : Datum
                                949                 :            378 : bitcmp(PG_FUNCTION_ARGS)
                                950                 :                : {
                                951                 :            378 :     VarBit     *arg1 = PG_GETARG_VARBIT_P(0);
                                952                 :            378 :     VarBit     *arg2 = PG_GETARG_VARBIT_P(1);
                                953                 :                :     int32       result;
                                954                 :                : 
                                955                 :            378 :     result = bit_cmp(arg1, arg2);
                                956                 :                : 
                                957         [ +  + ]:            378 :     PG_FREE_IF_COPY(arg1, 0);
                                958         [ +  + ]:            378 :     PG_FREE_IF_COPY(arg2, 1);
                                959                 :                : 
                                960                 :            378 :     PG_RETURN_INT32(result);
                                961                 :                : }
                                962                 :                : 
                                963                 :                : /*
                                964                 :                :  * bitcat
                                965                 :                :  * Concatenation of bit strings
                                966                 :                :  */
                                967                 :                : Datum
                                968                 :             81 : bitcat(PG_FUNCTION_ARGS)
                                969                 :                : {
                                970                 :             81 :     VarBit     *arg1 = PG_GETARG_VARBIT_P(0);
                                971                 :             81 :     VarBit     *arg2 = PG_GETARG_VARBIT_P(1);
                                972                 :                : 
 5193                           973                 :             81 :     PG_RETURN_VARBIT_P(bit_catenate(arg1, arg2));
                                974                 :                : }
                                975                 :                : 
                                976                 :                : static VarBit *
                                977                 :            105 : bit_catenate(VarBit *arg1, VarBit *arg2)
                                978                 :                : {
                                979                 :                :     VarBit     *result;
                                980                 :                :     int         bitlen1,
                                981                 :                :                 bitlen2,
                                982                 :                :                 bytelen,
                                983                 :                :                 bit1pad,
                                984                 :                :                 bit2shift;
                                985                 :                :     bits8      *pr,
                                986                 :                :                *pa;
                                987                 :                : 
 8768 bruce@momjian.us          988                 :            105 :     bitlen1 = VARBITLEN(arg1);
                                989                 :            105 :     bitlen2 = VARBITLEN(arg2);
                                990                 :                : 
 3709 noah@leadboat.com         991         [ -  + ]:            105 :     if (bitlen1 > VARBITMAXLEN - bitlen2)
 3709 noah@leadboat.com         992         [ #  # ]:UBC           0 :         ereport(ERROR,
                                993                 :                :                 (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
                                994                 :                :                  errmsg("bit string length exceeds the maximum allowed (%d)",
                                995                 :                :                         VARBITMAXLEN)));
 8637 tgl@sss.pgh.pa.us         996                 :CBC         105 :     bytelen = VARBITTOTALLEN(bitlen1 + bitlen2);
                                997                 :                : 
                                998                 :            105 :     result = (VarBit *) palloc(bytelen);
 6256                           999                 :            105 :     SET_VARSIZE(result, bytelen);
 8768 bruce@momjian.us         1000                 :            105 :     VARBITLEN(result) = bitlen1 + bitlen2;
                               1001                 :                : 
                               1002                 :                :     /* Copy the first bitstring in */
                               1003                 :            105 :     memcpy(VARBITS(result), VARBITS(arg1), VARBITBYTES(arg1));
                               1004                 :                : 
                               1005                 :                :     /* Copy the second bit string */
                               1006                 :            105 :     bit1pad = VARBITPAD(arg1);
                               1007         [ +  + ]:            105 :     if (bit1pad == 0)
                               1008                 :                :     {
                               1009                 :             18 :         memcpy(VARBITS(result) + VARBITBYTES(arg1), VARBITS(arg2),
                               1010                 :             18 :                VARBITBYTES(arg2));
                               1011                 :                :     }
                               1012         [ +  + ]:             87 :     else if (bitlen2 > 0)
                               1013                 :                :     {
                               1014                 :                :         /* We need to shift all the bits to fit */
 8632 tgl@sss.pgh.pa.us        1015                 :             81 :         bit2shift = BITS_PER_BYTE - bit1pad;
 8768 bruce@momjian.us         1016                 :             81 :         pr = VARBITS(result) + VARBITBYTES(arg1) - 1;
 8637 tgl@sss.pgh.pa.us        1017         [ +  + ]:            189 :         for (pa = VARBITS(arg2); pa < VARBITEND(arg2); pa++)
                               1018                 :                :         {
 8768 bruce@momjian.us         1019                 :            108 :             *pr |= ((*pa >> bit2shift) & BITMASK);
                               1020                 :            108 :             pr++;
                               1021         [ +  + ]:            108 :             if (pr < VARBITEND(result))
                               1022                 :             69 :                 *pr = (*pa << bit1pad) & BITMASK;
                               1023                 :                :         }
                               1024                 :                :     }
                               1025                 :                : 
                               1026                 :                :     /* The pad bits should be already zero at this point */
                               1027                 :                : 
 5193 tgl@sss.pgh.pa.us        1028                 :            105 :     return result;
                               1029                 :                : }
                               1030                 :                : 
                               1031                 :                : /*
                               1032                 :                :  * bitsubstr
                               1033                 :                :  * retrieve a substring from the bit string.
                               1034                 :                :  * Note, s is 1-based.
                               1035                 :                :  * SQL draft 6.10 9)
                               1036                 :                :  */
                               1037                 :                : Datum
 8637                          1038                 :             60 : bitsubstr(PG_FUNCTION_ARGS)
                               1039                 :                : {
 5211                          1040                 :             60 :     PG_RETURN_VARBIT_P(bitsubstring(PG_GETARG_VARBIT_P(0),
                               1041                 :                :                                     PG_GETARG_INT32(1),
                               1042                 :                :                                     PG_GETARG_INT32(2),
                               1043                 :                :                                     false));
                               1044                 :                : }
                               1045                 :                : 
                               1046                 :                : Datum
                               1047                 :             21 : bitsubstr_no_len(PG_FUNCTION_ARGS)
                               1048                 :                : {
                               1049                 :             21 :     PG_RETURN_VARBIT_P(bitsubstring(PG_GETARG_VARBIT_P(0),
                               1050                 :                :                                     PG_GETARG_INT32(1),
                               1051                 :                :                                     -1, true));
                               1052                 :                : }
                               1053                 :                : 
                               1054                 :                : static VarBit *
                               1055                 :            105 : bitsubstring(VarBit *arg, int32 s, int32 l, bool length_not_specified)
                               1056                 :                : {
                               1057                 :                :     VarBit     *result;
                               1058                 :                :     int         bitlen,
                               1059                 :                :                 rbitlen,
                               1060                 :                :                 len,
                               1061                 :                :                 ishift,
                               1062                 :                :                 i;
                               1063                 :                :     int32       e,
                               1064                 :                :                 s1,
                               1065                 :                :                 e1;
                               1066                 :                :     bits8      *r,
                               1067                 :                :                *ps;
                               1068                 :                : 
 8768 bruce@momjian.us         1069                 :            105 :     bitlen = VARBITLEN(arg);
                               1070                 :            105 :     s1 = Max(s, 1);
                               1071                 :                :     /* If we do not have an upper bound, use end of string */
 5211 tgl@sss.pgh.pa.us        1072         [ +  + ]:            105 :     if (length_not_specified)
                               1073                 :                :     {
                               1074                 :             33 :         e1 = bitlen + 1;
                               1075                 :                :     }
 1196                          1076         [ +  + ]:             72 :     else if (l < 0)
                               1077                 :                :     {
                               1078                 :                :         /* SQL99 says to throw an error for E < S, i.e., negative length */
                               1079         [ +  - ]:              6 :         ereport(ERROR,
                               1080                 :                :                 (errcode(ERRCODE_SUBSTRING_ERROR),
                               1081                 :                :                  errmsg("negative substring length not allowed")));
                               1082                 :                :         e1 = -1;                /* silence stupider compilers */
                               1083                 :                :     }
                               1084         [ +  + ]:             66 :     else if (pg_add_s32_overflow(s, l, &e))
                               1085                 :                :     {
                               1086                 :                :         /*
                               1087                 :                :          * L could be large enough for S + L to overflow, in which case the
                               1088                 :                :          * substring must run to end of string.
                               1089                 :                :          */
                               1090                 :              6 :         e1 = bitlen + 1;
                               1091                 :                :     }
                               1092                 :                :     else
                               1093                 :                :     {
 5211                          1094                 :             60 :         e1 = Min(e, bitlen + 1);
                               1095                 :                :     }
                               1096   [ +  +  -  + ]:             99 :     if (s1 > bitlen || e1 <= s1)
                               1097                 :                :     {
                               1098                 :                :         /* Need to return a zero-length bitstring */
 8637                          1099                 :             27 :         len = VARBITTOTALLEN(0);
                               1100                 :             27 :         result = (VarBit *) palloc(len);
 6256                          1101                 :             27 :         SET_VARSIZE(result, len);
 8637                          1102                 :             27 :         VARBITLEN(result) = 0;
                               1103                 :                :     }
                               1104                 :                :     else
                               1105                 :                :     {
                               1106                 :                :         /*
                               1107                 :                :          * OK, we've got a true substring starting at position s1-1 and ending
                               1108                 :                :          * at position e1-1
                               1109                 :                :          */
 8768 bruce@momjian.us         1110                 :             72 :         rbitlen = e1 - s1;
 8637 tgl@sss.pgh.pa.us        1111                 :             72 :         len = VARBITTOTALLEN(rbitlen);
                               1112                 :             72 :         result = (VarBit *) palloc(len);
 6256                          1113                 :             72 :         SET_VARSIZE(result, len);
 8637                          1114                 :             72 :         VARBITLEN(result) = rbitlen;
 8768 bruce@momjian.us         1115                 :             72 :         len -= VARHDRSZ + VARBITHDRSZ;
                               1116                 :                :         /* Are we copying from a byte boundary? */
 8632 tgl@sss.pgh.pa.us        1117         [ +  + ]:             72 :         if ((s1 - 1) % BITS_PER_BYTE == 0)
                               1118                 :                :         {
                               1119                 :                :             /* Yep, we are copying bytes */
                               1120                 :             21 :             memcpy(VARBITS(result), VARBITS(arg) + (s1 - 1) / BITS_PER_BYTE,
                               1121                 :                :                    len);
                               1122                 :                :         }
                               1123                 :                :         else
                               1124                 :                :         {
                               1125                 :                :             /* Figure out how much we need to shift the sequence by */
                               1126                 :             51 :             ishift = (s1 - 1) % BITS_PER_BYTE;
 8768 bruce@momjian.us         1127                 :             51 :             r = VARBITS(result);
 8632 tgl@sss.pgh.pa.us        1128                 :             51 :             ps = VARBITS(arg) + (s1 - 1) / BITS_PER_BYTE;
 8768 bruce@momjian.us         1129         [ +  + ]:            102 :             for (i = 0; i < len; i++)
                               1130                 :                :             {
                               1131                 :             51 :                 *r = (*ps << ishift) & BITMASK;
                               1132         [ +  + ]:             51 :                 if ((++ps) < VARBITEND(arg))
 8632 tgl@sss.pgh.pa.us        1133                 :             39 :                     *r |= *ps >> (BITS_PER_BYTE - ishift);
 8768 bruce@momjian.us         1134                 :             51 :                 r++;
                               1135                 :                :             }
                               1136                 :                :         }
                               1137                 :                : 
                               1138                 :                :         /* Make sure last byte is correctly zero-padded */
 1666 tgl@sss.pgh.pa.us        1139   [ +  -  -  +  :             72 :         VARBIT_PAD(result);
                                              +  + ]
                               1140                 :                :     }
                               1141                 :                : 
 5211                          1142                 :             99 :     return result;
                               1143                 :                : }
                               1144                 :                : 
                               1145                 :                : /*
                               1146                 :                :  * bitoverlay
                               1147                 :                :  *  Replace specified substring of first string with second
                               1148                 :                :  *
                               1149                 :                :  * The SQL standard defines OVERLAY() in terms of substring and concatenation.
                               1150                 :                :  * This code is a direct implementation of what the standard says.
                               1151                 :                :  */
                               1152                 :                : Datum
 5193                          1153                 :              3 : bitoverlay(PG_FUNCTION_ARGS)
                               1154                 :                : {
                               1155                 :              3 :     VarBit     *t1 = PG_GETARG_VARBIT_P(0);
                               1156                 :              3 :     VarBit     *t2 = PG_GETARG_VARBIT_P(1);
 2489                          1157                 :              3 :     int         sp = PG_GETARG_INT32(2);    /* substring start position */
                               1158                 :              3 :     int         sl = PG_GETARG_INT32(3);    /* substring length */
                               1159                 :                : 
 5193                          1160                 :              3 :     PG_RETURN_VARBIT_P(bit_overlay(t1, t2, sp, sl));
                               1161                 :                : }
                               1162                 :                : 
                               1163                 :                : Datum
                               1164                 :              9 : bitoverlay_no_len(PG_FUNCTION_ARGS)
                               1165                 :                : {
                               1166                 :              9 :     VarBit     *t1 = PG_GETARG_VARBIT_P(0);
                               1167                 :              9 :     VarBit     *t2 = PG_GETARG_VARBIT_P(1);
 2489                          1168                 :              9 :     int         sp = PG_GETARG_INT32(2);    /* substring start position */
                               1169                 :                :     int         sl;
                               1170                 :                : 
 5161 bruce@momjian.us         1171                 :              9 :     sl = VARBITLEN(t2);         /* defaults to length(t2) */
 5193 tgl@sss.pgh.pa.us        1172                 :              9 :     PG_RETURN_VARBIT_P(bit_overlay(t1, t2, sp, sl));
                               1173                 :                : }
                               1174                 :                : 
                               1175                 :                : static VarBit *
                               1176                 :             12 : bit_overlay(VarBit *t1, VarBit *t2, int sp, int sl)
                               1177                 :                : {
                               1178                 :                :     VarBit     *result;
                               1179                 :                :     VarBit     *s1;
                               1180                 :                :     VarBit     *s2;
                               1181                 :                :     int         sp_pl_sl;
                               1182                 :                : 
                               1183                 :                :     /*
                               1184                 :                :      * Check for possible integer-overflow cases.  For negative sp, throw a
                               1185                 :                :      * "substring length" error because that's what should be expected
                               1186                 :                :      * according to the spec's definition of OVERLAY().
                               1187                 :                :      */
                               1188         [ -  + ]:             12 :     if (sp <= 0)
 5193 tgl@sss.pgh.pa.us        1189         [ #  # ]:UBC           0 :         ereport(ERROR,
                               1190                 :                :                 (errcode(ERRCODE_SUBSTRING_ERROR),
                               1191                 :                :                  errmsg("negative substring length not allowed")));
 2315 andres@anarazel.de       1192         [ -  + ]:CBC          12 :     if (pg_add_s32_overflow(sp, sl, &sp_pl_sl))
 5193 tgl@sss.pgh.pa.us        1193         [ #  # ]:UBC           0 :         ereport(ERROR,
                               1194                 :                :                 (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
                               1195                 :                :                  errmsg("integer out of range")));
                               1196                 :                : 
 5161 bruce@momjian.us         1197                 :CBC          12 :     s1 = bitsubstring(t1, 1, sp - 1, false);
 5193 tgl@sss.pgh.pa.us        1198                 :             12 :     s2 = bitsubstring(t1, sp_pl_sl, -1, true);
                               1199                 :             12 :     result = bit_catenate(s1, t2);
                               1200                 :             12 :     result = bit_catenate(result, s2);
                               1201                 :                : 
                               1202                 :             12 :     return result;
                               1203                 :                : }
                               1204                 :                : 
                               1205                 :                : /*
                               1206                 :                :  * bit_count
                               1207                 :                :  *
                               1208                 :                :  * Returns the number of bits set in a bit string.
                               1209                 :                :  */
                               1210                 :                : Datum
 1118 peter@eisentraut.org     1211                 :             18 : bit_bit_count(PG_FUNCTION_ARGS)
                               1212                 :                : {
                               1213                 :             18 :     VarBit     *arg = PG_GETARG_VARBIT_P(0);
                               1214                 :                : 
                               1215                 :             18 :     PG_RETURN_INT64(pg_popcount((char *) VARBITS(arg), VARBITBYTES(arg)));
                               1216                 :                : }
                               1217                 :                : 
                               1218                 :                : /*
                               1219                 :                :  * bitlength, bitoctetlength
                               1220                 :                :  * Return the length of a bit string
                               1221                 :                :  */
                               1222                 :                : Datum
 8637 tgl@sss.pgh.pa.us        1223                 :             21 : bitlength(PG_FUNCTION_ARGS)
                               1224                 :                : {
                               1225                 :             21 :     VarBit     *arg = PG_GETARG_VARBIT_P(0);
                               1226                 :                : 
                               1227                 :             21 :     PG_RETURN_INT32(VARBITLEN(arg));
                               1228                 :                : }
                               1229                 :                : 
                               1230                 :                : Datum
 8637 tgl@sss.pgh.pa.us        1231                 :UBC           0 : bitoctetlength(PG_FUNCTION_ARGS)
                               1232                 :                : {
                               1233                 :              0 :     VarBit     *arg = PG_GETARG_VARBIT_P(0);
                               1234                 :                : 
                               1235                 :              0 :     PG_RETURN_INT32(VARBITBYTES(arg));
                               1236                 :                : }
                               1237                 :                : 
                               1238                 :                : /*
                               1239                 :                :  * bit_and
                               1240                 :                :  * perform a logical AND on two bit strings.
                               1241                 :                :  */
                               1242                 :                : Datum
 4857 tgl@sss.pgh.pa.us        1243                 :CBC          82 : bit_and(PG_FUNCTION_ARGS)
                               1244                 :                : {
 8637                          1245                 :             82 :     VarBit     *arg1 = PG_GETARG_VARBIT_P(0);
                               1246                 :             82 :     VarBit     *arg2 = PG_GETARG_VARBIT_P(1);
                               1247                 :                :     VarBit     *result;
                               1248                 :                :     int         len,
                               1249                 :                :                 bitlen1,
                               1250                 :                :                 bitlen2,
                               1251                 :                :                 i;
                               1252                 :                :     bits8      *p1,
                               1253                 :                :                *p2,
                               1254                 :                :                *r;
                               1255                 :                : 
                               1256                 :             82 :     bitlen1 = VARBITLEN(arg1);
                               1257                 :             82 :     bitlen2 = VARBITLEN(arg2);
                               1258         [ +  + ]:             82 :     if (bitlen1 != bitlen2)
 7567                          1259         [ +  - ]:              3 :         ereport(ERROR,
                               1260                 :                :                 (errcode(ERRCODE_STRING_DATA_LENGTH_MISMATCH),
                               1261                 :                :                  errmsg("cannot AND bit strings of different sizes")));
                               1262                 :                : 
 8637                          1263                 :             79 :     len = VARSIZE(arg1);
                               1264                 :             79 :     result = (VarBit *) palloc(len);
 6256                          1265                 :             79 :     SET_VARSIZE(result, len);
 8637                          1266                 :             79 :     VARBITLEN(result) = bitlen1;
                               1267                 :                : 
                               1268                 :             79 :     p1 = VARBITS(arg1);
                               1269                 :             79 :     p2 = VARBITS(arg2);
                               1270                 :             79 :     r = VARBITS(result);
                               1271         [ +  + ]:            239 :     for (i = 0; i < VARBITBYTES(arg1); i++)
 8768 bruce@momjian.us         1272                 :            160 :         *r++ = *p1++ & *p2++;
                               1273                 :                : 
                               1274                 :                :     /* Padding is not needed as & of 0 pads is 0 */
                               1275                 :                : 
 8637 tgl@sss.pgh.pa.us        1276                 :             79 :     PG_RETURN_VARBIT_P(result);
                               1277                 :                : }
                               1278                 :                : 
                               1279                 :                : /*
                               1280                 :                :  * bit_or
                               1281                 :                :  * perform a logical OR on two bit strings.
                               1282                 :                :  */
                               1283                 :                : Datum
 4857                          1284                 :             84 : bit_or(PG_FUNCTION_ARGS)
                               1285                 :                : {
 8637                          1286                 :             84 :     VarBit     *arg1 = PG_GETARG_VARBIT_P(0);
                               1287                 :             84 :     VarBit     *arg2 = PG_GETARG_VARBIT_P(1);
                               1288                 :                :     VarBit     *result;
                               1289                 :                :     int         len,
                               1290                 :                :                 bitlen1,
                               1291                 :                :                 bitlen2,
                               1292                 :                :                 i;
                               1293                 :                :     bits8      *p1,
                               1294                 :                :                *p2,
                               1295                 :                :                *r;
                               1296                 :                : 
                               1297                 :             84 :     bitlen1 = VARBITLEN(arg1);
                               1298                 :             84 :     bitlen2 = VARBITLEN(arg2);
                               1299         [ +  + ]:             84 :     if (bitlen1 != bitlen2)
 7567                          1300         [ +  - ]:              3 :         ereport(ERROR,
                               1301                 :                :                 (errcode(ERRCODE_STRING_DATA_LENGTH_MISMATCH),
                               1302                 :                :                  errmsg("cannot OR bit strings of different sizes")));
 8637                          1303                 :             81 :     len = VARSIZE(arg1);
                               1304                 :             81 :     result = (VarBit *) palloc(len);
 6256                          1305                 :             81 :     SET_VARSIZE(result, len);
 8637                          1306                 :             81 :     VARBITLEN(result) = bitlen1;
                               1307                 :                : 
                               1308                 :             81 :     p1 = VARBITS(arg1);
                               1309                 :             81 :     p2 = VARBITS(arg2);
                               1310                 :             81 :     r = VARBITS(result);
                               1311         [ +  + ]:            237 :     for (i = 0; i < VARBITBYTES(arg1); i++)
 8768 bruce@momjian.us         1312                 :            156 :         *r++ = *p1++ | *p2++;
                               1313                 :                : 
                               1314                 :                :     /* Padding is not needed as | of 0 pads is 0 */
                               1315                 :                : 
 8637 tgl@sss.pgh.pa.us        1316                 :             81 :     PG_RETURN_VARBIT_P(result);
                               1317                 :                : }
                               1318                 :                : 
                               1319                 :                : /*
                               1320                 :                :  * bitxor
                               1321                 :                :  * perform a logical XOR on two bit strings.
                               1322                 :                :  */
                               1323                 :                : Datum
                               1324                 :             69 : bitxor(PG_FUNCTION_ARGS)
                               1325                 :                : {
                               1326                 :             69 :     VarBit     *arg1 = PG_GETARG_VARBIT_P(0);
                               1327                 :             69 :     VarBit     *arg2 = PG_GETARG_VARBIT_P(1);
                               1328                 :                :     VarBit     *result;
                               1329                 :                :     int         len,
                               1330                 :                :                 bitlen1,
                               1331                 :                :                 bitlen2,
                               1332                 :                :                 i;
                               1333                 :                :     bits8      *p1,
                               1334                 :                :                *p2,
                               1335                 :                :                *r;
                               1336                 :                : 
                               1337                 :             69 :     bitlen1 = VARBITLEN(arg1);
                               1338                 :             69 :     bitlen2 = VARBITLEN(arg2);
                               1339         [ +  + ]:             69 :     if (bitlen1 != bitlen2)
 7567                          1340         [ +  - ]:              3 :         ereport(ERROR,
                               1341                 :                :                 (errcode(ERRCODE_STRING_DATA_LENGTH_MISMATCH),
                               1342                 :                :                  errmsg("cannot XOR bit strings of different sizes")));
                               1343                 :                : 
 8637                          1344                 :             66 :     len = VARSIZE(arg1);
                               1345                 :             66 :     result = (VarBit *) palloc(len);
 6256                          1346                 :             66 :     SET_VARSIZE(result, len);
 8637                          1347                 :             66 :     VARBITLEN(result) = bitlen1;
                               1348                 :                : 
                               1349                 :             66 :     p1 = VARBITS(arg1);
                               1350                 :             66 :     p2 = VARBITS(arg2);
                               1351                 :             66 :     r = VARBITS(result);
                               1352         [ +  + ]:            177 :     for (i = 0; i < VARBITBYTES(arg1); i++)
 8768 bruce@momjian.us         1353                 :            111 :         *r++ = *p1++ ^ *p2++;
                               1354                 :                : 
                               1355                 :                :     /* Padding is not needed as ^ of 0 pads is 0 */
                               1356                 :                : 
 8637 tgl@sss.pgh.pa.us        1357                 :             66 :     PG_RETURN_VARBIT_P(result);
                               1358                 :                : }
                               1359                 :                : 
                               1360                 :                : /*
                               1361                 :                :  * bitnot
                               1362                 :                :  * perform a logical NOT on a bit string.
                               1363                 :                :  */
                               1364                 :                : Datum
                               1365                 :             60 : bitnot(PG_FUNCTION_ARGS)
                               1366                 :                : {
                               1367                 :             60 :     VarBit     *arg = PG_GETARG_VARBIT_P(0);
                               1368                 :                :     VarBit     *result;
                               1369                 :                :     bits8      *p,
                               1370                 :                :                *r;
                               1371                 :                : 
                               1372                 :             60 :     result = (VarBit *) palloc(VARSIZE(arg));
 6256                          1373                 :             60 :     SET_VARSIZE(result, VARSIZE(arg));
 8768 bruce@momjian.us         1374                 :             60 :     VARBITLEN(result) = VARBITLEN(arg);
                               1375                 :                : 
 8637 tgl@sss.pgh.pa.us        1376                 :             60 :     p = VARBITS(arg);
                               1377                 :             60 :     r = VARBITS(result);
                               1378         [ +  + ]:            165 :     for (; p < VARBITEND(arg); p++)
 8424 bruce@momjian.us         1379                 :            105 :         *r++ = ~*p;
                               1380                 :                : 
                               1381                 :                :     /* Must zero-pad the result, because extra bits are surely 1's here */
 1666 tgl@sss.pgh.pa.us        1382   [ +  -  -  +  :             60 :     VARBIT_PAD_LAST(result, r);
                                              -  + ]
                               1383                 :                : 
 8637                          1384                 :             60 :     PG_RETURN_VARBIT_P(result);
                               1385                 :                : }
                               1386                 :                : 
                               1387                 :                : /*
                               1388                 :                :  * bitshiftleft
                               1389                 :                :  * do a left shift (i.e. towards the beginning of the string)
                               1390                 :                :  */
                               1391                 :                : Datum
                               1392                 :            348 : bitshiftleft(PG_FUNCTION_ARGS)
                               1393                 :                : {
                               1394                 :            348 :     VarBit     *arg = PG_GETARG_VARBIT_P(0);
                               1395                 :            348 :     int32       shft = PG_GETARG_INT32(1);
                               1396                 :                :     VarBit     *result;
                               1397                 :                :     int         byte_shift,
                               1398                 :                :                 ishift,
                               1399                 :                :                 len;
                               1400                 :                :     bits8      *p,
                               1401                 :                :                *r;
                               1402                 :                : 
                               1403                 :                :     /* Negative shift is a shift to the right */
 8768 bruce@momjian.us         1404         [ -  + ]:            348 :     if (shft < 0)
                               1405                 :                :     {
                               1406                 :                :         /* Prevent integer overflow in negation */
 2739 tgl@sss.pgh.pa.us        1407         [ #  # ]:UBC           0 :         if (shft < -VARBITMAXLEN)
                               1408                 :              0 :             shft = -VARBITMAXLEN;
 8637                          1409                 :              0 :         PG_RETURN_DATUM(DirectFunctionCall2(bitshiftright,
                               1410                 :                :                                             VarBitPGetDatum(arg),
                               1411                 :                :                                             Int32GetDatum(-shft)));
                               1412                 :                :     }
                               1413                 :                : 
 8637 tgl@sss.pgh.pa.us        1414                 :CBC         348 :     result = (VarBit *) palloc(VARSIZE(arg));
 6256                          1415                 :            348 :     SET_VARSIZE(result, VARSIZE(arg));
 8768 bruce@momjian.us         1416                 :            348 :     VARBITLEN(result) = VARBITLEN(arg);
 8637 tgl@sss.pgh.pa.us        1417                 :            348 :     r = VARBITS(result);
                               1418                 :                : 
                               1419                 :                :     /* If we shifted all the bits out, return an all-zero string */
                               1420         [ +  + ]:            348 :     if (shft >= VARBITLEN(arg))
                               1421                 :                :     {
 7879                          1422   [ +  -  -  +  :             12 :         MemSet(r, 0, VARBITBYTES(arg));
                                     -  -  -  -  -  
                                                 - ]
 8637                          1423                 :             12 :         PG_RETURN_VARBIT_P(result);
                               1424                 :                :     }
                               1425                 :                : 
 8632                          1426                 :            336 :     byte_shift = shft / BITS_PER_BYTE;
                               1427                 :            336 :     ishift = shft % BITS_PER_BYTE;
 8637                          1428                 :            336 :     p = VARBITS(arg) + byte_shift;
                               1429                 :                : 
 8768 bruce@momjian.us         1430         [ +  + ]:            336 :     if (ishift == 0)
                               1431                 :                :     {
                               1432                 :                :         /* Special case: we can do a memcpy */
                               1433                 :            132 :         len = VARBITBYTES(arg) - byte_shift;
                               1434                 :            132 :         memcpy(r, p, len);
 7879 tgl@sss.pgh.pa.us        1435   [ -  +  -  -  :            132 :         MemSet(r + len, 0, byte_shift);
                                     -  -  -  -  -  
                                                 - ]
                               1436                 :                :     }
                               1437                 :                :     else
                               1438                 :                :     {
 8768 bruce@momjian.us         1439         [ +  + ]:            597 :         for (; p < VARBITEND(arg); r++)
                               1440                 :                :         {
                               1441                 :            393 :             *r = *p << ishift;
                               1442         [ +  + ]:            393 :             if ((++p) < VARBITEND(arg))
 8632 tgl@sss.pgh.pa.us        1443                 :            189 :                 *r |= *p >> (BITS_PER_BYTE - ishift);
                               1444                 :                :         }
 8768 bruce@momjian.us         1445         [ -  + ]:            204 :         for (; r < VARBITEND(result); r++)
 8637 tgl@sss.pgh.pa.us        1446                 :UBC           0 :             *r = 0;
                               1447                 :                :     }
                               1448                 :                : 
                               1449                 :                :     /* The pad bits should be already zero at this point */
                               1450                 :                : 
 8637 tgl@sss.pgh.pa.us        1451                 :CBC         336 :     PG_RETURN_VARBIT_P(result);
                               1452                 :                : }
                               1453                 :                : 
                               1454                 :                : /*
                               1455                 :                :  * bitshiftright
                               1456                 :                :  * do a right shift (i.e. towards the end of the string)
                               1457                 :                :  */
                               1458                 :                : Datum
                               1459                 :            438 : bitshiftright(PG_FUNCTION_ARGS)
                               1460                 :                : {
                               1461                 :            438 :     VarBit     *arg = PG_GETARG_VARBIT_P(0);
                               1462                 :            438 :     int32       shft = PG_GETARG_INT32(1);
                               1463                 :                :     VarBit     *result;
                               1464                 :                :     int         byte_shift,
                               1465                 :                :                 ishift,
                               1466                 :                :                 len;
                               1467                 :                :     bits8      *p,
                               1468                 :                :                *r;
                               1469                 :                : 
                               1470                 :                :     /* Negative shift is a shift to the left */
 8768 bruce@momjian.us         1471         [ -  + ]:            438 :     if (shft < 0)
                               1472                 :                :     {
                               1473                 :                :         /* Prevent integer overflow in negation */
 2739 tgl@sss.pgh.pa.us        1474         [ #  # ]:UBC           0 :         if (shft < -VARBITMAXLEN)
                               1475                 :              0 :             shft = -VARBITMAXLEN;
 8637                          1476                 :              0 :         PG_RETURN_DATUM(DirectFunctionCall2(bitshiftleft,
                               1477                 :                :                                             VarBitPGetDatum(arg),
                               1478                 :                :                                             Int32GetDatum(-shft)));
                               1479                 :                :     }
                               1480                 :                : 
 8637 tgl@sss.pgh.pa.us        1481                 :CBC         438 :     result = (VarBit *) palloc(VARSIZE(arg));
 6256                          1482                 :            438 :     SET_VARSIZE(result, VARSIZE(arg));
 8768 bruce@momjian.us         1483                 :            438 :     VARBITLEN(result) = VARBITLEN(arg);
 8637 tgl@sss.pgh.pa.us        1484                 :            438 :     r = VARBITS(result);
                               1485                 :                : 
                               1486                 :                :     /* If we shifted all the bits out, return an all-zero string */
                               1487         [ +  + ]:            438 :     if (shft >= VARBITLEN(arg))
                               1488                 :                :     {
 7879                          1489   [ +  -  -  +  :             12 :         MemSet(r, 0, VARBITBYTES(arg));
                                     -  -  -  -  -  
                                                 - ]
 8637                          1490                 :             12 :         PG_RETURN_VARBIT_P(result);
                               1491                 :                :     }
                               1492                 :                : 
 8632                          1493                 :            426 :     byte_shift = shft / BITS_PER_BYTE;
                               1494                 :            426 :     ishift = shft % BITS_PER_BYTE;
 8637                          1495                 :            426 :     p = VARBITS(arg);
                               1496                 :                : 
                               1497                 :                :     /* Set the first part of the result to 0 */
 7879                          1498   [ +  -  +  +  :            426 :     MemSet(r, 0, byte_shift);
                                     +  -  +  -  -  
                                                 + ]
 8637                          1499                 :            426 :     r += byte_shift;
                               1500                 :                : 
 8768 bruce@momjian.us         1501         [ +  + ]:            426 :     if (ishift == 0)
                               1502                 :                :     {
                               1503                 :                :         /* Special case: we can do a memcpy */
                               1504                 :            180 :         len = VARBITBYTES(arg) - byte_shift;
 8637 tgl@sss.pgh.pa.us        1505                 :            180 :         memcpy(r, p, len);
 1654                          1506                 :            180 :         r += len;
                               1507                 :                :     }
                               1508                 :                :     else
                               1509                 :                :     {
 8637                          1510         [ +  - ]:            246 :         if (r < VARBITEND(result))
                               1511                 :            246 :             *r = 0;             /* initialize first byte */
 8768 bruce@momjian.us         1512         [ +  + ]:            714 :         for (; r < VARBITEND(result); p++)
                               1513                 :                :         {
                               1514                 :            468 :             *r |= *p >> ishift;
                               1515         [ +  + ]:            468 :             if ((++r) < VARBITEND(result))
 8632 tgl@sss.pgh.pa.us        1516                 :            222 :                 *r = (*p << (BITS_PER_BYTE - ishift)) & BITMASK;
                               1517                 :                :         }
                               1518                 :                :     }
                               1519                 :                : 
                               1520                 :                :     /* We may have shifted 1's into the pad bits, so fix that */
 1654                          1521   [ +  -  -  +  :            426 :     VARBIT_PAD_LAST(result, r);
                                              +  + ]
                               1522                 :                : 
 8637                          1523                 :            426 :     PG_RETURN_VARBIT_P(result);
                               1524                 :                : }
                               1525                 :                : 
                               1526                 :                : /*
                               1527                 :                :  * This is not defined in any standard. We retain the natural ordering of
                               1528                 :                :  * bits here, as it just seems more intuitive.
                               1529                 :                :  */
                               1530                 :                : Datum
                               1531                 :           1505 : bitfromint4(PG_FUNCTION_ARGS)
                               1532                 :                : {
                               1533                 :           1505 :     int32       a = PG_GETARG_INT32(0);
 7242                          1534                 :           1505 :     int32       typmod = PG_GETARG_INT32(1);
                               1535                 :                :     VarBit     *result;
                               1536                 :                :     bits8      *r;
                               1537                 :                :     int         rlen;
                               1538                 :                :     int         destbitsleft,
                               1539                 :                :                 srcbitsleft;
                               1540                 :                : 
 2739                          1541   [ +  -  -  + ]:           1505 :     if (typmod <= 0 || typmod > VARBITMAXLEN)
 7242 tgl@sss.pgh.pa.us        1542                 :UBC           0 :         typmod = 1;             /* default bit length */
                               1543                 :                : 
 7242 tgl@sss.pgh.pa.us        1544                 :CBC        1505 :     rlen = VARBITTOTALLEN(typmod);
                               1545                 :           1505 :     result = (VarBit *) palloc(rlen);
 6256                          1546                 :           1505 :     SET_VARSIZE(result, rlen);
 7242                          1547                 :           1505 :     VARBITLEN(result) = typmod;
                               1548                 :                : 
 8637                          1549                 :           1505 :     r = VARBITS(result);
 7242                          1550                 :           1505 :     destbitsleft = typmod;
                               1551                 :           1505 :     srcbitsleft = 32;
                               1552                 :                :     /* drop any input bits that don't fit */
                               1553                 :           1505 :     srcbitsleft = Min(srcbitsleft, destbitsleft);
                               1554                 :                :     /* sign-fill any excess bytes in output */
                               1555         [ -  + ]:           1505 :     while (destbitsleft >= srcbitsleft + 8)
                               1556                 :                :     {
 7242 tgl@sss.pgh.pa.us        1557         [ #  # ]:UBC           0 :         *r++ = (bits8) ((a < 0) ? BITMASK : 0);
                               1558                 :              0 :         destbitsleft -= 8;
                               1559                 :                :     }
                               1560                 :                :     /* store first fractional byte */
 7242 tgl@sss.pgh.pa.us        1561         [ -  + ]:CBC        1505 :     if (destbitsleft > srcbitsleft)
                               1562                 :                :     {
 2128 tgl@sss.pgh.pa.us        1563                 :UBC           0 :         unsigned int val = (unsigned int) (a >> (destbitsleft - 8));
                               1564                 :                : 
                               1565                 :                :         /* Force sign-fill in case the compiler implements >> as zero-fill */
 5237                          1566         [ #  # ]:              0 :         if (a < 0)
 2128                          1567                 :              0 :             val |= ((unsigned int) -1) << (srcbitsleft + 8 - destbitsleft);
 5237                          1568                 :              0 :         *r++ = (bits8) (val & BITMASK);
 7242                          1569                 :              0 :         destbitsleft -= 8;
                               1570                 :                :     }
                               1571                 :                :     /* Now srcbitsleft and destbitsleft are the same, need not track both */
                               1572                 :                :     /* store whole bytes */
 7242 tgl@sss.pgh.pa.us        1573         [ +  + ]:CBC        5875 :     while (destbitsleft >= 8)
                               1574                 :                :     {
                               1575                 :           4370 :         *r++ = (bits8) ((a >> (destbitsleft - 8)) & BITMASK);
                               1576                 :           4370 :         destbitsleft -= 8;
                               1577                 :                :     }
                               1578                 :                :     /* store last fractional byte */
                               1579         [ +  + ]:           1505 :     if (destbitsleft > 0)
                               1580                 :            330 :         *r = (bits8) ((a << (8 - destbitsleft)) & BITMASK);
                               1581                 :                : 
 8637                          1582                 :           1505 :     PG_RETURN_VARBIT_P(result);
                               1583                 :                : }
                               1584                 :                : 
                               1585                 :                : Datum
                               1586                 :            943 : bittoint4(PG_FUNCTION_ARGS)
                               1587                 :                : {
                               1588                 :            943 :     VarBit     *arg = PG_GETARG_VARBIT_P(0);
                               1589                 :                :     uint32      result;
                               1590                 :                :     bits8      *r;
                               1591                 :                : 
                               1592                 :                :     /* Check that the bit string is not too long */
 7242                          1593         [ -  + ]:            943 :     if (VARBITLEN(arg) > sizeof(result) * BITS_PER_BYTE)
 7567 tgl@sss.pgh.pa.us        1594         [ #  # ]:UBC           0 :         ereport(ERROR,
                               1595                 :                :                 (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
                               1596                 :                :                  errmsg("integer out of range")));
                               1597                 :                : 
 8637 tgl@sss.pgh.pa.us        1598                 :CBC         943 :     result = 0;
                               1599         [ +  + ]:           4610 :     for (r = VARBITS(arg); r < VARBITEND(arg); r++)
                               1600                 :                :     {
 8632                          1601                 :           3667 :         result <<= BITS_PER_BYTE;
 8637                          1602                 :           3667 :         result |= *r;
                               1603                 :                :     }
                               1604                 :                :     /* Now shift the result to take account of the padding at the end */
                               1605                 :            943 :     result >>= VARBITPAD(arg);
                               1606                 :                : 
                               1607                 :            943 :     PG_RETURN_INT32(result);
                               1608                 :                : }
                               1609                 :                : 
                               1610                 :                : Datum
 7924 lockhart@fourpalms.o     1611                 :            848 : bitfromint8(PG_FUNCTION_ARGS)
                               1612                 :                : {
                               1613                 :            848 :     int64       a = PG_GETARG_INT64(0);
 7242 tgl@sss.pgh.pa.us        1614                 :            848 :     int32       typmod = PG_GETARG_INT32(1);
                               1615                 :                :     VarBit     *result;
                               1616                 :                :     bits8      *r;
                               1617                 :                :     int         rlen;
                               1618                 :                :     int         destbitsleft,
                               1619                 :                :                 srcbitsleft;
                               1620                 :                : 
 2739                          1621   [ +  -  -  + ]:            848 :     if (typmod <= 0 || typmod > VARBITMAXLEN)
 7242 tgl@sss.pgh.pa.us        1622                 :UBC           0 :         typmod = 1;             /* default bit length */
                               1623                 :                : 
 7242 tgl@sss.pgh.pa.us        1624                 :CBC         848 :     rlen = VARBITTOTALLEN(typmod);
                               1625                 :            848 :     result = (VarBit *) palloc(rlen);
 6256                          1626                 :            848 :     SET_VARSIZE(result, rlen);
 7242                          1627                 :            848 :     VARBITLEN(result) = typmod;
                               1628                 :                : 
                               1629                 :            848 :     r = VARBITS(result);
                               1630                 :            848 :     destbitsleft = typmod;
                               1631                 :            848 :     srcbitsleft = 64;
                               1632                 :                :     /* drop any input bits that don't fit */
                               1633                 :            848 :     srcbitsleft = Min(srcbitsleft, destbitsleft);
                               1634                 :                :     /* sign-fill any excess bytes in output */
                               1635         [ -  + ]:            848 :     while (destbitsleft >= srcbitsleft + 8)
                               1636                 :                :     {
 7242 tgl@sss.pgh.pa.us        1637         [ #  # ]:UBC           0 :         *r++ = (bits8) ((a < 0) ? BITMASK : 0);
                               1638                 :              0 :         destbitsleft -= 8;
                               1639                 :                :     }
                               1640                 :                :     /* store first fractional byte */
 7242 tgl@sss.pgh.pa.us        1641         [ -  + ]:CBC         848 :     if (destbitsleft > srcbitsleft)
                               1642                 :                :     {
 2128 tgl@sss.pgh.pa.us        1643                 :UBC           0 :         unsigned int val = (unsigned int) (a >> (destbitsleft - 8));
                               1644                 :                : 
                               1645                 :                :         /* Force sign-fill in case the compiler implements >> as zero-fill */
 5237                          1646         [ #  # ]:              0 :         if (a < 0)
 2128                          1647                 :              0 :             val |= ((unsigned int) -1) << (srcbitsleft + 8 - destbitsleft);
 5237                          1648                 :              0 :         *r++ = (bits8) (val & BITMASK);
 7242                          1649                 :              0 :         destbitsleft -= 8;
                               1650                 :                :     }
                               1651                 :                :     /* Now srcbitsleft and destbitsleft are the same, need not track both */
                               1652                 :                :     /* store whole bytes */
 7242 tgl@sss.pgh.pa.us        1653         [ +  + ]:CBC        4240 :     while (destbitsleft >= 8)
                               1654                 :                :     {
                               1655                 :           3392 :         *r++ = (bits8) ((a >> (destbitsleft - 8)) & BITMASK);
                               1656                 :           3392 :         destbitsleft -= 8;
                               1657                 :                :     }
                               1658                 :                :     /* store last fractional byte */
                               1659         [ -  + ]:            848 :     if (destbitsleft > 0)
 7242 tgl@sss.pgh.pa.us        1660                 :UBC           0 :         *r = (bits8) ((a << (8 - destbitsleft)) & BITMASK);
                               1661                 :                : 
 7242 tgl@sss.pgh.pa.us        1662                 :CBC         848 :     PG_RETURN_VARBIT_P(result);
                               1663                 :                : }
                               1664                 :                : 
                               1665                 :                : Datum
 7924 lockhart@fourpalms.o     1666                 :            685 : bittoint8(PG_FUNCTION_ARGS)
                               1667                 :                : {
                               1668                 :            685 :     VarBit     *arg = PG_GETARG_VARBIT_P(0);
                               1669                 :                :     uint64      result;
                               1670                 :                :     bits8      *r;
                               1671                 :                : 
                               1672                 :                :     /* Check that the bit string is not too long */
                               1673         [ -  + ]:            685 :     if (VARBITLEN(arg) > sizeof(result) * BITS_PER_BYTE)
 7567 tgl@sss.pgh.pa.us        1674         [ #  # ]:UBC           0 :         ereport(ERROR,
                               1675                 :                :                 (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
                               1676                 :                :                  errmsg("bigint out of range")));
                               1677                 :                : 
 7924 lockhart@fourpalms.o     1678                 :CBC         685 :     result = 0;
                               1679         [ +  + ]:           6165 :     for (r = VARBITS(arg); r < VARBITEND(arg); r++)
                               1680                 :                :     {
                               1681                 :           5480 :         result <<= BITS_PER_BYTE;
                               1682                 :           5480 :         result |= *r;
                               1683                 :                :     }
                               1684                 :                :     /* Now shift the result to take account of the padding at the end */
                               1685                 :            685 :     result >>= VARBITPAD(arg);
                               1686                 :                : 
                               1687                 :            685 :     PG_RETURN_INT64(result);
                               1688                 :                : }
                               1689                 :                : 
                               1690                 :                : 
                               1691                 :                : /*
                               1692                 :                :  * Determines the position of S2 in the bitstring S1 (1-based string).
                               1693                 :                :  * If S2 does not appear in S1 this function returns 0.
                               1694                 :                :  * If S2 is of length 0 this function returns 1.
                               1695                 :                :  * Compatible in usage with POSITION() functions for other data types.
                               1696                 :                :  */
                               1697                 :                : Datum
 8566 peter_e@gmx.net          1698                 :            306 : bitposition(PG_FUNCTION_ARGS)
                               1699                 :                : {
 7924 lockhart@fourpalms.o     1700                 :            306 :     VarBit     *str = PG_GETARG_VARBIT_P(0);
 8424 bruce@momjian.us         1701                 :            306 :     VarBit     *substr = PG_GETARG_VARBIT_P(1);
                               1702                 :                :     int         substr_length,
                               1703                 :                :                 str_length,
                               1704                 :                :                 i,
                               1705                 :                :                 is;
                               1706                 :                :     bits8      *s,              /* pointer into substring */
                               1707                 :                :                *p;              /* pointer into str */
                               1708                 :                :     bits8       cmp,            /* shifted substring byte to compare */
                               1709                 :                :                 mask1,          /* mask for substring byte shifted right */
                               1710                 :                :                 mask2,          /* mask for substring byte shifted left */
                               1711                 :                :                 end_mask,       /* pad mask for last substring byte */
                               1712                 :                :                 str_mask;       /* pad mask for last string byte */
                               1713                 :                :     bool        is_match;
                               1714                 :                : 
                               1715                 :                :     /* Get the substring length */
 8566 peter_e@gmx.net          1716                 :            306 :     substr_length = VARBITLEN(substr);
 7924 lockhart@fourpalms.o     1717                 :            306 :     str_length = VARBITLEN(str);
                               1718                 :                : 
                               1719                 :                :     /* String has zero length or substring longer than string, return 0 */
                               1720   [ +  +  +  + ]:            306 :     if ((str_length == 0) || (substr_length > str_length))
 8424 bruce@momjian.us         1721                 :             12 :         PG_RETURN_INT32(0);
                               1722                 :                : 
                               1723                 :                :     /* zero-length substring means return 1 */
 8566 peter_e@gmx.net          1724         [ +  + ]:            294 :     if (substr_length == 0)
                               1725                 :              3 :         PG_RETURN_INT32(1);
                               1726                 :                : 
                               1727                 :                :     /* Initialise the padding masks */
                               1728                 :            291 :     end_mask = BITMASK << VARBITPAD(substr);
 7924 lockhart@fourpalms.o     1729                 :            291 :     str_mask = BITMASK << VARBITPAD(str);
                               1730         [ +  + ]:            468 :     for (i = 0; i < VARBITBYTES(str) - VARBITBYTES(substr) + 1; i++)
                               1731                 :                :     {
 8424 bruce@momjian.us         1732         [ +  + ]:           2568 :         for (is = 0; is < BITS_PER_BYTE; is++)
                               1733                 :                :         {
 8566 peter_e@gmx.net          1734                 :           2391 :             is_match = true;
 7924 lockhart@fourpalms.o     1735                 :           2391 :             p = VARBITS(str) + i;
 8566 peter_e@gmx.net          1736                 :           2391 :             mask1 = BITMASK >> is;
                               1737                 :           2391 :             mask2 = ~mask1;
 8424 bruce@momjian.us         1738                 :           2391 :             for (s = VARBITS(substr);
                               1739   [ +  +  +  + ]:           2670 :                  is_match && s < VARBITEND(substr); s++)
                               1740                 :                :             {
 8566 peter_e@gmx.net          1741                 :           2496 :                 cmp = *s >> is;
 8424 bruce@momjian.us         1742         [ +  + ]:           2496 :                 if (s == VARBITEND(substr) - 1)
                               1743                 :                :                 {
 8566 peter_e@gmx.net          1744                 :           1887 :                     mask1 &= end_mask >> is;
 7924 lockhart@fourpalms.o     1745         [ +  + ]:           1887 :                     if (p == VARBITEND(str) - 1)
                               1746                 :                :                     {
                               1747                 :                :                         /* Check that there is enough of str left */
                               1748         [ +  + ]:            495 :                         if (mask1 & ~str_mask)
                               1749                 :                :                         {
 8566 peter_e@gmx.net          1750                 :             30 :                             is_match = false;
                               1751                 :             30 :                             break;
                               1752                 :                :                         }
 7924 lockhart@fourpalms.o     1753                 :            465 :                         mask1 &= str_mask;
                               1754                 :                :                     }
                               1755                 :                :                 }
 8566 peter_e@gmx.net          1756                 :           2466 :                 is_match = ((cmp ^ *p) & mask1) == 0;
                               1757         [ +  + ]:           2466 :                 if (!is_match)
                               1758                 :           2025 :                     break;
                               1759                 :                :                 /* Move on to the next byte */
                               1760                 :            441 :                 p++;
 7924 lockhart@fourpalms.o     1761         [ +  + ]:            441 :                 if (p == VARBITEND(str))
                               1762                 :                :                 {
 8566 peter_e@gmx.net          1763                 :            162 :                     mask2 = end_mask << (BITS_PER_BYTE - is);
                               1764                 :            162 :                     is_match = mask2 == 0;
                               1765                 :                : #if 0
                               1766                 :                :                     elog(DEBUG4, "S. %d %d em=%2x sm=%2x r=%d",
                               1767                 :                :                          i, is, end_mask, mask2, is_match);
                               1768                 :                : #endif
                               1769                 :            162 :                     break;
                               1770                 :                :                 }
                               1771                 :            279 :                 cmp = *s << (BITS_PER_BYTE - is);
 8424 bruce@momjian.us         1772         [ +  + ]:            279 :                 if (s == VARBITEND(substr) - 1)
                               1773                 :                :                 {
 8566 peter_e@gmx.net          1774                 :            117 :                     mask2 &= end_mask << (BITS_PER_BYTE - is);
 7924 lockhart@fourpalms.o     1775         [ +  + ]:            117 :                     if (p == VARBITEND(str) - 1)
                               1776                 :                :                     {
                               1777         [ -  + ]:            114 :                         if (mask2 & ~str_mask)
                               1778                 :                :                         {
 8566 peter_e@gmx.net          1779                 :UBC           0 :                             is_match = false;
                               1780                 :              0 :                             break;
                               1781                 :                :                         }
 7924 lockhart@fourpalms.o     1782                 :CBC         114 :                         mask2 &= str_mask;
                               1783                 :                :                     }
                               1784                 :                :                 }
 8566 peter_e@gmx.net          1785                 :            279 :                 is_match = ((cmp ^ *p) & mask2) == 0;
                               1786                 :                :             }
                               1787                 :                :             /* Have we found a match? */
                               1788         [ +  + ]:           2391 :             if (is_match)
 8424 bruce@momjian.us         1789                 :            243 :                 PG_RETURN_INT32(i * BITS_PER_BYTE + is + 1);
                               1790                 :                :         }
                               1791                 :                :     }
 8566 peter_e@gmx.net          1792                 :             48 :     PG_RETURN_INT32(0);
                               1793                 :                : }
                               1794                 :                : 
                               1795                 :                : 
                               1796                 :                : /*
                               1797                 :                :  * bitsetbit
                               1798                 :                :  *
                               1799                 :                :  * Given an instance of type 'bit' creates a new one with
                               1800                 :                :  * the Nth bit set to the given value.
                               1801                 :                :  *
                               1802                 :                :  * The bit location is specified left-to-right in a zero-based fashion
                               1803                 :                :  * consistent with the other get_bit and set_bit functions, but
                               1804                 :                :  * inconsistent with the standard substring, position, overlay functions
                               1805                 :                :  */
                               1806                 :                : Datum
 5193 tgl@sss.pgh.pa.us        1807                 :              6 : bitsetbit(PG_FUNCTION_ARGS)
                               1808                 :                : {
                               1809                 :              6 :     VarBit     *arg1 = PG_GETARG_VARBIT_P(0);
                               1810                 :              6 :     int32       n = PG_GETARG_INT32(1);
                               1811                 :              6 :     int32       newBit = PG_GETARG_INT32(2);
                               1812                 :                :     VarBit     *result;
                               1813                 :                :     int         len,
                               1814                 :                :                 bitlen;
                               1815                 :                :     bits8      *r,
                               1816                 :                :                *p;
                               1817                 :                :     int         byteNo,
                               1818                 :                :                 bitNo;
                               1819                 :                : 
                               1820                 :              6 :     bitlen = VARBITLEN(arg1);
                               1821   [ +  -  +  + ]:              6 :     if (n < 0 || n >= bitlen)
                               1822         [ +  - ]:              3 :         ereport(ERROR,
                               1823                 :                :                 (errcode(ERRCODE_ARRAY_SUBSCRIPT_ERROR),
                               1824                 :                :                  errmsg("bit index %d out of valid range (0..%d)",
                               1825                 :                :                         n, bitlen - 1)));
                               1826                 :                : 
                               1827                 :                :     /*
                               1828                 :                :      * sanity check!
                               1829                 :                :      */
                               1830   [ +  -  -  + ]:              3 :     if (newBit != 0 && newBit != 1)
 5193 tgl@sss.pgh.pa.us        1831         [ #  # ]:UBC           0 :         ereport(ERROR,
                               1832                 :                :                 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
                               1833                 :                :                  errmsg("new bit must be 0 or 1")));
                               1834                 :                : 
 5193 tgl@sss.pgh.pa.us        1835                 :CBC           3 :     len = VARSIZE(arg1);
                               1836                 :              3 :     result = (VarBit *) palloc(len);
                               1837                 :              3 :     SET_VARSIZE(result, len);
                               1838                 :              3 :     VARBITLEN(result) = bitlen;
                               1839                 :                : 
                               1840                 :              3 :     p = VARBITS(arg1);
                               1841                 :              3 :     r = VARBITS(result);
                               1842                 :                : 
                               1843                 :              3 :     memcpy(r, p, VARBITBYTES(arg1));
                               1844                 :                : 
                               1845                 :              3 :     byteNo = n / BITS_PER_BYTE;
                               1846                 :              3 :     bitNo = BITS_PER_BYTE - 1 - (n % BITS_PER_BYTE);
                               1847                 :                : 
                               1848                 :                :     /*
                               1849                 :                :      * Update the byte.
                               1850                 :                :      */
                               1851         [ -  + ]:              3 :     if (newBit == 0)
 5193 tgl@sss.pgh.pa.us        1852                 :UBC           0 :         r[byteNo] &= (~(1 << bitNo));
                               1853                 :                :     else
 5193 tgl@sss.pgh.pa.us        1854                 :CBC           3 :         r[byteNo] |= (1 << bitNo);
                               1855                 :                : 
                               1856                 :              3 :     PG_RETURN_VARBIT_P(result);
                               1857                 :                : }
                               1858                 :                : 
                               1859                 :                : /*
                               1860                 :                :  * bitgetbit
                               1861                 :                :  *
                               1862                 :                :  * returns the value of the Nth bit of a bit array (0 or 1).
                               1863                 :                :  *
                               1864                 :                :  * The bit location is specified left-to-right in a zero-based fashion
                               1865                 :                :  * consistent with the other get_bit and set_bit functions, but
                               1866                 :                :  * inconsistent with the standard substring, position, overlay functions
                               1867                 :                :  */
                               1868                 :                : Datum
                               1869                 :              3 : bitgetbit(PG_FUNCTION_ARGS)
                               1870                 :                : {
                               1871                 :              3 :     VarBit     *arg1 = PG_GETARG_VARBIT_P(0);
                               1872                 :              3 :     int32       n = PG_GETARG_INT32(1);
                               1873                 :                :     int         bitlen;
                               1874                 :                :     bits8      *p;
                               1875                 :                :     int         byteNo,
                               1876                 :                :                 bitNo;
                               1877                 :                : 
                               1878                 :              3 :     bitlen = VARBITLEN(arg1);
                               1879   [ +  -  -  + ]:              3 :     if (n < 0 || n >= bitlen)
 5193 tgl@sss.pgh.pa.us        1880         [ #  # ]:UBC           0 :         ereport(ERROR,
                               1881                 :                :                 (errcode(ERRCODE_ARRAY_SUBSCRIPT_ERROR),
                               1882                 :                :                  errmsg("bit index %d out of valid range (0..%d)",
                               1883                 :                :                         n, bitlen - 1)));
                               1884                 :                : 
 5193 tgl@sss.pgh.pa.us        1885                 :CBC           3 :     p = VARBITS(arg1);
                               1886                 :                : 
                               1887                 :              3 :     byteNo = n / BITS_PER_BYTE;
                               1888                 :              3 :     bitNo = BITS_PER_BYTE - 1 - (n % BITS_PER_BYTE);
                               1889                 :                : 
                               1890         [ +  - ]:              3 :     if (p[byteNo] & (1 << bitNo))
                               1891                 :              3 :         PG_RETURN_INT32(1);
                               1892                 :                :     else
 5193 tgl@sss.pgh.pa.us        1893                 :UBC           0 :         PG_RETURN_INT32(0);
                               1894                 :                : }
        

Generated by: LCOV version 2.1-beta2-3-g6141622