aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorTom Lane <tgl@sss.pgh.pa.us>2009-12-12 19:24:44 +0000
committerTom Lane <tgl@sss.pgh.pa.us>2009-12-12 19:24:44 +0000
commite2668636ca5e306c213eef52082a6e2ed1246608 (patch)
tree8b9241ec06c08258fd5c06684afcb986a834f4dd /src
parent5cc7c13022bf08ef72abfd19d193bc6f2b6b6809 (diff)
downloadpostgresql-e2668636ca5e306c213eef52082a6e2ed1246608.tar.gz
postgresql-e2668636ca5e306c213eef52082a6e2ed1246608.zip
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.
Diffstat (limited to 'src')
-rw-r--r--src/backend/utils/adt/varbit.c16
1 files changed, 13 insertions, 3 deletions
diff --git a/src/backend/utils/adt/varbit.c b/src/backend/utils/adt/varbit.c
index ec5a5bebd0f..35a79a0b147 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.58 2009/01/01 17:23:50 momjian Exp $
+ * $PostgreSQL: pgsql/src/backend/utils/adt/varbit.c,v 1.58.2.1 2009/12/12 19:24:44 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -1346,7 +1346,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 */
@@ -1425,7 +1430,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 */