summaryrefslogtreecommitdiff
path: root/src/include/utils/varbit.h
diff options
context:
space:
mode:
authorTom Lane <tgl@sss.pgh.pa.us>2019-09-22 17:46:00 -0400
committerTom Lane <tgl@sss.pgh.pa.us>2019-09-22 17:46:00 -0400
commit096d34c3ba78fa56eb3ceb766f159b0fbf11adec (patch)
tree226accb589e65ebfe768dc355f4fef807aca1914 /src/include/utils/varbit.h
parent769802ef9e536e6d2dce11a59e757c32ea5c7cbf (diff)
Fix failure to zero-pad the result of bitshiftright().
If the bitstring length is not a multiple of 8, we'd shift the rightmost bits into the pad space, which must be zeroes --- bit_cmp, for one, depends on that. This'd lead to the result failing to compare equal to what it should compare equal to, as reported in bug #16013 from Daryl Waycott. This is, if memory serves, not the first such bug in the bitstring functions. In hopes of making it the last one, do a bit more work than minimally necessary to fix the bug: * Add assertion checks to bit_out() and varbit_out() to complain if they are given incorrectly-padded input. This will improve the odds that manual testing of any new patch finds problems. * Encapsulate the padding-related logic in macros to make it easier to use. Also, remove unnecessary padding logic from bit_or() and bitxor(). Somebody had already noted that we need not re-pad the result of bit_and() since the inputs are required to be the same length, but failed to extrapolate that to the other two. Also, move a comment block that once was near the head of varbit.c (but people kept putting other stuff in front of it), to put it in the header block. Note for the release notes: if anyone has inconsistent data as a result of saving the output of bitshiftright() in a table, it's possible to fix it with something like UPDATE mytab SET bitcol = ~(~bitcol) WHERE bitcol != ~(~bitcol); This has been broken since day one, so back-patch to all supported branches. Discussion: https://postgr.es/m/16013-c2765b6996aacae9@postgresql.org
Diffstat (limited to 'src/include/utils/varbit.h')
-rw-r--r--src/include/utils/varbit.h5
1 files changed, 5 insertions, 0 deletions
diff --git a/src/include/utils/varbit.h b/src/include/utils/varbit.h
index 2a4ec67698e..c4ae4685865 100644
--- a/src/include/utils/varbit.h
+++ b/src/include/utils/varbit.h
@@ -21,6 +21,11 @@
/*
* Modeled on struct varlena from postgres.h, but data type is bits8.
+ *
+ * Caution: if bit_len is not a multiple of BITS_PER_BYTE, the low-order
+ * bits of the last byte of bit_dat[] are unused and MUST be zeroes.
+ * (This allows bit_cmp() to not bother masking the last byte.)
+ * Also, there should not be any excess bytes counted in the header length.
*/
typedef struct
{