mirror of
https://github.com/ClickHouse/ClickHouse.git
synced 2024-11-24 00:22:29 +00:00
Merge pull request #71731 from ClickHouse/backport/24.3/71580
Backport #71580 to 24.3: Return 0 or default char instead of throwing an error in bitShift functions in case of out of bounds
This commit is contained in:
commit
a5b0c17a75
@ -24,6 +24,10 @@ struct BitShiftLeftImpl
|
||||
{
|
||||
if constexpr (is_big_int_v<B>)
|
||||
throw Exception(ErrorCodes::NOT_IMPLEMENTED, "BitShiftLeft is not implemented for big integers as second argument");
|
||||
else if (b < 0)
|
||||
throw Exception(ErrorCodes::ARGUMENT_OUT_OF_BOUND, "The number of shift positions needs to be a non-negative value");
|
||||
else if (static_cast<UInt256>(b) > 8 * sizeof(A))
|
||||
return static_cast<Result>(0);
|
||||
else if constexpr (is_big_int_v<A>)
|
||||
return static_cast<Result>(a) << static_cast<UInt32>(b);
|
||||
else
|
||||
@ -37,9 +41,13 @@ struct BitShiftLeftImpl
|
||||
throw Exception(ErrorCodes::NOT_IMPLEMENTED, "BitShiftLeft is not implemented for big integers as second argument");
|
||||
else
|
||||
{
|
||||
UInt8 word_size = 8;
|
||||
/// To prevent overflow
|
||||
if (static_cast<double>(b) >= (static_cast<double>(end - pos) * word_size) || b < 0)
|
||||
const UInt8 word_size = 8 * sizeof(*pos);
|
||||
size_t n = end - pos;
|
||||
const UInt128 bit_limit = static_cast<UInt128>(word_size) * n;
|
||||
if (b < 0)
|
||||
throw Exception(ErrorCodes::ARGUMENT_OUT_OF_BOUND, "The number of shift positions needs to be a non-negative value");
|
||||
|
||||
if (b == bit_limit || static_cast<decltype(bit_limit)>(b) > bit_limit)
|
||||
{
|
||||
// insert default value
|
||||
out_vec.push_back(0);
|
||||
@ -102,10 +110,13 @@ struct BitShiftLeftImpl
|
||||
throw Exception(ErrorCodes::NOT_IMPLEMENTED, "BitShiftLeft is not implemented for big integers as second argument");
|
||||
else
|
||||
{
|
||||
UInt8 word_size = 8;
|
||||
const UInt8 word_size = 8;
|
||||
size_t n = end - pos;
|
||||
/// To prevent overflow
|
||||
if (static_cast<double>(b) >= (static_cast<double>(n) * word_size) || b < 0)
|
||||
const UInt128 bit_limit = static_cast<UInt128>(word_size) * n;
|
||||
if (b < 0)
|
||||
throw Exception(ErrorCodes::ARGUMENT_OUT_OF_BOUND, "The number of shift positions needs to be a non-negative value");
|
||||
|
||||
if (b == bit_limit || static_cast<decltype(bit_limit)>(b) > bit_limit)
|
||||
{
|
||||
// insert default value
|
||||
out_vec.resize_fill(out_vec.size() + n);
|
||||
|
@ -25,6 +25,10 @@ struct BitShiftRightImpl
|
||||
{
|
||||
if constexpr (is_big_int_v<B>)
|
||||
throw Exception(ErrorCodes::NOT_IMPLEMENTED, "BitShiftRight is not implemented for big integers as second argument");
|
||||
else if (b < 0)
|
||||
throw Exception(ErrorCodes::ARGUMENT_OUT_OF_BOUND, "The number of shift positions needs to be a non-negative value");
|
||||
else if (static_cast<UInt256>(b) > 8 * sizeof(A))
|
||||
return static_cast<Result>(0);
|
||||
else if constexpr (is_big_int_v<A>)
|
||||
return static_cast<Result>(a) >> static_cast<UInt32>(b);
|
||||
else
|
||||
@ -53,9 +57,13 @@ struct BitShiftRightImpl
|
||||
throw Exception(ErrorCodes::NOT_IMPLEMENTED, "BitShiftRight is not implemented for big integers as second argument");
|
||||
else
|
||||
{
|
||||
UInt8 word_size = 8;
|
||||
/// To prevent overflow
|
||||
if (static_cast<double>(b) >= (static_cast<double>(end - pos) * word_size) || b < 0)
|
||||
const UInt8 word_size = 8;
|
||||
size_t n = end - pos;
|
||||
const UInt128 bit_limit = static_cast<UInt128>(word_size) * n;
|
||||
if (b < 0)
|
||||
throw Exception(ErrorCodes::ARGUMENT_OUT_OF_BOUND, "The number of shift positions needs to be a non-negative value");
|
||||
|
||||
if (b == bit_limit || static_cast<decltype(bit_limit)>(b) > bit_limit)
|
||||
{
|
||||
/// insert default value
|
||||
out_vec.push_back(0);
|
||||
@ -90,10 +98,13 @@ struct BitShiftRightImpl
|
||||
throw Exception(ErrorCodes::NOT_IMPLEMENTED, "BitShiftRight is not implemented for big integers as second argument");
|
||||
else
|
||||
{
|
||||
UInt8 word_size = 8;
|
||||
const UInt8 word_size = 8;
|
||||
size_t n = end - pos;
|
||||
/// To prevent overflow
|
||||
if (static_cast<double>(b) >= (static_cast<double>(n) * word_size) || b < 0)
|
||||
const UInt128 bit_limit = static_cast<UInt128>(word_size) * n;
|
||||
if (b < 0)
|
||||
throw Exception(ErrorCodes::ARGUMENT_OUT_OF_BOUND, "The number of shift positions needs to be a non-negative value");
|
||||
|
||||
if (b == bit_limit || static_cast<decltype(bit_limit)>(b) > bit_limit)
|
||||
{
|
||||
// insert default value
|
||||
out_vec.resize_fill(out_vec.size() + n);
|
||||
|
@ -0,0 +1,9 @@
|
||||
-- bitShiftRight
|
||||
0
|
||||
|
||||
\0\0\0\0\0\0\0\0
|
||||
-- bitShiftLeft
|
||||
0
|
||||
|
||||
\0\0\0\0\0\0\0\0
|
||||
OK
|
@ -0,0 +1,17 @@
|
||||
SELECT '-- bitShiftRight';
|
||||
SELECT bitShiftRight(1, -1); -- { serverError ARGUMENT_OUT_OF_BOUND }
|
||||
SELECT bitShiftRight(toUInt8(1), 8 + 1);
|
||||
SELECT bitShiftRight('hola', -1); -- { serverError ARGUMENT_OUT_OF_BOUND }
|
||||
SELECT bitShiftRight('hola', 4 * 8 + 1);
|
||||
SELECT bitShiftRight(toFixedString('hola', 8), -1); -- { serverError ARGUMENT_OUT_OF_BOUND }
|
||||
SELECT bitShiftRight(toFixedString('hola', 8), 8 * 8 + 1);
|
||||
|
||||
SELECT '-- bitShiftLeft';
|
||||
SELECT bitShiftLeft(1, -1); -- { serverError ARGUMENT_OUT_OF_BOUND }
|
||||
SELECT bitShiftLeft(toUInt8(1), 8 + 1);
|
||||
SELECT bitShiftLeft('hola', -1); -- { serverError ARGUMENT_OUT_OF_BOUND }
|
||||
SELECT bitShiftLeft('hola', 4 * 8 + 1);
|
||||
SELECT bitShiftLeft(toFixedString('hola', 8), -1); -- { serverError ARGUMENT_OUT_OF_BOUND }
|
||||
SELECT bitShiftLeft(toFixedString('hola', 8), 8 * 8 + 1);
|
||||
|
||||
SELECT 'OK';
|
Loading…
Reference in New Issue
Block a user