mirror of
https://github.com/ClickHouse/ClickHouse.git
synced 2024-09-20 08:40:50 +00:00
Merge pull request #55211 from Priyansh121096/master
Add function byteSwap
This commit is contained in:
commit
d02a718076
@ -441,3 +441,40 @@ DB::Exception: Decimal result's scale is less than argument's one: While process
|
||||
│ -12 │ 2.1 │ -5.7 │ -5.71428 │
|
||||
└─────┴─────┴────────────────────────────────────────────────────────────┴────────────────────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
## byteSwap
|
||||
|
||||
Reverses the bytes of an integer, i.e. changes its [endianness](https://en.wikipedia.org/wiki/Endianness). Currently, integers of up to 64 bit are supported.
|
||||
|
||||
**Syntax**
|
||||
|
||||
```sql
|
||||
byteSwap(a)
|
||||
```
|
||||
|
||||
**Example**
|
||||
|
||||
```sql
|
||||
byteSwap(3351772109)
|
||||
```
|
||||
|
||||
Result:
|
||||
|
||||
```result
|
||||
┌─byteSwap(3351772109)─┐
|
||||
│ 3455829959 │
|
||||
└──────────────────────┘
|
||||
```
|
||||
|
||||
The above example can be worked out in the following manner:
|
||||
1. Convert the base-10 integer to its equivalent hexadecimal format in big-endian format, i.e. 3351772109 -> C7 C7 FB CD (4 bytes)
|
||||
2. Reverse the bytes, i.e. C7 C7 FB CD -> CD FB C7 C7
|
||||
3. Convert the result back to an integer assuming big-endian, i.e. CD FB C7 C7 -> 3455829959
|
||||
|
||||
One use case of this function is reversing IPv4s:
|
||||
|
||||
```result
|
||||
┌─toIPv4(byteSwap(toUInt32(toIPv4('205.251.199.199'))))─┐
|
||||
│ 199.199.251.205 │
|
||||
└───────────────────────────────────────────────────────┘
|
||||
```
|
||||
|
97
src/Functions/byteSwap.cpp
Normal file
97
src/Functions/byteSwap.cpp
Normal file
@ -0,0 +1,97 @@
|
||||
#include <Functions/FunctionFactory.h>
|
||||
#include <Functions/FunctionUnaryArithmetic.h>
|
||||
|
||||
namespace DB
|
||||
{
|
||||
namespace ErrorCodes
|
||||
{
|
||||
extern const int NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
namespace
|
||||
{
|
||||
template <typename T>
|
||||
requires std::is_integral_v<T>
|
||||
T byteSwap(T x)
|
||||
{
|
||||
return std::byteswap(x);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
T byteSwap(T)
|
||||
{
|
||||
throw Exception(ErrorCodes::NOT_IMPLEMENTED, "byteSwap() is not implemented for {} datatype", demangle(typeid(T).name()));
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
struct ByteSwapImpl
|
||||
{
|
||||
using ResultType = T;
|
||||
static constexpr const bool allow_string_or_fixed_string = false;
|
||||
static T apply(T x) { return byteSwap<T>(x); }
|
||||
|
||||
#if USE_EMBEDDED_COMPILER
|
||||
static constexpr bool compilable = false;
|
||||
#endif
|
||||
};
|
||||
|
||||
struct NameByteSwap
|
||||
{
|
||||
static constexpr auto name = "byteSwap";
|
||||
};
|
||||
using FunctionByteSwap = FunctionUnaryArithmetic<ByteSwapImpl, NameByteSwap, true>;
|
||||
|
||||
}
|
||||
|
||||
template <>
|
||||
struct FunctionUnaryArithmeticMonotonicity<NameByteSwap>
|
||||
{
|
||||
static bool has() { return false; }
|
||||
static IFunction::Monotonicity get(const Field &, const Field &) { return {}; }
|
||||
};
|
||||
|
||||
REGISTER_FUNCTION(ByteSwap)
|
||||
{
|
||||
factory.registerFunction<FunctionByteSwap>(
|
||||
FunctionDocumentation{
|
||||
.description = R"(
|
||||
Reverses the bytes of an integer, i.e. changes its [endianness](https://en.wikipedia.org/wiki/Endianness). Currently, integers of up to 64 bit are supported.
|
||||
|
||||
**Example**
|
||||
|
||||
```sql
|
||||
byteSwap(3351772109)
|
||||
```
|
||||
|
||||
Result:
|
||||
|
||||
```result
|
||||
┌─byteSwap(3351772109)─┐
|
||||
│ 3455829959 │
|
||||
└──────────────────────┘
|
||||
```
|
||||
|
||||
The above example can be worked out in the following manner:
|
||||
1. Convert the base-10 integer to its equivalent hexadecimal format in big-endian format, i.e. 3351772109 -> C7 C7 FB CD (4 bytes)
|
||||
2. Reverse the bytes, i.e. C7 C7 FB CD -> CD FB C7 C7
|
||||
3. Convert the result back to an integer assuming big-endian, i.e. CD FB C7 C7 -> 3455829959
|
||||
|
||||
One use-case of this function is reversing IPv4s:
|
||||
|
||||
```result
|
||||
┌─toIPv4(byteSwap(toUInt32(toIPv4('205.251.199.199'))))─┐
|
||||
│ 199.199.251.205 │
|
||||
└───────────────────────────────────────────────────────┘
|
||||
```
|
||||
)",
|
||||
.examples{
|
||||
{"8-bit", "SELECT byteSwap(54)", "54"},
|
||||
{"16-bit", "SELECT byteSwap(4135)", "10000"},
|
||||
{"32-bit", "SELECT byteSwap(3351772109)", "3455829959"},
|
||||
{"64-bit", "SELECT byteSwap(123294967295)", "18439412204227788800"},
|
||||
},
|
||||
.categories{"Mathematical", "Arithmetic"}},
|
||||
FunctionFactory::CaseInsensitive);
|
||||
}
|
||||
|
||||
}
|
29
tests/queries/0_stateless/02887_byteswap.reference
Normal file
29
tests/queries/0_stateless/02887_byteswap.reference
Normal file
@ -0,0 +1,29 @@
|
||||
0
|
||||
1
|
||||
255
|
||||
1
|
||||
10000
|
||||
4135
|
||||
65535
|
||||
256
|
||||
3455829959
|
||||
3351772109
|
||||
4294967295
|
||||
16777216
|
||||
18439412204227788800
|
||||
123294967295
|
||||
18446744073709551615
|
||||
0
|
||||
-1
|
||||
-128
|
||||
32767
|
||||
-9745
|
||||
128
|
||||
-8388609
|
||||
855914552
|
||||
128
|
||||
-549755813889
|
||||
4039370097989451775
|
||||
128
|
||||
0
|
||||
1
|
57
tests/queries/0_stateless/02887_byteswap.sql
Normal file
57
tests/queries/0_stateless/02887_byteswap.sql
Normal file
@ -0,0 +1,57 @@
|
||||
SELECT byteSwap(0::UInt8);
|
||||
SELECT byteSwap(1::UInt8);
|
||||
SELECT byteSwap(255::UInt8);
|
||||
|
||||
SELECT byteSwap(256::UInt16);
|
||||
SELECT byteSwap(4135::UInt16);
|
||||
SELECT byteSwap(10000::UInt16);
|
||||
SELECT byteSwap(65535::UInt16);
|
||||
|
||||
SELECT byteSwap(65536::UInt32);
|
||||
SELECT byteSwap(3351772109::UInt32);
|
||||
SELECT byteSwap(3455829959::UInt32);
|
||||
SELECT byteSwap(4294967295::UInt32);
|
||||
|
||||
SELECT byteSwap(4294967296::UInt64);
|
||||
SELECT byteSwap(123294967295::UInt64);
|
||||
SELECT byteSwap(18439412204227788800::UInt64);
|
||||
SELECT byteSwap(18446744073709551615::UInt64);
|
||||
|
||||
SELECT byteSwap(-0::Int8);
|
||||
SELECT byteSwap(-1::Int8);
|
||||
SELECT byteSwap(-128::Int8);
|
||||
|
||||
SELECT byteSwap(-129::Int16);
|
||||
SELECT byteSwap(-4135::Int16);
|
||||
SELECT byteSwap(-32768::Int16);
|
||||
|
||||
SELECT byteSwap(-32769::Int32);
|
||||
SELECT byteSwap(-3351772109::Int32);
|
||||
SELECT byteSwap(-2147483648::Int32);
|
||||
|
||||
SELECT byteSwap(-2147483649::Int64);
|
||||
SELECT byteSwap(-1242525266376::Int64);
|
||||
SELECT byteSwap(-9223372036854775808::Int64);
|
||||
|
||||
-- Booleans are interpreted as UInt8
|
||||
SELECT byteSwap(false);
|
||||
SELECT byteSwap(true);
|
||||
|
||||
-- Number of arguments should equal 1
|
||||
SELECT byteSwap(); -- { serverError NUMBER_OF_ARGUMENTS_DOESNT_MATCH }
|
||||
SELECT byteSwap(128, 129); -- { serverError NUMBER_OF_ARGUMENTS_DOESNT_MATCH }
|
||||
|
||||
-- Input should be integral
|
||||
SELECT byteSwap('abc'); -- { serverError ILLEGAL_TYPE_OF_ARGUMENT }
|
||||
SELECT byteSwap(toFixedString('abc', 3)); -- { serverError ILLEGAL_TYPE_OF_ARGUMENT }
|
||||
SELECT byteSwap(toDate('2019-01-01')); -- { serverError ILLEGAL_TYPE_OF_ARGUMENT }
|
||||
SELECT byteSwap(toDate32('2019-01-01')); -- { serverError ILLEGAL_TYPE_OF_ARGUMENT }
|
||||
SELECT byteSwap(toDateTime32(1546300800)); -- { serverError ILLEGAL_TYPE_OF_ARGUMENT }
|
||||
SELECT byteSwap(toDateTime64(1546300800, 3)); -- { serverError ILLEGAL_TYPE_OF_ARGUMENT }
|
||||
SELECT byteSwap(generateUUIDv4()); -- { serverError ILLEGAL_TYPE_OF_ARGUMENT }
|
||||
SELECT byteSwap(toDecimal32(2, 4)); -- { serverError ILLEGAL_TYPE_OF_ARGUMENT }
|
||||
SELECT byteSwap(toFloat32(123.456)); -- { serverError NOT_IMPLEMENTED }
|
||||
SELECT byteSwap(toFloat64(123.456)); -- { serverError NOT_IMPLEMENTED }
|
||||
SELECT byteSwap(18446744073709551616::UInt128); -- { serverError NOT_IMPLEMENTED }
|
||||
SELECT byteSwap(-9223372036854775809::Int128); -- { serverError NOT_IMPLEMENTED }
|
||||
|
@ -1178,6 +1178,7 @@ buildId
|
||||
buildable
|
||||
builtins
|
||||
byteSize
|
||||
byteSwap
|
||||
bytebase
|
||||
bytesToCutForIPv
|
||||
editDistance
|
||||
@ -1421,6 +1422,7 @@ encodeXMLComponent
|
||||
encodings
|
||||
encryptions
|
||||
endian
|
||||
endianness
|
||||
endsWith
|
||||
endsWithUTF
|
||||
enum
|
||||
|
Loading…
Reference in New Issue
Block a user