Skip to content

Commit 051f87a

Browse files
authored
Merge pull request ClickHouse#71580 from ClickHouse/bitshift-return-0-instead-of-throwing-exception-for-out-of-bounds
Return 0 or default char instead of throwing an error in bitShift functions in case of out of bounds
2 parents 1794d8e + d8ff6f8 commit 051f87a

File tree

5 files changed

+37
-23
lines changed

5 files changed

+37
-23
lines changed

src/Functions/bitShiftLeft.cpp

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -25,8 +25,10 @@ struct BitShiftLeftImpl
2525
{
2626
if constexpr (is_big_int_v<B>)
2727
throw Exception(ErrorCodes::NOT_IMPLEMENTED, "BitShiftLeft is not implemented for big integers as second argument");
28-
else if (b < 0 || static_cast<UInt256>(b) > 8 * sizeof(A))
29-
throw Exception(ErrorCodes::ARGUMENT_OUT_OF_BOUND, "The number of shift positions needs to be a non-negative value and less or equal to the bit width of the value to shift");
28+
else if (b < 0)
29+
throw Exception(ErrorCodes::ARGUMENT_OUT_OF_BOUND, "The number of shift positions needs to be a non-negative value");
30+
else if (static_cast<UInt256>(b) > 8 * sizeof(A))
31+
return static_cast<Result>(0);
3032
else if constexpr (is_big_int_v<A>)
3133
return static_cast<Result>(a) << static_cast<UInt32>(b);
3234
else
@@ -43,9 +45,10 @@ struct BitShiftLeftImpl
4345
const UInt8 word_size = 8 * sizeof(*pos);
4446
size_t n = end - pos;
4547
const UInt128 bit_limit = static_cast<UInt128>(word_size) * n;
46-
if (b < 0 || static_cast<decltype(bit_limit)>(b) > bit_limit)
47-
throw Exception(ErrorCodes::ARGUMENT_OUT_OF_BOUND, "The number of shift positions needs to be a non-negative value and less or equal to the bit width of the value to shift");
48-
if (b == bit_limit)
48+
if (b < 0)
49+
throw Exception(ErrorCodes::ARGUMENT_OUT_OF_BOUND, "The number of shift positions needs to be a non-negative value");
50+
51+
if (b == bit_limit || static_cast<decltype(bit_limit)>(b) > bit_limit)
4952
{
5053
// insert default value
5154
out_vec.push_back(0);
@@ -111,9 +114,10 @@ struct BitShiftLeftImpl
111114
const UInt8 word_size = 8;
112115
size_t n = end - pos;
113116
const UInt128 bit_limit = static_cast<UInt128>(word_size) * n;
114-
if (b < 0 || static_cast<decltype(bit_limit)>(b) > bit_limit)
115-
throw Exception(ErrorCodes::ARGUMENT_OUT_OF_BOUND, "The number of shift positions needs to be a non-negative value and less or equal to the bit width of the value to shift");
116-
if (b == bit_limit)
117+
if (b < 0)
118+
throw Exception(ErrorCodes::ARGUMENT_OUT_OF_BOUND, "The number of shift positions needs to be a non-negative value");
119+
120+
if (b == bit_limit || static_cast<decltype(bit_limit)>(b) > bit_limit)
117121
{
118122
// insert default value
119123
out_vec.resize_fill(out_vec.size() + n);

src/Functions/bitShiftRight.cpp

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -26,8 +26,10 @@ struct BitShiftRightImpl
2626
{
2727
if constexpr (is_big_int_v<B>)
2828
throw Exception(ErrorCodes::NOT_IMPLEMENTED, "BitShiftRight is not implemented for big integers as second argument");
29-
else if (b < 0 || static_cast<UInt256>(b) > 8 * sizeof(A))
30-
throw Exception(ErrorCodes::ARGUMENT_OUT_OF_BOUND, "The number of shift positions needs to be a non-negative value and less or equal to the bit width of the value to shift");
29+
else if (b < 0)
30+
throw Exception(ErrorCodes::ARGUMENT_OUT_OF_BOUND, "The number of shift positions needs to be a non-negative value");
31+
else if (static_cast<UInt256>(b) > 8 * sizeof(A))
32+
return static_cast<Result>(0);
3133
else if constexpr (is_big_int_v<A>)
3234
return static_cast<Result>(a) >> static_cast<UInt32>(b);
3335
else
@@ -59,9 +61,10 @@ struct BitShiftRightImpl
5961
const UInt8 word_size = 8;
6062
size_t n = end - pos;
6163
const UInt128 bit_limit = static_cast<UInt128>(word_size) * n;
62-
if (b < 0 || static_cast<decltype(bit_limit)>(b) > bit_limit)
63-
throw Exception(ErrorCodes::ARGUMENT_OUT_OF_BOUND, "The number of shift positions needs to be a non-negative value and less or equal to the bit width of the value to shift");
64-
if (b == bit_limit)
64+
if (b < 0)
65+
throw Exception(ErrorCodes::ARGUMENT_OUT_OF_BOUND, "The number of shift positions needs to be a non-negative value");
66+
67+
if (b == bit_limit || static_cast<decltype(bit_limit)>(b) > bit_limit)
6568
{
6669
/// insert default value
6770
out_vec.push_back(0);
@@ -99,9 +102,10 @@ struct BitShiftRightImpl
99102
const UInt8 word_size = 8;
100103
size_t n = end - pos;
101104
const UInt128 bit_limit = static_cast<UInt128>(word_size) * n;
102-
if (b < 0 || static_cast<decltype(bit_limit)>(b) > bit_limit)
103-
throw Exception(ErrorCodes::ARGUMENT_OUT_OF_BOUND, "The number of shift positions needs to be a non-negative value and less or equal to the bit width of the value to shift");
104-
if (b == bit_limit)
105+
if (b < 0)
106+
throw Exception(ErrorCodes::ARGUMENT_OUT_OF_BOUND, "The number of shift positions needs to be a non-negative value");
107+
108+
if (b == bit_limit || static_cast<decltype(bit_limit)>(b) > bit_limit)
105109
{
106110
// insert default value
107111
out_vec.resize_fill(out_vec.size() + n);

tests/queries/0_stateless/02766_bitshift_with_const_arguments.sql

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ DROP TABLE IF EXISTS t1;
1010
CREATE TABLE t0 (vkey UInt32, pkey UInt32, c0 UInt32) engine = TinyLog;
1111
CREATE TABLE t1 (vkey UInt32) ENGINE = AggregatingMergeTree ORDER BY vkey;
1212
INSERT INTO t0 VALUES (15, 25000, 58);
13-
SELECT ref_5.pkey AS c_2_c2392_6 FROM t0 AS ref_5 WHERE 'J[' < multiIf(ref_5.pkey IN ( SELECT 1 ), bitShiftLeft(multiIf(ref_5.c0 > NULL, '1', ')'), 40), NULL); -- { serverError ARGUMENT_OUT_OF_BOUND }
13+
SELECT ref_5.pkey AS c_2_c2392_6 FROM t0 AS ref_5 WHERE 'J[' < multiIf(ref_5.pkey IN ( SELECT 1 ), bitShiftLeft(multiIf(ref_5.c0 > NULL, '1', ')'), 40), NULL);
1414
DROP TABLE t0;
1515
DROP TABLE t1;
1616

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,9 @@
11
-- bitShiftRight
2+
0
3+
4+
\0\0\0\0\0\0\0\0
25
-- bitShiftLeft
6+
0
7+
8+
\0\0\0\0\0\0\0\0
39
OK
Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,17 @@
11
SELECT '-- bitShiftRight';
22
SELECT bitShiftRight(1, -1); -- { serverError ARGUMENT_OUT_OF_BOUND }
3-
SELECT bitShiftRight(toUInt8(1), 8 + 1); -- { serverError ARGUMENT_OUT_OF_BOUND }
3+
SELECT bitShiftRight(toUInt8(1), 8 + 1);
44
SELECT bitShiftRight('hola', -1); -- { serverError ARGUMENT_OUT_OF_BOUND }
5-
SELECT bitShiftRight('hola', 4 * 8 + 1); -- { serverError ARGUMENT_OUT_OF_BOUND }
5+
SELECT bitShiftRight('hola', 4 * 8 + 1);
66
SELECT bitShiftRight(toFixedString('hola', 8), -1); -- { serverError ARGUMENT_OUT_OF_BOUND }
7-
SELECT bitShiftRight(toFixedString('hola', 8), 8 * 8 + 1); -- { serverError ARGUMENT_OUT_OF_BOUND }
7+
SELECT bitShiftRight(toFixedString('hola', 8), 8 * 8 + 1);
88

99
SELECT '-- bitShiftLeft';
1010
SELECT bitShiftLeft(1, -1); -- { serverError ARGUMENT_OUT_OF_BOUND }
11-
SELECT bitShiftLeft(toUInt8(1), 8 + 1); -- { serverError ARGUMENT_OUT_OF_BOUND }
11+
SELECT bitShiftLeft(toUInt8(1), 8 + 1);
1212
SELECT bitShiftLeft('hola', -1); -- { serverError ARGUMENT_OUT_OF_BOUND }
13-
SELECT bitShiftLeft('hola', 4 * 8 + 1); -- { serverError ARGUMENT_OUT_OF_BOUND }
13+
SELECT bitShiftLeft('hola', 4 * 8 + 1);
1414
SELECT bitShiftLeft(toFixedString('hola', 8), -1); -- { serverError ARGUMENT_OUT_OF_BOUND }
15-
SELECT bitShiftLeft(toFixedString('hola', 8), 8 * 8 + 1); -- { serverError ARGUMENT_OUT_OF_BOUND }
15+
SELECT bitShiftLeft(toFixedString('hola', 8), 8 * 8 + 1);
1616

1717
SELECT 'OK';

0 commit comments

Comments
 (0)