[feature](function) support ip function ipv6numtostring(alias inet6_ntoa) (#27342)
This commit is contained in:
@ -23,6 +23,7 @@
|
||||
#include <algorithm>
|
||||
#include <array>
|
||||
|
||||
#include "vec/common/hex.h"
|
||||
#include "vec/core/types.h"
|
||||
|
||||
namespace doris::vectorized {
|
||||
@ -75,4 +76,119 @@ consteval std::array<std::pair<const char*, size_t>, N> str_make_array() {
|
||||
/// This will generate static array of pair<const char *, size_t> for [0..255] at compile time
|
||||
extern constexpr std::array<std::pair<const char*, size_t>, 256> one_byte_to_string_lookup_table =
|
||||
str_make_array<256>();
|
||||
|
||||
/// integer logarithm, return ceil(log(value, base)) (the smallest integer greater or equal than log(value, base)
|
||||
static constexpr UInt32 intLog(const UInt32 value, const UInt32 base, const bool carry) {
|
||||
return value >= base ? 1 + intLog(value / base, base, value % base || carry)
|
||||
: value % base > 1 || carry;
|
||||
}
|
||||
|
||||
/// Print integer in desired base, faster than sprintf.
|
||||
/// NOTE This is not the best way. See https://github.com/miloyip/itoa-benchmark
|
||||
/// But it doesn't matter here.
|
||||
template <UInt32 base, typename T>
|
||||
static void print_integer(char*& out, T value) {
|
||||
if (value == 0) {
|
||||
*out++ = '0';
|
||||
} else {
|
||||
constexpr size_t buffer_size = sizeof(T) * intLog(256, base, false);
|
||||
|
||||
char buf[buffer_size];
|
||||
auto ptr = buf;
|
||||
|
||||
while (value > 0) {
|
||||
*ptr = hex_digit_lowercase(value % base);
|
||||
++ptr;
|
||||
value /= base;
|
||||
}
|
||||
|
||||
/// Copy to out reversed.
|
||||
while (ptr != buf) {
|
||||
--ptr;
|
||||
*out = *ptr;
|
||||
++out;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void formatIPv6(const unsigned char* src, char*& dst, uint8_t zeroed_tail_bytes_count) {
|
||||
struct {
|
||||
Int64 base, len;
|
||||
} best {-1, 0}, cur {-1, 0};
|
||||
std::array<UInt16, IPV6_BINARY_LENGTH / sizeof(UInt16)> words {};
|
||||
|
||||
/** Preprocess:
|
||||
* Copy the input (bytewise) array into a wordwise array.
|
||||
* Find the longest run of 0x00's in src[] for :: shorthanding. */
|
||||
for (size_t i = 0; i < (IPV6_BINARY_LENGTH - zeroed_tail_bytes_count); i += 2) {
|
||||
words[i / 2] = (src[i] << 8) | src[i + 1];
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < words.size(); i++) {
|
||||
if (words[i] == 0) {
|
||||
if (cur.base == -1) {
|
||||
cur.base = i;
|
||||
cur.len = 1;
|
||||
} else {
|
||||
cur.len++;
|
||||
}
|
||||
} else {
|
||||
if (cur.base != -1) {
|
||||
if (best.base == -1 || cur.len > best.len) {
|
||||
best = cur;
|
||||
}
|
||||
cur.base = -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (cur.base != -1) {
|
||||
if (best.base == -1 || cur.len > best.len) {
|
||||
best = cur;
|
||||
}
|
||||
}
|
||||
if (best.base != -1 && best.len < 2) {
|
||||
best.base = -1;
|
||||
}
|
||||
|
||||
/// Format the result.
|
||||
for (size_t i = 0; i < words.size(); i++) {
|
||||
/// Are we inside the best run of 0x00's?
|
||||
if (best.base != -1) {
|
||||
auto best_base = static_cast<size_t>(best.base);
|
||||
if (i >= best_base && i < (best_base + best.len)) {
|
||||
if (i == best_base) {
|
||||
*dst++ = ':';
|
||||
}
|
||||
continue;
|
||||
}
|
||||
}
|
||||
/// Are we following an initial run of 0x00s or any real hex?
|
||||
if (i != 0) {
|
||||
*dst++ = ':';
|
||||
}
|
||||
/// Is this address an encapsulated IPv4?
|
||||
if (i == 6 && best.base == 0 && (best.len == 6 || (best.len == 5 && words[5] == 0xffffu))) {
|
||||
uint8_t ipv4_buffer[IPV4_BINARY_LENGTH] = {0};
|
||||
memcpy(ipv4_buffer, src + 12, IPV4_BINARY_LENGTH);
|
||||
// Due to historical reasons formatIPv4() takes ipv4 in BE format, but inside ipv6 we store it in LE-format.
|
||||
#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
|
||||
std::reverse(std::begin(ipv4_buffer), std::end(ipv4_buffer));
|
||||
#endif
|
||||
formatIPv4(ipv4_buffer, dst,
|
||||
std::min(zeroed_tail_bytes_count, static_cast<uint8_t>(IPV4_BINARY_LENGTH)),
|
||||
"0");
|
||||
// formatIPv4 has already added a null-terminator for us.
|
||||
return;
|
||||
}
|
||||
print_integer<16>(dst, words[i]);
|
||||
}
|
||||
|
||||
/// Was it a trailing run of 0x00's?
|
||||
if (best.base != -1 &&
|
||||
static_cast<size_t>(best.base) + static_cast<size_t>(best.len) == words.size()) {
|
||||
*dst++ = ':';
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace doris::vectorized
|
||||
|
||||
@ -37,6 +37,7 @@ constexpr size_t IPV4_MAX_NUM_VALUE = 4294967295; //num value of '255.255.255.25
|
||||
constexpr int IPV4_MAX_OCTET_VALUE = 255; //max vulue of octet
|
||||
constexpr size_t IPV4_OCTET_BITS = 8;
|
||||
constexpr size_t DECIMAL_BASE = 10;
|
||||
constexpr size_t IPV6_BINARY_LENGTH = 16;
|
||||
|
||||
namespace doris::vectorized {
|
||||
|
||||
@ -191,4 +192,10 @@ inline bool parseIPv4whole(const char* src, unsigned char* dst) {
|
||||
return end != nullptr && *end == '\0';
|
||||
}
|
||||
|
||||
/** Rewritten inet_ntop6 from http://svn.apache.org/repos/asf/apr/apr/trunk/network_io/unix/inet_pton.c
|
||||
* performs significantly faster than the reference implementation due to the absence of sprintf calls,
|
||||
* bounds checking, unnecessary string copying and length calculation.
|
||||
*/
|
||||
void formatIPv6(const unsigned char* src, char*& dst, uint8_t zeroed_tail_bytes_count = 0);
|
||||
|
||||
} // namespace doris::vectorized
|
||||
|
||||
@ -30,5 +30,7 @@ void register_function_ip(SimpleFunctionFactory& factory) {
|
||||
factory.register_function<FunctionIPv4StringToNum<IPStringToNumExceptionMode::Null>>();
|
||||
factory.register_alias(FunctionIPv4StringToNum<IPStringToNumExceptionMode::Throw>::name,
|
||||
"inet_aton");
|
||||
factory.register_function<FunctionIPv6NumToString>();
|
||||
factory.register_alias(FunctionIPv6NumToString::name, "inet6_ntoa");
|
||||
}
|
||||
} // namespace doris::vectorized
|
||||
@ -26,9 +26,11 @@
|
||||
#include "vec/columns/column_vector.h"
|
||||
#include "vec/common/format_ip.h"
|
||||
#include "vec/core/column_with_type_and_name.h"
|
||||
#include "vec/data_types/data_type_ipv6.h"
|
||||
#include "vec/data_types/data_type_number.h"
|
||||
#include "vec/data_types/data_type_string.h"
|
||||
#include "vec/functions/function.h"
|
||||
#include "vec/functions/function_helpers.h"
|
||||
#include "vec/functions/simple_function_factory.h"
|
||||
|
||||
namespace doris::vectorized {
|
||||
@ -250,4 +252,100 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
void process_ipv6_column(const ColumnPtr& column, size_t input_rows_count,
|
||||
ColumnString::Chars& vec_res, ColumnString::Offsets& offsets_res,
|
||||
ColumnUInt8::MutablePtr& null_map, unsigned char* ipv6_address_data) {
|
||||
auto* begin = reinterpret_cast<char*>(vec_res.data());
|
||||
auto* pos = begin;
|
||||
|
||||
const auto* col = check_and_get_column<T>(column.get());
|
||||
|
||||
for (size_t i = 0; i < input_rows_count; ++i) {
|
||||
bool is_empty = false;
|
||||
|
||||
if constexpr (std::is_same_v<T, ColumnIPv6>) {
|
||||
const auto& vec_in = col->get_data();
|
||||
memcpy(ipv6_address_data, reinterpret_cast<const unsigned char*>(&vec_in[i]),
|
||||
IPV6_BINARY_LENGTH);
|
||||
} else {
|
||||
const auto str_ref = col->get_data_at(i);
|
||||
const char* value = str_ref.data;
|
||||
size_t value_size = str_ref.size;
|
||||
|
||||
if (value_size > IPV6_BINARY_LENGTH || value == nullptr || value_size == 0) {
|
||||
is_empty = true;
|
||||
} else {
|
||||
memcpy(ipv6_address_data, value, value_size);
|
||||
memset(ipv6_address_data + value_size, 0, IPV6_BINARY_LENGTH - value_size);
|
||||
}
|
||||
}
|
||||
|
||||
if (is_empty) {
|
||||
offsets_res[i] = pos - begin;
|
||||
null_map->get_data()[i] = 1;
|
||||
} else {
|
||||
formatIPv6(ipv6_address_data, pos);
|
||||
offsets_res[i] = pos - begin;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class FunctionIPv6NumToString : public IFunction {
|
||||
public:
|
||||
static constexpr auto name = "ipv6numtostring";
|
||||
static FunctionPtr create() { return std::make_shared<FunctionIPv6NumToString>(); }
|
||||
|
||||
String get_name() const override { return name; }
|
||||
|
||||
size_t get_number_of_arguments() const override { return 1; }
|
||||
|
||||
DataTypePtr get_return_type_impl(const DataTypes& arguments) const override {
|
||||
const auto* arg_string = check_and_get_data_type<DataTypeString>(arguments[0].get());
|
||||
const auto* arg_ipv6 = check_and_get_data_type<DataTypeIPv6>(arguments[0].get());
|
||||
if (!arg_ipv6 && !(arg_string))
|
||||
throw Exception(ErrorCode::INVALID_ARGUMENT,
|
||||
"Illegal type {} of argument of function {}, expected IPv6 or String",
|
||||
arguments[0]->get_name(), get_name());
|
||||
|
||||
return make_nullable(std::make_shared<DataTypeString>());
|
||||
}
|
||||
|
||||
bool use_default_implementation_for_nulls() const override { return true; }
|
||||
|
||||
Status execute_impl(FunctionContext* context, Block& block, const ColumnNumbers& arguments,
|
||||
size_t result, size_t input_rows_count) const override {
|
||||
const ColumnPtr& column = block.get_by_position(arguments[0]).column;
|
||||
const auto* col_ipv6 = check_and_get_column<ColumnIPv6>(column.get());
|
||||
const auto* col_string = check_and_get_column<ColumnString>(column.get());
|
||||
|
||||
if (!col_ipv6 && !col_string)
|
||||
throw Exception(ErrorCode::INVALID_ARGUMENT,
|
||||
"Illegal column {} of argument of function {}, expected IPv6 or String",
|
||||
column->get_name(), get_name());
|
||||
|
||||
auto col_res = ColumnString::create();
|
||||
ColumnString::Chars& vec_res = col_res->get_chars();
|
||||
ColumnString::Offsets& offsets_res = col_res->get_offsets();
|
||||
vec_res.resize(input_rows_count * (IPV6_MAX_TEXT_LENGTH + 1));
|
||||
offsets_res.resize(input_rows_count);
|
||||
|
||||
auto null_map = ColumnUInt8::create(input_rows_count, 0);
|
||||
|
||||
unsigned char ipv6_address_data[IPV6_BINARY_LENGTH];
|
||||
|
||||
if (col_ipv6) {
|
||||
process_ipv6_column<ColumnIPv6>(column, input_rows_count, vec_res, offsets_res,
|
||||
null_map, ipv6_address_data);
|
||||
} else {
|
||||
process_ipv6_column<ColumnString>(column, input_rows_count, vec_res, offsets_res,
|
||||
null_map, ipv6_address_data);
|
||||
}
|
||||
|
||||
block.replace_by_position(result,
|
||||
ColumnNullable::create(std::move(col_res), std::move(null_map)));
|
||||
return Status::OK();
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace doris::vectorized
|
||||
@ -0,0 +1,56 @@
|
||||
---
|
||||
{
|
||||
"title": "INET6_NTOA",
|
||||
"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_NTOA
|
||||
|
||||
<version since="dev">
|
||||
|
||||
INET6_NTOA
|
||||
|
||||
</version>
|
||||
|
||||
### description
|
||||
|
||||
#### Syntax
|
||||
|
||||
`VARCHAR INET6_NTOA(VARCHAR ipv6_num)`
|
||||
|
||||
Takes an IPv6 address in binary format of type String. Returns the string of this address in text format.
|
||||
The IPv4 address mapped by IPv6 starts with ::ffff:111.222.33.
|
||||
|
||||
### example
|
||||
|
||||
```
|
||||
mysql> select inet6_ntoa(unhex('2A0206B8000000000000000000000011')) as addr;
|
||||
+--------------+
|
||||
| addr |
|
||||
+--------------+
|
||||
| 2a02:6b8::11 |
|
||||
+--------------+
|
||||
1 row in set (0.01 sec)
|
||||
```
|
||||
|
||||
### keywords
|
||||
|
||||
INET6_NTOA, IP
|
||||
@ -0,0 +1,56 @@
|
||||
---
|
||||
{
|
||||
"title": "IPV6_NUM_TO_STRING",
|
||||
"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.
|
||||
-->
|
||||
|
||||
## IPv6NumToString
|
||||
|
||||
<version since="dev">
|
||||
|
||||
IPv6NumToString
|
||||
|
||||
</version>
|
||||
|
||||
### description
|
||||
|
||||
#### Syntax
|
||||
|
||||
`VARCHAR IPv6NumToString(VARCHAR ipv6_num)`
|
||||
|
||||
Takes an IPv6 address in binary format of type String. Returns the string of this address in text format.
|
||||
The IPv4 address mapped by IPv6 starts with ::ffff:111.222.33.
|
||||
|
||||
### example
|
||||
|
||||
```
|
||||
mysql> select ipv6numtostring(unhex('2A0206B8000000000000000000000011')) as addr;
|
||||
+--------------+
|
||||
| addr |
|
||||
+--------------+
|
||||
| 2a02:6b8::11 |
|
||||
+--------------+
|
||||
1 row in set (0.01 sec)
|
||||
```
|
||||
|
||||
### keywords
|
||||
|
||||
IPV6NUMTOSTRING, IP
|
||||
@ -785,7 +785,9 @@
|
||||
"sql-manual/sql-functions/ip-functions/ipv4-string-to-num",
|
||||
"sql-manual/sql-functions/ip-functions/inet-aton",
|
||||
"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/ipv4-string-to-num-or-null",
|
||||
"sql-manual/sql-functions/ip-functions/ipv6-num-to-string",
|
||||
"sql-manual/sql-functions/ip-functions/inet6-ntoa"
|
||||
]
|
||||
},
|
||||
{
|
||||
|
||||
@ -0,0 +1,56 @@
|
||||
---
|
||||
{
|
||||
"title": "INET6_NTOA",
|
||||
"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_NTOA
|
||||
|
||||
<version since="dev">
|
||||
|
||||
INET6_NTOA
|
||||
|
||||
</version>
|
||||
|
||||
### description
|
||||
|
||||
#### Syntax
|
||||
|
||||
`VARCHAR INET6_NTOA(VARCHAR ipv6_num)`
|
||||
|
||||
接受字符串类型的二进制格式的IPv6地址。以文本格式返回此地址的字符串。
|
||||
IPv6映射的IPv4地址以::ffff:111.222.33。
|
||||
|
||||
### example
|
||||
|
||||
```
|
||||
mysql> select inet6_ntoa(unhex('2A0206B8000000000000000000000011')) as addr;
|
||||
+--------------+
|
||||
| addr |
|
||||
+--------------+
|
||||
| 2a02:6b8::11 |
|
||||
+--------------+
|
||||
1 row in set (0.01 sec)
|
||||
```
|
||||
|
||||
### keywords
|
||||
|
||||
INET6_NTOA, IP
|
||||
@ -0,0 +1,56 @@
|
||||
---
|
||||
{
|
||||
"title": "IPV6_NUM_TO_STRING",
|
||||
"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.
|
||||
-->
|
||||
|
||||
## IPv6NumToString
|
||||
|
||||
<version since="dev">
|
||||
|
||||
IPv6NumToString
|
||||
|
||||
</version>
|
||||
|
||||
### description
|
||||
|
||||
#### Syntax
|
||||
|
||||
`VARCHAR IPv6NumToString(VARCHAR ipv6_num)`
|
||||
|
||||
接受字符串类型的二进制格式的IPv6地址。以文本格式返回此地址的字符串。
|
||||
IPv6映射的IPv4地址以::ffff:111.222.33。
|
||||
|
||||
### example
|
||||
|
||||
```
|
||||
mysql> select ipv6numtostring(unhex('2A0206B8000000000000000000000011')) as addr;
|
||||
+--------------+
|
||||
| addr |
|
||||
+--------------+
|
||||
| 2a02:6b8::11 |
|
||||
+--------------+
|
||||
1 row in set (0.01 sec)
|
||||
```
|
||||
|
||||
### keywords
|
||||
|
||||
IPV6NUMTOSTRING, IP
|
||||
@ -193,6 +193,7 @@ import org.apache.doris.nereids.trees.expressions.functions.scalar.Ipv4NumToStri
|
||||
import org.apache.doris.nereids.trees.expressions.functions.scalar.Ipv4StringToNum;
|
||||
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.JsonArray;
|
||||
import org.apache.doris.nereids.trees.expressions.functions.scalar.JsonContains;
|
||||
import org.apache.doris.nereids.trees.expressions.functions.scalar.JsonExtract;
|
||||
@ -588,6 +589,7 @@ public class BuiltinScalarFunctions implements FunctionHelper {
|
||||
scalar(Ipv4StringToNum.class, "ipv4stringtonum", "inet_aton"),
|
||||
scalar(Ipv4StringToNumOrDefault.class, "ipv4stringtonumordefault"),
|
||||
scalar(Ipv4StringToNumOrNull.class, "ipv4stringtonumornull"),
|
||||
scalar(Ipv6NumToString.class, "ipv6numtostring", "inet6_ntoa"),
|
||||
scalar(JsonArray.class, "json_array"),
|
||||
scalar(JsonObject.class, "json_object"),
|
||||
scalar(JsonQuote.class, "json_quote"),
|
||||
|
||||
@ -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 Ipv6NumToString
|
||||
*/
|
||||
public class Ipv6NumToString 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 Ipv6NumToString(Expression arg0) {
|
||||
super("ipv6numtostring", arg0);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Ipv6NumToString withChildren(List<Expression> children) {
|
||||
Preconditions.checkArgument(children.size() == 1,
|
||||
"ipv6numtostring accept 1 args, but got %s (%s)",
|
||||
children.size(),
|
||||
children);
|
||||
return new Ipv6NumToString(children.get(0));
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<FunctionSignature> getSignatures() {
|
||||
return SIGNATURES;
|
||||
}
|
||||
|
||||
@Override
|
||||
public <R, C> R accept(ExpressionVisitor<R, C> visitor, C context) {
|
||||
return visitor.visitIpv6NumToString(this, context);
|
||||
}
|
||||
}
|
||||
@ -189,6 +189,7 @@ import org.apache.doris.nereids.trees.expressions.functions.scalar.Ipv4NumToStri
|
||||
import org.apache.doris.nereids.trees.expressions.functions.scalar.Ipv4StringToNum;
|
||||
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.JsonArray;
|
||||
import org.apache.doris.nereids.trees.expressions.functions.scalar.JsonContains;
|
||||
import org.apache.doris.nereids.trees.expressions.functions.scalar.JsonExtract;
|
||||
@ -1111,6 +1112,10 @@ public interface ScalarFunctionVisitor<R, C> {
|
||||
return visitScalarFunction(ipv4StringToNumOrNull, context);
|
||||
}
|
||||
|
||||
default R visitIpv6NumToString(Ipv6NumToString ipv6NumToString, C context) {
|
||||
return visitScalarFunction(ipv6NumToString, context);
|
||||
}
|
||||
|
||||
default R visitJsonArray(JsonArray jsonArray, C context) {
|
||||
return visitScalarFunction(jsonArray, context);
|
||||
}
|
||||
|
||||
@ -2010,7 +2010,9 @@ visible_functions = {
|
||||
[['ipv4stringtonumordefault'], 'BIGINT', ['VARCHAR'], 'ALWAYS_NOT_NULLABLE'],
|
||||
[['ipv4stringtonumordefault'], 'BIGINT', ['STRING'], 'ALWAYS_NOT_NULLABLE'],
|
||||
[['ipv4stringtonumornull'], 'BIGINT', ['VARCHAR'], 'ALWAYS_NULLABLE'],
|
||||
[['ipv4stringtonumornull'], 'BIGINT', ['STRING'], 'ALWAYS_NULLABLE'],
|
||||
[['ipv4stringtonumornull'], 'BIGINT', ['STRING'], 'ALWAYS_NULLABLE'],
|
||||
[['ipv6numtostring','inet6_ntoa'], 'VARCHAR', ['VARCHAR'], 'ALWAYS_NULLABLE'],
|
||||
[['ipv6numtostring','inet6_ntoa'], 'STRING', ['STRING'], 'ALWAYS_NULLABLE'],
|
||||
],
|
||||
|
||||
"NonNullalbe": [
|
||||
|
||||
@ -34,3 +34,57 @@
|
||||
|
||||
-- !ip12 --
|
||||
3232235521
|
||||
|
||||
-- !ip13 --
|
||||
\N
|
||||
|
||||
-- !ip14 --
|
||||
2a02:6b8::11
|
||||
|
||||
-- !ip15 --
|
||||
fdfe::5a55:caff:fefa:9089
|
||||
|
||||
-- !ip16 --
|
||||
\N
|
||||
|
||||
-- !ip17 --
|
||||
\N
|
||||
|
||||
-- !ip18 --
|
||||
a00:509::
|
||||
|
||||
-- !ip19 --
|
||||
abcd:1234:5600::
|
||||
|
||||
-- !ip20 --
|
||||
\N
|
||||
|
||||
-- !ip21 --
|
||||
\N
|
||||
|
||||
-- !ip22 --
|
||||
2a02:6b8::11
|
||||
|
||||
-- !ip23 --
|
||||
\N
|
||||
|
||||
-- !ip24 --
|
||||
::
|
||||
|
||||
-- !ip25 --
|
||||
::
|
||||
|
||||
-- !ip26 --
|
||||
\N
|
||||
|
||||
-- !ip27 --
|
||||
aaaa:aaaa:ffff:ffff:ffff:ffff:aaaa:aaaa
|
||||
|
||||
-- !ip28 --
|
||||
\N
|
||||
|
||||
-- !ip29 --
|
||||
\N
|
||||
|
||||
-- !ip30 --
|
||||
::ffff:127.0.0.1
|
||||
@ -20,4 +20,58 @@
|
||||
0
|
||||
|
||||
-- !sql --
|
||||
3232235521
|
||||
3232235521
|
||||
|
||||
-- !sql --
|
||||
\N
|
||||
|
||||
-- !sql --
|
||||
2a02:6b8::11
|
||||
|
||||
-- !sql --
|
||||
fdfe::5a55:caff:fefa:9089
|
||||
|
||||
-- !sql --
|
||||
\N
|
||||
|
||||
-- !sql --
|
||||
\N
|
||||
|
||||
-- !sql --
|
||||
a00:509::
|
||||
|
||||
-- !sql --
|
||||
abcd:1234:5600::
|
||||
|
||||
-- !sql --
|
||||
\N
|
||||
|
||||
-- !sql --
|
||||
\N
|
||||
|
||||
-- !sql --
|
||||
2a02:6b8::11
|
||||
|
||||
-- !sql --
|
||||
\N
|
||||
|
||||
-- !sql --
|
||||
::
|
||||
|
||||
-- !sql --
|
||||
::
|
||||
|
||||
-- !sql --
|
||||
\N
|
||||
|
||||
-- !sql --
|
||||
aaaa:aaaa:ffff:ffff:ffff:ffff:aaaa:aaaa
|
||||
|
||||
-- !sql --
|
||||
\N
|
||||
|
||||
-- !sql --
|
||||
\N
|
||||
|
||||
-- !sql --
|
||||
::ffff:127.0.0.1
|
||||
@ -31,4 +31,23 @@ suite("ip_functions") {
|
||||
qt_ip10 "SELECT ipv4stringtonumornull('');"
|
||||
qt_ip11 "SELECT ipv4stringtonumordefault('');"
|
||||
qt_ip12 "SELECT inet_aton('192.168.0.1');"
|
||||
|
||||
qt_ip13 "SELECT ipv6numtostring(unhex('0A0005091'));"
|
||||
qt_ip14 "SELECT ipv6numtostring(unhex('2A0206B8000000000000000000000011'));"
|
||||
qt_ip15 "SELECT ipv6numtostring(unhex('FDFE0000000000005A55CAFFFEFA9089'));"
|
||||
qt_ip16 "SELECT ipv6numtostring(unhex(''));"
|
||||
qt_ip17 "SELECT ipv6numtostring(unhex('KK'));"
|
||||
qt_ip18 "SELECT ipv6numtostring(unhex('0A000509'));"
|
||||
qt_ip19 "SELECT ipv6numtostring(unhex('abcd123456'));"
|
||||
qt_ip20 "SELECT ipv6numtostring(unhex('ffffffffffffffffffffffffffffffffffffffffffffffffffffff'));"
|
||||
qt_ip21 "SELECT inet6_ntoa(unhex('0A0005091'));"
|
||||
qt_ip22 "SELECT inet6_ntoa(unhex('2A0206B8000000000000000000000011'));"
|
||||
qt_ip23 "SELECT inet6_ntoa(unhex(NULL));"
|
||||
qt_ip24 "SELECT inet6_ntoa(unhex('00000000000000000000000000000000'));"
|
||||
qt_ip25 "SELECT inet6_ntoa(unhex('0000000000000000000000000000'));"
|
||||
qt_ip26 "SELECT inet6_ntoa(unhex('000'));"
|
||||
qt_ip27 "SELECT inet6_ntoa(unhex('aaaaaaaaFFFFFFFFFFFFFFFFaaaaaaaa'));"
|
||||
qt_ip28 "SELECT inet6_ntoa(unhex('aaaa@#'));"
|
||||
qt_ip29 "SELECT inet6_ntoa(unhex('\0'));"
|
||||
qt_ip30 "SELECT inet6_ntoa(unhex('00000000000000000000FFFF7F000001'));"
|
||||
}
|
||||
@ -26,4 +26,23 @@ suite("test_ip_functions") {
|
||||
qt_sql "SELECT ipv4stringtonumornull('');"
|
||||
qt_sql "SELECT ipv4stringtonumordefault('');"
|
||||
qt_sql "SELECT inet_aton('192.168.0.1');"
|
||||
|
||||
qt_sql "SELECT ipv6numtostring(unhex('0A0005091'));"
|
||||
qt_sql "SELECT ipv6numtostring(unhex('2A0206B8000000000000000000000011'));"
|
||||
qt_sql "SELECT ipv6numtostring(unhex('FDFE0000000000005A55CAFFFEFA9089'));"
|
||||
qt_sql "SELECT ipv6numtostring(unhex(''));"
|
||||
qt_sql "SELECT ipv6numtostring(unhex('KK'));"
|
||||
qt_sql "SELECT ipv6numtostring(unhex('0A000509'));"
|
||||
qt_sql "SELECT ipv6numtostring(unhex('abcd123456'));"
|
||||
qt_sql "SELECT ipv6numtostring(unhex('ffffffffffffffffffffffffffffffffffffffffffffffffffffff'));"
|
||||
qt_sql "SELECT inet6_ntoa(unhex('0A0005091'));"
|
||||
qt_sql "SELECT inet6_ntoa(unhex('2A0206B8000000000000000000000011'));"
|
||||
qt_sql "SELECT inet6_ntoa(unhex(NULL));"
|
||||
qt_sql "SELECT inet6_ntoa(unhex('00000000000000000000000000000000'));"
|
||||
qt_sql "SELECT inet6_ntoa(unhex('0000000000000000000000000000'));"
|
||||
qt_sql "SELECT inet6_ntoa(unhex('000'));"
|
||||
qt_sql "SELECT inet6_ntoa(unhex('aaaaaaaaFFFFFFFFFFFFFFFFaaaaaaaa'));"
|
||||
qt_sql "SELECT inet6_ntoa(unhex('aaaa@#'));"
|
||||
qt_sql "SELECT inet6_ntoa(unhex('\0'));"
|
||||
qt_sql "SELECT inet6_ntoa(unhex('00000000000000000000FFFF7F000001'));"
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user