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-2014, PostgreSQL Global Development Group
24
39
25
40
#define HEXDIG (z ) ((z)<10 ? ((z)+'0') : ((z)-10+'A'))
26
41
42
+ /* Mask off any bits that should be zero in the last byte of a bitstring */
43
+ #define VARBIT_PAD (vb ) \
44
+ do { \
45
+ int32 pad_ = VARBITPAD(vb); \
46
+ Assert(pad_ >= 0 && pad_ < BITS_PER_BYTE); \
47
+ if (pad_ > 0) \
48
+ *(VARBITS(vb) + VARBITBYTES(vb) - 1) &= BITMASK << pad_; \
49
+ } while (0)
50
+
51
+ /*
52
+ * Many functions work byte-by-byte, so they have a pointer handy to the
53
+ * last-plus-one byte, which saves a cycle or two.
54
+ */
55
+ #define VARBIT_PAD_LAST (vb , ptr ) \
56
+ do { \
57
+ int32 pad_ = VARBITPAD(vb); \
58
+ Assert(pad_ >= 0 && pad_ < BITS_PER_BYTE); \
59
+ if (pad_ > 0) \
60
+ *((ptr) - 1) &= BITMASK << pad_; \
61
+ } while (0)
62
+
63
+ /* Assert proper padding of a bitstring */
64
+ #ifdef USE_ASSERT_CHECKING
65
+ #define VARBIT_CORRECTLY_PADDED (vb ) \
66
+ do { \
67
+ int32 pad_ = VARBITPAD(vb); \
68
+ Assert(pad_ >= 0 && pad_ < BITS_PER_BYTE); \
69
+ Assert(pad_ == 0 || \
70
+ (*(VARBITS(vb) + VARBITBYTES(vb) - 1) & ~(BITMASK << pad_)) == 0); \
71
+ } while (0)
72
+ #else
73
+ #define VARBIT_CORRECTLY_PADDED (vb ) ((void) 0)
74
+ #endif
75
+
27
76
static VarBit * bit_catenate (VarBit * arg1 , VarBit * arg2 );
28
77
static VarBit * bitsubstring (VarBit * arg , int32 s , int32 l ,
29
78
bool length_not_specified );
@@ -84,24 +133,6 @@ anybit_typmodout(int32 typmod)
84
133
}
85
134
86
135
87
- /*----------
88
- * attypmod -- contains the length of the bit string in bits, or for
89
- * varying bits the maximum length.
90
- *
91
- * The data structure contains the following elements:
92
- * header -- length of the whole data structure (incl header)
93
- * in bytes. (as with all varying length datatypes)
94
- * data section -- private data section for the bits data structures
95
- * bitlength -- length of the bit string in bits
96
- * bitdata -- bit string, most significant byte first
97
- *
98
- * The length of the bitdata vector should always be exactly as many
99
- * bytes as are needed for the given bitlength. If the bitlength is
100
- * not a multiple of 8, the extra low-order padding bits of the last
101
- * byte must be zeroes.
102
- *----------
103
- */
104
-
105
136
/*
106
137
* bit_in -
107
138
* converts a char string to the internal representation of a bitstring.
@@ -261,6 +292,9 @@ bit_out(PG_FUNCTION_ARGS)
261
292
len ,
262
293
bitlen ;
263
294
295
+ /* Assertion to help catch any bit functions that don't pad correctly */
296
+ VARBIT_CORRECTLY_PADDED (s );
297
+
264
298
bitlen = VARBITLEN (s );
265
299
len = (bitlen + 3 ) / 4 ;
266
300
result = (char * ) palloc (len + 2 );
@@ -301,8 +335,6 @@ bit_recv(PG_FUNCTION_ARGS)
301
335
VarBit * result ;
302
336
int len ,
303
337
bitlen ;
304
- int ipad ;
305
- bits8 mask ;
306
338
307
339
bitlen = pq_getmsgint (buf , sizeof (int32 ));
308
340
if (bitlen < 0 || bitlen > VARBITMAXLEN )
@@ -327,13 +359,8 @@ bit_recv(PG_FUNCTION_ARGS)
327
359
328
360
pq_copymsgbytes (buf , (char * ) VARBITS (result ), VARBITBYTES (result ));
329
361
330
- /* Make sure last byte is zero-padded if needed */
331
- ipad = VARBITPAD (result );
332
- if (ipad > 0 )
333
- {
334
- mask = BITMASK << ipad ;
335
- * (VARBITS (result ) + VARBITBYTES (result ) - 1 ) &= mask ;
336
- }
362
+ /* Make sure last byte is correctly zero-padded */
363
+ VARBIT_PAD (result );
337
364
338
365
PG_RETURN_VARBIT_P (result );
339
366
}
@@ -364,8 +391,6 @@ bit(PG_FUNCTION_ARGS)
364
391
bool isExplicit = PG_GETARG_BOOL (2 );
365
392
VarBit * result ;
366
393
int rlen ;
367
- int ipad ;
368
- bits8 mask ;
369
394
370
395
/* No work if typmod is invalid or supplied data matches it already */
371
396
if (len <= 0 || len > VARBITMAXLEN || len == VARBITLEN (arg ))
@@ -391,12 +416,7 @@ bit(PG_FUNCTION_ARGS)
391
416
* if source data was shorter than target length (we assume the last byte
392
417
* of the source data was itself correctly zero-padded).
393
418
*/
394
- ipad = VARBITPAD (result );
395
- if (ipad > 0 )
396
- {
397
- mask = BITMASK << ipad ;
398
- * (VARBITS (result ) + VARBITBYTES (result ) - 1 ) &= mask ;
399
- }
419
+ VARBIT_PAD (result );
400
420
401
421
PG_RETURN_VARBIT_P (result );
402
422
}
@@ -571,6 +591,9 @@ varbit_out(PG_FUNCTION_ARGS)
571
591
k ,
572
592
len ;
573
593
594
+ /* Assertion to help catch any bit functions that don't pad correctly */
595
+ VARBIT_CORRECTLY_PADDED (s );
596
+
574
597
len = VARBITLEN (s );
575
598
result = (char * ) palloc (len + 1 );
576
599
sp = VARBITS (s );
@@ -617,8 +640,6 @@ varbit_recv(PG_FUNCTION_ARGS)
617
640
VarBit * result ;
618
641
int len ,
619
642
bitlen ;
620
- int ipad ;
621
- bits8 mask ;
622
643
623
644
bitlen = pq_getmsgint (buf , sizeof (int32 ));
624
645
if (bitlen < 0 || bitlen > VARBITMAXLEN )
@@ -643,13 +664,8 @@ varbit_recv(PG_FUNCTION_ARGS)
643
664
644
665
pq_copymsgbytes (buf , (char * ) VARBITS (result ), VARBITBYTES (result ));
645
666
646
- /* Make sure last byte is zero-padded if needed */
647
- ipad = VARBITPAD (result );
648
- if (ipad > 0 )
649
- {
650
- mask = BITMASK << ipad ;
651
- * (VARBITS (result ) + VARBITBYTES (result ) - 1 ) &= mask ;
652
- }
667
+ /* Make sure last byte is correctly zero-padded */
668
+ VARBIT_PAD (result );
653
669
654
670
PG_RETURN_VARBIT_P (result );
655
671
}
@@ -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 0 pad is 0 */
1244
+ /* Padding is not needed as & of 0 pads 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 );
0 commit comments