Fix bitshiftright()'s zero-padding some more.
Commit 5ac0d9360 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
This commit is contained in:
parent
e5ff975719
commit
b8ddf0bdf7
@ -1473,6 +1473,7 @@ bitshiftright(PG_FUNCTION_ARGS)
|
|||||||
/* Special case: we can do a memcpy */
|
/* Special case: we can do a memcpy */
|
||||||
len = VARBITBYTES(arg) - byte_shift;
|
len = VARBITBYTES(arg) - byte_shift;
|
||||||
memcpy(r, p, len);
|
memcpy(r, p, len);
|
||||||
|
r += len;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -1484,9 +1485,10 @@ bitshiftright(PG_FUNCTION_ARGS)
|
|||||||
if ((++r) < VARBITEND(result))
|
if ((++r) < VARBITEND(result))
|
||||||
*r = (*p << (BITS_PER_BYTE - ishift)) & BITMASK;
|
*r = (*p << (BITS_PER_BYTE - ishift)) & BITMASK;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* We may have shifted 1's into the pad bits, so fix that */
|
/* We may have shifted 1's into the pad bits, so fix that */
|
||||||
VARBIT_PAD_LAST(result, r);
|
VARBIT_PAD_LAST(result, r);
|
||||||
}
|
|
||||||
|
|
||||||
PG_RETURN_VARBIT_P(result);
|
PG_RETURN_VARBIT_P(result);
|
||||||
}
|
}
|
||||||
|
@ -499,6 +499,28 @@ SELECT b, b >> 1 AS bsr, b << 1 AS bsl
|
|||||||
0000000000000001 | 0000000000000000 | 0000000000000010
|
0000000000000001 | 0000000000000000 | 0000000000000010
|
||||||
(16 rows)
|
(16 rows)
|
||||||
|
|
||||||
|
SELECT b, b >> 8 AS bsr8, b << 8 AS bsl8
|
||||||
|
FROM BIT_SHIFT_TABLE ;
|
||||||
|
b | bsr8 | bsl8
|
||||||
|
------------------+------------------+------------------
|
||||||
|
1101100000000000 | 0000000011011000 | 0000000000000000
|
||||||
|
0110110000000000 | 0000000001101100 | 0000000000000000
|
||||||
|
0011011000000000 | 0000000000110110 | 0000000000000000
|
||||||
|
0001101100000000 | 0000000000011011 | 0000000000000000
|
||||||
|
0000110110000000 | 0000000000001101 | 1000000000000000
|
||||||
|
0000011011000000 | 0000000000000110 | 1100000000000000
|
||||||
|
0000001101100000 | 0000000000000011 | 0110000000000000
|
||||||
|
0000000110110000 | 0000000000000001 | 1011000000000000
|
||||||
|
0000000011011000 | 0000000000000000 | 1101100000000000
|
||||||
|
0000000001101100 | 0000000000000000 | 0110110000000000
|
||||||
|
0000000000110110 | 0000000000000000 | 0011011000000000
|
||||||
|
0000000000011011 | 0000000000000000 | 0001101100000000
|
||||||
|
0000000000001101 | 0000000000000000 | 0000110100000000
|
||||||
|
0000000000000110 | 0000000000000000 | 0000011000000000
|
||||||
|
0000000000000011 | 0000000000000000 | 0000001100000000
|
||||||
|
0000000000000001 | 0000000000000000 | 0000000100000000
|
||||||
|
(16 rows)
|
||||||
|
|
||||||
SELECT b::bit(15), b::bit(15) >> 1 AS bsr, b::bit(15) << 1 AS bsl
|
SELECT b::bit(15), b::bit(15) >> 1 AS bsr, b::bit(15) << 1 AS bsl
|
||||||
FROM BIT_SHIFT_TABLE ;
|
FROM BIT_SHIFT_TABLE ;
|
||||||
b | bsr | bsl
|
b | bsr | bsl
|
||||||
@ -521,6 +543,28 @@ SELECT b::bit(15), b::bit(15) >> 1 AS bsr, b::bit(15) << 1 AS bsl
|
|||||||
000000000000000 | 000000000000000 | 000000000000000
|
000000000000000 | 000000000000000 | 000000000000000
|
||||||
(16 rows)
|
(16 rows)
|
||||||
|
|
||||||
|
SELECT b::bit(15), b::bit(15) >> 8 AS bsr8, b::bit(15) << 8 AS bsl8
|
||||||
|
FROM BIT_SHIFT_TABLE ;
|
||||||
|
b | bsr8 | bsl8
|
||||||
|
-----------------+-----------------+-----------------
|
||||||
|
110110000000000 | 000000001101100 | 000000000000000
|
||||||
|
011011000000000 | 000000000110110 | 000000000000000
|
||||||
|
001101100000000 | 000000000011011 | 000000000000000
|
||||||
|
000110110000000 | 000000000001101 | 000000000000000
|
||||||
|
000011011000000 | 000000000000110 | 100000000000000
|
||||||
|
000001101100000 | 000000000000011 | 110000000000000
|
||||||
|
000000110110000 | 000000000000001 | 011000000000000
|
||||||
|
000000011011000 | 000000000000000 | 101100000000000
|
||||||
|
000000001101100 | 000000000000000 | 110110000000000
|
||||||
|
000000000110110 | 000000000000000 | 011011000000000
|
||||||
|
000000000011011 | 000000000000000 | 001101100000000
|
||||||
|
000000000001101 | 000000000000000 | 000110100000000
|
||||||
|
000000000000110 | 000000000000000 | 000011000000000
|
||||||
|
000000000000011 | 000000000000000 | 000001100000000
|
||||||
|
000000000000001 | 000000000000000 | 000000100000000
|
||||||
|
000000000000000 | 000000000000000 | 000000000000000
|
||||||
|
(16 rows)
|
||||||
|
|
||||||
CREATE TABLE VARBIT_SHIFT_TABLE(v BIT VARYING(20));
|
CREATE TABLE VARBIT_SHIFT_TABLE(v BIT VARYING(20));
|
||||||
INSERT INTO VARBIT_SHIFT_TABLE VALUES (B'11011');
|
INSERT INTO VARBIT_SHIFT_TABLE VALUES (B'11011');
|
||||||
INSERT INTO VARBIT_SHIFT_TABLE SELECT CAST(v || B'0' AS BIT VARYING(6)) >>1 FROM VARBIT_SHIFT_TABLE;
|
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
|
|||||||
00000000000000011011 | 00000000000000001101 | 00000000000000110110
|
00000000000000011011 | 00000000000000001101 | 00000000000000110110
|
||||||
(16 rows)
|
(16 rows)
|
||||||
|
|
||||||
|
SELECT v, v >> 8 AS vsr8, v << 8 AS vsl8
|
||||||
|
FROM VARBIT_SHIFT_TABLE ;
|
||||||
|
v | vsr8 | vsl8
|
||||||
|
----------------------+----------------------+----------------------
|
||||||
|
11011 | 00000 | 00000
|
||||||
|
011011 | 000000 | 000000
|
||||||
|
0011011 | 0000000 | 0000000
|
||||||
|
00011011 | 00000000 | 00000000
|
||||||
|
000011011 | 000000000 | 100000000
|
||||||
|
0000011011 | 0000000000 | 1100000000
|
||||||
|
00000011011 | 00000000000 | 01100000000
|
||||||
|
000000011011 | 000000000000 | 101100000000
|
||||||
|
0000000011011 | 0000000000000 | 1101100000000
|
||||||
|
00000000011011 | 00000000000000 | 01101100000000
|
||||||
|
000000000011011 | 000000000000000 | 001101100000000
|
||||||
|
0000000000011011 | 0000000000000000 | 0001101100000000
|
||||||
|
00000000000011011 | 00000000000000000 | 00001101100000000
|
||||||
|
000000000000011011 | 000000000000000000 | 000001101100000000
|
||||||
|
0000000000000011011 | 0000000000000000000 | 0000001101100000000
|
||||||
|
00000000000000011011 | 00000000000000000000 | 00000001101100000000
|
||||||
|
(16 rows)
|
||||||
|
|
||||||
DROP TABLE BIT_SHIFT_TABLE;
|
DROP TABLE BIT_SHIFT_TABLE;
|
||||||
DROP TABLE VARBIT_SHIFT_TABLE;
|
DROP TABLE VARBIT_SHIFT_TABLE;
|
||||||
-- Get/Set bit
|
-- Get/Set bit
|
||||||
|
@ -170,8 +170,12 @@ SELECT POSITION(B'1101' IN b),
|
|||||||
FROM BIT_SHIFT_TABLE ;
|
FROM BIT_SHIFT_TABLE ;
|
||||||
SELECT b, b >> 1 AS bsr, b << 1 AS bsl
|
SELECT b, b >> 1 AS bsr, b << 1 AS bsl
|
||||||
FROM BIT_SHIFT_TABLE ;
|
FROM BIT_SHIFT_TABLE ;
|
||||||
|
SELECT b, b >> 8 AS bsr8, b << 8 AS bsl8
|
||||||
|
FROM BIT_SHIFT_TABLE ;
|
||||||
SELECT b::bit(15), b::bit(15) >> 1 AS bsr, b::bit(15) << 1 AS bsl
|
SELECT b::bit(15), b::bit(15) >> 1 AS bsr, b::bit(15) << 1 AS bsl
|
||||||
FROM BIT_SHIFT_TABLE ;
|
FROM BIT_SHIFT_TABLE ;
|
||||||
|
SELECT b::bit(15), b::bit(15) >> 8 AS bsr8, b::bit(15) << 8 AS bsl8
|
||||||
|
FROM BIT_SHIFT_TABLE ;
|
||||||
|
|
||||||
|
|
||||||
CREATE TABLE VARBIT_SHIFT_TABLE(v BIT VARYING(20));
|
CREATE TABLE VARBIT_SHIFT_TABLE(v BIT VARYING(20));
|
||||||
@ -186,6 +190,8 @@ SELECT POSITION(B'1101' IN v),
|
|||||||
FROM VARBIT_SHIFT_TABLE ;
|
FROM VARBIT_SHIFT_TABLE ;
|
||||||
SELECT v, v >> 1 AS vsr, v << 1 AS vsl
|
SELECT v, v >> 1 AS vsr, v << 1 AS vsl
|
||||||
FROM VARBIT_SHIFT_TABLE ;
|
FROM VARBIT_SHIFT_TABLE ;
|
||||||
|
SELECT v, v >> 8 AS vsr8, v << 8 AS vsl8
|
||||||
|
FROM VARBIT_SHIFT_TABLE ;
|
||||||
|
|
||||||
DROP TABLE BIT_SHIFT_TABLE;
|
DROP TABLE BIT_SHIFT_TABLE;
|
||||||
DROP TABLE VARBIT_SHIFT_TABLE;
|
DROP TABLE VARBIT_SHIFT_TABLE;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user