3
3
* varbit.c
4
4
* Functions for the SQL datatypes BIT() and BIT VARYING().
5
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
+ *
6
21
* Code originally contributed by Adriaan Joubert.
7
22
*
8
23
* Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group
26
41
27
42
#define HEXDIG (z ) ((z)<10 ? ((z)+'0') : ((z)-10+'A'))
28
43
44
+ /* Mask off any bits that should be zero in the last byte of a bitstring */
45
+ #define VARBIT_PAD (vb ) \
46
+ do { \
47
+ int32pad_ = VARBITPAD(vb); \
48
+ Assert(pad_ >= 0 && pad_ < BITS_PER_BYTE); \
49
+ if (pad_ > 0) \
50
+ *(VARBITS(vb) + VARBITBYTES(vb) - 1) &= BITMASK << pad_; \
51
+ } while (0)
52
+
53
+ /*
54
+ * Many functions work byte-by-byte, so they have a pointer handy to the
55
+ * last-plus-one byte, which saves a cycle or two.
56
+ */
57
+ #define VARBIT_PAD_LAST (vb ,ptr ) \
58
+ do { \
59
+ int32pad_ = VARBITPAD(vb); \
60
+ Assert(pad_ >= 0 && pad_ < BITS_PER_BYTE); \
61
+ if (pad_ > 0) \
62
+ *((ptr) - 1) &= BITMASK << pad_; \
63
+ } while (0)
64
+
65
+ /* Assert proper padding of a bitstring */
66
+ #ifdef USE_ASSERT_CHECKING
67
+ #define VARBIT_CORRECTLY_PADDED (vb ) \
68
+ do { \
69
+ int32pad_ = VARBITPAD(vb); \
70
+ Assert(pad_ >= 0 && pad_ < BITS_PER_BYTE); \
71
+ Assert(pad_ == 0 || \
72
+ (*(VARBITS(vb) + VARBITBYTES(vb) - 1) & ~(BITMASK << pad_)) == 0); \
73
+ } while (0)
74
+ #else
75
+ #define VARBIT_CORRECTLY_PADDED (vb ) ((void) 0)
76
+ #endif
77
+
29
78
static VarBit * bit_catenate (VarBit * arg1 ,VarBit * arg2 );
30
79
static VarBit * bitsubstring (VarBit * arg ,int32 s ,int32 l ,
31
80
bool length_not_specified );
@@ -86,24 +135,6 @@ anybit_typmodout(int32 typmod)
86
135
}
87
136
88
137
89
- /*----------
90
- *attypmod -- contains the length of the bit string in bits, or for
91
- * varying bits the maximum length.
92
- *
93
- *The data structure contains the following elements:
94
- * header -- length of the whole data structure (incl header)
95
- * in bytes. (as with all varying length datatypes)
96
- * data section -- private data section for the bits data structures
97
- *bitlength -- length of the bit string in bits
98
- *bitdata -- bit string, most significant byte first
99
- *
100
- *The length of the bitdata vector should always be exactly as many
101
- *bytes as are needed for the given bitlength. If the bitlength is
102
- *not a multiple of 8, the extra low-order padding bits of the last
103
- *byte must be zeroes.
104
- *----------
105
- */
106
-
107
138
/*
108
139
* bit_in -
109
140
* converts a char string to the internal representation of a bitstring.
@@ -263,6 +294,9 @@ bit_out(PG_FUNCTION_ARGS)
263
294
len ,
264
295
bitlen ;
265
296
297
+ /* Assertion to help catch any bit functions that don't pad correctly */
298
+ VARBIT_CORRECTLY_PADDED (s );
299
+
266
300
bitlen = VARBITLEN (s );
267
301
len = (bitlen + 3 ) /4 ;
268
302
result = (char * )palloc (len + 2 );
@@ -303,8 +337,6 @@ bit_recv(PG_FUNCTION_ARGS)
303
337
VarBit * result ;
304
338
int len ,
305
339
bitlen ;
306
- int ipad ;
307
- bits8 mask ;
308
340
309
341
bitlen = pq_getmsgint (buf ,sizeof (int32 ));
310
342
if (bitlen < 0 || bitlen > VARBITMAXLEN )
@@ -329,13 +361,8 @@ bit_recv(PG_FUNCTION_ARGS)
329
361
330
362
pq_copymsgbytes (buf , (char * )VARBITS (result ),VARBITBYTES (result ));
331
363
332
- /* Make sure last byte is zero-padded if needed */
333
- ipad = VARBITPAD (result );
334
- if (ipad > 0 )
335
- {
336
- mask = BITMASK <<ipad ;
337
- * (VARBITS (result )+ VARBITBYTES (result )- 1 ) &=mask ;
338
- }
364
+ /* Make sure last byte is correctly zero-padded */
365
+ VARBIT_PAD (result );
339
366
340
367
PG_RETURN_VARBIT_P (result );
341
368
}
@@ -366,8 +393,6 @@ bit(PG_FUNCTION_ARGS)
366
393
bool isExplicit = PG_GETARG_BOOL (2 );
367
394
VarBit * result ;
368
395
int rlen ;
369
- int ipad ;
370
- bits8 mask ;
371
396
372
397
/* No work if typmod is invalid or supplied data matches it already */
373
398
if (len <=0 || len > VARBITMAXLEN || len == VARBITLEN (arg ))
@@ -393,12 +418,7 @@ bit(PG_FUNCTION_ARGS)
393
418
* if source data was shorter than target length (we assume the last byte
394
419
* of the source data was itself correctly zero-padded).
395
420
*/
396
- ipad = VARBITPAD (result );
397
- if (ipad > 0 )
398
- {
399
- mask = BITMASK <<ipad ;
400
- * (VARBITS (result )+ VARBITBYTES (result )- 1 ) &=mask ;
401
- }
421
+ VARBIT_PAD (result );
402
422
403
423
PG_RETURN_VARBIT_P (result );
404
424
}
@@ -573,6 +593,9 @@ varbit_out(PG_FUNCTION_ARGS)
573
593
k ,
574
594
len ;
575
595
596
+ /* Assertion to help catch any bit functions that don't pad correctly */
597
+ VARBIT_CORRECTLY_PADDED (s );
598
+
576
599
len = VARBITLEN (s );
577
600
result = (char * )palloc (len + 1 );
578
601
sp = VARBITS (s );
@@ -619,8 +642,6 @@ varbit_recv(PG_FUNCTION_ARGS)
619
642
VarBit * result ;
620
643
int len ,
621
644
bitlen ;
622
- int ipad ;
623
- bits8 mask ;
624
645
625
646
bitlen = pq_getmsgint (buf ,sizeof (int32 ));
626
647
if (bitlen < 0 || bitlen > VARBITMAXLEN )
@@ -645,13 +666,8 @@ varbit_recv(PG_FUNCTION_ARGS)
645
666
646
667
pq_copymsgbytes (buf , (char * )VARBITS (result ),VARBITBYTES (result ));
647
668
648
- /* Make sure last byte is zero-padded if needed */
649
- ipad = VARBITPAD (result );
650
- if (ipad > 0 )
651
- {
652
- mask = BITMASK <<ipad ;
653
- * (VARBITS (result )+ VARBITBYTES (result )- 1 ) &=mask ;
654
- }
669
+ /* Make sure last byte is correctly zero-padded */
670
+ VARBIT_PAD (result );
655
671
656
672
PG_RETURN_VARBIT_P (result );
657
673
}
@@ -719,8 +735,6 @@ varbit(PG_FUNCTION_ARGS)
719
735
bool isExplicit = PG_GETARG_BOOL (2 );
720
736
VarBit * result ;
721
737
int rlen ;
722
- int ipad ;
723
- bits8 mask ;
724
738
725
739
/* No work if typmod is invalid or supplied data matches it already */
726
740
if (len <=0 || len >=VARBITLEN (arg ))
@@ -739,13 +753,8 @@ varbit(PG_FUNCTION_ARGS)
739
753
740
754
memcpy (VARBITS (result ),VARBITS (arg ),VARBITBYTES (result ));
741
755
742
- /* Make sure last byte is zero-padded if needed */
743
- ipad = VARBITPAD (result );
744
- if (ipad > 0 )
745
- {
746
- mask = BITMASK <<ipad ;
747
- * (VARBITS (result )+ VARBITBYTES (result )- 1 ) &=mask ;
748
- }
756
+ /* Make sure last byte is correctly zero-padded */
757
+ VARBIT_PAD (result );
749
758
750
759
PG_RETURN_VARBIT_P (result );
751
760
}
@@ -1003,6 +1012,8 @@ bit_catenate(VarBit *arg1, VarBit *arg2)
1003
1012
}
1004
1013
}
1005
1014
1015
+ /* The pad bits should be already zero at this point */
1016
+
1006
1017
return result ;
1007
1018
}
1008
1019
@@ -1036,14 +1047,12 @@ bitsubstring(VarBit *arg, int32 s, int32 l, bool length_not_specified)
1036
1047
int bitlen ,
1037
1048
rbitlen ,
1038
1049
len ,
1039
- ipad = 0 ,
1040
1050
ishift ,
1041
1051
i ;
1042
1052
int e ,
1043
1053
s1 ,
1044
1054
e1 ;
1045
- bits8 mask ,
1046
- * r ,
1055
+ bits8 * r ,
1047
1056
* ps ;
1048
1057
1049
1058
bitlen = VARBITLEN (arg );
@@ -1108,13 +1117,9 @@ bitsubstring(VarBit *arg, int32 s, int32 l, bool length_not_specified)
1108
1117
r ++ ;
1109
1118
}
1110
1119
}
1111
- /* Do we need to pad at the end? */
1112
- ipad = VARBITPAD (result );
1113
- if (ipad > 0 )
1114
- {
1115
- mask = BITMASK <<ipad ;
1116
- * (VARBITS (result )+ len - 1 ) &=mask ;
1117
- }
1120
+
1121
+ /* Make sure last byte is correctly zero-padded */
1122
+ VARBIT_PAD (result );
1118
1123
}
1119
1124
1120
1125
return result ;
@@ -1236,7 +1241,7 @@ bit_and(PG_FUNCTION_ARGS)
1236
1241
for (i = 0 ;i < VARBITBYTES (arg1 );i ++ )
1237
1242
* r ++ = * p1 ++ & * p2 ++ ;
1238
1243
1239
- /* Padding is not needed as & of 0pad is 0 */
1244
+ /* Padding is not needed as & of 0pads is 0 */
1240
1245
1241
1246
PG_RETURN_VARBIT_P (result );
1242
1247
}
@@ -1258,7 +1263,6 @@ bit_or(PG_FUNCTION_ARGS)
1258
1263
bits8 * p1 ,
1259
1264
* p2 ,
1260
1265
* r ;
1261
- bits8 mask ;
1262
1266
1263
1267
bitlen1 = VARBITLEN (arg1 );
1264
1268
bitlen2 = VARBITLEN (arg2 );
@@ -1277,13 +1281,7 @@ bit_or(PG_FUNCTION_ARGS)
1277
1281
for (i = 0 ;i < VARBITBYTES (arg1 );i ++ )
1278
1282
* r ++ = * p1 ++ |* p2 ++ ;
1279
1283
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 */
1287
1285
1288
1286
PG_RETURN_VARBIT_P (result );
1289
1287
}
@@ -1305,7 +1303,6 @@ bitxor(PG_FUNCTION_ARGS)
1305
1303
bits8 * p1 ,
1306
1304
* p2 ,
1307
1305
* r ;
1308
- bits8 mask ;
1309
1306
1310
1307
bitlen1 = VARBITLEN (arg1 );
1311
1308
bitlen2 = VARBITLEN (arg2 );
@@ -1325,13 +1322,7 @@ bitxor(PG_FUNCTION_ARGS)
1325
1322
for (i = 0 ;i < VARBITBYTES (arg1 );i ++ )
1326
1323
* r ++ = * p1 ++ ^* p2 ++ ;
1327
1324
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 */
1335
1326
1336
1327
PG_RETURN_VARBIT_P (result );
1337
1328
}
@@ -1347,7 +1338,6 @@ bitnot(PG_FUNCTION_ARGS)
1347
1338
VarBit * result ;
1348
1339
bits8 * p ,
1349
1340
* r ;
1350
- bits8 mask ;
1351
1341
1352
1342
result = (VarBit * )palloc (VARSIZE (arg ));
1353
1343
SET_VARSIZE (result ,VARSIZE (arg ));
@@ -1358,13 +1348,8 @@ bitnot(PG_FUNCTION_ARGS)
1358
1348
for (;p < VARBITEND (arg );p ++ )
1359
1349
* r ++ = ~* p ;
1360
1350
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 );
1368
1353
1369
1354
PG_RETURN_VARBIT_P (result );
1370
1355
}
@@ -1431,6 +1416,8 @@ bitshiftleft(PG_FUNCTION_ARGS)
1431
1416
* r = 0 ;
1432
1417
}
1433
1418
1419
+ /* The pad bits should be already zero at this point */
1420
+
1434
1421
PG_RETURN_VARBIT_P (result );
1435
1422
}
1436
1423
@@ -1497,6 +1484,8 @@ bitshiftright(PG_FUNCTION_ARGS)
1497
1484
if ((++ r )< VARBITEND (result ))
1498
1485
* r = (* p << (BITS_PER_BYTE - ishift ))& BITMASK ;
1499
1486
}
1487
+ /* We may have shifted 1's into the pad bits, so fix that */
1488
+ VARBIT_PAD_LAST (result ,r );
1500
1489
}
1501
1490
1502
1491
PG_RETURN_VARBIT_P (result );