Merge pull request #45150 from ClickHouse/fix-ip-function-mod

Binary arithmetic for IPv4
This commit is contained in:
Nikolai Kochetov 2023-01-24 13:11:02 +01:00 committed by GitHub
commit e4c0608a01
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 55 additions and 0 deletions

View File

@ -24,6 +24,7 @@
#include <DataTypes/DataTypeInterval.h>
#include <DataTypes/DataTypeTuple.h>
#include <DataTypes/DataTypeString.h>
#include <DataTypes/DataTypeIPv4andIPv6.h>
#include <DataTypes/DataTypesDecimal.h>
#include <DataTypes/DataTypesNumber.h>
#include <DataTypes/Native.h>
@ -107,6 +108,9 @@ template <typename DataType> constexpr bool IsDateOrDateTime = false;
template <> inline constexpr bool IsDateOrDateTime<DataTypeDate> = true;
template <> inline constexpr bool IsDateOrDateTime<DataTypeDateTime> = true;
template <typename DataType> constexpr bool IsIPv4 = false;
template <> inline constexpr bool IsIPv4<DataTypeIPv4> = true;
template <typename T0, typename T1> constexpr bool UseLeftDecimal = false;
template <> inline constexpr bool UseLeftDecimal<DataTypeDecimal<Decimal256>, DataTypeDecimal<Decimal128>> = true;
template <> inline constexpr bool UseLeftDecimal<DataTypeDecimal<Decimal256>, DataTypeDecimal<Decimal64>> = true;
@ -1210,6 +1214,17 @@ public:
return arguments[0];
}
/// Special case - one or both arguments are IPv4
if (isIPv4(arguments[0]) || isIPv4(arguments[1]))
{
DataTypes new_arguments {
isIPv4(arguments[0]) ? std::make_shared<DataTypeUInt32>() : arguments[0],
isIPv4(arguments[1]) ? std::make_shared<DataTypeUInt32>() : arguments[1],
};
return getReturnTypeImplStatic(new_arguments, context);
}
/// Special case when the function is plus or minus, one of arguments is Date/DateTime and another is Interval.
if (auto function_builder = getFunctionForIntervalArithmetic(arguments[0], arguments[1], context))
{
@ -1707,6 +1722,25 @@ public:
return executeAggregateAddition(arguments, result_type, input_rows_count);
}
/// Special case - one or both arguments are IPv4
if (isIPv4(arguments[0].type) || isIPv4(arguments[1].type))
{
ColumnsWithTypeAndName new_arguments {
{
isIPv4(arguments[0].type) ? castColumn(arguments[0], std::make_shared<DataTypeUInt32>()) : arguments[0].column,
isIPv4(arguments[0].type) ? std::make_shared<DataTypeUInt32>() : arguments[0].type,
arguments[0].name,
},
{
isIPv4(arguments[1].type) ? castColumn(arguments[1], std::make_shared<DataTypeUInt32>()) : arguments[1].column,
isIPv4(arguments[1].type) ? std::make_shared<DataTypeUInt32>() : arguments[1].type,
arguments[1].name
}
};
return executeImpl(new_arguments, result_type, input_rows_count);
}
/// Special case when the function is plus or minus, one of arguments is Date/DateTime and another is Interval.
if (auto function_builder = getFunctionForIntervalArithmetic(arguments[0].type, arguments[1].type, context))
{

View File

@ -0,0 +1,20 @@
10 1.2.3.4 0
11 1.2.3.4 3
12 1.2.3.4 4
13 1.2.3.4 12
14 1.2.3.4 0
15 1.2.3.4 10
16 1.2.3.4 4
17 1.2.3.4 10
18 1.2.3.4 4
19 1.2.3.4 10
20 1.2.3.4 0
21 1.2.3.4 7
22 1.2.3.4 14
23 1.2.3.4 12
24 1.2.3.4 4
25 1.2.3.4 10
26 1.2.3.4 12
27 1.2.3.4 13
28 1.2.3.4 0
29 1.2.3.4 1

View File

@ -0,0 +1 @@
SELECT number, ip, ip % number FROM (SELECT number, toIPv4('1.2.3.4') as ip FROM numbers(10, 20));