LCOV - differential code coverage report
Current view: top level - src/backend/utils/adt - varbit.c (source / functions) Coverage Total Hit UBC GNC CBC DCB
Current: 77aeca80249c9e640c811e80633a2e334a9320de vs 38afc3dcb25c45b744d4025029ce0a6c90b7059f Lines: 86.3 % 680 587 93 4 583 4
Current Date: 2026-07-25 19:08:27 +0900 Functions: 89.8 % 49 44 5 4 40
Baseline: lcov-20260725-baseline Branches: 63.5 % 496 315 181 8 307
Baseline Date: 2026-07-25 19:09:19 +0900 Line coverage date bins:
Legend: Lines:     hit not hit
Branches: + taken - not taken # not executed
(7,30] days: 100.0 % 4 4 4
(30,360] days: 60.0 % 20 12 8 12
(360..) days: 87.0 % 656 571 85 571
Function coverage date bins:
(360..) days: 89.8 % 49 44 5 4 40
Branch coverage date bins:
(7,30] days: 100.0 % 8 8 8
(30,360] days: 16.7 % 12 2 10 2
(360..) days: 64.1 % 476 305 171 305

 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-2026, 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
 7147 tgl@sss.pgh.pa.us          90                 :CBC        1439 : anybit_typmodin(ArrayType *ta, const char *typename)
                                 91                 :                : {
                                 92                 :                :     int32       typmod;
                                 93                 :                :     int32      *tl;
                                 94                 :                :     int         n;
                                 95                 :                : 
 6980                            96                 :           1439 :     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                 :                :      */
 7147                           102         [ -  + ]:           1439 :     if (n != 1)
 7147 tgl@sss.pgh.pa.us         103         [ #  # ]:UBC           0 :         ereport(ERROR,
                                104                 :                :                 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
                                105                 :                :                  errmsg("invalid type modifier")));
                                106                 :                : 
 7147 tgl@sss.pgh.pa.us         107         [ -  + ]:CBC        1439 :     if (*tl < 1)
 7147 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)));
 7147 tgl@sss.pgh.pa.us         112         [ -  + ]:CBC        1439 :     if (*tl > (MaxAttrSize * BITS_PER_BYTE))
 7147 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                 :                : 
 7147 tgl@sss.pgh.pa.us         118                 :CBC        1439 :     typmod = *tl;
                                119                 :                : 
                                120                 :           1439 :     return typmod;
                                121                 :                : }
                                122                 :                : 
                                123                 :                : /*
                                124                 :                :  * common code for bittypmodout and varbittypmodout
                                125                 :                :  */
                                126                 :                : static char *
                                127                 :            216 : anybit_typmodout(int32 typmod)
                                128                 :                : {
 6827 bruce@momjian.us          129                 :            216 :     char       *res = (char *) palloc(64);
                                130                 :                : 
 7147 tgl@sss.pgh.pa.us         131         [ +  - ]:            216 :     if (typmod >= 0)
                                132                 :            216 :         snprintf(res, 64, "(%d)", typmod);
                                133                 :                :     else
 7147 tgl@sss.pgh.pa.us         134                 :UBC           0 :         *res = '\0';
                                135                 :                : 
 7147 tgl@sss.pgh.pa.us         136                 :CBC         216 :     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
 9195 peter_e@gmx.net           147                 :           3624 : bit_in(PG_FUNCTION_ARGS)
                                148                 :                : {
 9380                           149                 :           3624 :     char       *input_string = PG_GETARG_CSTRING(0);
                                150                 :                : #ifdef NOT_USED
                                151                 :                :     Oid         typelem = PG_GETARG_OID(1);
                                152                 :                : #endif
 9469 tgl@sss.pgh.pa.us         153                 :           3624 :     int32       atttypmod = PG_GETARG_INT32(2);
 1319                           154                 :           3624 :     Node       *escontext = fcinfo->context;
                                155                 :                :     VarBit     *result;         /* The resulting bit string           */
                                156                 :                :     char       *sp;             /* pointer into the character string  */
                                157                 :                :     uint8      *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;
  117 nathan@postgresql.or      163                 :           3624 :     uint8       x = 0;
                                164                 :                : 
                                165                 :                :     /* Check that the first character is a b or an x */
 9380 peter_e@gmx.net           166   [ +  +  +  + ]:           3624 :     if (input_string[0] == 'b' || input_string[0] == 'B')
                                167                 :                :     {
 9469 tgl@sss.pgh.pa.us         168                 :            521 :         bit_not_hex = true;
 9380 peter_e@gmx.net           169                 :            521 :         sp = input_string + 1;
                                170                 :                :     }
                                171   [ +  +  +  + ]:           3103 :     else if (input_string[0] == 'x' || input_string[0] == 'X')
                                172                 :                :     {
 9469 tgl@sss.pgh.pa.us         173                 :           2304 :         bit_not_hex = false;
 9380 peter_e@gmx.net           174                 :           2304 :         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                 :            799 :         bit_not_hex = true;
                                183                 :            799 :         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                 :           3624 :     slen = strlen(sp);
 9469 tgl@sss.pgh.pa.us         191         [ +  + ]:           3624 :     if (bit_not_hex)
                                192                 :           1320 :         bitlen = slen;
                                193                 :                :     else
                                194                 :                :     {
 4541 noah@leadboat.com         195         [ -  + ]:           2304 :         if (slen > VARBITMAXLEN / 4)
 1319 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)));
 9469 tgl@sss.pgh.pa.us         200                 :CBC        2304 :         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         [ +  + ]:           3624 :     if (atttypmod <= 0)
 9600 bruce@momjian.us          208                 :           2900 :         atttypmod = bitlen;
 9195 peter_e@gmx.net           209         [ +  + ]:            724 :     else if (bitlen != atttypmod)
 1319 tgl@sss.pgh.pa.us         210         [ +  + ]:             16 :         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                 :                : 
 9469                           215                 :           3608 :     len = VARBITTOTALLEN(atttypmod);
                                216                 :                :     /* set to 0 so that *r is always initialised and string is zero-padded */
 8655 bruce@momjian.us          217                 :           3608 :     result = (VarBit *) palloc0(len);
 7088 tgl@sss.pgh.pa.us         218                 :           3608 :     SET_VARSIZE(result, len);
 9600 bruce@momjian.us          219                 :           3608 :     VARBITLEN(result) = atttypmod;
                                220                 :                : 
                                221                 :           3608 :     r = VARBITS(result);
                                222         [ +  + ]:           3608 :     if (bit_not_hex)
                                223                 :                :     {
                                224                 :                :         /* Parse the bit representation of the string */
                                225                 :                :         /* We know it fits, as bitlen was compared to atttypmod */
 7517                           226                 :           1304 :         x = HIGHBIT;
 9469 tgl@sss.pgh.pa.us         227         [ +  + ]:          38466 :         for (; *sp; sp++)
                                228                 :                :         {
 9600 bruce@momjian.us          229         [ +  + ]:          37178 :             if (*sp == '1')
                                230                 :          19051 :                 *r |= x;
 9469 tgl@sss.pgh.pa.us         231         [ +  + ]:          18127 :             else if (*sp != '0')
 1319                           232         [ +  + ]:             16 :                 ereturn(escontext, (Datum) 0,
                                233                 :                :                         (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
                                234                 :                :                          errmsg("\"%.*s\" is not a valid binary digit",
                                235                 :                :                                 pg_mblen_cstr(sp), sp)));
                                236                 :                : 
 9469                           237                 :          37162 :             x >>= 1;
                                238         [ +  + ]:          37162 :             if (x == 0)
                                239                 :                :             {
 7517 bruce@momjian.us          240                 :           4346 :                 x = HIGHBIT;
 9600                           241                 :           4346 :                 r++;
                                242                 :                :             }
                                243                 :                :         }
                                244                 :                :     }
                                245                 :                :     else
                                246                 :                :     {
                                247                 :                :         /* Parse the hex representation of the string */
 9469 tgl@sss.pgh.pa.us         248         [ +  + ]:          27119 :         for (bc = 0; *sp; sp++)
                                249                 :                :         {
 9600 bruce@momjian.us          250   [ +  +  +  + ]:          24831 :             if (*sp >= '0' && *sp <= '9')
  117 nathan@postgresql.or      251                 :          17083 :                 x = (uint8) (*sp - '0');
 9600 bruce@momjian.us          252   [ +  +  +  + ]:           7748 :             else if (*sp >= 'A' && *sp <= 'F')
  117 nathan@postgresql.or      253                 :            160 :                 x = (uint8) (*sp - 'A') + 10;
 9600 bruce@momjian.us          254   [ +  +  +  - ]:           7588 :             else if (*sp >= 'a' && *sp <= 'f')
  117 nathan@postgresql.or      255                 :           7572 :                 x = (uint8) (*sp - 'a') + 10;
                                256                 :                :             else
 1319 tgl@sss.pgh.pa.us         257         [ +  + ]:             16 :                 ereturn(escontext, (Datum) 0,
                                258                 :                :                         (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
                                259                 :                :                          errmsg("\"%.*s\" is not a valid hexadecimal digit",
                                260                 :                :                                 pg_mblen_cstr(sp), sp)));
                                261                 :                : 
 9600 bruce@momjian.us          262         [ +  + ]:          24815 :             if (bc)
                                263                 :                :             {
                                264                 :          12323 :                 *r++ |= x;
 9469 tgl@sss.pgh.pa.us         265                 :          12323 :                 bc = 0;
                                266                 :                :             }
                                267                 :                :             else
                                268                 :                :             {
 9600 bruce@momjian.us          269                 :          12492 :                 *r = x << 4;
 9469 tgl@sss.pgh.pa.us         270                 :          12492 :                 bc = 1;
                                271                 :                :             }
                                272                 :                :         }
                                273                 :                :     }
                                274                 :                : 
                                275                 :           3576 :     PG_RETURN_VARBIT_P(result);
                                276                 :                : }
                                277                 :                : 
                                278                 :                : 
                                279                 :                : Datum
 9195 peter_e@gmx.net           280                 :           2660 : bit_out(PG_FUNCTION_ARGS)
                                281                 :                : {
                                282                 :                : #if 1
                                283                 :                :     /* same as varbit output */
 9382                           284                 :           2660 :     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                 :                :     uint8      *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
 8475 tgl@sss.pgh.pa.us         331                 :UBC           0 : bit_recv(PG_FUNCTION_ARGS)
                                332                 :                : {
 7685                           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));
 3571                           344   [ #  #  #  # ]:              0 :     if (bitlen < 0 || bitlen > VARBITMAXLEN)
 7685                           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);
 7088                           361                 :              0 :     SET_VARSIZE(result, len);
 7685                           362                 :              0 :     VARBITLEN(result) = bitlen;
                                363                 :                : 
  517 peter@eisentraut.org      364                 :              0 :     pq_copymsgbytes(buf, VARBITS(result), VARBITBYTES(result));
                                365                 :                : 
                                366                 :                :     /* Make sure last byte is correctly zero-padded */
 2498 tgl@sss.pgh.pa.us         367   [ #  #  #  #  :              0 :     VARBIT_PAD(result);
                                              #  # ]
                                368                 :                : 
 7685                           369                 :              0 :     PG_RETURN_VARBIT_P(result);
                                370                 :                : }
                                371                 :                : 
                                372                 :                : /*
                                373                 :                :  *      bit_send            - converts bit to binary format
                                374                 :                :  */
                                375                 :                : Datum
 8475                           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
 9195 peter_e@gmx.net           391                 :CBC         701 : bit(PG_FUNCTION_ARGS)
                                392                 :                : {
 9469 tgl@sss.pgh.pa.us         393                 :            701 :     VarBit     *arg = PG_GETARG_VARBIT_P(0);
                                394                 :            701 :     int32       len = PG_GETARG_INT32(1);
 8711                           395                 :            701 :     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 */
 3571                           400   [ +  -  +  -  :            701 :     if (len <= 0 || len > VARBITMAXLEN || len == VARBITLEN(arg))
                                              +  + ]
 9469                           401                 :            286 :         PG_RETURN_VARBIT_P(arg);
                                402                 :                : 
 8711                           403         [ +  + ]:            415 :     if (!isExplicit)
  123 peter@eisentraut.org      404         [ +  - ]:             20 :         ereturn(fcinfo->context, (Datum) 0,
                                405                 :                :                 (errcode(ERRCODE_STRING_DATA_LENGTH_MISMATCH),
                                406                 :                :                  errmsg("bit string length %d does not match type bit(%d)",
                                407                 :                :                         VARBITLEN(arg), len)));
                                408                 :                : 
 8711 tgl@sss.pgh.pa.us         409                 :            395 :     rlen = VARBITTOTALLEN(len);
                                410                 :                :     /* set to 0 so that string is zero-padded */
 8655 bruce@momjian.us          411                 :            395 :     result = (VarBit *) palloc0(rlen);
 7088 tgl@sss.pgh.pa.us         412                 :            395 :     SET_VARSIZE(result, rlen);
 8711                           413                 :            395 :     VARBITLEN(result) = len;
                                414                 :                : 
                                415                 :            395 :     memcpy(VARBITS(result), VARBITS(arg),
                                416         [ -  + ]:            395 :            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                 :                :      */
 2498                           423   [ +  -  -  +  :            395 :     VARBIT_PAD(result);
                                              +  - ]
                                424                 :                : 
 8711                           425                 :            395 :     PG_RETURN_VARBIT_P(result);
                                426                 :                : }
                                427                 :                : 
                                428                 :                : Datum
 7147                           429                 :           1275 : bittypmodin(PG_FUNCTION_ARGS)
                                430                 :                : {
 6827 bruce@momjian.us          431                 :           1275 :     ArrayType  *ta = PG_GETARG_ARRAYTYPE_P(0);
                                432                 :                : 
 7147 tgl@sss.pgh.pa.us         433                 :           1275 :     PG_RETURN_INT32(anybit_typmodin(ta, "bit"));
                                434                 :                : }
                                435                 :                : 
                                436                 :                : Datum
                                437                 :            133 : bittypmodout(PG_FUNCTION_ARGS)
                                438                 :                : {
 6827 bruce@momjian.us          439                 :            133 :     int32       typmod = PG_GETARG_INT32(0);
                                440                 :                : 
 7147 tgl@sss.pgh.pa.us         441                 :            133 :     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
 9469                           452                 :           1036 : varbit_in(PG_FUNCTION_ARGS)
                                453                 :                : {
 9380 peter_e@gmx.net           454                 :           1036 :     char       *input_string = PG_GETARG_CSTRING(0);
                                455                 :                : #ifdef NOT_USED
                                456                 :                :     Oid         typelem = PG_GETARG_OID(1);
                                457                 :                : #endif
 9469 tgl@sss.pgh.pa.us         458                 :           1036 :     int32       atttypmod = PG_GETARG_INT32(2);
 1319                           459                 :           1036 :     Node       *escontext = fcinfo->context;
                                460                 :                :     VarBit     *result;         /* The resulting bit string           */
                                461                 :                :     char       *sp;             /* pointer into the character string  */
                                462                 :                :     uint8      *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;
  117 nathan@postgresql.or      468                 :           1036 :     uint8       x = 0;
                                469                 :                : 
                                470                 :                :     /* Check that the first character is a b or an x */
 9380 peter_e@gmx.net           471   [ +  -  -  + ]:           1036 :     if (input_string[0] == 'b' || input_string[0] == 'B')
                                472                 :                :     {
 9469 tgl@sss.pgh.pa.us         473                 :UBC           0 :         bit_not_hex = true;
 9380 peter_e@gmx.net           474                 :              0 :         sp = input_string + 1;
                                475                 :                :     }
 9380 peter_e@gmx.net           476   [ +  +  +  + ]:CBC        1036 :     else if (input_string[0] == 'x' || input_string[0] == 'X')
                                477                 :                :     {
 9469 tgl@sss.pgh.pa.us         478                 :             88 :         bit_not_hex = false;
 9380 peter_e@gmx.net           479                 :             88 :         sp = input_string + 1;
                                480                 :                :     }
                                481                 :                :     else
                                482                 :                :     {
                                483                 :            948 :         bit_not_hex = true;
                                484                 :            948 :         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                 :           1036 :     slen = strlen(sp);
 9469 tgl@sss.pgh.pa.us         492         [ +  + ]:           1036 :     if (bit_not_hex)
                                493                 :            948 :         bitlen = slen;
                                494                 :                :     else
                                495                 :                :     {
 4541 noah@leadboat.com         496         [ -  + ]:             88 :         if (slen > VARBITMAXLEN / 4)
 1319 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)));
 9469 tgl@sss.pgh.pa.us         501                 :CBC          88 :         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         [ +  + ]:           1036 :     if (atttypmod <= 0)
                                509                 :            948 :         atttypmod = bitlen;
 9195 peter_e@gmx.net           510         [ +  + ]:             88 :     else if (bitlen > atttypmod)
 1319 tgl@sss.pgh.pa.us         511         [ -  + ]:              8 :         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                 :                : 
 9469                           516                 :           1028 :     len = VARBITTOTALLEN(bitlen);
                                517                 :                :     /* set to 0 so that *r is always initialised and string is zero-padded */
 8655 bruce@momjian.us          518                 :           1028 :     result = (VarBit *) palloc0(len);
 7088 tgl@sss.pgh.pa.us         519                 :           1028 :     SET_VARSIZE(result, len);
 9469                           520                 :           1028 :     VARBITLEN(result) = Min(bitlen, atttypmod);
                                521                 :                : 
 9600 bruce@momjian.us          522                 :           1028 :     r = VARBITS(result);
                                523         [ +  + ]:           1028 :     if (bit_not_hex)
                                524                 :                :     {
                                525                 :                :         /* Parse the bit representation of the string */
                                526                 :                :         /* We know it fits, as bitlen was compared to atttypmod */
 7517                           527                 :            940 :         x = HIGHBIT;
 9469 tgl@sss.pgh.pa.us         528         [ +  + ]:          33989 :         for (; *sp; sp++)
                                529                 :                :         {
 9600 bruce@momjian.us          530         [ +  + ]:          33057 :             if (*sp == '1')
                                531                 :          16479 :                 *r |= x;
 9469 tgl@sss.pgh.pa.us         532         [ +  + ]:          16578 :             else if (*sp != '0')
 1319                           533         [ +  + ]:              8 :                 ereturn(escontext, (Datum) 0,
                                534                 :                :                         (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
                                535                 :                :                          errmsg("\"%.*s\" is not a valid binary digit",
                                536                 :                :                                 pg_mblen_cstr(sp), sp)));
                                537                 :                : 
 9469                           538                 :          33049 :             x >>= 1;
                                539         [ +  + ]:          33049 :             if (x == 0)
                                540                 :                :             {
 7517 bruce@momjian.us          541                 :           3793 :                 x = HIGHBIT;
 9600                           542                 :           3793 :                 r++;
                                543                 :                :             }
                                544                 :                :         }
                                545                 :                :     }
                                546                 :                :     else
                                547                 :                :     {
                                548                 :                :         /* Parse the hex representation of the string */
 9469 tgl@sss.pgh.pa.us         549         [ +  + ]:            368 :         for (bc = 0; *sp; sp++)
                                550                 :                :         {
 9600 bruce@momjian.us          551   [ +  -  +  + ]:            288 :             if (*sp >= '0' && *sp <= '9')
  117 nathan@postgresql.or      552                 :            212 :                 x = (uint8) (*sp - '0');
 9600 bruce@momjian.us          553   [ +  -  +  + ]:             76 :             else if (*sp >= 'A' && *sp <= 'F')
  117 nathan@postgresql.or      554                 :             68 :                 x = (uint8) (*sp - 'A') + 10;
 9600 bruce@momjian.us          555   [ -  +  -  - ]:              8 :             else if (*sp >= 'a' && *sp <= 'f')
  117 nathan@postgresql.or      556                 :UBC           0 :                 x = (uint8) (*sp - 'a') + 10;
                                557                 :                :             else
 1319 tgl@sss.pgh.pa.us         558         [ +  + ]:CBC           8 :                 ereturn(escontext, (Datum) 0,
                                559                 :                :                         (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
                                560                 :                :                          errmsg("\"%.*s\" is not a valid hexadecimal digit",
                                561                 :                :                                 pg_mblen_cstr(sp), sp)));
                                562                 :                : 
 9600 bruce@momjian.us          563         [ +  + ]:            280 :             if (bc)
                                564                 :                :             {
                                565                 :            136 :                 *r++ |= x;
 9469 tgl@sss.pgh.pa.us         566                 :            136 :                 bc = 0;
                                567                 :                :             }
                                568                 :                :             else
                                569                 :                :             {
 9600 bruce@momjian.us          570                 :            144 :                 *r = x << 4;
 9469 tgl@sss.pgh.pa.us         571                 :            144 :                 bc = 1;
                                572                 :                :             }
                                573                 :                :         }
                                574                 :                :     }
                                575                 :                : 
                                576                 :           1012 :     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                 :           3818 : varbit_out(PG_FUNCTION_ARGS)
                                588                 :                : {
                                589                 :           3818 :     VarBit     *s = PG_GETARG_VARBIT_P(0);
                                590                 :                :     char       *result,
                                591                 :                :                *r;
                                592                 :                :     uint8      *sp;
                                593                 :                :     uint8       x;
                                594                 :                :     int         i,
                                595                 :                :                 k,
                                596                 :                :                 len;
                                597                 :                : 
                                598                 :                :     /* Assertion to help catch any bit functions that don't pad correctly */
 2498                           599   [ +  -  -  +  :           3818 :     VARBIT_CORRECTLY_PADDED(s);
                                        +  +  -  + ]
                                600                 :                : 
 9469                           601                 :           3818 :     len = VARBITLEN(s);
 9380 peter_e@gmx.net           602                 :           3818 :     result = (char *) palloc(len + 1);
 9469 tgl@sss.pgh.pa.us         603                 :           3818 :     sp = VARBITS(s);
                                604                 :           3818 :     r = result;
 6913                           605         [ +  + ]:           8937 :     for (i = 0; i <= len - BITS_PER_BYTE; i += BITS_PER_BYTE, sp++)
                                606                 :                :     {
                                607                 :                :         /* print full bytes */
 9469                           608                 :           5119 :         x = *sp;
 9464                           609         [ +  + ]:          46071 :         for (k = 0; k < BITS_PER_BYTE; k++)
                                610                 :                :         {
 7517 bruce@momjian.us          611         [ +  + ]:          40952 :             *r++ = IS_HIGHBIT_SET(x) ? '1' : '0';
 9469 tgl@sss.pgh.pa.us         612                 :          40952 :             x <<= 1;
                                613                 :                :         }
                                614                 :                :     }
 6913                           615         [ +  + ]:           3818 :     if (i < len)
                                616                 :                :     {
                                617                 :                :         /* print the last partial byte */
                                618                 :           1810 :         x = *sp;
                                619         [ +  + ]:           9022 :         for (k = i; k < len; k++)
                                620                 :                :         {
                                621         [ +  + ]:           7212 :             *r++ = IS_HIGHBIT_SET(x) ? '1' : '0';
                                622                 :           7212 :             x <<= 1;
                                623                 :                :         }
                                624                 :                :     }
 9469                           625                 :           3818 :     *r = '\0';
                                626                 :                : 
                                627                 :           3818 :     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
 8475 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
 7685                           643                 :              0 :     int32       atttypmod = PG_GETARG_INT32(2);
                                644                 :                :     VarBit     *result;
                                645                 :                :     int         len,
                                646                 :                :                 bitlen;
                                647                 :                : 
 8475                           648                 :              0 :     bitlen = pq_getmsgint(buf, sizeof(int32));
 3571                           649   [ #  #  #  # ]:              0 :     if (bitlen < 0 || bitlen > VARBITMAXLEN)
 8399                           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                 :                :      */
 7685                           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                 :                : 
 8475                           664                 :              0 :     len = VARBITTOTALLEN(bitlen);
                                665                 :              0 :     result = (VarBit *) palloc(len);
 7088                           666                 :              0 :     SET_VARSIZE(result, len);
 8475                           667                 :              0 :     VARBITLEN(result) = bitlen;
                                668                 :                : 
  517 peter@eisentraut.org      669                 :              0 :     pq_copymsgbytes(buf, VARBITS(result), VARBITBYTES(result));
                                670                 :                : 
                                671                 :                :     /* Make sure last byte is correctly zero-padded */
 2498 tgl@sss.pgh.pa.us         672   [ #  #  #  #  :              0 :     VARBIT_PAD(result);
                                              #  # ]
                                673                 :                : 
 8475                           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);
 3209 andres@anarazel.de        687                 :              0 :     pq_sendint32(&buf, VARBITLEN(s));
 1257 peter@eisentraut.org      688                 :              0 :     pq_sendbytes(&buf, VARBITS(s), VARBITBYTES(s));
 8475 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
 2723 tgl@sss.pgh.pa.us         702                 :CBC         100 : varbit_support(PG_FUNCTION_ARGS)
                                703                 :                : {
                                704                 :            100 :     Node       *rawreq = (Node *) PG_GETARG_POINTER(0);
 5282 rhaas@postgresql.org      705                 :            100 :     Node       *ret = NULL;
                                706                 :                : 
 2723 tgl@sss.pgh.pa.us         707         [ +  + ]:            100 :     if (IsA(rawreq, SupportRequestSimplify))
                                708                 :                :     {
                                709                 :             50 :         SupportRequestSimplify *req = (SupportRequestSimplify *) rawreq;
                                710                 :             50 :         FuncExpr   *expr = req->fcall;
                                711                 :                :         Node       *typmod;
                                712                 :                : 
                                713         [ -  + ]:             50 :         Assert(list_length(expr->args) >= 2);
                                714                 :                : 
                                715                 :             50 :         typmod = (Node *) lsecond(expr->args);
                                716                 :                : 
 2261                           717   [ +  -  +  - ]:             50 :         if (IsA(typmod, Const) && !((Const *) typmod)->constisnull)
                                718                 :                :         {
 2723                           719                 :             50 :             Node       *source = (Node *) linitial(expr->args);
                                720                 :             50 :             int32       new_typmod = DatumGetInt32(((Const *) typmod)->constvalue);
                                721                 :             50 :             int32       old_max = exprTypmod(source);
                                722                 :             50 :             int32       new_max = new_typmod;
                                723                 :                : 
                                724                 :                :             /* Note: varbit() treats typmod 0 as invalid, so we do too */
                                725   [ +  -  -  +  :             50 :             if (new_max <= 0 || (old_max > 0 && old_max <= new_max))
                                              -  - ]
 2723 tgl@sss.pgh.pa.us         726                 :UBC           0 :                 ret = relabel_to_typmod(source, new_typmod);
                                727                 :                :         }
                                728                 :                :     }
                                729                 :                : 
 5282 rhaas@postgresql.org      730                 :CBC         100 :     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
 9469 tgl@sss.pgh.pa.us         742                 :            693 : varbit(PG_FUNCTION_ARGS)
                                743                 :                : {
                                744                 :            693 :     VarBit     *arg = PG_GETARG_VARBIT_P(0);
                                745                 :            693 :     int32       len = PG_GETARG_INT32(1);
 8711                           746                 :            693 :     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 */
 9469                           751   [ +  -  +  + ]:            693 :     if (len <= 0 || len >= VARBITLEN(arg))
                                752                 :            685 :         PG_RETURN_VARBIT_P(arg);
                                753                 :                : 
 8711                           754         [ +  - ]:              8 :     if (!isExplicit)
  123 peter@eisentraut.org      755         [ +  - ]:              8 :         ereturn(fcinfo->context, (Datum) 0,
                                756                 :                :                 (errcode(ERRCODE_STRING_DATA_RIGHT_TRUNCATION),
                                757                 :                :                  errmsg("bit string too long for type bit varying(%d)",
                                758                 :                :                         len)));
                                759                 :                : 
 9469 tgl@sss.pgh.pa.us         760                 :UBC           0 :     rlen = VARBITTOTALLEN(len);
                                761                 :              0 :     result = (VarBit *) palloc(rlen);
 7088                           762                 :              0 :     SET_VARSIZE(result, rlen);
 9469                           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 */
 2498                           768   [ #  #  #  #  :              0 :     VARBIT_PAD(result);
                                              #  # ]
                                769                 :                : 
 8711                           770                 :              0 :     PG_RETURN_VARBIT_P(result);
                                771                 :                : }
                                772                 :                : 
                                773                 :                : Datum
 7147 tgl@sss.pgh.pa.us         774                 :CBC         164 : varbittypmodin(PG_FUNCTION_ARGS)
                                775                 :                : {
 6827 bruce@momjian.us          776                 :            164 :     ArrayType  *ta = PG_GETARG_ARRAYTYPE_P(0);
                                777                 :                : 
 7147 tgl@sss.pgh.pa.us         778                 :            164 :     PG_RETURN_INT32(anybit_typmodin(ta, "varbit"));
                                779                 :                : }
                                780                 :                : 
                                781                 :                : Datum
                                782                 :             83 : varbittypmodout(PG_FUNCTION_ARGS)
                                783                 :                : {
 6827 bruce@momjian.us          784                 :             83 :     int32       typmod = PG_GETARG_INT32(0);
                                785                 :                : 
 7147 tgl@sss.pgh.pa.us         786                 :             83 :     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
 9214                           818                 :          36966 : bit_cmp(VarBit *arg1, VarBit *arg2)
                                819                 :                : {
                                820                 :                :     int         bitlen1,
                                821                 :                :                 bytelen1,
                                822                 :                :                 bitlen2,
                                823                 :                :                 bytelen2;
                                824                 :                :     int32       cmp;
                                825                 :                : 
                                826                 :          36966 :     bytelen1 = VARBITBYTES(arg1);
                                827                 :          36966 :     bytelen2 = VARBITBYTES(arg2);
                                828                 :                : 
                                829                 :          36966 :     cmp = memcmp(VARBITS(arg1), VARBITS(arg2), Min(bytelen1, bytelen2));
                                830         [ +  + ]:          36966 :     if (cmp == 0)
                                831                 :                :     {
                                832                 :           4249 :         bitlen1 = VARBITLEN(arg1);
                                833                 :           4249 :         bitlen2 = VARBITLEN(arg2);
                                834         [ +  + ]:           4249 :         if (bitlen1 != bitlen2)
                                835         [ +  + ]:            107 :             cmp = (bitlen1 < bitlen2) ? -1 : 1;
                                836                 :                :     }
                                837                 :          36966 :     return cmp;
                                838                 :                : }
                                839                 :                : 
                                840                 :                : Datum
 9469                           841                 :           3059 : biteq(PG_FUNCTION_ARGS)
                                842                 :                : {
                                843                 :           3059 :     VarBit     *arg1 = PG_GETARG_VARBIT_P(0);
                                844                 :           3059 :     VarBit     *arg2 = PG_GETARG_VARBIT_P(1);
                                845                 :                :     bool        result;
                                846                 :                :     int         bitlen1,
                                847                 :                :                 bitlen2;
                                848                 :                : 
 9600 bruce@momjian.us          849                 :           3059 :     bitlen1 = VARBITLEN(arg1);
                                850                 :           3059 :     bitlen2 = VARBITLEN(arg2);
                                851                 :                : 
                                852                 :                :     /* fast path for different-length inputs */
                                853         [ +  + ]:           3059 :     if (bitlen1 != bitlen2)
 9469 tgl@sss.pgh.pa.us         854                 :            743 :         result = false;
                                855                 :                :     else
 9214                           856                 :           2316 :         result = (bit_cmp(arg1, arg2) == 0);
                                857                 :                : 
 9469                           858         [ +  + ]:           3059 :     PG_FREE_IF_COPY(arg1, 0);
                                859         [ +  + ]:           3059 :     PG_FREE_IF_COPY(arg2, 1);
                                860                 :                : 
                                861                 :           3059 :     PG_RETURN_BOOL(result);
                                862                 :                : }
                                863                 :                : 
                                864                 :                : Datum
                                865                 :            665 : bitne(PG_FUNCTION_ARGS)
                                866                 :                : {
                                867                 :            665 :     VarBit     *arg1 = PG_GETARG_VARBIT_P(0);
                                868                 :            665 :     VarBit     *arg2 = PG_GETARG_VARBIT_P(1);
                                869                 :                :     bool        result;
                                870                 :                :     int         bitlen1,
                                871                 :                :                 bitlen2;
                                872                 :                : 
 9600 bruce@momjian.us          873                 :            665 :     bitlen1 = VARBITLEN(arg1);
                                874                 :            665 :     bitlen2 = VARBITLEN(arg2);
                                875                 :                : 
                                876                 :                :     /* fast path for different-length inputs */
                                877         [ +  + ]:            665 :     if (bitlen1 != bitlen2)
 9469 tgl@sss.pgh.pa.us         878                 :              4 :         result = true;
                                879                 :                :     else
 9214                           880                 :            661 :         result = (bit_cmp(arg1, arg2) != 0);
                                881                 :                : 
 9469                           882         [ +  + ]:            665 :     PG_FREE_IF_COPY(arg1, 0);
                                883         [ +  + ]:            665 :     PG_FREE_IF_COPY(arg2, 1);
                                884                 :                : 
                                885                 :            665 :     PG_RETURN_BOOL(result);
                                886                 :                : }
                                887                 :                : 
                                888                 :                : Datum
                                889                 :           6260 : bitlt(PG_FUNCTION_ARGS)
                                890                 :                : {
                                891                 :           6260 :     VarBit     *arg1 = PG_GETARG_VARBIT_P(0);
                                892                 :           6260 :     VarBit     *arg2 = PG_GETARG_VARBIT_P(1);
                                893                 :                :     bool        result;
                                894                 :                : 
                                895                 :           6260 :     result = (bit_cmp(arg1, arg2) < 0);
                                896                 :                : 
                                897         [ +  + ]:           6260 :     PG_FREE_IF_COPY(arg1, 0);
                                898         [ +  + ]:           6260 :     PG_FREE_IF_COPY(arg2, 1);
                                899                 :                : 
                                900                 :           6260 :     PG_RETURN_BOOL(result);
                                901                 :                : }
                                902                 :                : 
                                903                 :                : Datum
                                904                 :           5380 : bitle(PG_FUNCTION_ARGS)
                                905                 :                : {
                                906                 :           5380 :     VarBit     *arg1 = PG_GETARG_VARBIT_P(0);
                                907                 :           5380 :     VarBit     *arg2 = PG_GETARG_VARBIT_P(1);
                                908                 :                :     bool        result;
                                909                 :                : 
                                910                 :           5380 :     result = (bit_cmp(arg1, arg2) <= 0);
                                911                 :                : 
                                912         [ +  + ]:           5380 :     PG_FREE_IF_COPY(arg1, 0);
                                913         [ +  + ]:           5380 :     PG_FREE_IF_COPY(arg2, 1);
                                914                 :                : 
                                915                 :           5380 :     PG_RETURN_BOOL(result);
                                916                 :                : }
                                917                 :                : 
                                918                 :                : Datum
                                919                 :           5960 : bitgt(PG_FUNCTION_ARGS)
                                920                 :                : {
                                921                 :           5960 :     VarBit     *arg1 = PG_GETARG_VARBIT_P(0);
                                922                 :           5960 :     VarBit     *arg2 = PG_GETARG_VARBIT_P(1);
                                923                 :                :     bool        result;
                                924                 :                : 
                                925                 :           5960 :     result = (bit_cmp(arg1, arg2) > 0);
                                926                 :                : 
                                927         [ +  + ]:           5960 :     PG_FREE_IF_COPY(arg1, 0);
                                928         [ +  + ]:           5960 :     PG_FREE_IF_COPY(arg2, 1);
                                929                 :                : 
                                930                 :           5960 :     PG_RETURN_BOOL(result);
                                931                 :                : }
                                932                 :                : 
                                933                 :                : Datum
                                934                 :           4584 : bitge(PG_FUNCTION_ARGS)
                                935                 :                : {
                                936                 :           4584 :     VarBit     *arg1 = PG_GETARG_VARBIT_P(0);
                                937                 :           4584 :     VarBit     *arg2 = PG_GETARG_VARBIT_P(1);
                                938                 :                :     bool        result;
                                939                 :                : 
                                940                 :           4584 :     result = (bit_cmp(arg1, arg2) >= 0);
                                941                 :                : 
                                942         [ +  + ]:           4584 :     PG_FREE_IF_COPY(arg1, 0);
                                943         [ +  + ]:           4584 :     PG_FREE_IF_COPY(arg2, 1);
                                944                 :                : 
                                945                 :           4584 :     PG_RETURN_BOOL(result);
                                946                 :                : }
                                947                 :                : 
                                948                 :                : Datum
                                949                 :          11805 : bitcmp(PG_FUNCTION_ARGS)
                                950                 :                : {
                                951                 :          11805 :     VarBit     *arg1 = PG_GETARG_VARBIT_P(0);
                                952                 :          11805 :     VarBit     *arg2 = PG_GETARG_VARBIT_P(1);
                                953                 :                :     int32       result;
                                954                 :                : 
                                955                 :          11805 :     result = bit_cmp(arg1, arg2);
                                956                 :                : 
                                957         [ +  + ]:          11805 :     PG_FREE_IF_COPY(arg1, 0);
                                958         [ +  + ]:          11805 :     PG_FREE_IF_COPY(arg2, 1);
                                959                 :                : 
                                960                 :          11805 :     PG_RETURN_INT32(result);
                                961                 :                : }
                                962                 :                : 
                                963                 :                : /*
                                964                 :                :  * bitcat
                                965                 :                :  * Concatenation of bit strings
                                966                 :                :  */
                                967                 :                : Datum
                                968                 :            108 : bitcat(PG_FUNCTION_ARGS)
                                969                 :                : {
                                970                 :            108 :     VarBit     *arg1 = PG_GETARG_VARBIT_P(0);
                                971                 :            108 :     VarBit     *arg2 = PG_GETARG_VARBIT_P(1);
                                972                 :                : 
 6025                           973                 :            108 :     PG_RETURN_VARBIT_P(bit_catenate(arg1, arg2));
                                974                 :                : }
                                975                 :                : 
                                976                 :                : static VarBit *
                                977                 :            148 : bit_catenate(VarBit *arg1, VarBit *arg2)
                                978                 :                : {
                                979                 :                :     VarBit     *result;
                                980                 :                :     int         bitlen1,
                                981                 :                :                 bitlen2,
                                982                 :                :                 bytelen,
                                983                 :                :                 bit1pad,
                                984                 :                :                 bit2shift;
                                985                 :                :     uint8      *pr,
                                986                 :                :                *pa;
                                987                 :                : 
 9600 bruce@momjian.us          988                 :            148 :     bitlen1 = VARBITLEN(arg1);
                                989                 :            148 :     bitlen2 = VARBITLEN(arg2);
                                990                 :                : 
 4541 noah@leadboat.com         991         [ -  + ]:            148 :     if (bitlen1 > VARBITMAXLEN - bitlen2)
 4541 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)));
 9469 tgl@sss.pgh.pa.us         996                 :CBC         148 :     bytelen = VARBITTOTALLEN(bitlen1 + bitlen2);
                                997                 :                : 
                                998                 :            148 :     result = (VarBit *) palloc(bytelen);
 7088                           999                 :            148 :     SET_VARSIZE(result, bytelen);
 9600 bruce@momjian.us         1000                 :            148 :     VARBITLEN(result) = bitlen1 + bitlen2;
                               1001                 :                : 
                               1002                 :                :     /* Copy the first bitstring in */
                               1003                 :            148 :     memcpy(VARBITS(result), VARBITS(arg1), VARBITBYTES(arg1));
                               1004                 :                : 
                               1005                 :                :     /* Copy the second bit string */
                               1006                 :            148 :     bit1pad = VARBITPAD(arg1);
                               1007         [ +  + ]:            148 :     if (bit1pad == 0)
                               1008                 :                :     {
                               1009                 :             25 :         memcpy(VARBITS(result) + VARBITBYTES(arg1), VARBITS(arg2),
                               1010                 :             25 :                VARBITBYTES(arg2));
                               1011                 :                :     }
                               1012         [ +  + ]:            123 :     else if (bitlen2 > 0)
                               1013                 :                :     {
                               1014                 :                :         /* We need to shift all the bits to fit */
 9464 tgl@sss.pgh.pa.us        1015                 :            113 :         bit2shift = BITS_PER_BYTE - bit1pad;
 9600 bruce@momjian.us         1016                 :            113 :         pr = VARBITS(result) + VARBITBYTES(arg1) - 1;
 9469 tgl@sss.pgh.pa.us        1017         [ +  + ]:            262 :         for (pa = VARBITS(arg2); pa < VARBITEND(arg2); pa++)
                               1018                 :                :         {
 9600 bruce@momjian.us         1019                 :            149 :             *pr |= ((*pa >> bit2shift) & BITMASK);
                               1020                 :            149 :             pr++;
                               1021         [ +  + ]:            149 :             if (pr < VARBITEND(result))
                               1022                 :             93 :                 *pr = (*pa << bit1pad) & BITMASK;
                               1023                 :                :         }
                               1024                 :                :     }
                               1025                 :                : 
                               1026                 :                :     /* The pad bits should be already zero at this point */
                               1027                 :                : 
 6025 tgl@sss.pgh.pa.us        1028                 :            148 :     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
 9469                          1038                 :             84 : bitsubstr(PG_FUNCTION_ARGS)
                               1039                 :                : {
 6043                          1040                 :             84 :     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                 :             28 : bitsubstr_no_len(PG_FUNCTION_ARGS)
                               1048                 :                : {
                               1049                 :             28 :     PG_RETURN_VARBIT_P(bitsubstring(PG_GETARG_VARBIT_P(0),
                               1050                 :                :                                     PG_GETARG_INT32(1),
                               1051                 :                :                                     -1, true));
                               1052                 :                : }
                               1053                 :                : 
                               1054                 :                : static VarBit *
                               1055                 :            152 : 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                 :                :     uint8      *r,
                               1067                 :                :                *ps;
                               1068                 :                : 
 9600 bruce@momjian.us         1069                 :            152 :     bitlen = VARBITLEN(arg);
                               1070                 :            152 :     s1 = Max(s, 1);
                               1071                 :                :     /* If we do not have an upper bound, use end of string */
 6043 tgl@sss.pgh.pa.us        1072         [ +  + ]:            152 :     if (length_not_specified)
                               1073                 :                :     {
                               1074                 :             48 :         e1 = bitlen + 1;
                               1075                 :                :     }
 2028                          1076         [ +  + ]:            104 :     else if (l < 0)
                               1077                 :                :     {
                               1078                 :                :         /* SQL99 says to throw an error for E < S, i.e., negative length */
                               1079         [ +  - ]:              8 :         ereport(ERROR,
                               1080                 :                :                 (errcode(ERRCODE_SUBSTRING_ERROR),
                               1081                 :                :                  errmsg("negative substring length not allowed")));
                               1082                 :                :         e1 = -1;                /* silence stupider compilers */
                               1083                 :                :     }
                               1084         [ +  + ]:             96 :     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                 :             10 :         e1 = bitlen + 1;
                               1091                 :                :     }
                               1092                 :                :     else
                               1093                 :                :     {
 6043                          1094                 :             86 :         e1 = Min(e, bitlen + 1);
                               1095                 :                :     }
                               1096   [ +  +  -  + ]:            144 :     if (s1 > bitlen || e1 <= s1)
                               1097                 :                :     {
                               1098                 :                :         /* Need to return a zero-length bitstring */
 9469                          1099                 :             38 :         len = VARBITTOTALLEN(0);
                               1100                 :             38 :         result = (VarBit *) palloc(len);
 7088                          1101                 :             38 :         SET_VARSIZE(result, len);
 9469                          1102                 :             38 :         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                 :                :          */
 9600 bruce@momjian.us         1110                 :            106 :         rbitlen = e1 - s1;
 9469 tgl@sss.pgh.pa.us        1111                 :            106 :         len = VARBITTOTALLEN(rbitlen);
                               1112                 :            106 :         result = (VarBit *) palloc(len);
 7088                          1113                 :            106 :         SET_VARSIZE(result, len);
 9469                          1114                 :            106 :         VARBITLEN(result) = rbitlen;
 9600 bruce@momjian.us         1115                 :            106 :         len -= VARHDRSZ + VARBITHDRSZ;
                               1116                 :                :         /* Are we copying from a byte boundary? */
 9464 tgl@sss.pgh.pa.us        1117         [ +  + ]:            106 :         if ((s1 - 1) % BITS_PER_BYTE == 0)
                               1118                 :                :         {
                               1119                 :                :             /* Yep, we are copying bytes */
                               1120                 :             35 :             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                 :             71 :             ishift = (s1 - 1) % BITS_PER_BYTE;
 9600 bruce@momjian.us         1127                 :             71 :             r = VARBITS(result);
 9464 tgl@sss.pgh.pa.us        1128                 :             71 :             ps = VARBITS(arg) + (s1 - 1) / BITS_PER_BYTE;
 9600 bruce@momjian.us         1129         [ +  + ]:            142 :             for (i = 0; i < len; i++)
                               1130                 :                :             {
                               1131                 :             71 :                 *r = (*ps << ishift) & BITMASK;
                               1132         [ +  + ]:             71 :                 if ((++ps) < VARBITEND(arg))
 9464 tgl@sss.pgh.pa.us        1133                 :             53 :                     *r |= *ps >> (BITS_PER_BYTE - ishift);
 9600 bruce@momjian.us         1134                 :             71 :                 r++;
                               1135                 :                :             }
                               1136                 :                :         }
                               1137                 :                : 
                               1138                 :                :         /* Make sure last byte is correctly zero-padded */
 2498 tgl@sss.pgh.pa.us        1139   [ +  -  -  +  :            106 :         VARBIT_PAD(result);
                                              +  + ]
                               1140                 :                :     }
                               1141                 :                : 
 6043                          1142                 :            144 :     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
 6025                          1153                 :              5 : bitoverlay(PG_FUNCTION_ARGS)
                               1154                 :                : {
                               1155                 :              5 :     VarBit     *t1 = PG_GETARG_VARBIT_P(0);
                               1156                 :              5 :     VarBit     *t2 = PG_GETARG_VARBIT_P(1);
 3321                          1157                 :              5 :     int         sp = PG_GETARG_INT32(2);    /* substring start position */
                               1158                 :              5 :     int         sl = PG_GETARG_INT32(3);    /* substring length */
                               1159                 :                : 
 6025                          1160                 :              5 :     PG_RETURN_VARBIT_P(bit_overlay(t1, t2, sp, sl));
                               1161                 :                : }
                               1162                 :                : 
                               1163                 :                : Datum
                               1164                 :             15 : bitoverlay_no_len(PG_FUNCTION_ARGS)
                               1165                 :                : {
                               1166                 :             15 :     VarBit     *t1 = PG_GETARG_VARBIT_P(0);
                               1167                 :             15 :     VarBit     *t2 = PG_GETARG_VARBIT_P(1);
 3321                          1168                 :             15 :     int         sp = PG_GETARG_INT32(2);    /* substring start position */
                               1169                 :                :     int         sl;
                               1170                 :                : 
 5993 bruce@momjian.us         1171                 :             15 :     sl = VARBITLEN(t2);         /* defaults to length(t2) */
 6025 tgl@sss.pgh.pa.us        1172                 :             15 :     PG_RETURN_VARBIT_P(bit_overlay(t1, t2, sp, sl));
                               1173                 :                : }
                               1174                 :                : 
                               1175                 :                : static VarBit *
                               1176                 :             20 : 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         [ -  + ]:             20 :     if (sp <= 0)
 6025 tgl@sss.pgh.pa.us        1189         [ #  # ]:UBC           0 :         ereport(ERROR,
                               1190                 :                :                 (errcode(ERRCODE_SUBSTRING_ERROR),
                               1191                 :                :                  errmsg("negative substring length not allowed")));
 3147 andres@anarazel.de       1192         [ -  + ]:CBC          20 :     if (pg_add_s32_overflow(sp, sl, &sp_pl_sl))
 6025 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                 :                : 
 5993 bruce@momjian.us         1197                 :CBC          20 :     s1 = bitsubstring(t1, 1, sp - 1, false);
 6025 tgl@sss.pgh.pa.us        1198                 :             20 :     s2 = bitsubstring(t1, sp_pl_sl, -1, true);
                               1199                 :             20 :     result = bit_catenate(s1, t2);
                               1200                 :             20 :     result = bit_catenate(result, s2);
                               1201                 :                : 
                               1202                 :             20 :     return result;
                               1203                 :                : }
                               1204                 :                : 
                               1205                 :                : /*
                               1206                 :                :  * bit_count
                               1207                 :                :  *
                               1208                 :                :  * Returns the number of bits set in a bit string.
                               1209                 :                :  */
                               1210                 :                : Datum
 1950 peter@eisentraut.org     1211                 :             30 : bit_bit_count(PG_FUNCTION_ARGS)
                               1212                 :                : {
                               1213                 :             30 :     VarBit     *arg = PG_GETARG_VARBIT_P(0);
                               1214                 :                : 
                               1215                 :             30 :     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
 9469 tgl@sss.pgh.pa.us        1223                 :             28 : bitlength(PG_FUNCTION_ARGS)
                               1224                 :                : {
                               1225                 :             28 :     VarBit     *arg = PG_GETARG_VARBIT_P(0);
                               1226                 :                : 
                               1227                 :             28 :     PG_RETURN_INT32(VARBITLEN(arg));
                               1228                 :                : }
                               1229                 :                : 
                               1230                 :                : Datum
 9469 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
 5689 tgl@sss.pgh.pa.us        1243                 :CBC          92 : bit_and(PG_FUNCTION_ARGS)
                               1244                 :                : {
 9469                          1245                 :             92 :     VarBit     *arg1 = PG_GETARG_VARBIT_P(0);
                               1246                 :             92 :     VarBit     *arg2 = PG_GETARG_VARBIT_P(1);
                               1247                 :                :     VarBit     *result;
                               1248                 :                :     int         len,
                               1249                 :                :                 bitlen1,
                               1250                 :                :                 bitlen2;
                               1251                 :                :     uint8      *p1,
                               1252                 :                :                *p2,
                               1253                 :                :                *r;
                               1254                 :                : 
                               1255                 :             92 :     bitlen1 = VARBITLEN(arg1);
                               1256                 :             92 :     bitlen2 = VARBITLEN(arg2);
                               1257         [ +  + ]:             92 :     if (bitlen1 != bitlen2)
 8399                          1258         [ +  - ]:              4 :         ereport(ERROR,
                               1259                 :                :                 (errcode(ERRCODE_STRING_DATA_LENGTH_MISMATCH),
                               1260                 :                :                  errmsg("cannot AND bit strings of different sizes")));
                               1261                 :                : 
 9469                          1262                 :             88 :     len = VARSIZE(arg1);
                               1263                 :             88 :     result = (VarBit *) palloc(len);
 7088                          1264                 :             88 :     SET_VARSIZE(result, len);
 9469                          1265                 :             88 :     VARBITLEN(result) = bitlen1;
                               1266                 :                : 
                               1267                 :             88 :     p1 = VARBITS(arg1);
                               1268                 :             88 :     p2 = VARBITS(arg2);
                               1269                 :             88 :     r = VARBITS(result);
   14 peter@eisentraut.org     1270         [ +  + ]:GNC         236 :     for (size_t i = 0; i < VARBITBYTES(arg1); i++)
 9600 bruce@momjian.us         1271                 :CBC         148 :         *r++ = *p1++ & *p2++;
                               1272                 :                : 
                               1273                 :                :     /* Padding is not needed as & of 0 pads is 0 */
                               1274                 :                : 
 9469 tgl@sss.pgh.pa.us        1275                 :             88 :     PG_RETURN_VARBIT_P(result);
                               1276                 :                : }
                               1277                 :                : 
                               1278                 :                : /*
                               1279                 :                :  * bit_or
                               1280                 :                :  * perform a logical OR on two bit strings.
                               1281                 :                :  */
                               1282                 :                : Datum
 5689                          1283                 :            117 : bit_or(PG_FUNCTION_ARGS)
                               1284                 :                : {
 9469                          1285                 :            117 :     VarBit     *arg1 = PG_GETARG_VARBIT_P(0);
                               1286                 :            117 :     VarBit     *arg2 = PG_GETARG_VARBIT_P(1);
                               1287                 :                :     VarBit     *result;
                               1288                 :                :     int         len,
                               1289                 :                :                 bitlen1,
                               1290                 :                :                 bitlen2;
                               1291                 :                :     uint8      *p1,
                               1292                 :                :                *p2,
                               1293                 :                :                *r;
                               1294                 :                : 
                               1295                 :            117 :     bitlen1 = VARBITLEN(arg1);
                               1296                 :            117 :     bitlen2 = VARBITLEN(arg2);
                               1297         [ +  + ]:            117 :     if (bitlen1 != bitlen2)
 8399                          1298         [ +  - ]:              4 :         ereport(ERROR,
                               1299                 :                :                 (errcode(ERRCODE_STRING_DATA_LENGTH_MISMATCH),
                               1300                 :                :                  errmsg("cannot OR bit strings of different sizes")));
 9469                          1301                 :            113 :     len = VARSIZE(arg1);
                               1302                 :            113 :     result = (VarBit *) palloc(len);
 7088                          1303                 :            113 :     SET_VARSIZE(result, len);
 9469                          1304                 :            113 :     VARBITLEN(result) = bitlen1;
                               1305                 :                : 
                               1306                 :            113 :     p1 = VARBITS(arg1);
                               1307                 :            113 :     p2 = VARBITS(arg2);
                               1308                 :            113 :     r = VARBITS(result);
   14 peter@eisentraut.org     1309         [ +  + ]:GNC         336 :     for (size_t i = 0; i < VARBITBYTES(arg1); i++)
 9600 bruce@momjian.us         1310                 :CBC         223 :         *r++ = *p1++ | *p2++;
                               1311                 :                : 
                               1312                 :                :     /* Padding is not needed as | of 0 pads is 0 */
                               1313                 :                : 
 9469 tgl@sss.pgh.pa.us        1314                 :            113 :     PG_RETURN_VARBIT_P(result);
                               1315                 :                : }
                               1316                 :                : 
                               1317                 :                : /*
                               1318                 :                :  * bitxor
                               1319                 :                :  * perform a logical XOR on two bit strings.
                               1320                 :                :  */
                               1321                 :                : Datum
                               1322                 :             92 : bitxor(PG_FUNCTION_ARGS)
                               1323                 :                : {
                               1324                 :             92 :     VarBit     *arg1 = PG_GETARG_VARBIT_P(0);
                               1325                 :             92 :     VarBit     *arg2 = PG_GETARG_VARBIT_P(1);
                               1326                 :                :     VarBit     *result;
                               1327                 :                :     int         len,
                               1328                 :                :                 bitlen1,
                               1329                 :                :                 bitlen2;
                               1330                 :                :     uint8      *p1,
                               1331                 :                :                *p2,
                               1332                 :                :                *r;
                               1333                 :                : 
                               1334                 :             92 :     bitlen1 = VARBITLEN(arg1);
                               1335                 :             92 :     bitlen2 = VARBITLEN(arg2);
                               1336         [ +  + ]:             92 :     if (bitlen1 != bitlen2)
 8399                          1337         [ +  - ]:              4 :         ereport(ERROR,
                               1338                 :                :                 (errcode(ERRCODE_STRING_DATA_LENGTH_MISMATCH),
                               1339                 :                :                  errmsg("cannot XOR bit strings of different sizes")));
                               1340                 :                : 
 9469                          1341                 :             88 :     len = VARSIZE(arg1);
                               1342                 :             88 :     result = (VarBit *) palloc(len);
 7088                          1343                 :             88 :     SET_VARSIZE(result, len);
 9469                          1344                 :             88 :     VARBITLEN(result) = bitlen1;
                               1345                 :                : 
                               1346                 :             88 :     p1 = VARBITS(arg1);
                               1347                 :             88 :     p2 = VARBITS(arg2);
                               1348                 :             88 :     r = VARBITS(result);
   14 peter@eisentraut.org     1349         [ +  + ]:GNC         236 :     for (size_t i = 0; i < VARBITBYTES(arg1); i++)
 9600 bruce@momjian.us         1350                 :CBC         148 :         *r++ = *p1++ ^ *p2++;
                               1351                 :                : 
                               1352                 :                :     /* Padding is not needed as ^ of 0 pads is 0 */
                               1353                 :                : 
 9469 tgl@sss.pgh.pa.us        1354                 :             88 :     PG_RETURN_VARBIT_P(result);
                               1355                 :                : }
                               1356                 :                : 
                               1357                 :                : /*
                               1358                 :                :  * bitnot
                               1359                 :                :  * perform a logical NOT on a bit string.
                               1360                 :                :  */
                               1361                 :                : Datum
                               1362                 :             80 : bitnot(PG_FUNCTION_ARGS)
                               1363                 :                : {
                               1364                 :             80 :     VarBit     *arg = PG_GETARG_VARBIT_P(0);
                               1365                 :                :     VarBit     *result;
                               1366                 :                :     uint8      *p,
                               1367                 :                :                *r;
                               1368                 :                : 
                               1369                 :             80 :     result = (VarBit *) palloc(VARSIZE(arg));
 7088                          1370                 :             80 :     SET_VARSIZE(result, VARSIZE(arg));
 9600 bruce@momjian.us         1371                 :             80 :     VARBITLEN(result) = VARBITLEN(arg);
                               1372                 :                : 
 9469 tgl@sss.pgh.pa.us        1373                 :             80 :     p = VARBITS(arg);
                               1374                 :             80 :     r = VARBITS(result);
                               1375         [ +  + ]:            220 :     for (; p < VARBITEND(arg); p++)
 9256 bruce@momjian.us         1376                 :            140 :         *r++ = ~*p;
                               1377                 :                : 
                               1378                 :                :     /* Must zero-pad the result, because extra bits are surely 1's here */
 2498 tgl@sss.pgh.pa.us        1379   [ +  -  -  +  :             80 :     VARBIT_PAD_LAST(result, r);
                                              -  + ]
                               1380                 :                : 
 9469                          1381                 :             80 :     PG_RETURN_VARBIT_P(result);
                               1382                 :                : }
                               1383                 :                : 
                               1384                 :                : /*
                               1385                 :                :  * bitshiftleft
                               1386                 :                :  * do a left shift (i.e. towards the beginning of the string)
                               1387                 :                :  */
                               1388                 :                : Datum
                               1389                 :            464 : bitshiftleft(PG_FUNCTION_ARGS)
                               1390                 :                : {
                               1391                 :            464 :     VarBit     *arg = PG_GETARG_VARBIT_P(0);
                               1392                 :            464 :     int32       shft = PG_GETARG_INT32(1);
                               1393                 :                :     VarBit     *result;
                               1394                 :                :     int         byte_shift,
                               1395                 :                :                 ishift,
                               1396                 :                :                 len;
                               1397                 :                :     uint8      *p,
                               1398                 :                :                *r;
                               1399                 :                : 
                               1400                 :                :     /* Negative shift is a shift to the right */
 9600 bruce@momjian.us         1401         [ -  + ]:            464 :     if (shft < 0)
                               1402                 :                :     {
                               1403                 :                :         /* Prevent integer overflow in negation */
 3571 tgl@sss.pgh.pa.us        1404         [ #  # ]:UBC           0 :         if (shft < -VARBITMAXLEN)
                               1405                 :              0 :             shft = -VARBITMAXLEN;
 9469                          1406                 :              0 :         PG_RETURN_DATUM(DirectFunctionCall2(bitshiftright,
                               1407                 :                :                                             VarBitPGetDatum(arg),
                               1408                 :                :                                             Int32GetDatum(-shft)));
                               1409                 :                :     }
                               1410                 :                : 
 9469 tgl@sss.pgh.pa.us        1411                 :CBC         464 :     result = (VarBit *) palloc(VARSIZE(arg));
 7088                          1412                 :            464 :     SET_VARSIZE(result, VARSIZE(arg));
 9600 bruce@momjian.us         1413                 :            464 :     VARBITLEN(result) = VARBITLEN(arg);
 9469 tgl@sss.pgh.pa.us        1414                 :            464 :     r = VARBITS(result);
                               1415                 :                : 
                               1416                 :                :     /* If we shifted all the bits out, return an all-zero string */
                               1417         [ +  + ]:            464 :     if (shft >= VARBITLEN(arg))
                               1418                 :                :     {
 8711                          1419   [ +  -  -  +  :             16 :         MemSet(r, 0, VARBITBYTES(arg));
                                     -  -  -  -  -  
                                                 - ]
 9469                          1420                 :             16 :         PG_RETURN_VARBIT_P(result);
                               1421                 :                :     }
                               1422                 :                : 
 9464                          1423                 :            448 :     byte_shift = shft / BITS_PER_BYTE;
                               1424                 :            448 :     ishift = shft % BITS_PER_BYTE;
 9469                          1425                 :            448 :     p = VARBITS(arg) + byte_shift;
                               1426                 :                : 
 9600 bruce@momjian.us         1427         [ +  + ]:            448 :     if (ishift == 0)
                               1428                 :                :     {
                               1429                 :                :         /* Special case: we can do a memcpy */
                               1430                 :            176 :         len = VARBITBYTES(arg) - byte_shift;
                               1431                 :            176 :         memcpy(r, p, len);
 8711 tgl@sss.pgh.pa.us        1432   [ -  +  -  -  :            176 :         MemSet(r + len, 0, byte_shift);
                                     -  -  -  -  -  
                                                 - ]
                               1433                 :                :     }
                               1434                 :                :     else
                               1435                 :                :     {
 9600 bruce@momjian.us         1436         [ +  + ]:            796 :         for (; p < VARBITEND(arg); r++)
                               1437                 :                :         {
                               1438                 :            524 :             *r = *p << ishift;
                               1439         [ +  + ]:            524 :             if ((++p) < VARBITEND(arg))
 9464 tgl@sss.pgh.pa.us        1440                 :            252 :                 *r |= *p >> (BITS_PER_BYTE - ishift);
                               1441                 :                :         }
 9600 bruce@momjian.us         1442         [ -  + ]:            272 :         for (; r < VARBITEND(result); r++)
 9469 tgl@sss.pgh.pa.us        1443                 :UBC           0 :             *r = 0;
                               1444                 :                :     }
                               1445                 :                : 
                               1446                 :                :     /* The pad bits should be already zero at this point */
                               1447                 :                : 
 9469 tgl@sss.pgh.pa.us        1448                 :CBC         448 :     PG_RETURN_VARBIT_P(result);
                               1449                 :                : }
                               1450                 :                : 
                               1451                 :                : /*
                               1452                 :                :  * bitshiftright
                               1453                 :                :  * do a right shift (i.e. towards the end of the string)
                               1454                 :                :  */
                               1455                 :                : Datum
                               1456                 :            584 : bitshiftright(PG_FUNCTION_ARGS)
                               1457                 :                : {
                               1458                 :            584 :     VarBit     *arg = PG_GETARG_VARBIT_P(0);
                               1459                 :            584 :     int32       shft = PG_GETARG_INT32(1);
                               1460                 :                :     VarBit     *result;
                               1461                 :                :     int         byte_shift,
                               1462                 :                :                 ishift,
                               1463                 :                :                 len;
                               1464                 :                :     uint8      *p,
                               1465                 :                :                *r;
                               1466                 :                : 
                               1467                 :                :     /* Negative shift is a shift to the left */
 9600 bruce@momjian.us         1468         [ -  + ]:            584 :     if (shft < 0)
                               1469                 :                :     {
                               1470                 :                :         /* Prevent integer overflow in negation */
 3571 tgl@sss.pgh.pa.us        1471         [ #  # ]:UBC           0 :         if (shft < -VARBITMAXLEN)
                               1472                 :              0 :             shft = -VARBITMAXLEN;
 9469                          1473                 :              0 :         PG_RETURN_DATUM(DirectFunctionCall2(bitshiftleft,
                               1474                 :                :                                             VarBitPGetDatum(arg),
                               1475                 :                :                                             Int32GetDatum(-shft)));
                               1476                 :                :     }
                               1477                 :                : 
 9469 tgl@sss.pgh.pa.us        1478                 :CBC         584 :     result = (VarBit *) palloc(VARSIZE(arg));
 7088                          1479                 :            584 :     SET_VARSIZE(result, VARSIZE(arg));
 9600 bruce@momjian.us         1480                 :            584 :     VARBITLEN(result) = VARBITLEN(arg);
 9469 tgl@sss.pgh.pa.us        1481                 :            584 :     r = VARBITS(result);
                               1482                 :                : 
                               1483                 :                :     /* If we shifted all the bits out, return an all-zero string */
                               1484         [ +  + ]:            584 :     if (shft >= VARBITLEN(arg))
                               1485                 :                :     {
 8711                          1486   [ +  -  -  +  :             16 :         MemSet(r, 0, VARBITBYTES(arg));
                                     -  -  -  -  -  
                                                 - ]
 9469                          1487                 :             16 :         PG_RETURN_VARBIT_P(result);
                               1488                 :                :     }
                               1489                 :                : 
 9464                          1490                 :            568 :     byte_shift = shft / BITS_PER_BYTE;
                               1491                 :            568 :     ishift = shft % BITS_PER_BYTE;
 9469                          1492                 :            568 :     p = VARBITS(arg);
                               1493                 :                : 
                               1494                 :                :     /* Set the first part of the result to 0 */
 8711                          1495   [ +  -  +  +  :            568 :     MemSet(r, 0, byte_shift);
                                     +  -  +  -  -  
                                                 + ]
 9469                          1496                 :            568 :     r += byte_shift;
                               1497                 :                : 
 9600 bruce@momjian.us         1498         [ +  + ]:            568 :     if (ishift == 0)
                               1499                 :                :     {
                               1500                 :                :         /* Special case: we can do a memcpy */
                               1501                 :            240 :         len = VARBITBYTES(arg) - byte_shift;
 9469 tgl@sss.pgh.pa.us        1502                 :            240 :         memcpy(r, p, len);
 2486                          1503                 :            240 :         r += len;
                               1504                 :                :     }
                               1505                 :                :     else
                               1506                 :                :     {
 9469                          1507         [ +  - ]:            328 :         if (r < VARBITEND(result))
                               1508                 :            328 :             *r = 0;             /* initialize first byte */
 9600 bruce@momjian.us         1509         [ +  + ]:            952 :         for (; r < VARBITEND(result); p++)
                               1510                 :                :         {
                               1511                 :            624 :             *r |= *p >> ishift;
                               1512         [ +  + ]:            624 :             if ((++r) < VARBITEND(result))
 9464 tgl@sss.pgh.pa.us        1513                 :            296 :                 *r = (*p << (BITS_PER_BYTE - ishift)) & BITMASK;
                               1514                 :                :         }
                               1515                 :                :     }
                               1516                 :                : 
                               1517                 :                :     /* We may have shifted 1's into the pad bits, so fix that */
 2486                          1518   [ +  -  -  +  :            568 :     VARBIT_PAD_LAST(result, r);
                                              +  + ]
                               1519                 :                : 
 9469                          1520                 :            568 :     PG_RETURN_VARBIT_P(result);
                               1521                 :                : }
                               1522                 :                : 
                               1523                 :                : /*
                               1524                 :                :  * This is not defined in any standard. We retain the natural ordering of
                               1525                 :                :  * bits here, as it just seems more intuitive.
                               1526                 :                :  */
                               1527                 :                : Datum
                               1528                 :           2044 : bitfromint4(PG_FUNCTION_ARGS)
                               1529                 :                : {
                               1530                 :           2044 :     int32       a = PG_GETARG_INT32(0);
 8074                          1531                 :           2044 :     int32       typmod = PG_GETARG_INT32(1);
                               1532                 :                :     VarBit     *result;
                               1533                 :                :     uint8      *r;
                               1534                 :                :     int         rlen;
                               1535                 :                :     int         destbitsleft,
                               1536                 :                :                 srcbitsleft;
                               1537                 :                : 
 3571                          1538   [ +  -  -  + ]:           2044 :     if (typmod <= 0 || typmod > VARBITMAXLEN)
 8074 tgl@sss.pgh.pa.us        1539                 :UBC           0 :         typmod = 1;             /* default bit length */
                               1540                 :                : 
 8074 tgl@sss.pgh.pa.us        1541                 :CBC        2044 :     rlen = VARBITTOTALLEN(typmod);
                               1542                 :           2044 :     result = (VarBit *) palloc(rlen);
 7088                          1543                 :           2044 :     SET_VARSIZE(result, rlen);
 8074                          1544                 :           2044 :     VARBITLEN(result) = typmod;
                               1545                 :                : 
 9469                          1546                 :           2044 :     r = VARBITS(result);
 8074                          1547                 :           2044 :     destbitsleft = typmod;
                               1548                 :           2044 :     srcbitsleft = 32;
                               1549                 :                :     /* drop any input bits that don't fit */
                               1550                 :           2044 :     srcbitsleft = Min(srcbitsleft, destbitsleft);
                               1551                 :                :     /* sign-fill any excess bytes in output */
                               1552         [ -  + ]:           2044 :     while (destbitsleft >= srcbitsleft + 8)
                               1553                 :                :     {
  117 nathan@postgresql.or     1554         [ #  # ]:UBC           0 :         *r++ = (uint8) ((a < 0) ? BITMASK : 0);
 8074 tgl@sss.pgh.pa.us        1555                 :              0 :         destbitsleft -= 8;
                               1556                 :                :     }
                               1557                 :                :     /* store first fractional byte */
 8074 tgl@sss.pgh.pa.us        1558         [ -  + ]:CBC        2044 :     if (destbitsleft > srcbitsleft)
                               1559                 :                :     {
 2960 tgl@sss.pgh.pa.us        1560                 :UBC           0 :         unsigned int val = (unsigned int) (a >> (destbitsleft - 8));
                               1561                 :                : 
                               1562                 :                :         /* Force sign-fill in case the compiler implements >> as zero-fill */
 6069                          1563         [ #  # ]:              0 :         if (a < 0)
 2960                          1564                 :              0 :             val |= ((unsigned int) -1) << (srcbitsleft + 8 - destbitsleft);
  117 nathan@postgresql.or     1565                 :              0 :         *r++ = (uint8) (val & BITMASK);
 8074 tgl@sss.pgh.pa.us        1566                 :              0 :         destbitsleft -= 8;
                               1567                 :                :     }
                               1568                 :                :     /* Now srcbitsleft and destbitsleft are the same, need not track both */
                               1569                 :                :     /* store whole bytes */
 8074 tgl@sss.pgh.pa.us        1570         [ +  + ]:CBC        8000 :     while (destbitsleft >= 8)
                               1571                 :                :     {
  117 nathan@postgresql.or     1572                 :           5956 :         *r++ = (uint8) ((a >> (destbitsleft - 8)) & BITMASK);
 8074 tgl@sss.pgh.pa.us        1573                 :           5956 :         destbitsleft -= 8;
                               1574                 :                :     }
                               1575                 :                :     /* store last fractional byte */
                               1576         [ +  + ]:           2044 :     if (destbitsleft > 0)
  117 nathan@postgresql.or     1577                 :            445 :         *r = (uint8) ((a << (8 - destbitsleft)) & BITMASK);
                               1578                 :                : 
 9469 tgl@sss.pgh.pa.us        1579                 :           2044 :     PG_RETURN_VARBIT_P(result);
                               1580                 :                : }
                               1581                 :                : 
                               1582                 :                : Datum
                               1583                 :           1309 : bittoint4(PG_FUNCTION_ARGS)
                               1584                 :                : {
                               1585                 :           1309 :     VarBit     *arg = PG_GETARG_VARBIT_P(0);
                               1586                 :                :     uint32      result;
                               1587                 :                :     uint8      *r;
                               1588                 :                : 
                               1589                 :                :     /* Check that the bit string is not too long */
 8074                          1590         [ -  + ]:           1309 :     if (VARBITLEN(arg) > sizeof(result) * BITS_PER_BYTE)
  123 peter@eisentraut.org     1591         [ #  # ]:UBC           0 :         ereturn(fcinfo->context, (Datum) 0,
                               1592                 :                :                 (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
                               1593                 :                :                  errmsg("integer out of range")));
                               1594                 :                : 
 9469 tgl@sss.pgh.pa.us        1595                 :CBC        1309 :     result = 0;
                               1596         [ +  + ]:           6355 :     for (r = VARBITS(arg); r < VARBITEND(arg); r++)
                               1597                 :                :     {
 9464                          1598                 :           5046 :         result <<= BITS_PER_BYTE;
 9469                          1599                 :           5046 :         result |= *r;
                               1600                 :                :     }
                               1601                 :                :     /* Now shift the result to take account of the padding at the end */
                               1602                 :           1309 :     result >>= VARBITPAD(arg);
                               1603                 :                : 
                               1604                 :           1309 :     PG_RETURN_INT32(result);
                               1605                 :                : }
                               1606                 :                : 
                               1607                 :                : Datum
 8756 lockhart@fourpalms.o     1608                 :           1164 : bitfromint8(PG_FUNCTION_ARGS)
                               1609                 :                : {
                               1610                 :           1164 :     int64       a = PG_GETARG_INT64(0);
 8074 tgl@sss.pgh.pa.us        1611                 :           1164 :     int32       typmod = PG_GETARG_INT32(1);
                               1612                 :                :     VarBit     *result;
                               1613                 :                :     uint8      *r;
                               1614                 :                :     int         rlen;
                               1615                 :                :     int         destbitsleft,
                               1616                 :                :                 srcbitsleft;
                               1617                 :                : 
 3571                          1618   [ +  -  -  + ]:           1164 :     if (typmod <= 0 || typmod > VARBITMAXLEN)
 8074 tgl@sss.pgh.pa.us        1619                 :UBC           0 :         typmod = 1;             /* default bit length */
                               1620                 :                : 
 8074 tgl@sss.pgh.pa.us        1621                 :CBC        1164 :     rlen = VARBITTOTALLEN(typmod);
                               1622                 :           1164 :     result = (VarBit *) palloc(rlen);
 7088                          1623                 :           1164 :     SET_VARSIZE(result, rlen);
 8074                          1624                 :           1164 :     VARBITLEN(result) = typmod;
                               1625                 :                : 
                               1626                 :           1164 :     r = VARBITS(result);
                               1627                 :           1164 :     destbitsleft = typmod;
                               1628                 :           1164 :     srcbitsleft = 64;
                               1629                 :                :     /* drop any input bits that don't fit */
                               1630                 :           1164 :     srcbitsleft = Min(srcbitsleft, destbitsleft);
                               1631                 :                :     /* sign-fill any excess bytes in output */
                               1632         [ -  + ]:           1164 :     while (destbitsleft >= srcbitsleft + 8)
                               1633                 :                :     {
  117 nathan@postgresql.or     1634         [ #  # ]:UBC           0 :         *r++ = (uint8) ((a < 0) ? BITMASK : 0);
 8074 tgl@sss.pgh.pa.us        1635                 :              0 :         destbitsleft -= 8;
                               1636                 :                :     }
                               1637                 :                :     /* store first fractional byte */
 8074 tgl@sss.pgh.pa.us        1638         [ -  + ]:CBC        1164 :     if (destbitsleft > srcbitsleft)
                               1639                 :                :     {
 2960 tgl@sss.pgh.pa.us        1640                 :UBC           0 :         unsigned int val = (unsigned int) (a >> (destbitsleft - 8));
                               1641                 :                : 
                               1642                 :                :         /* Force sign-fill in case the compiler implements >> as zero-fill */
 6069                          1643         [ #  # ]:              0 :         if (a < 0)
 2960                          1644                 :              0 :             val |= ((unsigned int) -1) << (srcbitsleft + 8 - destbitsleft);
  117 nathan@postgresql.or     1645                 :              0 :         *r++ = (uint8) (val & BITMASK);
 8074 tgl@sss.pgh.pa.us        1646                 :              0 :         destbitsleft -= 8;
                               1647                 :                :     }
                               1648                 :                :     /* Now srcbitsleft and destbitsleft are the same, need not track both */
                               1649                 :                :     /* store whole bytes */
 8074 tgl@sss.pgh.pa.us        1650         [ +  + ]:CBC        5820 :     while (destbitsleft >= 8)
                               1651                 :                :     {
  117 nathan@postgresql.or     1652                 :           4656 :         *r++ = (uint8) ((a >> (destbitsleft - 8)) & BITMASK);
 8074 tgl@sss.pgh.pa.us        1653                 :           4656 :         destbitsleft -= 8;
                               1654                 :                :     }
                               1655                 :                :     /* store last fractional byte */
                               1656         [ -  + ]:           1164 :     if (destbitsleft > 0)
  117 nathan@postgresql.or     1657                 :UBC           0 :         *r = (uint8) ((a << (8 - destbitsleft)) & BITMASK);
                               1658                 :                : 
 8074 tgl@sss.pgh.pa.us        1659                 :CBC        1164 :     PG_RETURN_VARBIT_P(result);
                               1660                 :                : }
                               1661                 :                : 
                               1662                 :                : Datum
 8756 lockhart@fourpalms.o     1663                 :            912 : bittoint8(PG_FUNCTION_ARGS)
                               1664                 :                : {
                               1665                 :            912 :     VarBit     *arg = PG_GETARG_VARBIT_P(0);
                               1666                 :                :     uint64      result;
                               1667                 :                :     uint8      *r;
                               1668                 :                : 
                               1669                 :                :     /* Check that the bit string is not too long */
                               1670         [ -  + ]:            912 :     if (VARBITLEN(arg) > sizeof(result) * BITS_PER_BYTE)
  123 peter@eisentraut.org     1671         [ #  # ]:UBC           0 :         ereturn(fcinfo->context, (Datum) 0,
                               1672                 :                :                 (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
                               1673                 :                :                  errmsg("bigint out of range")));
                               1674                 :                : 
 8756 lockhart@fourpalms.o     1675                 :CBC         912 :     result = 0;
                               1676         [ +  + ]:           8208 :     for (r = VARBITS(arg); r < VARBITEND(arg); r++)
                               1677                 :                :     {
                               1678                 :           7296 :         result <<= BITS_PER_BYTE;
                               1679                 :           7296 :         result |= *r;
                               1680                 :                :     }
                               1681                 :                :     /* Now shift the result to take account of the padding at the end */
                               1682                 :            912 :     result >>= VARBITPAD(arg);
                               1683                 :                : 
                               1684                 :            912 :     PG_RETURN_INT64(result);
                               1685                 :                : }
                               1686                 :                : 
                               1687                 :                : 
                               1688                 :                : /*
                               1689                 :                :  * Determines the position of S2 in the bitstring S1 (1-based string).
                               1690                 :                :  * If S2 does not appear in S1 this function returns 0.
                               1691                 :                :  * If S2 is of length 0 this function returns 1.
                               1692                 :                :  * Compatible in usage with POSITION() functions for other data types.
                               1693                 :                :  */
                               1694                 :                : Datum
 9398 peter_e@gmx.net          1695                 :            446 : bitposition(PG_FUNCTION_ARGS)
                               1696                 :                : {
 8756 lockhart@fourpalms.o     1697                 :            446 :     VarBit     *str = PG_GETARG_VARBIT_P(0);
 9256 bruce@momjian.us         1698                 :            446 :     VarBit     *substr = PG_GETARG_VARBIT_P(1);
                               1699                 :                :     int         substr_length,
                               1700                 :                :                 str_length,
                               1701                 :                :                 is;
                               1702                 :                :     uint8      *s,              /* pointer into substring */
                               1703                 :                :                *p;              /* pointer into str */
                               1704                 :                :     uint8       cmp,            /* shifted substring byte to compare */
                               1705                 :                :                 mask1,          /* mask for substring byte shifted right */
                               1706                 :                :                 mask2,          /* mask for substring byte shifted left */
                               1707                 :                :                 end_mask,       /* pad mask for last substring byte */
                               1708                 :                :                 str_mask;       /* pad mask for last string byte */
                               1709                 :                :     bool        is_match;
                               1710                 :                : 
                               1711                 :                :     /* Get the substring length */
 9398 peter_e@gmx.net          1712                 :            446 :     substr_length = VARBITLEN(substr);
 8756 lockhart@fourpalms.o     1713                 :            446 :     str_length = VARBITLEN(str);
                               1714                 :                : 
                               1715                 :                :     /* String has zero length or substring longer than string, return 0 */
                               1716   [ +  +  +  + ]:            446 :     if ((str_length == 0) || (substr_length > str_length))
 9256 bruce@momjian.us         1717                 :             20 :         PG_RETURN_INT32(0);
                               1718                 :                : 
                               1719                 :                :     /* zero-length substring means return 1 */
 9398 peter_e@gmx.net          1720         [ +  + ]:            426 :     if (substr_length == 0)
                               1721                 :              5 :         PG_RETURN_INT32(1);
                               1722                 :                : 
                               1723                 :                :     /* Initialise the padding masks */
                               1724                 :            421 :     end_mask = BITMASK << VARBITPAD(substr);
 8756 lockhart@fourpalms.o     1725                 :            421 :     str_mask = BITMASK << VARBITPAD(str);
   14 peter@eisentraut.org     1726         [ +  + ]:GNC         677 :     for (size_t i = 0; i < VARBITBYTES(str) - VARBITBYTES(substr) + 1; i++)
                               1727                 :                :     {
 9256 bruce@momjian.us         1728         [ +  + ]:CBC        3688 :         for (is = 0; is < BITS_PER_BYTE; is++)
                               1729                 :                :         {
 9398 peter_e@gmx.net          1730                 :           3432 :             is_match = true;
 8756 lockhart@fourpalms.o     1731                 :           3432 :             p = VARBITS(str) + i;
 9398 peter_e@gmx.net          1732                 :           3432 :             mask1 = BITMASK >> is;
                               1733                 :           3432 :             mask2 = ~mask1;
 9256 bruce@momjian.us         1734                 :           3432 :             for (s = VARBITS(substr);
                               1735   [ +  +  +  + ]:           3865 :                  is_match && s < VARBITEND(substr); s++)
                               1736                 :                :             {
 9398 peter_e@gmx.net          1737                 :           3607 :                 cmp = *s >> is;
 9256 bruce@momjian.us         1738         [ +  + ]:           3607 :                 if (s == VARBITEND(substr) - 1)
                               1739                 :                :                 {
 9398 peter_e@gmx.net          1740                 :           2592 :                     mask1 &= end_mask >> is;
 8756 lockhart@fourpalms.o     1741         [ +  + ]:           2592 :                     if (p == VARBITEND(str) - 1)
                               1742                 :                :                     {
                               1743                 :                :                         /* Check that there is enough of str left */
                               1744         [ +  + ]:            704 :                         if (mask1 & ~str_mask)
                               1745                 :                :                         {
 9398 peter_e@gmx.net          1746                 :             50 :                             is_match = false;
                               1747                 :             50 :                             break;
                               1748                 :                :                         }
 8756 lockhart@fourpalms.o     1749                 :            654 :                         mask1 &= str_mask;
                               1750                 :                :                     }
                               1751                 :                :                 }
 9398 peter_e@gmx.net          1752                 :           3557 :                 is_match = ((cmp ^ *p) & mask1) == 0;
                               1753         [ +  + ]:           3557 :                 if (!is_match)
                               1754                 :           2889 :                     break;
                               1755                 :                :                 /* Move on to the next byte */
                               1756                 :            668 :                 p++;
 8756 lockhart@fourpalms.o     1757         [ +  + ]:            668 :                 if (p == VARBITEND(str))
                               1758                 :                :                 {
 9398 peter_e@gmx.net          1759                 :            235 :                     mask2 = end_mask << (BITS_PER_BYTE - is);
                               1760                 :            235 :                     is_match = mask2 == 0;
                               1761                 :                : #if 0
                               1762                 :                :                     elog(DEBUG4, "S. %d %d em=%2x sm=%2x r=%d",
                               1763                 :                :                          i, is, end_mask, mask2, is_match);
                               1764                 :                : #endif
                               1765                 :            235 :                     break;
                               1766                 :                :                 }
                               1767                 :            433 :                 cmp = *s << (BITS_PER_BYTE - is);
 9256 bruce@momjian.us         1768         [ +  + ]:            433 :                 if (s == VARBITEND(substr) - 1)
                               1769                 :                :                 {
 9398 peter_e@gmx.net          1770                 :            163 :                     mask2 &= end_mask << (BITS_PER_BYTE - is);
 8756 lockhart@fourpalms.o     1771         [ +  + ]:            163 :                     if (p == VARBITEND(str) - 1)
                               1772                 :                :                     {
                               1773         [ -  + ]:            158 :                         if (mask2 & ~str_mask)
                               1774                 :                :                         {
 9398 peter_e@gmx.net          1775                 :UBC           0 :                             is_match = false;
                               1776                 :              0 :                             break;
                               1777                 :                :                         }
 8756 lockhart@fourpalms.o     1778                 :CBC         158 :                         mask2 &= str_mask;
                               1779                 :                :                     }
                               1780                 :                :                 }
 9398 peter_e@gmx.net          1781                 :            433 :                 is_match = ((cmp ^ *p) & mask2) == 0;
                               1782                 :                :             }
                               1783                 :                :             /* Have we found a match? */
                               1784         [ +  + ]:           3432 :             if (is_match)
 9256 bruce@momjian.us         1785                 :            348 :                 PG_RETURN_INT32(i * BITS_PER_BYTE + is + 1);
                               1786                 :                :         }
                               1787                 :                :     }
 9398 peter_e@gmx.net          1788                 :             73 :     PG_RETURN_INT32(0);
                               1789                 :                : }
                               1790                 :                : 
                               1791                 :                : 
                               1792                 :                : /*
                               1793                 :                :  * bitsetbit
                               1794                 :                :  *
                               1795                 :                :  * Given an instance of type 'bit' creates a new one with
                               1796                 :                :  * the Nth bit set to the given value.
                               1797                 :                :  *
                               1798                 :                :  * The bit location is specified left-to-right in a zero-based fashion
                               1799                 :                :  * consistent with the other get_bit and set_bit functions, but
                               1800                 :                :  * inconsistent with the standard substring, position, overlay functions
                               1801                 :                :  */
                               1802                 :                : Datum
 6025 tgl@sss.pgh.pa.us        1803                 :              9 : bitsetbit(PG_FUNCTION_ARGS)
                               1804                 :                : {
                               1805                 :              9 :     VarBit     *arg1 = PG_GETARG_VARBIT_P(0);
                               1806                 :              9 :     int32       n = PG_GETARG_INT32(1);
                               1807                 :              9 :     int32       newBit = PG_GETARG_INT32(2);
                               1808                 :                :     VarBit     *result;
                               1809                 :                :     int         len,
                               1810                 :                :                 bitlen;
                               1811                 :                :     uint8      *r,
                               1812                 :                :                *p;
                               1813                 :                :     int         byteNo,
                               1814                 :                :                 bitNo;
                               1815                 :                : 
                               1816                 :              9 :     bitlen = VARBITLEN(arg1);
                               1817   [ +  -  +  + ]:              9 :     if (n < 0 || n >= bitlen)
                               1818         [ +  - ]:              4 :         ereport(ERROR,
                               1819                 :                :                 (errcode(ERRCODE_ARRAY_SUBSCRIPT_ERROR),
                               1820                 :                :                  errmsg("bit index %d out of valid range (0..%d)",
                               1821                 :                :                         n, bitlen - 1)));
                               1822                 :                : 
                               1823                 :                :     /*
                               1824                 :                :      * sanity check!
                               1825                 :                :      */
                               1826   [ +  -  -  + ]:              5 :     if (newBit != 0 && newBit != 1)
 6025 tgl@sss.pgh.pa.us        1827         [ #  # ]:UBC           0 :         ereport(ERROR,
                               1828                 :                :                 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
                               1829                 :                :                  errmsg("new bit must be 0 or 1")));
                               1830                 :                : 
 6025 tgl@sss.pgh.pa.us        1831                 :CBC           5 :     len = VARSIZE(arg1);
                               1832                 :              5 :     result = (VarBit *) palloc(len);
                               1833                 :              5 :     SET_VARSIZE(result, len);
                               1834                 :              5 :     VARBITLEN(result) = bitlen;
                               1835                 :                : 
                               1836                 :              5 :     p = VARBITS(arg1);
                               1837                 :              5 :     r = VARBITS(result);
                               1838                 :                : 
                               1839                 :              5 :     memcpy(r, p, VARBITBYTES(arg1));
                               1840                 :                : 
                               1841                 :              5 :     byteNo = n / BITS_PER_BYTE;
                               1842                 :              5 :     bitNo = BITS_PER_BYTE - 1 - (n % BITS_PER_BYTE);
                               1843                 :                : 
                               1844                 :                :     /*
                               1845                 :                :      * Update the byte.
                               1846                 :                :      */
                               1847         [ -  + ]:              5 :     if (newBit == 0)
 6025 tgl@sss.pgh.pa.us        1848                 :UBC           0 :         r[byteNo] &= (~(1 << bitNo));
                               1849                 :                :     else
 6025 tgl@sss.pgh.pa.us        1850                 :CBC           5 :         r[byteNo] |= (1 << bitNo);
                               1851                 :                : 
                               1852                 :              5 :     PG_RETURN_VARBIT_P(result);
                               1853                 :                : }
                               1854                 :                : 
                               1855                 :                : /*
                               1856                 :                :  * bitgetbit
                               1857                 :                :  *
                               1858                 :                :  * returns the value of the Nth bit of a bit array (0 or 1).
                               1859                 :                :  *
                               1860                 :                :  * The bit location is specified left-to-right in a zero-based fashion
                               1861                 :                :  * consistent with the other get_bit and set_bit functions, but
                               1862                 :                :  * inconsistent with the standard substring, position, overlay functions
                               1863                 :                :  */
                               1864                 :                : Datum
                               1865                 :              5 : bitgetbit(PG_FUNCTION_ARGS)
                               1866                 :                : {
                               1867                 :              5 :     VarBit     *arg1 = PG_GETARG_VARBIT_P(0);
                               1868                 :              5 :     int32       n = PG_GETARG_INT32(1);
                               1869                 :                :     int         bitlen;
                               1870                 :                :     uint8      *p;
                               1871                 :                :     int         byteNo,
                               1872                 :                :                 bitNo;
                               1873                 :                : 
                               1874                 :              5 :     bitlen = VARBITLEN(arg1);
                               1875   [ +  -  -  + ]:              5 :     if (n < 0 || n >= bitlen)
 6025 tgl@sss.pgh.pa.us        1876         [ #  # ]:UBC           0 :         ereport(ERROR,
                               1877                 :                :                 (errcode(ERRCODE_ARRAY_SUBSCRIPT_ERROR),
                               1878                 :                :                  errmsg("bit index %d out of valid range (0..%d)",
                               1879                 :                :                         n, bitlen - 1)));
                               1880                 :                : 
 6025 tgl@sss.pgh.pa.us        1881                 :CBC           5 :     p = VARBITS(arg1);
                               1882                 :                : 
                               1883                 :              5 :     byteNo = n / BITS_PER_BYTE;
                               1884                 :              5 :     bitNo = BITS_PER_BYTE - 1 - (n % BITS_PER_BYTE);
                               1885                 :                : 
                               1886         [ +  - ]:              5 :     if (p[byteNo] & (1 << bitNo))
                               1887                 :              5 :         PG_RETURN_INT32(1);
                               1888                 :                :     else
 6025 tgl@sss.pgh.pa.us        1889                 :UBC           0 :         PG_RETURN_INT32(0);
                               1890                 :                : }
        

Generated by: LCOV version 2.0-1