Skip to content

Commit 61aa9f5

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 f2369bc commit 61aa9f5

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)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy