33 * varbit.c
44 * Functions for the SQL datatypes BIT() and BIT VARYING().
55 *
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+ *
621 * Code originally contributed by Adriaan Joubert.
722 *
823 * Portions Copyright (c) 1996-2017, PostgreSQL Global Development Group
2540
2641#define HEXDIG (z ) ((z)<10 ? ((z)+'0') : ((z)-10+'A'))
2742
43+ /* Mask off any bits that should be zero in the last byte of a bitstring */
44+ #define VARBIT_PAD (vb ) \
45+ do { \
46+ int32pad_ = VARBITPAD(vb); \
47+ Assert(pad_ >= 0 && pad_ < BITS_PER_BYTE); \
48+ if (pad_ > 0) \
49+ *(VARBITS(vb) + VARBITBYTES(vb) - 1) &= BITMASK << pad_; \
50+ } while (0)
51+
52+ /*
53+ * Many functions work byte-by-byte, so they have a pointer handy to the
54+ * last-plus-one byte, which saves a cycle or two.
55+ */
56+ #define VARBIT_PAD_LAST (vb ,ptr ) \
57+ do { \
58+ int32pad_ = VARBITPAD(vb); \
59+ Assert(pad_ >= 0 && pad_ < BITS_PER_BYTE); \
60+ if (pad_ > 0) \
61+ *((ptr) - 1) &= BITMASK << pad_; \
62+ } while (0)
63+
64+ /* Assert proper padding of a bitstring */
65+ #ifdef USE_ASSERT_CHECKING
66+ #define VARBIT_CORRECTLY_PADDED (vb ) \
67+ do { \
68+ int32pad_ = VARBITPAD(vb); \
69+ Assert(pad_ >= 0 && pad_ < BITS_PER_BYTE); \
70+ Assert(pad_ == 0 || \
71+ (*(VARBITS(vb) + VARBITBYTES(vb) - 1) & ~(BITMASK << pad_)) == 0); \
72+ } while (0)
73+ #else
74+ #define VARBIT_CORRECTLY_PADDED (vb ) ((void) 0)
75+ #endif
76+
2877static VarBit * bit_catenate (VarBit * arg1 ,VarBit * arg2 );
2978static VarBit * bitsubstring (VarBit * arg ,int32 s ,int32 l ,
3079bool length_not_specified );
@@ -85,24 +134,6 @@ anybit_typmodout(int32 typmod)
85134}
86135
87136
88- /*----------
89- *attypmod -- contains the length of the bit string in bits, or for
90- * varying bits the maximum length.
91- *
92- *The data structure contains the following elements:
93- * header -- length of the whole data structure (incl header)
94- * in bytes. (as with all varying length datatypes)
95- * data section -- private data section for the bits data structures
96- *bitlength -- length of the bit string in bits
97- *bitdata -- bit string, most significant byte first
98- *
99- *The length of the bitdata vector should always be exactly as many
100- *bytes as are needed for the given bitlength. If the bitlength is
101- *not a multiple of 8, the extra low-order padding bits of the last
102- *byte must be zeroes.
103- *----------
104- */
105-
106137/*
107138 * bit_in -
108139 * converts a char string to the internal representation of a bitstring.
@@ -262,6 +293,9 @@ bit_out(PG_FUNCTION_ARGS)
262293len ,
263294bitlen ;
264295
296+ /* Assertion to help catch any bit functions that don't pad correctly */
297+ VARBIT_CORRECTLY_PADDED (s );
298+
265299bitlen = VARBITLEN (s );
266300len = (bitlen + 3 ) /4 ;
267301result = (char * )palloc (len + 2 );
@@ -302,8 +336,6 @@ bit_recv(PG_FUNCTION_ARGS)
302336VarBit * result ;
303337int len ,
304338bitlen ;
305- int ipad ;
306- bits8 mask ;
307339
308340bitlen = pq_getmsgint (buf ,sizeof (int32 ));
309341if (bitlen < 0 || bitlen > VARBITMAXLEN )
@@ -328,13 +360,8 @@ bit_recv(PG_FUNCTION_ARGS)
328360
329361pq_copymsgbytes (buf , (char * )VARBITS (result ),VARBITBYTES (result ));
330362
331- /* Make sure last byte is zero-padded if needed */
332- ipad = VARBITPAD (result );
333- if (ipad > 0 )
334- {
335- mask = BITMASK <<ipad ;
336- * (VARBITS (result )+ VARBITBYTES (result )- 1 ) &=mask ;
337- }
363+ /* Make sure last byte is correctly zero-padded */
364+ VARBIT_PAD (result );
338365
339366PG_RETURN_VARBIT_P (result );
340367}
@@ -365,8 +392,6 @@ bit(PG_FUNCTION_ARGS)
365392bool isExplicit = PG_GETARG_BOOL (2 );
366393VarBit * result ;
367394int rlen ;
368- int ipad ;
369- bits8 mask ;
370395
371396/* No work if typmod is invalid or supplied data matches it already */
372397if (len <=0 || len > VARBITMAXLEN || len == VARBITLEN (arg ))
@@ -392,12 +417,7 @@ bit(PG_FUNCTION_ARGS)
392417 * if source data was shorter than target length (we assume the last byte
393418 * of the source data was itself correctly zero-padded).
394419 */
395- ipad = VARBITPAD (result );
396- if (ipad > 0 )
397- {
398- mask = BITMASK <<ipad ;
399- * (VARBITS (result )+ VARBITBYTES (result )- 1 ) &=mask ;
400- }
420+ VARBIT_PAD (result );
401421
402422PG_RETURN_VARBIT_P (result );
403423}
@@ -572,6 +592,9 @@ varbit_out(PG_FUNCTION_ARGS)
572592k ,
573593len ;
574594
595+ /* Assertion to help catch any bit functions that don't pad correctly */
596+ VARBIT_CORRECTLY_PADDED (s );
597+
575598len = VARBITLEN (s );
576599result = (char * )palloc (len + 1 );
577600sp = VARBITS (s );
@@ -618,8 +641,6 @@ varbit_recv(PG_FUNCTION_ARGS)
618641VarBit * result ;
619642int len ,
620643bitlen ;
621- int ipad ;
622- bits8 mask ;
623644
624645bitlen = pq_getmsgint (buf ,sizeof (int32 ));
625646if (bitlen < 0 || bitlen > VARBITMAXLEN )
@@ -644,13 +665,8 @@ varbit_recv(PG_FUNCTION_ARGS)
644665
645666pq_copymsgbytes (buf , (char * )VARBITS (result ),VARBITBYTES (result ));
646667
647- /* Make sure last byte is zero-padded if needed */
648- ipad = VARBITPAD (result );
649- if (ipad > 0 )
650- {
651- mask = BITMASK <<ipad ;
652- * (VARBITS (result )+ VARBITBYTES (result )- 1 ) &=mask ;
653- }
668+ /* Make sure last byte is correctly zero-padded */
669+ VARBIT_PAD (result );
654670
655671PG_RETURN_VARBIT_P (result );
656672}
@@ -718,8 +734,6 @@ varbit(PG_FUNCTION_ARGS)
718734bool isExplicit = PG_GETARG_BOOL (2 );
719735VarBit * result ;
720736int rlen ;
721- int ipad ;
722- bits8 mask ;
723737
724738/* No work if typmod is invalid or supplied data matches it already */
725739if (len <=0 || len >=VARBITLEN (arg ))
@@ -738,13 +752,8 @@ varbit(PG_FUNCTION_ARGS)
738752
739753memcpy (VARBITS (result ),VARBITS (arg ),VARBITBYTES (result ));
740754
741- /* Make sure last byte is zero-padded if needed */
742- ipad = VARBITPAD (result );
743- if (ipad > 0 )
744- {
745- mask = BITMASK <<ipad ;
746- * (VARBITS (result )+ VARBITBYTES (result )- 1 ) &=mask ;
747- }
755+ /* Make sure last byte is correctly zero-padded */
756+ VARBIT_PAD (result );
748757
749758PG_RETURN_VARBIT_P (result );
750759}
@@ -1002,6 +1011,8 @@ bit_catenate(VarBit *arg1, VarBit *arg2)
10021011}
10031012}
10041013
1014+ /* The pad bits should be already zero at this point */
1015+
10051016return result ;
10061017}
10071018
@@ -1035,14 +1046,12 @@ bitsubstring(VarBit *arg, int32 s, int32 l, bool length_not_specified)
10351046int bitlen ,
10361047rbitlen ,
10371048len ,
1038- ipad = 0 ,
10391049ishift ,
10401050i ;
10411051int e ,
10421052s1 ,
10431053e1 ;
1044- bits8 mask ,
1045- * r ,
1054+ bits8 * r ,
10461055* ps ;
10471056
10481057bitlen = VARBITLEN (arg );
@@ -1107,13 +1116,9 @@ bitsubstring(VarBit *arg, int32 s, int32 l, bool length_not_specified)
11071116r ++ ;
11081117}
11091118}
1110- /* Do we need to pad at the end? */
1111- ipad = VARBITPAD (result );
1112- if (ipad > 0 )
1113- {
1114- mask = BITMASK <<ipad ;
1115- * (VARBITS (result )+ len - 1 ) &=mask ;
1116- }
1119+
1120+ /* Make sure last byte is correctly zero-padded */
1121+ VARBIT_PAD (result );
11171122}
11181123
11191124return result ;
@@ -1236,7 +1241,7 @@ bit_and(PG_FUNCTION_ARGS)
12361241for (i = 0 ;i < VARBITBYTES (arg1 );i ++ )
12371242* r ++ = * p1 ++ & * p2 ++ ;
12381243
1239- /* Padding is not needed as & of 0pad is 0 */
1244+ /* Padding is not needed as & of 0pads is 0 */
12401245
12411246PG_RETURN_VARBIT_P (result );
12421247}
@@ -1258,7 +1263,6 @@ bit_or(PG_FUNCTION_ARGS)
12581263bits8 * p1 ,
12591264* p2 ,
12601265* r ;
1261- bits8 mask ;
12621266
12631267bitlen1 = VARBITLEN (arg1 );
12641268bitlen2 = VARBITLEN (arg2 );
@@ -1277,13 +1281,7 @@ bit_or(PG_FUNCTION_ARGS)
12771281for (i = 0 ;i < VARBITBYTES (arg1 );i ++ )
12781282* r ++ = * p1 ++ |* p2 ++ ;
12791283
1280- /* Pad the result */
1281- mask = BITMASK <<VARBITPAD (result );
1282- if (mask )
1283- {
1284- r -- ;
1285- * r &=mask ;
1286- }
1284+ /* Padding is not needed as | of 0 pads is 0 */
12871285
12881286PG_RETURN_VARBIT_P (result );
12891287}
@@ -1305,7 +1303,6 @@ bitxor(PG_FUNCTION_ARGS)
13051303bits8 * p1 ,
13061304* p2 ,
13071305* r ;
1308- bits8 mask ;
13091306
13101307bitlen1 = VARBITLEN (arg1 );
13111308bitlen2 = VARBITLEN (arg2 );
@@ -1325,13 +1322,7 @@ bitxor(PG_FUNCTION_ARGS)
13251322for (i = 0 ;i < VARBITBYTES (arg1 );i ++ )
13261323* r ++ = * p1 ++ ^* p2 ++ ;
13271324
1328- /* Pad the result */
1329- mask = BITMASK <<VARBITPAD (result );
1330- if (mask )
1331- {
1332- r -- ;
1333- * r &=mask ;
1334- }
1325+ /* Padding is not needed as ^ of 0 pads is 0 */
13351326
13361327PG_RETURN_VARBIT_P (result );
13371328}
@@ -1347,7 +1338,6 @@ bitnot(PG_FUNCTION_ARGS)
13471338VarBit * result ;
13481339bits8 * p ,
13491340* r ;
1350- bits8 mask ;
13511341
13521342result = (VarBit * )palloc (VARSIZE (arg ));
13531343SET_VARSIZE (result ,VARSIZE (arg ));
@@ -1358,13 +1348,8 @@ bitnot(PG_FUNCTION_ARGS)
13581348for (;p < VARBITEND (arg );p ++ )
13591349* r ++ = ~* p ;
13601350
1361- /* Pad the result */
1362- mask = BITMASK <<VARBITPAD (result );
1363- if (mask )
1364- {
1365- r -- ;
1366- * r &=mask ;
1367- }
1351+ /* Must zero-pad the result, because extra bits are surely 1's here */
1352+ VARBIT_PAD_LAST (result ,r );
13681353
13691354PG_RETURN_VARBIT_P (result );
13701355}
@@ -1431,6 +1416,8 @@ bitshiftleft(PG_FUNCTION_ARGS)
14311416* r = 0 ;
14321417}
14331418
1419+ /* The pad bits should be already zero at this point */
1420+
14341421PG_RETURN_VARBIT_P (result );
14351422}
14361423
@@ -1497,6 +1484,8 @@ bitshiftright(PG_FUNCTION_ARGS)
14971484if ((++ r )< VARBITEND (result ))
14981485* r = (* p << (BITS_PER_BYTE - ishift ))& BITMASK ;
14991486}
1487+ /* We may have shifted 1's into the pad bits, so fix that */
1488+ VARBIT_PAD_LAST (result ,r );
15001489}
15011490
15021491PG_RETURN_VARBIT_P (result );