Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Skip to content

Commit a4e035b

Browse files
committed
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.
1 parent 02490d4 commit a4e035b

File tree

1 file changed

+13
-3
lines changed

1 file changed

+13
-3
lines changed

src/backend/utils/adt/varbit.c

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
* Portions Copyright (c) 1994, Regents of the University of California
1010
*
1111
* IDENTIFICATION
12-
* $PostgreSQL: pgsql/src/backend/utils/adt/varbit.c,v 1.58 2009/01/01 17:23:50 momjian Exp $
12+
* $PostgreSQL: pgsql/src/backend/utils/adt/varbit.c,v 1.59 2009/12/12 19:24:35 tgl Exp $
1313
*
1414
*-------------------------------------------------------------------------
1515
*/
@@ -1346,7 +1346,12 @@ bitfromint4(PG_FUNCTION_ARGS)
13461346
/* store first fractional byte */
13471347
if (destbitsleft > srcbitsleft)
13481348
{
1349-
*r++ = (bits8) ((a >> (srcbitsleft - 8)) & BITMASK);
1349+
int val = (int) (a >> (destbitsleft - 8));
1350+
1351+
/* Force sign-fill in case the compiler implements >> as zero-fill */
1352+
if (a < 0)
1353+
val |= (-1) << (srcbitsleft + 8 - destbitsleft);
1354+
*r++ = (bits8) (val & BITMASK);
13501355
destbitsleft -= 8;
13511356
}
13521357
/* Now srcbitsleft and destbitsleft are the same, need not track both */
@@ -1425,7 +1430,12 @@ bitfromint8(PG_FUNCTION_ARGS)
14251430
/* store first fractional byte */
14261431
if (destbitsleft > srcbitsleft)
14271432
{
1428-
*r++ = (bits8) ((a >> (srcbitsleft - 8)) & BITMASK);
1433+
int val = (int) (a >> (destbitsleft - 8));
1434+
1435+
/* Force sign-fill in case the compiler implements >> as zero-fill */
1436+
if (a < 0)
1437+
val |= (-1) << (srcbitsleft + 8 - destbitsleft);
1438+
*r++ = (bits8) (val & BITMASK);
14291439
destbitsleft -= 8;
14301440
}
14311441
/* Now srcbitsleft and destbitsleft are the same, need not track both */

0 commit comments

Comments
 (0)