postgres.git / summary / log / commit / refs
commit 3bd13da63ba3be6ff143190fc234e15783d51357
Author: Tom Lane <tgl@sss.pgh.pa.us>
Date: Sat Dec 12 19:25:04 2009 +0000
First released in: 9.0.0, 8.0.24, 8.1.20, 8.2.16, 8.3.10, 8.4.3
Fix integer-to-bit-string conversions to handle the first fractional byte
correctly when the output bit width is wider than the given integer by
something other than a multiple of 8 bits.
This has been wrong since I first wrote that code for 8.0 :-(. Kudos to
Roman Kononov for being the first to notice, though I didn't use his
patch. Per bug #5237.
src/backend/utils/adt/varbit.c | 16 +++++++++++++---
1 file changed, 13 insertions(+), 3 deletions(-)
diff --git a/src/backend/utils/adt/varbit.c b/src/backend/utils/adt/varbit.c
index 389749961c6..e027a017dcc 100644
--- a/src/backend/utils/adt/varbit.c
+++ b/src/backend/utils/adt/varbit.c
@@ -9,7 +9,7 @@
* Portions Copyright (c) 1994, Regents of the University of California
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/utils/adt/varbit.c,v 1.47.2.1 2007/08/21 02:40:18 tgl Exp $
+ * $PostgreSQL: pgsql/src/backend/utils/adt/varbit.c,v 1.47.2.2 2009/12/12 19:25:04 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -1265,7 +1265,12 @@ bitfromint4(PG_FUNCTION_ARGS)
/* store first fractional byte */
if (destbitsleft > srcbitsleft)
{
- *r++ = (bits8) ((a >> (srcbitsleft - 8)) & BITMASK);
+ int val = (int) (a >> (destbitsleft - 8));
+
+ /* Force sign-fill in case the compiler implements >> as zero-fill */
+ if (a < 0)
+ val |= (-1) << (srcbitsleft + 8 - destbitsleft);
+ *r++ = (bits8) (val & BITMASK);
destbitsleft -= 8;
}
/* Now srcbitsleft and destbitsleft are the same, need not track both */
@@ -1344,7 +1349,12 @@ bitfromint8(PG_FUNCTION_ARGS)
/* store first fractional byte */
if (destbitsleft > srcbitsleft)
{
- *r++ = (bits8) ((a >> (srcbitsleft - 8)) & BITMASK);
+ int val = (int) (a >> (destbitsleft - 8));
+
+ /* Force sign-fill in case the compiler implements >> as zero-fill */
+ if (a < 0)
+ val |= (-1) << (srcbitsleft + 8 - destbitsleft);
+ *r++ = (bits8) (val & BITMASK);
destbitsleft -= 8;
}
/* Now srcbitsleft and destbitsleft are the same, need not track both */
[parent: c89eec506415]