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-2019, PostgreSQL Global Development Group
2742
2843#define HEXDIG (z ) ((z)<10 ? ((z)+'0') : ((z)-10+'A'))
2944
45+ /* Mask off any bits that should be zero in the last byte of a bitstring */
46+ #define VARBIT_PAD (vb ) \
47+ do { \
48+ int32pad_ = VARBITPAD(vb); \
49+ Assert(pad_ >= 0 && pad_ < BITS_PER_BYTE); \
50+ if (pad_ > 0) \
51+ *(VARBITS(vb) + VARBITBYTES(vb) - 1) &= BITMASK << pad_; \
52+ } while (0)
53+
54+ /*
55+ * Many functions work byte-by-byte, so they have a pointer handy to the
56+ * last-plus-one byte, which saves a cycle or two.
57+ */
58+ #define VARBIT_PAD_LAST (vb ,ptr ) \
59+ do { \
60+ int32pad_ = VARBITPAD(vb); \
61+ Assert(pad_ >= 0 && pad_ < BITS_PER_BYTE); \
62+ if (pad_ > 0) \
63+ *((ptr) - 1) &= BITMASK << pad_; \
64+ } while (0)
65+
66+ /* Assert proper padding of a bitstring */
67+ #ifdef USE_ASSERT_CHECKING
68+ #define VARBIT_CORRECTLY_PADDED (vb ) \
69+ do { \
70+ int32pad_ = VARBITPAD(vb); \
71+ Assert(pad_ >= 0 && pad_ < BITS_PER_BYTE); \
72+ Assert(pad_ == 0 || \
73+ (*(VARBITS(vb) + VARBITBYTES(vb) - 1) & ~(BITMASK << pad_)) == 0); \
74+ } while (0)
75+ #else
76+ #define VARBIT_CORRECTLY_PADDED (vb ) ((void) 0)
77+ #endif
78+
3079static VarBit * bit_catenate (VarBit * arg1 ,VarBit * arg2 );
3180static VarBit * bitsubstring (VarBit * arg ,int32 s ,int32 l ,
3281bool length_not_specified );
@@ -87,24 +136,6 @@ anybit_typmodout(int32 typmod)
87136}
88137
89138
90- /*----------
91- *attypmod -- contains the length of the bit string in bits, or for
92- * varying bits the maximum length.
93- *
94- *The data structure contains the following elements:
95- * header -- length of the whole data structure (incl header)
96- * in bytes. (as with all varying length datatypes)
97- * data section -- private data section for the bits data structures
98- *bitlength -- length of the bit string in bits
99- *bitdata -- bit string, most significant byte first
100- *
101- *The length of the bitdata vector should always be exactly as many
102- *bytes as are needed for the given bitlength. If the bitlength is
103- *not a multiple of 8, the extra low-order padding bits of the last
104- *byte must be zeroes.
105- *----------
106- */
107-
108139/*
109140 * bit_in -
110141 * converts a char string to the internal representation of a bitstring.
@@ -264,6 +295,9 @@ bit_out(PG_FUNCTION_ARGS)
264295len ,
265296bitlen ;
266297
298+ /* Assertion to help catch any bit functions that don't pad correctly */
299+ VARBIT_CORRECTLY_PADDED (s );
300+
267301bitlen = VARBITLEN (s );
268302len = (bitlen + 3 ) /4 ;
269303result = (char * )palloc (len + 2 );
@@ -304,8 +338,6 @@ bit_recv(PG_FUNCTION_ARGS)
304338VarBit * result ;
305339int len ,
306340bitlen ;
307- int ipad ;
308- bits8 mask ;
309341
310342bitlen = pq_getmsgint (buf ,sizeof (int32 ));
311343if (bitlen < 0 || bitlen > VARBITMAXLEN )
@@ -330,13 +362,8 @@ bit_recv(PG_FUNCTION_ARGS)
330362
331363pq_copymsgbytes (buf , (char * )VARBITS (result ),VARBITBYTES (result ));
332364
333- /* Make sure last byte is zero-padded if needed */
334- ipad = VARBITPAD (result );
335- if (ipad > 0 )
336- {
337- mask = BITMASK <<ipad ;
338- * (VARBITS (result )+ VARBITBYTES (result )- 1 ) &=mask ;
339- }
365+ /* Make sure last byte is correctly zero-padded */
366+ VARBIT_PAD (result );
340367
341368PG_RETURN_VARBIT_P (result );
342369}
@@ -367,8 +394,6 @@ bit(PG_FUNCTION_ARGS)
367394bool isExplicit = PG_GETARG_BOOL (2 );
368395VarBit * result ;
369396int rlen ;
370- int ipad ;
371- bits8 mask ;
372397
373398/* No work if typmod is invalid or supplied data matches it already */
374399if (len <=0 || len > VARBITMAXLEN || len == VARBITLEN (arg ))
@@ -394,12 +419,7 @@ bit(PG_FUNCTION_ARGS)
394419 * if source data was shorter than target length (we assume the last byte
395420 * of the source data was itself correctly zero-padded).
396421 */
397- ipad = VARBITPAD (result );
398- if (ipad > 0 )
399- {
400- mask = BITMASK <<ipad ;
401- * (VARBITS (result )+ VARBITBYTES (result )- 1 ) &=mask ;
402- }
422+ VARBIT_PAD (result );
403423
404424PG_RETURN_VARBIT_P (result );
405425}
@@ -574,6 +594,9 @@ varbit_out(PG_FUNCTION_ARGS)
574594k ,
575595len ;
576596
597+ /* Assertion to help catch any bit functions that don't pad correctly */
598+ VARBIT_CORRECTLY_PADDED (s );
599+
577600len = VARBITLEN (s );
578601result = (char * )palloc (len + 1 );
579602sp = VARBITS (s );
@@ -620,8 +643,6 @@ varbit_recv(PG_FUNCTION_ARGS)
620643VarBit * result ;
621644int len ,
622645bitlen ;
623- int ipad ;
624- bits8 mask ;
625646
626647bitlen = pq_getmsgint (buf ,sizeof (int32 ));
627648if (bitlen < 0 || bitlen > VARBITMAXLEN )
@@ -646,13 +667,8 @@ varbit_recv(PG_FUNCTION_ARGS)
646667
647668pq_copymsgbytes (buf , (char * )VARBITS (result ),VARBITBYTES (result ));
648669
649- /* Make sure last byte is zero-padded if needed */
650- ipad = VARBITPAD (result );
651- if (ipad > 0 )
652- {
653- mask = BITMASK <<ipad ;
654- * (VARBITS (result )+ VARBITBYTES (result )- 1 ) &=mask ;
655- }
670+ /* Make sure last byte is correctly zero-padded */
671+ VARBIT_PAD (result );
656672
657673PG_RETURN_VARBIT_P (result );
658674}
@@ -729,8 +745,6 @@ varbit(PG_FUNCTION_ARGS)
729745bool isExplicit = PG_GETARG_BOOL (2 );
730746VarBit * result ;
731747int rlen ;
732- int ipad ;
733- bits8 mask ;
734748
735749/* No work if typmod is invalid or supplied data matches it already */
736750if (len <=0 || len >=VARBITLEN (arg ))
@@ -749,13 +763,8 @@ varbit(PG_FUNCTION_ARGS)
749763
750764memcpy (VARBITS (result ),VARBITS (arg ),VARBITBYTES (result ));
751765
752- /* Make sure last byte is zero-padded if needed */
753- ipad = VARBITPAD (result );
754- if (ipad > 0 )
755- {
756- mask = BITMASK <<ipad ;
757- * (VARBITS (result )+ VARBITBYTES (result )- 1 ) &=mask ;
758- }
766+ /* Make sure last byte is correctly zero-padded */
767+ VARBIT_PAD (result );
759768
760769PG_RETURN_VARBIT_P (result );
761770}
@@ -1013,6 +1022,8 @@ bit_catenate(VarBit *arg1, VarBit *arg2)
10131022}
10141023}
10151024
1025+ /* The pad bits should be already zero at this point */
1026+
10161027return result ;
10171028}
10181029
@@ -1046,14 +1057,12 @@ bitsubstring(VarBit *arg, int32 s, int32 l, bool length_not_specified)
10461057int bitlen ,
10471058rbitlen ,
10481059len ,
1049- ipad = 0 ,
10501060ishift ,
10511061i ;
10521062int e ,
10531063s1 ,
10541064e1 ;
1055- bits8 mask ,
1056- * r ,
1065+ bits8 * r ,
10571066* ps ;
10581067
10591068bitlen = VARBITLEN (arg );
@@ -1118,13 +1127,9 @@ bitsubstring(VarBit *arg, int32 s, int32 l, bool length_not_specified)
11181127r ++ ;
11191128}
11201129}
1121- /* Do we need to pad at the end? */
1122- ipad = VARBITPAD (result );
1123- if (ipad > 0 )
1124- {
1125- mask = BITMASK <<ipad ;
1126- * (VARBITS (result )+ len - 1 ) &=mask ;
1127- }
1130+
1131+ /* Make sure last byte is correctly zero-padded */
1132+ VARBIT_PAD (result );
11281133}
11291134
11301135return result ;
@@ -1246,7 +1251,7 @@ bit_and(PG_FUNCTION_ARGS)
12461251for (i = 0 ;i < VARBITBYTES (arg1 );i ++ )
12471252* r ++ = * p1 ++ & * p2 ++ ;
12481253
1249- /* Padding is not needed as & of 0pad is 0 */
1254+ /* Padding is not needed as & of 0pads is 0 */
12501255
12511256PG_RETURN_VARBIT_P (result );
12521257}
@@ -1268,7 +1273,6 @@ bit_or(PG_FUNCTION_ARGS)
12681273bits8 * p1 ,
12691274* p2 ,
12701275* r ;
1271- bits8 mask ;
12721276
12731277bitlen1 = VARBITLEN (arg1 );
12741278bitlen2 = VARBITLEN (arg2 );
@@ -1287,13 +1291,7 @@ bit_or(PG_FUNCTION_ARGS)
12871291for (i = 0 ;i < VARBITBYTES (arg1 );i ++ )
12881292* r ++ = * p1 ++ |* p2 ++ ;
12891293
1290- /* Pad the result */
1291- mask = BITMASK <<VARBITPAD (result );
1292- if (mask )
1293- {
1294- r -- ;
1295- * r &=mask ;
1296- }
1294+ /* Padding is not needed as | of 0 pads is 0 */
12971295
12981296PG_RETURN_VARBIT_P (result );
12991297}
@@ -1315,7 +1313,6 @@ bitxor(PG_FUNCTION_ARGS)
13151313bits8 * p1 ,
13161314* p2 ,
13171315* r ;
1318- bits8 mask ;
13191316
13201317bitlen1 = VARBITLEN (arg1 );
13211318bitlen2 = VARBITLEN (arg2 );
@@ -1335,13 +1332,7 @@ bitxor(PG_FUNCTION_ARGS)
13351332for (i = 0 ;i < VARBITBYTES (arg1 );i ++ )
13361333* r ++ = * p1 ++ ^* p2 ++ ;
13371334
1338- /* Pad the result */
1339- mask = BITMASK <<VARBITPAD (result );
1340- if (mask )
1341- {
1342- r -- ;
1343- * r &=mask ;
1344- }
1335+ /* Padding is not needed as ^ of 0 pads is 0 */
13451336
13461337PG_RETURN_VARBIT_P (result );
13471338}
@@ -1357,7 +1348,6 @@ bitnot(PG_FUNCTION_ARGS)
13571348VarBit * result ;
13581349bits8 * p ,
13591350* r ;
1360- bits8 mask ;
13611351
13621352result = (VarBit * )palloc (VARSIZE (arg ));
13631353SET_VARSIZE (result ,VARSIZE (arg ));
@@ -1368,13 +1358,8 @@ bitnot(PG_FUNCTION_ARGS)
13681358for (;p < VARBITEND (arg );p ++ )
13691359* r ++ = ~* p ;
13701360
1371- /* Pad the result */
1372- mask = BITMASK <<VARBITPAD (result );
1373- if (mask )
1374- {
1375- r -- ;
1376- * r &=mask ;
1377- }
1361+ /* Must zero-pad the result, because extra bits are surely 1's here */
1362+ VARBIT_PAD_LAST (result ,r );
13781363
13791364PG_RETURN_VARBIT_P (result );
13801365}
@@ -1441,6 +1426,8 @@ bitshiftleft(PG_FUNCTION_ARGS)
14411426* r = 0 ;
14421427}
14431428
1429+ /* The pad bits should be already zero at this point */
1430+
14441431PG_RETURN_VARBIT_P (result );
14451432}
14461433
@@ -1507,6 +1494,8 @@ bitshiftright(PG_FUNCTION_ARGS)
15071494if ((++ r )< VARBITEND (result ))
15081495* r = (* p << (BITS_PER_BYTE - ishift ))& BITMASK ;
15091496}
1497+ /* We may have shifted 1's into the pad bits, so fix that */
1498+ VARBIT_PAD_LAST (result ,r );
15101499}
15111500
15121501PG_RETURN_VARBIT_P (result );