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-2017, PostgreSQL Global Development Group
25
40
26
41
#define HEXDIG (z ) ((z)<10 ? ((z)+'0') : ((z)-10+'A'))
27
42
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
+
28
77
static VarBit * bit_catenate (VarBit * arg1 ,VarBit * arg2 );
29
78
static VarBit * bitsubstring (VarBit * arg ,int32 s ,int32 l ,
30
79
bool length_not_specified );
@@ -85,24 +134,6 @@ anybit_typmodout(int32 typmod)
85
134
}
86
135
87
136
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
-
106
137
/*
107
138
* bit_in -
108
139
* converts a char string to the internal representation of a bitstring.
@@ -262,6 +293,9 @@ bit_out(PG_FUNCTION_ARGS)
262
293
len ,
263
294
bitlen ;
264
295
296
+ /* Assertion to help catch any bit functions that don't pad correctly */
297
+ VARBIT_CORRECTLY_PADDED (s );
298
+
265
299
bitlen = VARBITLEN (s );
266
300
len = (bitlen + 3 ) /4 ;
267
301
result = (char * )palloc (len + 2 );
@@ -302,8 +336,6 @@ bit_recv(PG_FUNCTION_ARGS)
302
336
VarBit * result ;
303
337
int len ,
304
338
bitlen ;
305
- int ipad ;
306
- bits8 mask ;
307
339
308
340
bitlen = pq_getmsgint (buf ,sizeof (int32 ));
309
341
if (bitlen < 0 || bitlen > VARBITMAXLEN )
@@ -328,13 +360,8 @@ bit_recv(PG_FUNCTION_ARGS)
328
360
329
361
pq_copymsgbytes (buf , (char * )VARBITS (result ),VARBITBYTES (result ));
330
362
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 );
338
365
339
366
PG_RETURN_VARBIT_P (result );
340
367
}
@@ -365,8 +392,6 @@ bit(PG_FUNCTION_ARGS)
365
392
bool isExplicit = PG_GETARG_BOOL (2 );
366
393
VarBit * result ;
367
394
int rlen ;
368
- int ipad ;
369
- bits8 mask ;
370
395
371
396
/* No work if typmod is invalid or supplied data matches it already */
372
397
if (len <=0 || len > VARBITMAXLEN || len == VARBITLEN (arg ))
@@ -392,12 +417,7 @@ bit(PG_FUNCTION_ARGS)
392
417
* if source data was shorter than target length (we assume the last byte
393
418
* of the source data was itself correctly zero-padded).
394
419
*/
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 );
401
421
402
422
PG_RETURN_VARBIT_P (result );
403
423
}
@@ -572,6 +592,9 @@ varbit_out(PG_FUNCTION_ARGS)
572
592
k ,
573
593
len ;
574
594
595
+ /* Assertion to help catch any bit functions that don't pad correctly */
596
+ VARBIT_CORRECTLY_PADDED (s );
597
+
575
598
len = VARBITLEN (s );
576
599
result = (char * )palloc (len + 1 );
577
600
sp = VARBITS (s );
@@ -618,8 +641,6 @@ varbit_recv(PG_FUNCTION_ARGS)
618
641
VarBit * result ;
619
642
int len ,
620
643
bitlen ;
621
- int ipad ;
622
- bits8 mask ;
623
644
624
645
bitlen = pq_getmsgint (buf ,sizeof (int32 ));
625
646
if (bitlen < 0 || bitlen > VARBITMAXLEN )
@@ -644,13 +665,8 @@ varbit_recv(PG_FUNCTION_ARGS)
644
665
645
666
pq_copymsgbytes (buf , (char * )VARBITS (result ),VARBITBYTES (result ));
646
667
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 );
654
670
655
671
PG_RETURN_VARBIT_P (result );
656
672
}
@@ -718,8 +734,6 @@ varbit(PG_FUNCTION_ARGS)
718
734
bool isExplicit = PG_GETARG_BOOL (2 );
719
735
VarBit * result ;
720
736
int rlen ;
721
- int ipad ;
722
- bits8 mask ;
723
737
724
738
/* No work if typmod is invalid or supplied data matches it already */
725
739
if (len <=0 || len >=VARBITLEN (arg ))
@@ -738,13 +752,8 @@ varbit(PG_FUNCTION_ARGS)
738
752
739
753
memcpy (VARBITS (result ),VARBITS (arg ),VARBITBYTES (result ));
740
754
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 );
748
757
749
758
PG_RETURN_VARBIT_P (result );
750
759
}
@@ -1002,6 +1011,8 @@ bit_catenate(VarBit *arg1, VarBit *arg2)
1002
1011
}
1003
1012
}
1004
1013
1014
+ /* The pad bits should be already zero at this point */
1015
+
1005
1016
return result ;
1006
1017
}
1007
1018
@@ -1035,14 +1046,12 @@ bitsubstring(VarBit *arg, int32 s, int32 l, bool length_not_specified)
1035
1046
int bitlen ,
1036
1047
rbitlen ,
1037
1048
len ,
1038
- ipad = 0 ,
1039
1049
ishift ,
1040
1050
i ;
1041
1051
int e ,
1042
1052
s1 ,
1043
1053
e1 ;
1044
- bits8 mask ,
1045
- * r ,
1054
+ bits8 * r ,
1046
1055
* ps ;
1047
1056
1048
1057
bitlen = VARBITLEN (arg );
@@ -1107,13 +1116,9 @@ bitsubstring(VarBit *arg, int32 s, int32 l, bool length_not_specified)
1107
1116
r ++ ;
1108
1117
}
1109
1118
}
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 );
1117
1122
}
1118
1123
1119
1124
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 );