[feature](function) support ip function ipv6_string_to_num(_or_default, _or_null), inet6_aton (#28361)

This commit is contained in:
Chester
2024-01-05 19:24:45 +08:00
committed by GitHub
parent 2a6150b057
commit 7402fee1fc
25 changed files with 1248 additions and 8 deletions

View File

@ -23,9 +23,6 @@
#include <algorithm>
#include <array>
#include "vec/common/hex.h"
#include "vec/core/types.h"
namespace doris::vectorized {
/** Further we want to generate constexpr array of strings with sizes from sequence of unsigned ints [0..N)

View File

@ -22,6 +22,7 @@
#include <vec/common/hex.h>
#include <vec/common/string_utils/string_utils.h>
#include <vec/core/types.h>
#include <algorithm>
#include <array>

View File

@ -32,5 +32,10 @@ void register_function_ip(SimpleFunctionFactory& factory) {
"inet_aton");
factory.register_function<FunctionIPv6NumToString>();
factory.register_alias(FunctionIPv6NumToString::name, "inet6_ntoa");
factory.register_function<FunctionIPv6StringToNum<IPStringToNumExceptionMode::Throw>>();
factory.register_function<FunctionIPv6StringToNum<IPStringToNumExceptionMode::Default>>();
factory.register_function<FunctionIPv6StringToNum<IPStringToNumExceptionMode::Null>>();
factory.register_alias(FunctionIPv6StringToNum<IPStringToNumExceptionMode::Throw>::name,
"inet6_aton");
}
} // namespace doris::vectorized

View File

@ -348,4 +348,261 @@ public:
}
};
namespace detail {
template <IPStringToNumExceptionMode exception_mode, typename ToColumn = ColumnIPv6,
typename StringColumnType>
ColumnPtr convertToIPv6(const StringColumnType& string_column,
const PaddedPODArray<UInt8>* null_map = nullptr) {
if constexpr (!std::is_same_v<ToColumn, ColumnString> &&
!std::is_same_v<ToColumn, ColumnIPv6>) {
throw Exception(ErrorCode::INVALID_ARGUMENT,
"Illegal return column type {}. Expected IPv6 or String",
TypeName<typename ToColumn::ValueType>::get());
}
const size_t column_size = string_column.size();
ColumnUInt8::MutablePtr col_null_map_to;
ColumnUInt8::Container* vec_null_map_to = nullptr;
if constexpr (exception_mode == IPStringToNumExceptionMode::Null) {
col_null_map_to = ColumnUInt8::create(column_size, false);
vec_null_map_to = &col_null_map_to->get_data();
}
/// This is a special treatment for source column of type String
/// to preserve previous behavior when IPv6 was a domain type of String
if constexpr (std::is_same_v<StringColumnType, ColumnString>) {
if (string_column.get_offsets()[0] - 1 == IPV6_BINARY_LENGTH) {
if constexpr (std::is_same_v<ToColumn, ColumnString>) {
auto col_res = ColumnString::create();
if constexpr (exception_mode == IPStringToNumExceptionMode::Null) {
col_null_map_to = ColumnUInt8::create(column_size, false);
if (null_map) {
memcpy(col_null_map_to->get_data().data(), null_map->data(), column_size);
}
return ColumnNullable::create(std::move(col_res), std::move(col_null_map_to));
}
return col_res;
} else {
auto col_res = ColumnIPv6::create();
auto& vec_res = col_res->get_data();
vec_res.resize(column_size);
memcpy(vec_res.data(), string_column.get_chars().data(),
column_size * IPV6_BINARY_LENGTH);
if constexpr (exception_mode == IPStringToNumExceptionMode::Null) {
col_null_map_to = ColumnUInt8::create(column_size, false);
if (null_map) {
memcpy(col_null_map_to->get_data().data(), null_map->data(), column_size);
}
return ColumnNullable::create(std::move(col_res), std::move(col_null_map_to));
}
return col_res;
}
}
}
auto column_create = [](size_t column_size) -> typename ToColumn::MutablePtr {
if constexpr (std::is_same_v<ToColumn, ColumnString>) {
auto column_string = ColumnString::create();
column_string->get_chars().reserve(column_size * IPV6_BINARY_LENGTH);
column_string->get_offsets().reserve(column_size);
return column_string;
} else {
return ColumnIPv6::create();
}
};
auto get_vector = [](auto& col_res, size_t col_size) -> decltype(auto) {
if constexpr (std::is_same_v<ToColumn, ColumnString>) {
auto& vec_res = col_res->get_chars();
vec_res.resize(col_size * IPV6_BINARY_LENGTH);
return (vec_res);
} else {
auto& vec_res = col_res->get_data();
vec_res.resize(col_size);
return (vec_res);
}
};
auto col_res = column_create(column_size);
auto& vec_res = get_vector(col_res, column_size);
using Chars = typename StringColumnType::Chars;
const Chars& vec_src = string_column.get_chars();
size_t src_offset = 0;
char src_ipv4_buf[sizeof("::ffff:") + IPV4_MAX_TEXT_LENGTH + 1] = "::ffff:";
/// ColumnString contains not null terminated strings. But functions parseIPv6, parseIPv4 expect null terminated string.
/// TODO fix this - now parseIPv6/parseIPv4 accept end iterator, so can be parsed in-place
std::string string_buffer;
int offset_inc = 1;
if constexpr (std::is_same_v<ToColumn, ColumnString>) {
offset_inc = IPV6_BINARY_LENGTH;
}
for (size_t out_offset = 0, i = 0; i < column_size; out_offset += offset_inc, ++i) {
size_t src_next_offset = src_offset;
const char* src_value = nullptr;
auto* res_value = reinterpret_cast<unsigned char*>(&vec_res[out_offset]);
if constexpr (std::is_same_v<StringColumnType, ColumnString>) {
src_value = reinterpret_cast<const char*>(&vec_src[src_offset]);
src_next_offset = string_column.get_offsets()[i];
string_buffer.assign(src_value, src_next_offset - src_offset);
src_value = string_buffer.c_str();
}
if (null_map && (*null_map)[i]) {
if (exception_mode == IPStringToNumExceptionMode::Throw) {
throw Exception(ErrorCode::INVALID_ARGUMENT, "Invalid IPv6 value");
} else if (exception_mode == IPStringToNumExceptionMode::Default) {
std::fill_n(&vec_res[out_offset], offset_inc, 0);
} else {
std::fill_n(&vec_res[out_offset], offset_inc, 0);
(*vec_null_map_to)[i] = true;
if constexpr (std::is_same_v<ToColumn, ColumnString>) {
auto* column_string = assert_cast<ColumnString*>(col_res.get());
column_string->get_offsets().push_back((i + 1) * IPV6_BINARY_LENGTH);
}
}
src_offset = src_next_offset;
continue;
}
bool parse_result = false;
Int64 dummy_result = 0;
/// For both cases below: In case of failure, the function parseIPv6 fills vec_res with zero bytes.
/// If the source IP address is parsable as an IPv4 address, then transform it into a valid IPv6 address.
/// Keeping it simple by just prefixing `::ffff:` to the IPv4 address to represent it as a valid IPv6 address.
size_t string_length = src_next_offset - src_offset;
if (string_length != 0) {
if (tryParseIPv4(src_value, dummy_result)) {
strcat(src_ipv4_buf, src_value);
parse_result = parseIPv6whole(src_ipv4_buf, res_value);
} else {
parse_result = parseIPv6whole(src_value, res_value);
}
}
if (parse_result && string_length != 0) {
if constexpr (std::is_same_v<ToColumn, ColumnString>) {
auto* column_string = assert_cast<ColumnString*>(col_res.get());
std::copy(res_value, res_value + IPV6_BINARY_LENGTH,
column_string->get_chars().begin() + i * IPV6_BINARY_LENGTH);
column_string->get_offsets().push_back((i + 1) * IPV6_BINARY_LENGTH);
} else {
col_res->insert_data(reinterpret_cast<const char*>(res_value), IPV6_BINARY_LENGTH);
}
} else {
if (exception_mode == IPStringToNumExceptionMode::Throw) {
throw Exception(ErrorCode::INVALID_ARGUMENT, "Invalid IPv6 value");
}
std::fill_n(&vec_res[out_offset], offset_inc, 0);
if constexpr (std::is_same_v<ToColumn, ColumnString>) {
auto* column_string = assert_cast<ColumnString*>(col_res.get());
column_string->get_offsets().push_back((i + 1) * IPV6_BINARY_LENGTH);
}
if constexpr (exception_mode == IPStringToNumExceptionMode::Null) {
(*vec_null_map_to)[i] = true;
}
}
src_offset = src_next_offset;
}
if constexpr (exception_mode == IPStringToNumExceptionMode::Null) {
return ColumnNullable::create(std::move(col_res), std::move(col_null_map_to));
}
return col_res;
}
} // namespace detail
template <IPStringToNumExceptionMode exception_mode, typename ToColumn = ColumnIPv6>
ColumnPtr convertToIPv6(ColumnPtr column, const PaddedPODArray<UInt8>* null_map = nullptr) {
if (const auto* column_input_string = check_and_get_column<ColumnString>(column.get())) {
auto result =
detail::convertToIPv6<exception_mode, ToColumn>(*column_input_string, null_map);
return result;
} else {
throw Exception(ErrorCode::INVALID_ARGUMENT, "Illegal column type {}. Expected String",
column->get_name());
}
}
template <IPStringToNumExceptionMode exception_mode>
class FunctionIPv6StringToNum : public IFunction {
public:
static constexpr auto name = exception_mode == IPStringToNumExceptionMode::Throw
? "ipv6_string_to_num"
: (exception_mode == IPStringToNumExceptionMode::Default
? "ipv6_string_to_num_or_default"
: "ipv6_string_to_num_or_null");
static FunctionPtr create() {
return std::make_shared<FunctionIPv6StringToNum<exception_mode>>();
}
String get_name() const override { return name; }
size_t get_number_of_arguments() const override { return 1; }
bool use_default_implementation_for_nulls() const override { return false; }
DataTypePtr get_return_type_impl(const DataTypes& arguments) const override {
if (!is_string(remove_nullable(arguments[0]))) {
throw Exception(ErrorCode::INVALID_ARGUMENT,
"Illegal type {} of argument of function {}", arguments[0]->get_name(),
get_name());
}
auto result_type = std::make_shared<DataTypeString>();
if constexpr (exception_mode == IPStringToNumExceptionMode::Null) {
return make_nullable(result_type);
}
return result_type;
}
Status execute_impl(FunctionContext* context, Block& block, const ColumnNumbers& arguments,
size_t result, size_t input_rows_count) const override {
ColumnPtr column = block.get_by_position(arguments[0]).column;
ColumnPtr null_map_column;
const NullMap* null_map = nullptr;
if (column->is_nullable()) {
const auto* column_nullable = assert_cast<const ColumnNullable*>(column.get());
column = column_nullable->get_nested_column_ptr();
if constexpr (exception_mode == IPStringToNumExceptionMode::Null) {
null_map_column = column_nullable->get_null_map_column_ptr();
null_map = &column_nullable->get_null_map_data();
}
}
auto col_res = convertToIPv6<exception_mode, ColumnString>(column, null_map);
if (null_map && !col_res->is_nullable()) {
block.replace_by_position(result,
ColumnNullable::create(IColumn::mutate(col_res),
IColumn::mutate(null_map_column)));
return Status::OK();
}
block.replace_by_position(result, col_res);
return Status::OK();
}
};
} // namespace doris::vectorized

View File

@ -0,0 +1,70 @@
---
{
"title": "INET6_ATON",
"language": "en"
}
---
<!--
Licensed to the Apache Software Foundation (ASF) under one
or more contributor license agreements. See the NOTICE file
distributed with this work for additional information
regarding copyright ownership. The ASF licenses this file
to you under the Apache License, Version 2.0 (the
"License"); you may not use this file except in compliance
with the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing,
software distributed under the License is distributed on an
"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
KIND, either express or implied. See the License for the
specific language governing permissions and limitations
under the License.
-->
## INET6_ATON
<version since="dev">
inet6_aton
</version>
### description
#### Syntax
`VARCHAR INET6_ATON(VARCHAR ipv6_string)`
The reverse function of IPv6NumToString, it takes an IP address String and returns an IPv6 address in binary format.
If the input string contains a valid IPv4 address, returns its IPv6 equivalent.
### notice
`will return an error if the input string is not a valid IP address`
### example
```
mysql> select hex(inet6_aton('1111::ffff'));
+----------------------------------+
| hex(inet6_aton('1111::ffff')) |
+----------------------------------+
| 1111000000000000000000000000FFFF |
+----------------------------------+
1 row in set (0.02 sec)
mysql> select hex(inet6_aton('192.168.0.1'));
+----------------------------------+
| hex(inet6_aton('192.168.0.1')) |
+----------------------------------+
| 00000000000000000000FFFFC0A80001 |
+----------------------------------+
1 row in set (0.02 sec)
mysql> select hex(inet6_aton('notaaddress'));
ERROR 1105 (HY000): errCode = 2, detailMessage = (172.17.0.2)[CANCELLED][E33] Invalid IPv6 value
```
### keywords
INET6_ATON, IP

View File

@ -0,0 +1,75 @@
---
{
"title": "IPV6_STRING_TO_NUM_OR_DEFAULT",
"language": "en"
}
---
<!--
Licensed to the Apache Software Foundation (ASF) under one
or more contributor license agreements. See the NOTICE file
distributed with this work for additional information
regarding copyright ownership. The ASF licenses this file
to you under the Apache License, Version 2.0 (the
"License"); you may not use this file except in compliance
with the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing,
software distributed under the License is distributed on an
"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
KIND, either express or implied. See the License for the
specific language governing permissions and limitations
under the License.
-->
## IPV6_STRING_TO_NUM_OR_DEFAULT
<version since="dev">
IPV6_STRING_TO_NUM_OR_DEFAULT
</version>
### description
#### Syntax
`VARCHAR IPV6_STRING_TO_NUM_OR_DEFAULT(VARCHAR ipv6_string)`
The reverse function of IPv6NumToString, it takes an IP address String and returns an IPv6 address in binary format.
If the input string contains a valid IPv4 address, returns its IPv6 equivalent.
### notice
`will return zero if the input string is not a valid IP address`
### example
```
mysql> select hex(ipv6_string_to_num_or_default('1111::ffff'));
+--------------------------------------------------+
| hex(ipv6_string_to_num_or_default('1111::ffff')) |
+--------------------------------------------------+
| 1111000000000000000000000000FFFF |
+--------------------------------------------------+
1 row in set (0.01 sec)
mysql> select hex(ipv6_string_to_num_or_default('192.168.0.1'));
+---------------------------------------------------+
| hex(ipv6_string_to_num_or_default('192.168.0.1')) |
+---------------------------------------------------+
| 00000000000000000000FFFFC0A80001 |
+---------------------------------------------------+
1 row in set (0.02 sec)
mysql> select hex(ipv6_string_to_num_or_default('notaaddress'));
+---------------------------------------------------+
| hex(ipv6_string_to_num_or_default('notaaddress')) |
+---------------------------------------------------+
| 00000000000000000000000000000000 |
+---------------------------------------------------+
1 row in set (0.02 sec)
```
### keywords
IPV6_STRING_TO_NUM_OR_DEFAULT, IP

View File

@ -0,0 +1,75 @@
---
{
"title": "IPV6_STRING_TO_NUM_OR_NULL",
"language": "en"
}
---
<!--
Licensed to the Apache Software Foundation (ASF) under one
or more contributor license agreements. See the NOTICE file
distributed with this work for additional information
regarding copyright ownership. The ASF licenses this file
to you under the Apache License, Version 2.0 (the
"License"); you may not use this file except in compliance
with the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing,
software distributed under the License is distributed on an
"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
KIND, either express or implied. See the License for the
specific language governing permissions and limitations
under the License.
-->
## IPV6_STRING_TO_NUM_OR_NULL
<version since="dev">
IPV6_STRING_TO_NUM_OR_NULL
</version>
### description
#### Syntax
`VARCHAR IPV6_STRING_TO_NUM_OR_NULL(VARCHAR ipv6_string)`
The reverse function of IPv6NumToString, it takes an IP address String and returns an IPv6 address in binary format.
If the input string contains a valid IPv4 address, returns its IPv6 equivalent.
### notice
`will return NULL if the input string is not a valid IP address`
### example
```
mysql> select hex(ipv6_string_to_num_or_null('1111::ffff'));
+-----------------------------------------------+
| hex(ipv6_string_to_num_or_null('1111::ffff')) |
+-----------------------------------------------+
| 1111000000000000000000000000FFFF |
+-----------------------------------------------+
1 row in set (0.01 sec)
mysql> select hex(ipv6_string_to_num_or_null('192.168.0.1'));
+------------------------------------------------+
| hex(ipv6_string_to_num_or_null('192.168.0.1')) |
+------------------------------------------------+
| 00000000000000000000FFFFC0A80001 |
+------------------------------------------------+
1 row in set (0.02 sec)
mysql> select hex(ipv6_string_to_num_or_null('notaaddress'));
+------------------------------------------------+
| hex(ipv6_string_to_num_or_null('notaaddress')) |
+------------------------------------------------+
| NULL |
+------------------------------------------------+
1 row in set (0.02 sec)
```
### keywords
IPV6_STRING_TO_NUM_OR_NULL, IP

View File

@ -0,0 +1,70 @@
---
{
"title": "IPV6_STRING_TO_NUM",
"language": "en"
}
---
<!--
Licensed to the Apache Software Foundation (ASF) under one
or more contributor license agreements. See the NOTICE file
distributed with this work for additional information
regarding copyright ownership. The ASF licenses this file
to you under the Apache License, Version 2.0 (the
"License"); you may not use this file except in compliance
with the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing,
software distributed under the License is distributed on an
"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
KIND, either express or implied. See the License for the
specific language governing permissions and limitations
under the License.
-->
## IPV6_STRING_TO_NUM
<version since="dev">
IPV6_STRING_TO_NUM
</version>
### description
#### Syntax
`VARCHAR IPV6_STRING_TO_NUM(VARCHAR ipv6_string)`
The reverse function of IPv6NumToString, it takes an IP address String and returns an IPv6 address in binary format.
If the input string contains a valid IPv4 address, returns its IPv6 equivalent.
### notice
`will return an error if the input string is not a valid IP address`
### example
```
mysql> select hex(ipv6_string_to_num('1111::ffff'));
+---------------------------------------+
| hex(ipv6_string_to_num('1111::ffff')) |
+---------------------------------------+
| 1111000000000000000000000000FFFF |
+---------------------------------------+
1 row in set (0.02 sec)
mysql> select hex(ipv6_string_to_num('192.168.0.1'));
+----------------------------------------+
| hex(ipv6_string_to_num('192.168.0.1')) |
+----------------------------------------+
| 00000000000000000000FFFFC0A80001 |
+----------------------------------------+
1 row in set (0.02 sec)
mysql> select hex(ipv6_string_to_num('notaaddress'));
ERROR 1105 (HY000): errCode = 2, detailMessage = (172.17.0.2)[CANCELLED][E33] Invalid IPv6 value
```
### keywords
IPV6_STRING_TO_NUM, IP

View File

@ -800,7 +800,12 @@
"sql-manual/sql-functions/ip-functions/ipv4-string-to-num-or-default",
"sql-manual/sql-functions/ip-functions/ipv4-string-to-num-or-null",
"sql-manual/sql-functions/ip-functions/ipv6-num-to-string",
"sql-manual/sql-functions/ip-functions/inet6-ntoa"
"sql-manual/sql-functions/ip-functions/inet6-ntoa",
"sql-manual/sql-functions/ip-functions/ipv6-num-to-string",
"sql-manual/sql-functions/ip-functions/inet6-aton",
"sql-manual/sql-functions/ip-functions/ipv6-string-to-num-or-default",
"sql-manual/sql-functions/ip-functions/ipv6-string-to-num-or-null"
]
},
{

View File

@ -0,0 +1,70 @@
---
{
"title": "INET6_ATON",
"language": "zh-CN"
}
---
<!--
Licensed to the Apache Software Foundation (ASF) under one
or more contributor license agreements. See the NOTICE file
distributed with this work for additional information
regarding copyright ownership. The ASF licenses this file
to you under the Apache License, Version 2.0 (the
"License"); you may not use this file except in compliance
with the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing,
software distributed under the License is distributed on an
"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
KIND, either express or implied. See the License for the
specific language governing permissions and limitations
under the License.
-->
## INET6_ATON
<version since="dev">
inet6_aton
</version>
### description
#### Syntax
`VARCHAR INET6_ATON(VARCHAR ipv6_string)`
IPv6NumToString 的反向函数,它接受一个 IP 地址字符串并返回二进制格式的 IPv6 地址。
如果输入字符串包含有效的 IPv4 地址,则返回其等效的 IPv6 地址。
### notice
`如果输入非法的IP地址,会抛出异常`
### example
```
mysql> select hex(inet6_aton('1111::ffff'));
+----------------------------------+
| hex(inet6_aton('1111::ffff')) |
+----------------------------------+
| 1111000000000000000000000000FFFF |
+----------------------------------+
1 row in set (0.02 sec)
mysql> select hex(inet6_aton('192.168.0.1'));
+----------------------------------+
| hex(inet6_aton('192.168.0.1')) |
+----------------------------------+
| 00000000000000000000FFFFC0A80001 |
+----------------------------------+
1 row in set (0.02 sec)
mysql> select hex(inet6_aton('notaaddress'));
ERROR 1105 (HY000): errCode = 2, detailMessage = (172.17.0.2)[CANCELLED][E33] Invalid IPv6 value
```
### keywords
INET6_ATON, IP

View File

@ -1,7 +1,7 @@
---
{
"title": "INET6_NTOA",
"language": "en"
"language": "zh-CN"
}
---

View File

@ -1,7 +1,7 @@
---
{
"title": "IPV6_NUM_TO_STRING",
"language": "en"
"language": "zh-CN"
}
---

View File

@ -0,0 +1,75 @@
---
{
"title": "IPV6_STRING_TO_NUM_OR_DEFAULT",
"language": "zh-CN"
}
---
<!--
Licensed to the Apache Software Foundation (ASF) under one
or more contributor license agreements. See the NOTICE file
distributed with this work for additional information
regarding copyright ownership. The ASF licenses this file
to you under the Apache License, Version 2.0 (the
"License"); you may not use this file except in compliance
with the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing,
software distributed under the License is distributed on an
"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
KIND, either express or implied. See the License for the
specific language governing permissions and limitations
under the License.
-->
## IPV6_STRING_TO_NUM_OR_DEFAULT
<version since="dev">
IPV6_STRING_TO_NUM_OR_DEFAULT
</version>
### description
#### Syntax
`VARCHAR IPV6_STRING_TO_NUM_OR_DEFAULT(VARCHAR ipv6_string)`
IPv6NumToString 的反向函数,它接受一个 IP 地址字符串并返回二进制格式的 IPv6 地址。
如果输入字符串包含有效的 IPv4 地址,则返回其等效的 IPv6 地址。
### notice
`如果输入非法的IP地址,会返回0`
### example
```
mysql> select hex(ipv6_string_to_num_or_default('1111::ffff'));
+--------------------------------------------------+
| hex(ipv6_string_to_num_or_default('1111::ffff')) |
+--------------------------------------------------+
| 1111000000000000000000000000FFFF |
+--------------------------------------------------+
1 row in set (0.01 sec)
mysql> select hex(ipv6_string_to_num_or_default('192.168.0.1'));
+---------------------------------------------------+
| hex(ipv6_string_to_num_or_default('192.168.0.1')) |
+---------------------------------------------------+
| 00000000000000000000FFFFC0A80001 |
+---------------------------------------------------+
1 row in set (0.02 sec)
mysql> select hex(ipv6_string_to_num_or_default('notaaddress'));
+---------------------------------------------------+
| hex(ipv6_string_to_num_or_default('notaaddress')) |
+---------------------------------------------------+
| 00000000000000000000000000000000 |
+---------------------------------------------------+
1 row in set (0.02 sec)
```
### keywords
IPV6_STRING_TO_NUM_OR_DEFAULT, IP

View File

@ -0,0 +1,75 @@
---
{
"title": "IPV6_STRING_TO_NUM_OR_NULL",
"language": "zh-CN"
}
---
<!--
Licensed to the Apache Software Foundation (ASF) under one
or more contributor license agreements. See the NOTICE file
distributed with this work for additional information
regarding copyright ownership. The ASF licenses this file
to you under the Apache License, Version 2.0 (the
"License"); you may not use this file except in compliance
with the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing,
software distributed under the License is distributed on an
"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
KIND, either express or implied. See the License for the
specific language governing permissions and limitations
under the License.
-->
## IPV6_STRING_TO_NUM_OR_NULL
<version since="dev">
IPV6_STRING_TO_NUM_OR_NULL
</version>
### description
#### Syntax
`VARCHAR IPV6_STRING_TO_NUM_OR_NULL(VARCHAR ipv6_string)`
IPv6NumToString 的反向函数,它接受一个 IP 地址字符串并返回二进制格式的 IPv6 地址。
如果输入字符串包含有效的 IPv4 地址,则返回其等效的 IPv6 地址。
### notice
`如果输入非法的IP地址,会返回NULL`
### example
```
mysql> select hex(ipv6_string_to_num_or_null('1111::ffff'));
+-----------------------------------------------+
| hex(ipv6_string_to_num_or_null('1111::ffff')) |
+-----------------------------------------------+
| 1111000000000000000000000000FFFF |
+-----------------------------------------------+
1 row in set (0.01 sec)
mysql> select hex(ipv6_string_to_num_or_null('192.168.0.1'));
+------------------------------------------------+
| hex(ipv6_string_to_num_or_null('192.168.0.1')) |
+------------------------------------------------+
| 00000000000000000000FFFFC0A80001 |
+------------------------------------------------+
1 row in set (0.02 sec)
mysql> select hex(ipv6_string_to_num_or_null('notaaddress'));
+------------------------------------------------+
| hex(ipv6_string_to_num_or_null('notaaddress')) |
+------------------------------------------------+
| NULL |
+------------------------------------------------+
1 row in set (0.02 sec)
```
### keywords
IPV6_STRING_TO_NUM_OR_NULL, IP

View File

@ -0,0 +1,70 @@
---
{
"title": "IPV6_STRING_TO_NUM",
"language": "zh-CN"
}
---
<!--
Licensed to the Apache Software Foundation (ASF) under one
or more contributor license agreements. See the NOTICE file
distributed with this work for additional information
regarding copyright ownership. The ASF licenses this file
to you under the Apache License, Version 2.0 (the
"License"); you may not use this file except in compliance
with the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing,
software distributed under the License is distributed on an
"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
KIND, either express or implied. See the License for the
specific language governing permissions and limitations
under the License.
-->
## IPV6_STRING_TO_NUM
<version since="dev">
IPV6_STRING_TO_NUM
</version>
### description
#### Syntax
`VARCHAR IPV6_STRING_TO_NUM(VARCHAR ipv6_string)`
IPv6NumToString 的反向函数,它接受一个 IP 地址字符串并返回二进制格式的 IPv6 地址。
如果输入字符串包含有效的 IPv4 地址,则返回其等效的 IPv6 地址。
### notice
`如果输入非法的IP地址,会抛出异常`
### example
```
mysql> select hex(ipv6_string_to_num('1111::ffff'));
+---------------------------------------+
| hex(ipv6_string_to_num('1111::ffff')) |
+---------------------------------------+
| 1111000000000000000000000000FFFF |
+---------------------------------------+
1 row in set (0.02 sec)
mysql> select hex(ipv6_string_to_num('192.168.0.1'));
+----------------------------------------+
| hex(ipv6_string_to_num('192.168.0.1')) |
+----------------------------------------+
| 00000000000000000000FFFFC0A80001 |
+----------------------------------------+
1 row in set (0.02 sec)
mysql> select hex(ipv6_string_to_num('notaaddress'));
ERROR 1105 (HY000): errCode = 2, detailMessage = (172.17.0.2)[CANCELLED][E33] Invalid IPv6 value
```
### keywords
IPV6_STRING_TO_NUM, IP

View File

@ -195,6 +195,9 @@ import org.apache.doris.nereids.trees.expressions.functions.scalar.Ipv4StringToN
import org.apache.doris.nereids.trees.expressions.functions.scalar.Ipv4StringToNumOrDefault;
import org.apache.doris.nereids.trees.expressions.functions.scalar.Ipv4StringToNumOrNull;
import org.apache.doris.nereids.trees.expressions.functions.scalar.Ipv6NumToString;
import org.apache.doris.nereids.trees.expressions.functions.scalar.Ipv6StringToNum;
import org.apache.doris.nereids.trees.expressions.functions.scalar.Ipv6StringToNumOrDefault;
import org.apache.doris.nereids.trees.expressions.functions.scalar.Ipv6StringToNumOrNull;
import org.apache.doris.nereids.trees.expressions.functions.scalar.JsonArray;
import org.apache.doris.nereids.trees.expressions.functions.scalar.JsonContains;
import org.apache.doris.nereids.trees.expressions.functions.scalar.JsonExtract;
@ -593,6 +596,9 @@ public class BuiltinScalarFunctions implements FunctionHelper {
scalar(Ipv4StringToNumOrDefault.class, "ipv4stringtonumordefault"),
scalar(Ipv4StringToNumOrNull.class, "ipv4stringtonumornull"),
scalar(Ipv6NumToString.class, "ipv6numtostring", "inet6_ntoa"),
scalar(Ipv6StringToNum.class, "ipv6_string_to_num", "inet6_aton"),
scalar(Ipv6StringToNumOrDefault.class, "ipv6_string_to_num_or_default"),
scalar(Ipv6StringToNumOrNull.class, "ipv6_string_to_num_or_null"),
scalar(JsonArray.class, "json_array"),
scalar(JsonObject.class, "json_object"),
scalar(JsonQuote.class, "json_quote"),

View File

@ -0,0 +1,66 @@
// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements. See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership. The ASF licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License. You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied. See the License for the
// specific language governing permissions and limitations
// under the License.
package org.apache.doris.nereids.trees.expressions.functions.scalar;
import org.apache.doris.catalog.FunctionSignature;
import org.apache.doris.nereids.trees.expressions.Expression;
import org.apache.doris.nereids.trees.expressions.functions.AlwaysNotNullable;
import org.apache.doris.nereids.trees.expressions.functions.ExplicitlyCastableSignature;
import org.apache.doris.nereids.trees.expressions.shape.BinaryExpression;
import org.apache.doris.nereids.trees.expressions.visitor.ExpressionVisitor;
import org.apache.doris.nereids.types.StringType;
import org.apache.doris.nereids.types.VarcharType;
import com.google.common.base.Preconditions;
import com.google.common.collect.ImmutableList;
import java.util.List;
/**
* scalar function ipv6_string_to_num
*/
public class Ipv6StringToNum extends ScalarFunction
implements BinaryExpression, ExplicitlyCastableSignature, AlwaysNotNullable {
public static final List<FunctionSignature> SIGNATURES = ImmutableList.of(
FunctionSignature.ret(VarcharType.SYSTEM_DEFAULT).args(VarcharType.SYSTEM_DEFAULT),
FunctionSignature.ret(StringType.INSTANCE).args(StringType.INSTANCE));
public Ipv6StringToNum(Expression arg0) {
super("ipv6_string_to_num", arg0);
}
@Override
public Ipv6StringToNum withChildren(List<Expression> children) {
Preconditions.checkArgument(children.size() == 1,
"ipv6_string_to_num accept 1 args, but got %s (%s)",
children.size(),
children);
return new Ipv6StringToNum(children.get(0));
}
@Override
public List<FunctionSignature> getSignatures() {
return SIGNATURES;
}
@Override
public <R, C> R accept(ExpressionVisitor<R, C> visitor, C context) {
return visitor.visitIpv6StringToNum(this, context);
}
}

View File

@ -0,0 +1,66 @@
// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements. See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership. The ASF licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License. You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied. See the License for the
// specific language governing permissions and limitations
// under the License.
package org.apache.doris.nereids.trees.expressions.functions.scalar;
import org.apache.doris.catalog.FunctionSignature;
import org.apache.doris.nereids.trees.expressions.Expression;
import org.apache.doris.nereids.trees.expressions.functions.AlwaysNotNullable;
import org.apache.doris.nereids.trees.expressions.functions.ExplicitlyCastableSignature;
import org.apache.doris.nereids.trees.expressions.shape.BinaryExpression;
import org.apache.doris.nereids.trees.expressions.visitor.ExpressionVisitor;
import org.apache.doris.nereids.types.StringType;
import org.apache.doris.nereids.types.VarcharType;
import com.google.common.base.Preconditions;
import com.google.common.collect.ImmutableList;
import java.util.List;
/**
* scalar function ipv6_string_to_num_or_default
*/
public class Ipv6StringToNumOrDefault extends ScalarFunction
implements BinaryExpression, ExplicitlyCastableSignature, AlwaysNotNullable {
public static final List<FunctionSignature> SIGNATURES = ImmutableList.of(
FunctionSignature.ret(VarcharType.SYSTEM_DEFAULT).args(VarcharType.SYSTEM_DEFAULT),
FunctionSignature.ret(StringType.INSTANCE).args(StringType.INSTANCE));
public Ipv6StringToNumOrDefault(Expression arg0) {
super("ipv6_string_to_num_or_default", arg0);
}
@Override
public Ipv6StringToNumOrDefault withChildren(List<Expression> children) {
Preconditions.checkArgument(children.size() == 1,
"ipv6_string_to_num_or_default accept 1 args, but got %s (%s)",
children.size(),
children);
return new Ipv6StringToNumOrDefault(children.get(0));
}
@Override
public List<FunctionSignature> getSignatures() {
return SIGNATURES;
}
@Override
public <R, C> R accept(ExpressionVisitor<R, C> visitor, C context) {
return visitor.visitIpv6StringToNumOrDefault(this, context);
}
}

View File

@ -0,0 +1,66 @@
// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements. See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership. The ASF licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License. You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied. See the License for the
// specific language governing permissions and limitations
// under the License.
package org.apache.doris.nereids.trees.expressions.functions.scalar;
import org.apache.doris.catalog.FunctionSignature;
import org.apache.doris.nereids.trees.expressions.Expression;
import org.apache.doris.nereids.trees.expressions.functions.AlwaysNullable;
import org.apache.doris.nereids.trees.expressions.functions.ExplicitlyCastableSignature;
import org.apache.doris.nereids.trees.expressions.shape.BinaryExpression;
import org.apache.doris.nereids.trees.expressions.visitor.ExpressionVisitor;
import org.apache.doris.nereids.types.StringType;
import org.apache.doris.nereids.types.VarcharType;
import com.google.common.base.Preconditions;
import com.google.common.collect.ImmutableList;
import java.util.List;
/**
* scalar function ipv6_string_to_num_or_null
*/
public class Ipv6StringToNumOrNull extends ScalarFunction
implements BinaryExpression, ExplicitlyCastableSignature, AlwaysNullable {
public static final List<FunctionSignature> SIGNATURES = ImmutableList.of(
FunctionSignature.ret(VarcharType.SYSTEM_DEFAULT).args(VarcharType.SYSTEM_DEFAULT),
FunctionSignature.ret(StringType.INSTANCE).args(StringType.INSTANCE));
public Ipv6StringToNumOrNull(Expression arg0) {
super("ipv6_string_to_num_or_null", arg0);
}
@Override
public Ipv6StringToNumOrNull withChildren(List<Expression> children) {
Preconditions.checkArgument(children.size() == 1,
"ipv6_string_to_num_or_null accept 1 args, but got %s (%s)",
children.size(),
children);
return new Ipv6StringToNumOrNull(children.get(0));
}
@Override
public List<FunctionSignature> getSignatures() {
return SIGNATURES;
}
@Override
public <R, C> R accept(ExpressionVisitor<R, C> visitor, C context) {
return visitor.visitIpv6StringToNumOrNull(this, context);
}
}

View File

@ -191,6 +191,9 @@ import org.apache.doris.nereids.trees.expressions.functions.scalar.Ipv4StringToN
import org.apache.doris.nereids.trees.expressions.functions.scalar.Ipv4StringToNumOrDefault;
import org.apache.doris.nereids.trees.expressions.functions.scalar.Ipv4StringToNumOrNull;
import org.apache.doris.nereids.trees.expressions.functions.scalar.Ipv6NumToString;
import org.apache.doris.nereids.trees.expressions.functions.scalar.Ipv6StringToNum;
import org.apache.doris.nereids.trees.expressions.functions.scalar.Ipv6StringToNumOrDefault;
import org.apache.doris.nereids.trees.expressions.functions.scalar.Ipv6StringToNumOrNull;
import org.apache.doris.nereids.trees.expressions.functions.scalar.JsonArray;
import org.apache.doris.nereids.trees.expressions.functions.scalar.JsonContains;
import org.apache.doris.nereids.trees.expressions.functions.scalar.JsonExtract;
@ -1121,6 +1124,18 @@ public interface ScalarFunctionVisitor<R, C> {
return visitScalarFunction(ipv6NumToString, context);
}
default R visitIpv6StringToNum(Ipv6StringToNum ipv6StringToNum, C context) {
return visitScalarFunction(ipv6StringToNum, context);
}
default R visitIpv6StringToNumOrDefault(Ipv6StringToNumOrDefault ipv6StringToNumOrDefault, C context) {
return visitScalarFunction(ipv6StringToNumOrDefault, context);
}
default R visitIpv6StringToNumOrNull(Ipv6StringToNumOrNull ipv6StringToNumOrNull, C context) {
return visitScalarFunction(ipv6StringToNumOrNull, context);
}
default R visitJsonArray(JsonArray jsonArray, C context) {
return visitScalarFunction(jsonArray, context);
}

View File

@ -2006,6 +2006,12 @@ visible_functions = {
[['ipv4stringtonumornull'], 'BIGINT', ['STRING'], 'ALWAYS_NULLABLE'],
[['ipv6numtostring','inet6_ntoa'], 'VARCHAR', ['VARCHAR'], 'ALWAYS_NULLABLE'],
[['ipv6numtostring','inet6_ntoa'], 'STRING', ['STRING'], 'ALWAYS_NULLABLE'],
[['ipv6_string_to_num','inet6_aton'], 'VARCHAR', ['VARCHAR'], 'ALWAYS_NOT_NULLABLE'],
[['ipv6_string_to_num','inet6_aton'], 'STRING', ['STRING'], 'ALWAYS_NOT_NULLABLE'],
[['ipv6_string_to_num_or_default'], 'VARCHAR', ['VARCHAR'], 'ALWAYS_NOT_NULLABLE'],
[['ipv6_string_to_num_or_default'], 'STRING', ['STRING'], 'ALWAYS_NOT_NULLABLE'],
[['ipv6_string_to_num_or_null'], 'VARCHAR', ['VARCHAR'], 'ALWAYS_NULLABLE'],
[['ipv6_string_to_num_or_null'], 'STRING', ['STRING'], 'ALWAYS_NULLABLE'],
],
"NonNullalbe": [

View File

@ -87,4 +87,67 @@ aaaa:aaaa:ffff:ffff:ffff:ffff:aaaa:aaaa
\N
-- !ip30 --
::ffff:127.0.0.1
::ffff:127.0.0.1
-- !ip31 --
00000000000000000000FFFFC0A80001
-- !ip32 --
2A0206B8000000000000000000000011
-- !ip33 --
00000000000000000000000000000000
-- !ip34 --
00A00050910000000000000000000000
-- !ip35 --
00000000000000000000FFFFC0A80001
-- !ip36 --
2A0206B8000000000000000000000011
-- !ip37 --
00000000000000000000000000000000
-- !ip38 --
00000000000000000000000000000000
-- !ip39 --
00000000000000000000000000000000
-- !ip40 --
00000000000000000000FFFFC0A80001
-- !ip41 --
2A0206B8000000000000000000000011
-- !ip42 --
00000000000000000000000000000000
-- !ip43 --
\N
-- !ip44 --
\N
-- !ip45 --
\N
-- !ip46 --
\N
-- !ip47 --
\N
-- !ip48 --
\N
-- !ip49 --
AAAAAAAAFFFFFFFFFFFFFFFFAAAAAAAA
-- !ip50 --
00000000000000000000FFFFC0A80001
-- !ip51 --
2A0206B8000000000000000000000011

View File

@ -74,4 +74,67 @@ aaaa:aaaa:ffff:ffff:ffff:ffff:aaaa:aaaa
\N
-- !sql --
::ffff:127.0.0.1
::ffff:127.0.0.1
-- !sql --
00000000000000000000FFFFC0A80001
-- !sql --
2A0206B8000000000000000000000011
-- !sql --
00000000000000000000000000000000
-- !sql --
00A00050910000000000000000000000
-- !sql --
00000000000000000000FFFFC0A80001
-- !sql --
2A0206B8000000000000000000000011
-- !sql --
00000000000000000000000000000000
-- !sql --
00000000000000000000000000000000
-- !sql --
00000000000000000000000000000000
-- !sql --
00000000000000000000FFFFC0A80001
-- !sql --
2A0206B8000000000000000000000011
-- !sql --
00000000000000000000000000000000
-- !sql --
\N
-- !sql --
\N
-- !sql --
\N
-- !sql --
\N
-- !sql --
\N
-- !sql --
\N
-- !sql --
AAAAAAAAFFFFFFFFFFFFFFFFAAAAAAAA
-- !sql --
00000000000000000000FFFFC0A80001
-- !sql --
2A0206B8000000000000000000000011

View File

@ -50,4 +50,26 @@ suite("ip_functions") {
qt_ip28 "SELECT inet6_ntoa(unhex('aaaa@#'));"
qt_ip29 "SELECT inet6_ntoa(unhex('\0'));"
qt_ip30 "SELECT inet6_ntoa(unhex('00000000000000000000FFFF7F000001'));"
qt_ip31 "SELECT hex(ipv6_string_to_num('192.168.0.1'));"
qt_ip32 "SELECT hex(ipv6_string_to_num('2a02:6b8::11'));"
qt_ip33 "SELECT hex(ipv6_string_to_num('::'));"
qt_ip34 "SELECT hex(ipv6_string_to_num('a0:50:9100::'));"
qt_ip35 "SELECT hex(ipv6_string_to_num_or_default('192.168.0.1'));"
qt_ip36 "SELECT hex(ipv6_string_to_num_or_default('2a02:6b8::11'));"
qt_ip37 "SELECT hex(ipv6_string_to_num_or_default('::'));"
qt_ip38 "SELECT hex(ipv6_string_to_num_or_default('KK'));"
qt_ip39 "SELECT hex(ipv6_string_to_num_or_default('ffffffffffffffffffffffffffffffffffffffffffffffffffffff'));"
qt_ip40 "SELECT hex(ipv6_string_to_num_or_null('192.168.0.1'));"
qt_ip41 "SELECT hex(ipv6_string_to_num_or_null('2a02:6b8::11'));"
qt_ip42 "SELECT hex(ipv6_string_to_num_or_null('::'));"
qt_ip43 "SELECT hex(ipv6_string_to_num_or_null('KK'));"
qt_ip44 "SELECT hex(ipv6_string_to_num_or_null('ffffffffffffffffffffffffffffffffffffffffffffffffffffff'));"
qt_ip45 "SELECT hex(ipv6_string_to_num_or_null(''));"
qt_ip46 "SELECT hex(ipv6_string_to_num_or_null(NULL));"
qt_ip47 "SELECT hex(ipv6_string_to_num_or_null('\0'));"
qt_ip48 "SELECT hex(ipv6_string_to_num_or_null('00'));"
qt_ip49 "SELECT hex(ipv6_string_to_num_or_null('aaaa:aaaa:ffff:ffff:ffff:ffff:aaaa:aaaa'));"
qt_ip50 "SELECT hex(inet6_aton('192.168.0.1'));"
qt_ip51 "SELECT hex(inet6_aton('2a02:6b8::11'));"
}

View File

@ -45,4 +45,26 @@ suite("test_ip_functions", "arrow_flight_sql") {
qt_sql "SELECT inet6_ntoa(unhex('aaaa@#'));"
qt_sql "SELECT inet6_ntoa(unhex('\0'));"
qt_sql "SELECT inet6_ntoa(unhex('00000000000000000000FFFF7F000001'));"
qt_sql "SELECT hex(ipv6_string_to_num('192.168.0.1'));"
qt_sql "SELECT hex(ipv6_string_to_num('2a02:6b8::11'));"
qt_sql "SELECT hex(ipv6_string_to_num('::'));"
qt_sql "SELECT hex(ipv6_string_to_num('a0:50:9100::'));"
qt_sql "SELECT hex(ipv6_string_to_num_or_default('192.168.0.1'));"
qt_sql "SELECT hex(ipv6_string_to_num_or_default('2a02:6b8::11'));"
qt_sql "SELECT hex(ipv6_string_to_num_or_default('::'));"
qt_sql "SELECT hex(ipv6_string_to_num_or_default('KK'));"
qt_sql "SELECT hex(ipv6_string_to_num_or_default('ffffffffffffffffffffffffffffffffffffffffffffffffffffff'));"
qt_sql "SELECT hex(ipv6_string_to_num_or_null('192.168.0.1'));"
qt_sql "SELECT hex(ipv6_string_to_num_or_null('2a02:6b8::11'));"
qt_sql "SELECT hex(ipv6_string_to_num_or_null('::'));"
qt_sql "SELECT hex(ipv6_string_to_num_or_null('KK'));"
qt_sql "SELECT hex(ipv6_string_to_num_or_null('ffffffffffffffffffffffffffffffffffffffffffffffffffffff'));"
qt_sql "SELECT hex(ipv6_string_to_num_or_null(''));"
qt_sql "SELECT hex(ipv6_string_to_num_or_null(NULL));"
qt_sql "SELECT hex(ipv6_string_to_num_or_null('\0'));"
qt_sql "SELECT hex(ipv6_string_to_num_or_null('00'));"
qt_sql "SELECT hex(ipv6_string_to_num_or_null('aaaa:aaaa:ffff:ffff:ffff:ffff:aaaa:aaaa'));"
qt_sql "SELECT hex(inet6_aton('192.168.0.1'));"
qt_sql "SELECT hex(inet6_aton('2a02:6b8::11'));"
}