Skip to content

Commit 6c3b640

Browse files
committed
Fix bitshiftright()'s zero-padding some more.
Commit 5ac0d93 failed to entirely fix bitshiftright's habit of leaving one-bits in the pad space that should be all zeroes, because in a moment of sheer brain fade I'd concluded that only the code path used for not-a-multiple-of-8 shift distances needed to be fixed. Of course, a multiple-of-8 shift distance can also cause the problem, so we need to forcibly zero the extra bits in both cases. Per bug #16037 from Alexander Lakhin. As before, back-patch to all supported branches. Discussion: https://postgr.es/m/16037-1d1ebca564db54f4@postgresql.org
1 parent c2e3b31 commit 6c3b640

File tree

3 files changed

+76
-2
lines changed

3 files changed

+76
-2
lines changed

src/backend/utils/adt/varbit.c

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1483,6 +1483,7 @@ bitshiftright(PG_FUNCTION_ARGS)
14831483
/* Special case: we can do a memcpy */
14841484
len = VARBITBYTES(arg) - byte_shift;
14851485
memcpy(r, p, len);
1486+
r += len;
14861487
}
14871488
else
14881489
{
@@ -1494,10 +1495,11 @@ bitshiftright(PG_FUNCTION_ARGS)
14941495
if ((++r) < VARBITEND(result))
14951496
*r = (*p << (BITS_PER_BYTE - ishift)) & BITMASK;
14961497
}
1497-
/* We may have shifted 1's into the pad bits, so fix that */
1498-
VARBIT_PAD_LAST(result, r);
14991498
}
15001499

1500+
/* We may have shifted 1's into the pad bits, so fix that */
1501+
VARBIT_PAD_LAST(result, r);
1502+
15011503
PG_RETURN_VARBIT_P(result);
15021504
}
15031505

src/test/regress/expected/bit.out

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -499,6 +499,28 @@ SELECT b, b >> 1 AS bsr, b << 1 AS bsl
499499
0000000000000001 | 0000000000000000 | 0000000000000010
500500
(16 rows)
501501

502+
SELECT b, b >> 8 AS bsr8, b << 8 AS bsl8
503+
FROM BIT_SHIFT_TABLE ;
504+
b | bsr8 | bsl8
505+
------------------+------------------+------------------
506+
1101100000000000 | 0000000011011000 | 0000000000000000
507+
0110110000000000 | 0000000001101100 | 0000000000000000
508+
0011011000000000 | 0000000000110110 | 0000000000000000
509+
0001101100000000 | 0000000000011011 | 0000000000000000
510+
0000110110000000 | 0000000000001101 | 1000000000000000
511+
0000011011000000 | 0000000000000110 | 1100000000000000
512+
0000001101100000 | 0000000000000011 | 0110000000000000
513+
0000000110110000 | 0000000000000001 | 1011000000000000
514+
0000000011011000 | 0000000000000000 | 1101100000000000
515+
0000000001101100 | 0000000000000000 | 0110110000000000
516+
0000000000110110 | 0000000000000000 | 0011011000000000
517+
0000000000011011 | 0000000000000000 | 0001101100000000
518+
0000000000001101 | 0000000000000000 | 0000110100000000
519+
0000000000000110 | 0000000000000000 | 0000011000000000
520+
0000000000000011 | 0000000000000000 | 0000001100000000
521+
0000000000000001 | 0000000000000000 | 0000000100000000
522+
(16 rows)
523+
502524
SELECT b::bit(15), b::bit(15) >> 1 AS bsr, b::bit(15) << 1 AS bsl
503525
FROM BIT_SHIFT_TABLE ;
504526
b | bsr | bsl
@@ -521,6 +543,28 @@ SELECT b::bit(15), b::bit(15) >> 1 AS bsr, b::bit(15) << 1 AS bsl
521543
000000000000000 | 000000000000000 | 000000000000000
522544
(16 rows)
523545

546+
SELECT b::bit(15), b::bit(15) >> 8 AS bsr8, b::bit(15) << 8 AS bsl8
547+
FROM BIT_SHIFT_TABLE ;
548+
b | bsr8 | bsl8
549+
-----------------+-----------------+-----------------
550+
110110000000000 | 000000001101100 | 000000000000000
551+
011011000000000 | 000000000110110 | 000000000000000
552+
001101100000000 | 000000000011011 | 000000000000000
553+
000110110000000 | 000000000001101 | 000000000000000
554+
000011011000000 | 000000000000110 | 100000000000000
555+
000001101100000 | 000000000000011 | 110000000000000
556+
000000110110000 | 000000000000001 | 011000000000000
557+
000000011011000 | 000000000000000 | 101100000000000
558+
000000001101100 | 000000000000000 | 110110000000000
559+
000000000110110 | 000000000000000 | 011011000000000
560+
000000000011011 | 000000000000000 | 001101100000000
561+
000000000001101 | 000000000000000 | 000110100000000
562+
000000000000110 | 000000000000000 | 000011000000000
563+
000000000000011 | 000000000000000 | 000001100000000
564+
000000000000001 | 000000000000000 | 000000100000000
565+
000000000000000 | 000000000000000 | 000000000000000
566+
(16 rows)
567+
524568
CREATE TABLE VARBIT_SHIFT_TABLE(v BIT VARYING(20));
525569
INSERT INTO VARBIT_SHIFT_TABLE VALUES (B'11011');
526570
INSERT INTO VARBIT_SHIFT_TABLE SELECT CAST(v || B'0' AS BIT VARYING(6)) >>1 FROM VARBIT_SHIFT_TABLE;
@@ -573,6 +617,28 @@ SELECT v, v >> 1 AS vsr, v << 1 AS vsl
573617
00000000000000011011 | 00000000000000001101 | 00000000000000110110
574618
(16 rows)
575619

620+
SELECT v, v >> 8 AS vsr8, v << 8 AS vsl8
621+
FROM VARBIT_SHIFT_TABLE ;
622+
v | vsr8 | vsl8
623+
----------------------+----------------------+----------------------
624+
11011 | 00000 | 00000
625+
011011 | 000000 | 000000
626+
0011011 | 0000000 | 0000000
627+
00011011 | 00000000 | 00000000
628+
000011011 | 000000000 | 100000000
629+
0000011011 | 0000000000 | 1100000000
630+
00000011011 | 00000000000 | 01100000000
631+
000000011011 | 000000000000 | 101100000000
632+
0000000011011 | 0000000000000 | 1101100000000
633+
00000000011011 | 00000000000000 | 01101100000000
634+
000000000011011 | 000000000000000 | 001101100000000
635+
0000000000011011 | 0000000000000000 | 0001101100000000
636+
00000000000011011 | 00000000000000000 | 00001101100000000
637+
000000000000011011 | 000000000000000000 | 000001101100000000
638+
0000000000000011011 | 0000000000000000000 | 0000001101100000000
639+
00000000000000011011 | 00000000000000000000 | 00000001101100000000
640+
(16 rows)
641+
576642
DROP TABLE BIT_SHIFT_TABLE;
577643
DROP TABLE VARBIT_SHIFT_TABLE;
578644
-- Get/Set bit

src/test/regress/sql/bit.sql

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -170,8 +170,12 @@ SELECT POSITION(B'1101' IN b),
170170
FROM BIT_SHIFT_TABLE ;
171171
SELECT b, b >> 1 AS bsr, b << 1 AS bsl
172172
FROM BIT_SHIFT_TABLE ;
173+
SELECT b, b >> 8 AS bsr8, b << 8 AS bsl8
174+
FROM BIT_SHIFT_TABLE ;
173175
SELECT b::bit(15), b::bit(15) >> 1 AS bsr, b::bit(15) << 1 AS bsl
174176
FROM BIT_SHIFT_TABLE ;
177+
SELECT b::bit(15), b::bit(15) >> 8 AS bsr8, b::bit(15) << 8 AS bsl8
178+
FROM BIT_SHIFT_TABLE ;
175179

176180

177181
CREATE TABLE VARBIT_SHIFT_TABLE(v BIT VARYING(20));
@@ -186,6 +190,8 @@ SELECT POSITION(B'1101' IN v),
186190
FROM VARBIT_SHIFT_TABLE ;
187191
SELECT v, v >> 1 AS vsr, v << 1 AS vsl
188192
FROM VARBIT_SHIFT_TABLE ;
193+
SELECT v, v >> 8 AS vsr8, v << 8 AS vsl8
194+
FROM VARBIT_SHIFT_TABLE ;
189195

190196
DROP TABLE BIT_SHIFT_TABLE;
191197
DROP TABLE VARBIT_SHIFT_TABLE;

0 commit comments

Comments
 (0)