This is an automated email from the ASF dual-hosted git repository.
yiguolei pushed a commit to branch branch-4.0
in repository https://gitbox.apache.org/repos/asf/doris.git
The following commit(s) were added to refs/heads/branch-4.0 by this push:
new da379662353 branch-4.0: [Feature](varbinary) add length,
from_base64_binary, to_base64_bianry, sub_binary for VarBinary type #56648
(#57334)
da379662353 is described below
commit da379662353aa73009b2ac2e9ca407fa93102b5b
Author: github-actions[bot]
<41898282+github-actions[bot]@users.noreply.github.com>
AuthorDate: Mon Oct 27 09:48:03 2025 +0800
branch-4.0: [Feature](varbinary) add length, from_base64_binary,
to_base64_bianry, sub_binary for VarBinary type #56648 (#57334)
Cherry-picked from #56648
Co-authored-by: admiring_xm <[email protected]>
---
be/src/vec/columns/column_varbinary.h | 8 +
be/src/vec/common/pod_array.h | 5 +
be/src/vec/common/string_view.h | 2 +
be/src/vec/functions/function_string.cpp | 2 +
be/src/vec/functions/function_totype.h | 81 ++--
be/src/vec/functions/function_varbinary.cpp | 136 ++++++-
be/src/vec/functions/function_varbinary.h | 53 +++
be/src/vec/utils/varbinaryop_subbinary.h | 119 ++++++
be/test/vec/function/function_hash_test.cpp | 23 +-
be/test/vec/function/function_string_test.cpp | 68 ++--
be/test/vec/function/function_test_util.cpp | 4 +-
be/test/vec/function/function_test_util.h | 32 +-
be/test/vec/function/function_varbinary_test.cpp | 426 +++++++++++++++++++++
.../doris/catalog/BuiltinScalarFunctions.java | 6 +
.../scalar/{Length.java => FromBase64Binary.java} | 30 +-
.../trees/expressions/functions/scalar/Length.java | 5 +-
.../scalar/{Length.java => SubBinary.java} | 54 ++-
.../scalar/{Length.java => ToBase64Binary.java} | 23 +-
.../expressions/visitor/ScalarFunctionVisitor.java | 15 +
.../binary_functions/test_binary_function.groovy | 128 +++++++
20 files changed, 1083 insertions(+), 137 deletions(-)
diff --git a/be/src/vec/columns/column_varbinary.h
b/be/src/vec/columns/column_varbinary.h
index 20417ba2d66..6411eb26ec0 100644
--- a/be/src/vec/columns/column_varbinary.h
+++ b/be/src/vec/columns/column_varbinary.h
@@ -70,6 +70,8 @@ public:
StringRef get_data_at(size_t n) const override { return
_data[n].to_string_ref(); }
+ char* alloc(size_t length) { return _arena.alloc(length); }
+
void insert(const Field& x) override {
auto value = vectorized::get<const doris::StringView&>(x);
insert_data(value.data(), value.size());
@@ -101,6 +103,12 @@ public:
void insert_default() override { _data.push_back(doris::StringView()); }
+ int compare_at(size_t n, size_t m, const IColumn& rhs_,
+ int /*nan_direction_hint*/) const override {
+ const ColumnVarbinary& rhs = assert_cast<const ColumnVarbinary&>(rhs_);
+ return this->_data[n].compare(rhs.get_data()[m]);
+ }
+
void pop_back(size_t n) override { resize(size() - n); }
StringRef serialize_value_into_arena(size_t n, Arena& arena,
diff --git a/be/src/vec/common/pod_array.h b/be/src/vec/common/pod_array.h
index f361f1e078b..8c0121c916d 100644
--- a/be/src/vec/common/pod_array.h
+++ b/be/src/vec/common/pod_array.h
@@ -548,6 +548,11 @@ public:
void pop_back() { this->c_end -= this->byte_size(1); }
+ void pop_back(size_t n) {
+ DCHECK_GE(this->size(), n);
+ this->c_end -= this->byte_size(n);
+ }
+
/// Do not insert into the array a piece of itself. Because with the
resize, the iterators on themselves can be invalidated.
template <typename It1, typename It2, typename... TAllocatorParams>
void insert_prepare(It1 from_begin, It2 from_end, TAllocatorParams&&...
allocator_params) {
diff --git a/be/src/vec/common/string_view.h b/be/src/vec/common/string_view.h
index 88fcc14c6d8..5cd560aad4a 100644
--- a/be/src/vec/common/string_view.h
+++ b/be/src/vec/common/string_view.h
@@ -99,6 +99,8 @@ public:
uint32_t size() const { return size_; }
bool empty() const { return size() == 0; }
+ void set_size(uint32_t size) { size_ = size; }
+
bool operator==(const StringView& other) const;
friend std::ostream& operator<<(std::ostream& os, const StringView&
stringView) {
os.write(stringView.data(), stringView.size());
diff --git a/be/src/vec/functions/function_string.cpp
b/be/src/vec/functions/function_string.cpp
index f52e90a5bdf..7a6c71eadbe 100644
--- a/be/src/vec/functions/function_string.cpp
+++ b/be/src/vec/functions/function_string.cpp
@@ -972,6 +972,7 @@ struct UnHexImpl {
static constexpr auto name = Name::name;
using ReturnType = DataTypeString;
using ColumnType = ColumnString;
+ static constexpr auto PrimitiveTypeImpl = PrimitiveType::TYPE_STRING;
static Status vector(const ColumnString::Chars& data, const
ColumnString::Offsets& offsets,
ColumnString::Chars& dst_data, ColumnString::Offsets&
dst_offsets) {
@@ -1081,6 +1082,7 @@ struct ToBase64Impl {
static constexpr auto name = "to_base64";
using ReturnType = DataTypeString;
using ColumnType = ColumnString;
+ static constexpr auto PrimitiveTypeImpl = PrimitiveType::TYPE_STRING;
static Status vector(const ColumnString::Chars& data, const
ColumnString::Offsets& offsets,
ColumnString::Chars& dst_data, ColumnString::Offsets&
dst_offsets) {
diff --git a/be/src/vec/functions/function_totype.h
b/be/src/vec/functions/function_totype.h
index 714d2fd1661..a0bb623a355 100644
--- a/be/src/vec/functions/function_totype.h
+++ b/be/src/vec/functions/function_totype.h
@@ -22,6 +22,7 @@
#include "vec/columns/column_const.h"
#include "vec/columns/column_nullable.h"
#include "vec/columns/column_string.h"
+#include "vec/columns/column_varbinary.h"
#include "vec/columns/column_vector.h"
#include "vec/data_types/data_type.h"
#include "vec/data_types/data_type_bitmap.h"
@@ -123,6 +124,13 @@ private:
block.replace_by_position(result, std::move(col_res));
return Status::OK();
}
+ } else if constexpr (Impl::PrimitiveTypeImpl ==
PrimitiveType::TYPE_VARBINARY) {
+ if (const auto* col =
check_and_get_column<ColumnVarbinary>(column.get())) {
+ auto col_res = Impl::ReturnColumnType::create();
+ RETURN_IF_ERROR(Impl::vector(col->get_data(),
col_res->get_data()));
+ block.replace_by_position(result, std::move(col_res));
+ return Status::OK();
+ }
}
return Status::RuntimeError("Illegal column {} of argument of function
{}",
block.get_by_position(arguments[0]).column->get_name(),
@@ -465,11 +473,19 @@ public:
auto& col_ptr = block.get_by_position(arguments[0]).column;
- auto res = Impl::ColumnType::create();
if (const auto* col =
check_and_get_column<ColumnString>(col_ptr.get())) {
auto col_res = Impl::ColumnType::create();
- RETURN_IF_ERROR(Impl::vector(col->get_chars(), col->get_offsets(),
col_res->get_chars(),
- col_res->get_offsets(),
null_map->get_data()));
+ if constexpr (std::is_same_v<typename Impl::ReturnType,
DataTypeString>) {
+ RETURN_IF_ERROR(Impl::vector(col->get_chars(),
col->get_offsets(),
+ col_res->get_chars(),
col_res->get_offsets(),
+ null_map->get_data()));
+ } else if (std::is_same_v<typename Impl::ReturnType,
DataTypeVarbinary>) {
+ RETURN_IF_ERROR(Impl::vector(col->get_chars(),
col->get_offsets(), col_res.get(),
+ null_map->get_data()));
+ } else {
+ return Status::RuntimeError("Illegal returntype {} of argument
of function {}",
+ col_res->get_name(), get_name());
+ }
block.replace_by_position(
result, ColumnNullable::create(std::move(col_res),
std::move(null_map)));
} else {
@@ -506,31 +522,48 @@ public:
if constexpr (is_allow_null) {
auto null_map = ColumnUInt8::create(input_rows_count, 0);
auto& null_map_data = null_map->get_data();
- if (const auto* col = assert_cast<const
ColumnString*>(col_ptr.get())) {
- auto col_res = Impl::ColumnType::create();
- RETURN_IF_ERROR(Impl::vector(col->get_chars(),
col->get_offsets(),
- col_res->get_chars(),
col_res->get_offsets(),
- &null_map_data));
- block.get_by_position(result).column =
- ColumnNullable::create(std::move(col_res),
std::move(null_map));
- } else {
- return Status::RuntimeError("Illegal column {} of argument of
function {}",
-
block.get_by_position(arguments[0]).column->get_name(),
- get_name());
+ if constexpr (Impl::PrimitiveTypeImpl ==
PrimitiveType::TYPE_STRING) {
+ if (const auto* col = assert_cast<const
ColumnString*>(col_ptr.get())) {
+ auto col_res = Impl::ColumnType::create();
+ RETURN_IF_ERROR(Impl::vector(col->get_chars(),
col->get_offsets(),
+ col_res->get_chars(),
col_res->get_offsets(),
+ &null_map_data));
+ block.get_by_position(result).column =
+ ColumnNullable::create(std::move(col_res),
std::move(null_map));
+ return Status::OK();
+ }
+ } else if (Impl::PrimitiveTypeImpl ==
PrimitiveType::TYPE_VARBINARY) {
+ if (const auto* col = assert_cast<const
ColumnVarbinary*>(col_ptr.get())) {
+ auto col_res = Impl::ColumnType::create();
+ RETURN_IF_ERROR(Impl::vector(col->get_data(),
col_res->get_chars(),
+ col_res->get_offsets(),
&null_map_data));
+ block.get_by_position(result).column =
+ ColumnNullable::create(std::move(col_res),
std::move(null_map));
+ return Status::OK();
+ }
}
} else {
- if (const auto* col = assert_cast<const
ColumnString*>(col_ptr.get())) {
- auto col_res = Impl::ColumnType::create();
- RETURN_IF_ERROR(Impl::vector(col->get_chars(),
col->get_offsets(),
- col_res->get_chars(),
col_res->get_offsets()));
- block.replace_by_position(result, std::move(col_res));
- } else {
- return Status::RuntimeError("Illegal column {} of argument of
function {}",
-
block.get_by_position(arguments[0]).column->get_name(),
- get_name());
+ if constexpr (Impl::PrimitiveTypeImpl ==
PrimitiveType::TYPE_STRING) {
+ if (const auto* col = assert_cast<const
ColumnString*>(col_ptr.get())) {
+ auto col_res = Impl::ColumnType::create();
+ RETURN_IF_ERROR(Impl::vector(col->get_chars(),
col->get_offsets(),
+ col_res->get_chars(),
col_res->get_offsets()));
+ block.replace_by_position(result, std::move(col_res));
+ return Status::OK();
+ }
+ } else if (Impl::PrimitiveTypeImpl ==
PrimitiveType::TYPE_VARBINARY) {
+ if (const auto* col = assert_cast<const
ColumnVarbinary*>(col_ptr.get())) {
+ auto col_res = Impl::ColumnType::create();
+ RETURN_IF_ERROR(Impl::vector(col->get_data(),
col_res->get_chars(),
+ col_res->get_offsets()));
+ block.replace_by_position(result, std::move(col_res));
+ return Status::OK();
+ }
}
}
- return Status::OK();
+ return Status::RuntimeError("Illegal column {} of argument of function
{}",
+
block.get_by_position(arguments[0]).column->get_name(),
+ get_name());
}
};
} // namespace doris::vectorized
diff --git a/be/src/vec/functions/function_varbinary.cpp
b/be/src/vec/functions/function_varbinary.cpp
index a64cd99392c..ec592c236bc 100644
--- a/be/src/vec/functions/function_varbinary.cpp
+++ b/be/src/vec/functions/function_varbinary.cpp
@@ -15,12 +15,15 @@
// specific language governing permissions and limitations
// under the License.
+#include "vec/functions/function_varbinary.h"
+
#include <glog/logging.h>
#include <cstddef>
#include <memory>
#include "common/status.h"
+#include "util/url_coding.h"
#include "vec/columns/column_const.h"
#include "vec/columns/column_nullable.h"
#include "vec/columns/column_string.h"
@@ -32,10 +35,12 @@
#include "vec/data_types/data_type_varbinary.h"
#include "vec/functions/function.h"
#include "vec/functions/function_helpers.h"
+#include "vec/functions/function_totype.h"
#include "vec/functions/simple_function_factory.h"
#include "vec/functions/string_hex_util.h"
namespace doris::vectorized {
+#include "common/compile_check_begin.h"
class FunctionToBinary : public IFunction {
public:
@@ -59,30 +64,24 @@ public:
auto col_res = ColumnVarbinary::create();
const auto& data = col->get_chars();
const auto& offsets = col->get_offsets();
+ col_res->get_data().assign(input_rows_count, StringView());
- std::array<char, string_hex::MAX_STACK_CIPHER_LEN> stack_buf;
- std::vector<char> heap_buf;
for (int i = 0; i < input_rows_count; ++i) {
const auto* source = reinterpret_cast<const
char*>(&data[offsets[i - 1]]);
ColumnString::Offset srclen = offsets[i] - offsets[i - 1];
- auto cipher_len = srclen / 2;
- char* dst = nullptr;
- if (cipher_len <= stack_buf.size()) {
- dst = stack_buf.data();
- } else {
- heap_buf.resize(cipher_len);
- dst = heap_buf.data();
- }
+ int cipher_len = srclen / 2;
+ auto [cipher_inline, dst] = VarBinaryOP::alloc(col_res.get(),
i, cipher_len);
+
int outlen = string_hex::hex_decode(source, srclen, dst);
// if empty string or decode failed, may return NULL
if (outlen == 0) {
null_map->get_data()[i] = 1;
- col_res->insert_default();
continue;
}
- col_res->insert_data(dst, outlen);
+ VarBinaryOP::check_and_insert_data(col_res->get_data()[i], dst,
+ cast_set<uint32_t>(outlen),
cipher_inline);
}
block.replace_by_position(
result, ColumnNullable::create(std::move(col_res),
std::move(null_map)));
@@ -143,11 +142,124 @@ public:
}
};
+struct NameVarbinaryLength {
+ static constexpr auto name = "length";
+};
+
+struct VarbinaryLengthImpl {
+ using ReturnType = DataTypeInt32;
+ using ReturnColumnType = ColumnInt32;
+ static constexpr auto PrimitiveTypeImpl = PrimitiveType::TYPE_VARBINARY;
+
+ static DataTypes get_variadic_argument_types() {
+ return {std::make_shared<DataTypeVarbinary>()};
+ }
+
+ static Status vector(const PaddedPODArray<doris::StringView>& data,
+ PaddedPODArray<Int32>& res) {
+ size_t rows_count = data.size();
+ res.resize(rows_count);
+ for (size_t i = 0; i < rows_count; ++i) {
+ res[i] = data[i].size();
+ }
+ return Status::OK();
+ }
+};
+
+using FunctionBinaryLength = FunctionUnaryToType<VarbinaryLengthImpl,
NameVarbinaryLength>;
+
+struct ToBase64BinaryImpl {
+ static constexpr auto name = "to_base64_binary";
+ using ReturnType = DataTypeString;
+ using ColumnType = ColumnString;
+ static constexpr auto PrimitiveTypeImpl = PrimitiveType::TYPE_VARBINARY;
+
+ static Status vector(const PaddedPODArray<doris::StringView>& data,
+ ColumnString::Chars& dst_data, ColumnString::Offsets&
dst_offsets) {
+ auto rows_count = data.size();
+ dst_offsets.resize(rows_count);
+
+ size_t total_size = 0;
+ for (size_t i = 0; i < rows_count; i++) {
+ total_size += 4 * ((data[i].size() + 2) / 3);
+ }
+ ColumnString::check_chars_length(total_size, rows_count);
+ dst_data.resize(total_size);
+ auto* dst_data_ptr = dst_data.data();
+ size_t offset = 0;
+
+ for (size_t i = 0; i < rows_count; i++) {
+ auto binary = data[i];
+ auto binlen = binary.size();
+
+ if (UNLIKELY(binlen == 0)) {
+ dst_offsets[i] = cast_set<uint32_t>(offset);
+ continue;
+ }
+
+ auto outlen = doris::base64_encode(
+ reinterpret_cast<const unsigned char*>(binary.data()),
binlen,
+ reinterpret_cast<unsigned char*>(dst_data_ptr + offset));
+
+ offset += outlen;
+ dst_offsets[i] = cast_set<uint32_t>(offset);
+ }
+
+ dst_data.pop_back(total_size - offset);
+
+ return Status::OK();
+ }
+};
+
+using FunctionToBase64Binary = FunctionStringEncode<ToBase64BinaryImpl, false>;
+
+struct FromBase64BinaryImpl {
+ static constexpr auto name = "from_base64_binary";
+ using ReturnType = DataTypeVarbinary;
+ using ColumnType = ColumnVarbinary;
+
+ static Status vector(const ColumnString::Chars& data, const
ColumnString::Offsets& offsets,
+ ColumnVarbinary* res, NullMap& null_map) {
+ auto rows_count = offsets.size();
+ res->get_data().assign(rows_count, StringView());
+
+ for (size_t i = 0; i < rows_count; i++) {
+ const auto* source = reinterpret_cast<const char*>(&data[offsets[i
- 1]]);
+ ColumnString::Offset slen = offsets[i] - offsets[i - 1];
+
+ if (UNLIKELY(slen == 0)) {
+ continue;
+ }
+
+ int cipher_len = slen / 4 * 3;
+ auto [cipher_inline, dst] = VarBinaryOP::alloc(res, i, cipher_len);
+
+ auto outlen = doris::base64_decode(source, slen, dst);
+
+ if (outlen < 0) {
+ null_map[i] = 1;
+ } else {
+ VarBinaryOP::check_and_insert_data(res->get_data()[i], dst,
+ cast_set<uint32_t>(outlen),
cipher_inline);
+ }
+ }
+
+ return Status::OK();
+ }
+};
+
+using FunctionFromBase64Binary =
FunctionStringOperateToNullType<FromBase64BinaryImpl>;
+
void register_function_binary(SimpleFunctionFactory& factory) {
+ factory.register_function<FunctionBinaryLength>();
+ factory.register_function<FunctionToBase64Binary>();
+ factory.register_function<FunctionFromBase64Binary>();
+ factory.register_function<FunctionSubBinary>();
factory.register_function<FunctionToBinary>();
factory.register_function<FunctionFromBinary>();
factory.register_alias("from_binary", "from_hex");
factory.register_alias("to_binary", "to_hex");
}
+#include "common/compile_check_end.h"
} // namespace doris::vectorized
diff --git a/be/src/vec/functions/function_varbinary.h
b/be/src/vec/functions/function_varbinary.h
new file mode 100644
index 00000000000..87a7008ae97
--- /dev/null
+++ b/be/src/vec/functions/function_varbinary.h
@@ -0,0 +1,53 @@
+// 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.
+
+#pragma once
+
+#include "common/status.h"
+#include "vec/columns/column_const.h"
+#include "vec/columns/column_string.h"
+#include "vec/columns/column_varbinary.h"
+#include "vec/core/block.h"
+#include "vec/core/types.h"
+#include "vec/data_types/data_type_number.h"
+#include "vec/data_types/data_type_string.h"
+#include "vec/data_types/data_type_varbinary.h"
+#include "vec/functions/function.h"
+#include "vec/utils/varbinaryop_subbinary.h"
+
+namespace doris::vectorized {
+#include "common/compile_check_begin.h"
+
+class FunctionSubBinary : public IFunction {
+public:
+ static constexpr auto name = "sub_binary";
+ static FunctionPtr create() { return
std::make_shared<FunctionSubBinary>(); }
+ String get_name() const override { return name; }
+ size_t get_number_of_arguments() const override { return 3; }
+ DataTypePtr get_return_type_impl(const DataTypes& arguments) const
override {
+ return std::make_shared<DataTypeVarbinary>();
+ }
+
+ Status execute_impl(FunctionContext* context, Block& block, const
ColumnNumbers& arguments,
+ uint32_t result, size_t input_rows_count) const
override {
+ SubBinaryUtil::sub_binary_execute(block, arguments, result,
input_rows_count);
+ return Status::OK();
+ }
+};
+
+#include "common/compile_check_end.h"
+} // namespace doris::vectorized
diff --git a/be/src/vec/utils/varbinaryop_subbinary.h
b/be/src/vec/utils/varbinaryop_subbinary.h
new file mode 100644
index 00000000000..ef4d0b1d20a
--- /dev/null
+++ b/be/src/vec/utils/varbinaryop_subbinary.h
@@ -0,0 +1,119 @@
+// 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.
+
+#pragma once
+
+#include "vec/columns/column_const.h"
+#include "vec/columns/column_varbinary.h"
+#include "vec/core/block.h"
+#include "vec/core/types.h"
+#include "vec/data_types/data_type_number.h"
+#include "vec/data_types/data_type_varbinary.h"
+
+namespace doris::vectorized {
+#include "common/compile_check_begin.h"
+
+constexpr auto SIZE_OF_UINT = sizeof(uint32_t);
+
+struct VarBinaryOP {
+ static void check_and_insert_data(doris::StringView& sView, const char*
data, uint32_t len,
+ bool before_is_inline) {
+ if (before_is_inline) {
+ sView.set_size(len);
+ } else {
+ sView = doris::StringView(data, len);
+ }
+ }
+
+ static std::pair<bool, char*> alloc(ColumnVarbinary* res_col, size_t
index, uint32_t len) {
+ bool is_inline = StringView::isInline(len);
+ char* dst = nullptr;
+ if (is_inline) {
+ dst = reinterpret_cast<char*>(&(res_col->get_data()[index])) +
SIZE_OF_UINT;
+ } else {
+ dst = res_col->alloc(len);
+ }
+ return {is_inline, dst};
+ }
+};
+
+struct SubBinaryUtil {
+ static void sub_binary_execute(Block& block, const ColumnNumbers&
arguments, uint32_t result,
+ size_t input_rows_count) {
+ DCHECK_EQ(arguments.size(), 3);
+ auto res = ColumnVarbinary::create();
+
+ bool col_const[3];
+ ColumnPtr argument_columns[3];
+ for (int i = 0; i < 3; ++i) {
+ std::tie(argument_columns[i], col_const[i]) =
+
unpack_if_const(block.get_by_position(arguments[i]).column);
+ }
+
+ const auto* specific_binary_column =
+ assert_cast<const ColumnVarbinary*>(argument_columns[0].get());
+ const auto* specific_start_column =
+ assert_cast<const ColumnInt32*>(argument_columns[1].get());
+ const auto* specific_len_column =
+ assert_cast<const ColumnInt32*>(argument_columns[2].get());
+
+ std::visit(
+ [&](auto binary_const, auto start_const, auto len_const) {
+ vectors<binary_const, start_const, len_const>(
+ specific_binary_column, specific_start_column,
specific_len_column,
+ res.get(), input_rows_count);
+ },
+ vectorized::make_bool_variant(col_const[0]),
+ vectorized::make_bool_variant(col_const[1]),
+ vectorized::make_bool_variant(col_const[2]));
+ block.get_by_position(result).column = std::move(res);
+ }
+
+private:
+ template <bool binary_const, bool start_const, bool len_const>
+ static void vectors(const ColumnVarbinary* binarys, const ColumnInt32*
start,
+ const ColumnInt32* len, ColumnVarbinary* res, size_t
size) {
+ res->get_data().reserve(size);
+
+ for (size_t i = 0; i < size; ++i) {
+ doris::StringView binary =
binarys->get_data()[index_check_const<binary_const>(i)];
+ int binary_size = static_cast<int>(binary.size());
+
+ int start_value =
start->get_data()[index_check_const<start_const>(i)];
+ int len_value = len->get_data()[index_check_const<len_const>(i)];
+
+ bool start_out_of_range = (start_value > binary_size) ||
(start_value < -binary_size);
+ bool len_non_positive = len_value <= 0;
+ bool input_empty = binary_size == 0;
+
+ if (start_out_of_range || len_non_positive || input_empty) {
+ res->insert_default();
+ continue;
+ }
+ int fixed_pos = start_value - 1;
+ if (fixed_pos < 0) {
+ fixed_pos = binary_size + fixed_pos + 1;
+ }
+ int fixed_len = std::min(binary_size - fixed_pos, len_value);
+
+ res->insert_data(binary.data() + fixed_pos, fixed_len);
+ }
+ }
+};
+
+#include "common/compile_check_end.h"
+} // namespace doris::vectorized
diff --git a/be/test/vec/function/function_hash_test.cpp
b/be/test/vec/function/function_hash_test.cpp
index f98430b3c64..3333fa72e9b 100644
--- a/be/test/vec/function/function_hash_test.cpp
+++ b/be/test/vec/function/function_hash_test.cpp
@@ -29,6 +29,7 @@
#include "vec/data_types/data_type_number.h"
namespace doris::vectorized {
+using namespace ut_type;
TEST(HashFunctionTest, murmur_hash_3_test) {
std::string func_name = "murmur_hash3_32";
@@ -130,7 +131,7 @@ TEST(HashFunctionTest, xxhash_32_test) {
{
InputTypeSet input_types = {PrimitiveType::TYPE_VARBINARY};
- DataSet data_set = {{{Null()}, Null()}, {{std::string("hello")},
(int32_t)-83855367}};
+ DataSet data_set = {{{Null()}, Null()}, {{VARBINARY("hello")},
(int32_t)-83855367}};
static_cast<void>(check_function<DataTypeInt32, true>(func_name,
input_types, data_set));
};
@@ -138,8 +139,8 @@ TEST(HashFunctionTest, xxhash_32_test) {
{
InputTypeSet input_types = {PrimitiveType::TYPE_VARBINARY,
PrimitiveType::TYPE_VARBINARY};
- DataSet data_set = {{{std::string("hello"), std::string("world")},
(int32_t)-920844969},
- {{std::string("hello"), Null()}, Null()}};
+ DataSet data_set = {{{VARBINARY("hello"), VARBINARY("world")},
(int32_t)-920844969},
+ {{VARBINARY("hello"), Null()}, Null()}};
static_cast<void>(check_function<DataTypeInt32, true>(func_name,
input_types, data_set));
};
@@ -148,9 +149,9 @@ TEST(HashFunctionTest, xxhash_32_test) {
InputTypeSet input_types = {PrimitiveType::TYPE_VARBINARY,
PrimitiveType::TYPE_VARBINARY,
PrimitiveType::TYPE_VARBINARY};
- DataSet data_set = {{{std::string("hello"), std::string("world"),
std::string("!")},
- (int32_t)352087701},
- {{std::string("hello"), std::string("world"),
Null()}, Null()}};
+ DataSet data_set = {
+ {{VARBINARY("hello"), VARBINARY("world"), VARBINARY("!")},
(int32_t)352087701},
+ {{VARBINARY("hello"), VARBINARY("world"), Null()}, Null()}};
static_cast<void>(check_function<DataTypeInt32, true>(func_name,
input_types, data_set));
};
@@ -193,7 +194,7 @@ TEST(HashFunctionTest, xxhash_64_test) {
InputTypeSet input_types = {PrimitiveType::TYPE_VARBINARY};
DataSet data_set = {{{Null()}, Null()},
- {{std::string("hello")},
(int64_t)-7685981735718036227}};
+ {{VARBINARY("hello")},
(int64_t)-7685981735718036227}};
static_cast<void>(check_function<DataTypeInt64, true>(func_name,
input_types, data_set));
};
@@ -202,8 +203,8 @@ TEST(HashFunctionTest, xxhash_64_test) {
InputTypeSet input_types = {PrimitiveType::TYPE_VARBINARY,
PrimitiveType::TYPE_VARBINARY};
DataSet data_set = {
- {{std::string("hello"), std::string("world")},
(int64_t)7001965798170371843},
- {{std::string("hello"), Null()}, Null()}};
+ {{VARBINARY("hello"), VARBINARY("world")},
(int64_t)7001965798170371843},
+ {{VARBINARY("hello"), Null()}, Null()}};
static_cast<void>(check_function<DataTypeInt64, true>(func_name,
input_types, data_set));
};
@@ -212,9 +213,9 @@ TEST(HashFunctionTest, xxhash_64_test) {
InputTypeSet input_types = {PrimitiveType::TYPE_VARBINARY,
PrimitiveType::TYPE_VARBINARY,
PrimitiveType::TYPE_VARBINARY};
- DataSet data_set = {{{std::string("hello"), std::string("world"),
std::string("!")},
+ DataSet data_set = {{{VARBINARY("hello"), VARBINARY("world"),
VARBINARY("!")},
(int64_t)6796829678999971400},
- {{std::string("hello"), std::string("world"),
Null()}, Null()}};
+ {{VARBINARY("hello"), VARBINARY("world"), Null()},
Null()}};
static_cast<void>(check_function<DataTypeInt64, true>(func_name,
input_types, data_set));
};
diff --git a/be/test/vec/function/function_string_test.cpp
b/be/test/vec/function/function_string_test.cpp
index e5c2a044fe6..84272d4475c 100644
--- a/be/test/vec/function/function_string_test.cpp
+++ b/be/test/vec/function/function_string_test.cpp
@@ -1970,27 +1970,27 @@ TEST(function_string_test, function_md5sum_test) {
{
InputTypeSet input_types = {PrimitiveType::TYPE_VARBINARY};
DataSet data_set = {
- {{std::string("asd你好")},
{std::string("a38c15675555017e6b8ea042f2eb24f5")}},
- {{std::string("hello world")},
{std::string("5eb63bbbe01eeed093cb22bb8f5acdc3")}},
- {{std::string("HELLO,!^%")},
{std::string("b8e6e34d1cc3dc76b784ddfdfb7df800")}},
- {{std::string("")},
{std::string("d41d8cd98f00b204e9800998ecf8427e")}},
- {{std::string(" ")},
{std::string("7215ee9c7d9dc229d2921a40e899ec5f")}},
+ {{VARBINARY("asd你好")},
{std::string("a38c15675555017e6b8ea042f2eb24f5")}},
+ {{VARBINARY("hello world")},
{std::string("5eb63bbbe01eeed093cb22bb8f5acdc3")}},
+ {{VARBINARY("HELLO,!^%")},
{std::string("b8e6e34d1cc3dc76b784ddfdfb7df800")}},
+ {{VARBINARY("")},
{std::string("d41d8cd98f00b204e9800998ecf8427e")}},
+ {{VARBINARY(" ")},
{std::string("7215ee9c7d9dc229d2921a40e899ec5f")}},
{{Null()}, {Null()}},
- {{std::string("MYtestSTR")},
{std::string("cd24c90b3fc1192eb1879093029e87d4")}},
- {{std::string("ò&ø")},
{std::string("fd157b4cb921fa91acc667380184d59c")}}};
+ {{VARBINARY("MYtestSTR")},
{std::string("cd24c90b3fc1192eb1879093029e87d4")}},
+ {{VARBINARY("ò&ø")},
{std::string("fd157b4cb921fa91acc667380184d59c")}}};
check_function_all_arg_comb<DataTypeString, true>(func_name,
input_types, data_set);
}
{
InputTypeSet input_types = {PrimitiveType::TYPE_VARBINARY,
PrimitiveType::TYPE_VARBINARY};
- DataSet data_set = {{{std::string("asd"), std::string("你好")},
+ DataSet data_set = {{{VARBINARY("asd"), VARBINARY("你好")},
{std::string("a38c15675555017e6b8ea042f2eb24f5")}},
- {{std::string("hello "), std::string("world")},
+ {{VARBINARY("hello "), VARBINARY("world")},
{std::string("5eb63bbbe01eeed093cb22bb8f5acdc3")}},
- {{std::string("HELLO"), std::string(",!^%")},
+ {{VARBINARY("HELLO"), VARBINARY(",!^%")},
{std::string("b8e6e34d1cc3dc76b784ddfdfb7df800")}},
- {{Null(), std::string("HELLO")}, {Null()}}};
+ {{Null(), VARBINARY("HELLO")}, {Null()}}};
check_function_all_arg_comb<DataTypeString, true>(func_name,
input_types, data_set);
}
@@ -1998,13 +1998,13 @@ TEST(function_string_test, function_md5sum_test) {
{
InputTypeSet input_types = {PrimitiveType::TYPE_VARBINARY,
PrimitiveType::TYPE_VARBINARY,
PrimitiveType::TYPE_VARBINARY};
- DataSet data_set = {{{std::string("a"), std::string("sd"),
std::string("你好")},
+ DataSet data_set = {{{VARBINARY("a"), VARBINARY("sd"),
VARBINARY("你好")},
{std::string("a38c15675555017e6b8ea042f2eb24f5")}},
- {{std::string(""), std::string(""),
std::string("")},
+ {{VARBINARY(""), VARBINARY(""), VARBINARY("")},
{std::string("d41d8cd98f00b204e9800998ecf8427e")}},
- {{std::string("HEL"), std::string("LO,!"),
std::string("^%")},
+ {{VARBINARY("HEL"), VARBINARY("LO,!"),
VARBINARY("^%")},
{std::string("b8e6e34d1cc3dc76b784ddfdfb7df800")}},
- {{Null(), std::string("HELLO"), Null()},
{Null()}}};
+ {{Null(), VARBINARY("HELLO"), Null()}, {Null()}}};
check_function_all_arg_comb<DataTypeString, true>(func_name,
input_types, data_set);
}
@@ -2068,20 +2068,20 @@ TEST(function_string_test, function_sm3sum_test) {
{
InputTypeSet input_types = {PrimitiveType::TYPE_VARBINARY};
DataSet data_set = {
- {{std::string("asd你好")},
+ {{VARBINARY("asd你好")},
{std::string("0d6b9dfa8fe5708eb0dccfbaff4f2964abaaa976cc4445a7ecace49c0ceb31d3")}},
- {{std::string("hello world")},
+ {{VARBINARY("hello world")},
{std::string("44f0061e69fa6fdfc290c494654a05dc0c053da7e5c52b84ef93a9d67d3fff88")}},
- {{std::string("HELLO,!^%")},
+ {{VARBINARY("HELLO,!^%")},
{std::string("5fc6e38f40b31a659a59e1daba9b68263615f20c02037b419d9deb3509e6b5c6")}},
- {{std::string("")},
+ {{VARBINARY("")},
{std::string("1ab21d8355cfa17f8e61194831e81a8f22bec8c728fefb747ed035eb5082aa2b")}},
- {{std::string(" ")},
+ {{VARBINARY(" ")},
{std::string("2ae1d69bb8483e5944310c877573b21d0a420c3bf4a2a91b1a8370d760ba67c5")}},
{{Null()}, {Null()}},
- {{std::string("MYtestSTR")},
+ {{VARBINARY("MYtestSTR")},
{std::string("3155ae9f834cae035385fc15b69b6f2c051b91de943ea9a03ab8bfd497aef4c6")}},
- {{std::string("ò&ø")},
+ {{VARBINARY("ò&ø")},
{std::string(
"aa47ac31c85aa819d4cc80c932e7900fa26a3073a67aa7eb011bc2ba4924a066")}}};
@@ -2091,13 +2091,13 @@ TEST(function_string_test, function_sm3sum_test) {
{
InputTypeSet input_types = {PrimitiveType::TYPE_VARBINARY,
PrimitiveType::TYPE_VARBINARY};
DataSet data_set = {
- {{std::string("asd"), std::string("你好")},
+ {{VARBINARY("asd"), VARBINARY("你好")},
{std::string("0d6b9dfa8fe5708eb0dccfbaff4f2964abaaa976cc4445a7ecace49c0ceb31d3")}},
- {{std::string("hello "), std::string("world")},
+ {{VARBINARY("hello "), VARBINARY("world")},
{std::string("44f0061e69fa6fdfc290c494654a05dc0c053da7e5c52b84ef93a9d67d3fff88")}},
- {{std::string("HELLO "), std::string(",!^%")},
+ {{VARBINARY("HELLO "), VARBINARY(",!^%")},
{std::string("1f5866e786ebac9ffed0dbd8f2586e3e99d1d05f7efe7c5915478b57b7423570")}},
- {{Null(), std::string("HELLO")}, {Null()}}};
+ {{Null(), VARBINARY("HELLO")}, {Null()}}};
check_function_all_arg_comb<DataTypeString, true>(func_name,
input_types, data_set);
}
@@ -2106,13 +2106,13 @@ TEST(function_string_test, function_sm3sum_test) {
InputTypeSet input_types = {PrimitiveType::TYPE_VARBINARY,
PrimitiveType::TYPE_VARBINARY,
PrimitiveType::TYPE_VARBINARY};
DataSet data_set = {
- {{std::string("a"), std::string("sd"), std::string("你好")},
+ {{VARBINARY("a"), VARBINARY("sd"), VARBINARY("你好")},
{std::string("0d6b9dfa8fe5708eb0dccfbaff4f2964abaaa976cc4445a7ecace49c0ceb31d3")}},
- {{std::string(""), std::string(""), std::string("")},
+ {{VARBINARY(""), VARBINARY(""), VARBINARY("")},
{std::string("1ab21d8355cfa17f8e61194831e81a8f22bec8c728fefb747ed035eb5082aa2b")}},
- {{std::string("HEL"), std::string("LO,!"), std::string("^%")},
+ {{VARBINARY("HEL"), VARBINARY("LO,!"), VARBINARY("^%")},
{std::string("5fc6e38f40b31a659a59e1daba9b68263615f20c02037b419d9deb3509e6b5c6")}},
- {{Null(), std::string("HELLO"), Null()}, {Null()}}};
+ {{Null(), VARBINARY("HELLO"), Null()}, {Null()}}};
check_function_all_arg_comb<DataTypeString, true>(func_name,
input_types, data_set);
}
@@ -3789,11 +3789,11 @@ TEST(function_string_test, function_sha1_test) {
{
InputTypeSet input_types = {PrimitiveType::TYPE_VARBINARY};
DataSet data_set = {
- {{std::string("hello world")},
+ {{VARBINARY("hello world")},
{std::string("2aae6c35c94fcfb415dbe95f408b9ce91ee846ed")}},
- {{std::string("doris")},
{std::string("c29bb8e55610dcfecabb065ce5d01be6e3e810e9")}},
- {{std::string("")},
{std::string("da39a3ee5e6b4b0d3255bfef95601890afd80709")}},
- {{std::string("abc")},
{std::string("a9993e364706816aba3e25717850c26c9cd0d89d")}},
+ {{VARBINARY("doris")},
{std::string("c29bb8e55610dcfecabb065ce5d01be6e3e810e9")}},
+ {{VARBINARY("")},
{std::string("da39a3ee5e6b4b0d3255bfef95601890afd80709")}},
+ {{VARBINARY("abc")},
{std::string("a9993e364706816aba3e25717850c26c9cd0d89d")}},
{{Null()}, {Null()}}};
check_function_all_arg_comb<DataTypeString, true>(func_name,
input_types, data_set);
diff --git a/be/test/vec/function/function_test_util.cpp
b/be/test/vec/function/function_test_util.cpp
index ae111c9d10f..53e8e2d8571 100644
--- a/be/test/vec/function/function_test_util.cpp
+++ b/be/test/vec/function/function_test_util.cpp
@@ -382,8 +382,8 @@ bool insert_cell(MutableColumnPtr& column, DataTypePtr
type_ptr, const AnyType&
break;
}
case PrimitiveType::TYPE_VARBINARY: {
- auto str = any_cast<ut_type::STRING>(cell);
- column->insert_data(str.c_str(), str.size());
+ auto binary = any_cast<ut_type::VARBINARY>(cell);
+ column->insert_data(binary.data(), binary.size());
break;
}
case PrimitiveType::TYPE_JSONB: {
diff --git a/be/test/vec/function/function_test_util.h
b/be/test/vec/function/function_test_util.h
index 663bc15cd46..7e2799c9dd5 100644
--- a/be/test/vec/function/function_test_util.h
+++ b/be/test/vec/function/function_test_util.h
@@ -59,6 +59,7 @@
#include "vec/data_types/data_type_string.h"
#include "vec/data_types/data_type_struct.h"
#include "vec/data_types/data_type_time.h"
+#include "vec/data_types/data_type_varbinary.h"
#include "vec/functions/simple_function_factory.h"
namespace doris::vectorized {
@@ -103,6 +104,8 @@ using VARCHAR = std::string;
using CHAR = std::string;
using STRING = std::string;
+using VARBINARY = doris::StringView;
+
using DOUBLE = double;
using FLOAT = float;
@@ -129,6 +132,11 @@ struct ut_input_type<DataTypeString> {
inline static type default_value = "test_default";
};
template <>
+struct ut_input_type<DataTypeVarbinary> {
+ using type = doris::StringView;
+ inline static type default_value = doris::StringView("test_default");
+};
+template <>
struct ut_input_type<DataTypeDate> {
using type = std::string;
inline static type default_value = "1970-01-01";
@@ -275,6 +283,10 @@ DataTypePtr get_return_type_descriptor(int scale, int
precision) {
}
}
+inline std::string debug_hex_string(const std::string& str) {
+ return ut_type::VARBINARY(str).dump_hex();
+}
+
struct Consted {
PrimitiveType tp;
};
@@ -444,11 +456,21 @@ Status check_function(const std::string& func_name, const
InputTypeSet& input_ty
<< ", expected result: " <<
result_type_ptr->to_string(*expected_col_ptr, i);
} else {
auto comp_res = column->compare_at(i, i, *expected_col_ptr, 1);
- EXPECT_EQ(0, comp_res)
- << ", function " << func_name << ". input row:\n"
- << block.dump_data(i, 1)
- << "result: " <<
block.get_data_types()[result]->to_string(*column, i)
- << ", expected result: " <<
result_type_ptr->to_string(*expected_col_ptr, i);
+ if (std::is_same_v<ResultType, DataTypeVarbinary>) {
+ EXPECT_EQ(0, comp_res)
+ << ", function " << func_name << ". input row:\n"
+ << block.dump_data(i, 1) << "result: "
+ <<
debug_hex_string(block.get_data_types()[result]->to_string(*column, i))
+ << ", expected result: "
+ <<
debug_hex_string(result_type_ptr->to_string(*expected_col_ptr, i));
+ } else {
+ EXPECT_EQ(0, comp_res)
+ << ", function " << func_name << ". input row:\n"
+ << block.dump_data(i, 1)
+ << "result: " <<
block.get_data_types()[result]->to_string(*column, i)
+ << ", expected result: "
+ << result_type_ptr->to_string(*expected_col_ptr, i);
+ }
}
}
diff --git a/be/test/vec/function/function_varbinary_test.cpp
b/be/test/vec/function/function_varbinary_test.cpp
new file mode 100644
index 00000000000..50baa3c0e51
--- /dev/null
+++ b/be/test/vec/function/function_varbinary_test.cpp
@@ -0,0 +1,426 @@
+// 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.
+
+#include "vec/functions/function_varbinary.h"
+
+#include "function_test_util.h"
+#include "vec/data_types/data_type_varbinary.h"
+
+namespace doris::vectorized {
+
+using namespace ut_type;
+
+TEST(function_binary_test, function_binary_length_test) {
+ std::string func_name = "length";
+ InputTypeSet input_types = {PrimitiveType::TYPE_VARBINARY};
+ DataSet data_set = {
+ {{VARBINARY("YXNk5L2g5aW9")}, std::int32_t(12)},
+ {{VARBINARY("aGVsbG8gd29ybGQ")}, std::int32_t(15)},
+ {{VARBINARY("SEVMTE8sIV4l")}, std::int32_t(12)},
+ {{VARBINARY("__123hehe1")}, std::int32_t(10)},
+ {{VARBINARY("")}, std::int32_t(0)},
+ {{VARBINARY("5ZWK5ZOI5ZOI5ZOI8J+YhCDjgILigJTigJQh")},
std::int32_t(36)},
+ {{VARBINARY("ò&ø")}, std::int32_t(5)},
+ {{VARBINARY("TVl0ZXN0U1RS")}, std::int32_t(12)},
+ {{VARBINARY("123321!@#@$!@%!@#!@$!@")}, std::int32_t(22)},
+ {{VARBINARY("123")}, std::int32_t(3)},
+ {{VARBINARY("Hello, World!")}, std::int32_t(13)},
+ {{VARBINARY("Привет, мир!")}, std::int32_t(21)},
+ {{VARBINARY("こんにちは世界")}, std::int32_t(21)},
+ {{VARBINARY("안녕하세요세계")}, std::int32_t(21)},
+ {{VARBINARY("你好,世界!")}, std::int32_t(18)},
+ {{VARBINARY("مرحبا بالعالم!")}, std::int32_t(26)},
+ {{VARBINARY("1234567890")}, std::int32_t(10)},
+ {{VARBINARY("👨👨👧👦")}, std::int32_t(25)},
+ {{VARBINARY("🇺🇸🇨🇳🇯🇵🇰🇷")}, std::int32_t(32)},
+ {{VARBINARY("\u00F1")}, std::int32_t(2)},
+ {{VARBINARY("\u65E5\u672C\u8A9E")}, std::int32_t(9)},
+ {{VARBINARY("Hello, 世界!")}, std::int32_t(16)},
+ {{VARBINARY("😀😃😄😁")}, std::int32_t(16)},
+ {{VARBINARY("Quick brown 狐 jumps over a lazy 狗.")},
std::int32_t(38)},
+ {{VARBINARY("Löwe 老虎 Léopard")}, std::int32_t(21)},
+ {{VARBINARY("Café 美丽")}, std::int32_t(12)},
+ {{VARBINARY("Björk")}, std::int32_t(6)},
+ {{VARBINARY("¿Dónde está la biblioteca?")}, std::int32_t(29)},
+ {{VARBINARY("Zażółć gęślą jaźń")}, std::int32_t(26)},
+ {{Null()}, Null()},
+ {{VARBINARY(" ")}, std::int32_t(1)},
+ {{VARBINARY(" ")}, std::int32_t(2)},
+
+ };
+
+ check_function_all_arg_comb<DataTypeInt32, true>(func_name, input_types,
data_set);
+}
+
+TEST(function_binary_test, function_to_base64_binary_test) {
+ std::string func_name = "to_base64_binary";
+ InputTypeSet input_types = {PrimitiveType::TYPE_VARBINARY};
+
+ DataSet data_set = {
+ {{VARBINARY("ABC")}, std::string("QUJD")},
+ {{VARBINARY("ABB")}, std::string("QUJC")},
+ {{VARBINARY("HEHE")}, std::string("SEVIRQ==")},
+ {{VARBINARY("__123hehe1")}, std::string("X18xMjNoZWhlMQ==")},
+ {{VARBINARY("5ZWK5ZOI5ZOI5ZOI8J+YhCDjgILigJTigJQh")},
+ std::string("NVpXSzVaT0k1Wk9JNVpPSThKK1loQ0RqZ0lMaWdKVGlnSlFo")},
+ {{VARBINARY("ò&ø")}, std::string("w7Imw7g=")},
+ {{VARBINARY("hehe")}, std::string("aGVoZQ==")},
+ {{VARBINARY("`~!@#$%^&*()-_=+")},
std::string("YH4hQCMkJV4mKigpLV89Kw==")},
+ {{VARBINARY("test ")}, std::string("dGVzdCA=")},
+ {{VARBINARY("")}, std::string("")},
+ {{Null()}, Null()},
+ };
+
+ check_function_all_arg_comb<DataTypeString, true>(func_name, input_types,
data_set);
+}
+
+TEST(function_binary_test, function_from_base64_binary_test) {
+ std::string func_name = "from_base64_binary";
+ InputTypeSet input_types = {PrimitiveType::TYPE_VARCHAR};
+
+ DataSet data_set = {
+ {{std::string("YXNk5L2g5aW9")}, VARBINARY("asd你好")},
+ {{std::string("aGVsbG8gd29ybGQ")}, Null()},
+ {{std::string("SEVMTE8sIV4l")}, VARBINARY("HELLO,!^%")},
+ {{std::string("__123hehe1")}, Null()},
+ {{std::string("")}, VARBINARY("")},
+ {{std::string("5ZWK5ZOI5ZOI5ZOI8J+YhCDjgILigJTigJQh")},
VARBINARY("啊哈哈哈😄 。——!")},
+ {{std::string("ò&ø")}, Null()},
+ {{std::string("TVl0ZXN0U1RS")}, VARBINARY("MYtestSTR")},
+ {{std::string("YWFhYWFhYWFhYWE=")}, VARBINARY("aaaaaaaaaaa")},
+ {{std::string("TVl0ZXN0U1RSTVl0ZXN0U1RSTVl0ZXN0U1RS")},
+ VARBINARY("MYtestSTRMYtestSTRMYtestSTR")},
+ {{std::string("SEVMTE8sIV4lSEVMTE8sIV4lSEVMTE8sIV4lSEVMTE8sIV4l")},
+ VARBINARY("HELLO,!^%HELLO,!^%HELLO,!^%HELLO,!^%")},
+ {{Null()}, Null()},
+ };
+
+ check_function_all_arg_comb<DataTypeVarbinary, true>(func_name,
input_types, data_set);
+}
+
+TEST(function_binary_test, function_subbinary_test) {
+ std::string func_name = "sub_binary";
+
+ {
+ InputTypeSet input_types = {PrimitiveType::TYPE_VARBINARY,
PrimitiveType::TYPE_INT,
+ PrimitiveType::TYPE_INT};
+
+ DataSet data_set = {
+ {{VARBINARY("AbCdEfg"), std::int32_t(1), std::int32_t(1)},
VARBINARY("A")},
+ {{VARBINARY("AbCdEfg"), std::int32_t(1), std::int32_t(5)},
VARBINARY("AbCdE")},
+ {{VARBINARY("AbCdEfg"), std::int32_t(1), std::int32_t(-1)},
VARBINARY("")},
+ {{VARBINARY("AbCdEfg"), std::int32_t(1), std::int32_t(100)},
VARBINARY("AbCdEfg")},
+ {{VARBINARY("AbCdEfg"), std::int32_t(1), Null()}, Null()},
+ {{VARBINARY("AbCdEfg"), std::int32_t(5), std::int32_t(1)},
VARBINARY("E")},
+ {{VARBINARY("AbCdEfg"), std::int32_t(5), std::int32_t(5)},
VARBINARY("Efg")},
+ {{VARBINARY("AbCdEfg"), std::int32_t(5), std::int32_t(-1)},
VARBINARY("")},
+ {{VARBINARY("AbCdEfg"), std::int32_t(5), std::int32_t(100)},
VARBINARY("Efg")},
+ {{VARBINARY("AbCdEfg"), std::int32_t(5), Null()}, Null()},
+ {{VARBINARY("AbCdEfg"), std::int32_t(-1), std::int32_t(1)},
VARBINARY("g")},
+ {{VARBINARY("AbCdEfg"), std::int32_t(-1), std::int32_t(5)},
VARBINARY("g")},
+ {{VARBINARY("AbCdEfg"), std::int32_t(-1), std::int32_t(-1)},
VARBINARY("")},
+ {{VARBINARY("AbCdEfg"), std::int32_t(-1), std::int32_t(100)},
VARBINARY("g")},
+ {{VARBINARY("AbCdEfg"), std::int32_t(-1), Null()}, Null()},
+ {{VARBINARY("AbCdEfg"), std::int32_t(100), std::int32_t(1)},
VARBINARY("")},
+ {{VARBINARY("AbCdEfg"), std::int32_t(100), std::int32_t(5)},
VARBINARY("")},
+ {{VARBINARY("AbCdEfg"), std::int32_t(100), std::int32_t(-1)},
VARBINARY("")},
+ {{VARBINARY("AbCdEfg"), std::int32_t(100), std::int32_t(100)},
VARBINARY("")},
+ {{VARBINARY("AbCdEfg"), std::int32_t(100), Null()}, Null()},
+ {{VARBINARY("AbCdEfg"), Null(), std::int32_t(1)}, Null()},
+ {{VARBINARY("AbCdEfg"), Null(), std::int32_t(5)}, Null()},
+ {{VARBINARY("AbCdEfg"), Null(), std::int32_t(-1)}, Null()},
+ {{VARBINARY("AbCdEfg"), Null(), std::int32_t(100)}, Null()},
+ {{VARBINARY("AbCdEfg"), Null(), Null()}, Null()},
+ {{VARBINARY("HELLO123"), std::int32_t(1), std::int32_t(1)},
VARBINARY("H")},
+ {{VARBINARY("HELLO123"), std::int32_t(1), std::int32_t(5)},
VARBINARY("HELLO")},
+ {{VARBINARY("HELLO123"), std::int32_t(1), std::int32_t(-1)},
VARBINARY("")},
+ {{VARBINARY("HELLO123"), std::int32_t(1), std::int32_t(100)},
+ VARBINARY("HELLO123")},
+ {{VARBINARY("HELLO123"), std::int32_t(1), Null()}, Null()},
+ {{VARBINARY("HELLO123"), std::int32_t(5), std::int32_t(1)},
VARBINARY("O")},
+ {{VARBINARY("HELLO123"), std::int32_t(5), std::int32_t(5)},
VARBINARY("O123")},
+ {{VARBINARY("HELLO123"), std::int32_t(5), std::int32_t(-1)},
VARBINARY("")},
+ {{VARBINARY("HELLO123"), std::int32_t(5), std::int32_t(100)},
VARBINARY("O123")},
+ {{VARBINARY("HELLO123"), std::int32_t(5), Null()}, Null()},
+ {{VARBINARY("HELLO123"), std::int32_t(-1), std::int32_t(1)},
VARBINARY("3")},
+ {{VARBINARY("HELLO123"), std::int32_t(-1), std::int32_t(5)},
VARBINARY("3")},
+ {{VARBINARY("HELLO123"), std::int32_t(-1), std::int32_t(-1)},
VARBINARY("")},
+ {{VARBINARY("HELLO123"), std::int32_t(-1), std::int32_t(100)},
VARBINARY("3")},
+ {{VARBINARY("HELLO123"), std::int32_t(-1), Null()}, Null()},
+ {{VARBINARY("HELLO123"), std::int32_t(100), std::int32_t(1)},
VARBINARY("")},
+ {{VARBINARY("HELLO123"), std::int32_t(100), std::int32_t(5)},
VARBINARY("")},
+ {{VARBINARY("HELLO123"), std::int32_t(100), std::int32_t(-1)},
VARBINARY("")},
+ {{VARBINARY("HELLO123"), std::int32_t(100),
std::int32_t(100)}, VARBINARY("")},
+ {{VARBINARY("HELLO123"), std::int32_t(100), Null()}, Null()},
+ {{VARBINARY("HELLO123"), Null(), std::int32_t(1)}, Null()},
+ {{VARBINARY("HELLO123"), Null(), std::int32_t(5)}, Null()},
+ {{VARBINARY("HELLO123"), Null(), std::int32_t(-1)}, Null()},
+ {{VARBINARY("HELLO123"), Null(), std::int32_t(100)}, Null()},
+ {{VARBINARY("HELLO123"), Null(), Null()}, Null()},
+ // VARBINARY("\xE4\xBD\xA0\xE5\xA5\xBD\x48\x45\x4C\x4C\x4F")
== VARBINARY("你好HELLO")
+ {{VARBINARY("你好HELLO"), std::int32_t(1), std::int32_t(1)},
VARBINARY("\xE4")},
+ {{VARBINARY("你好HELLO"), std::int32_t(1), std::int32_t(5)},
+ VARBINARY("\xE4\xBD\xA0\xE5\xA5")},
+ {{VARBINARY("你好HELLO"), std::int32_t(1), std::int32_t(-1)},
VARBINARY("")},
+ {{VARBINARY("你好HELLO"), std::int32_t(1), std::int32_t(100)},
+ VARBINARY("你好HELLO")},
+ {{VARBINARY("你好HELLO"), std::int32_t(1), Null()}, Null()},
+ {{VARBINARY("你好HELLO"), std::int32_t(5), std::int32_t(1)},
VARBINARY("\xA5")},
+ {{VARBINARY("你好HELLO"), std::int32_t(5), std::int32_t(5)},
+ VARBINARY("\xA5\xBD\x48\x45\x4C")},
+ {{VARBINARY("你好HELLO"), std::int32_t(5), std::int32_t(-1)},
VARBINARY("")},
+ {{VARBINARY("你好HELLO"), std::int32_t(5), std::int32_t(100)},
+ VARBINARY("\xA5\xBDHELLO")},
+ {{VARBINARY("你好HELLO"), std::int32_t(5), Null()}, Null()},
+ {{VARBINARY("你好HELLO"), std::int32_t(-1), std::int32_t(1)},
VARBINARY("O")},
+ {{VARBINARY("你好HELLO"), std::int32_t(-1), std::int32_t(5)},
VARBINARY("O")},
+ {{VARBINARY("你好HELLO"), std::int32_t(-1), std::int32_t(-1)},
VARBINARY("")},
+ {{VARBINARY("你好HELLO"), std::int32_t(-1), std::int32_t(100)},
VARBINARY("O")},
+ {{VARBINARY("你好HELLO"), std::int32_t(-1), Null()}, Null()},
+ {{VARBINARY("你好HELLO"), std::int32_t(100), std::int32_t(1)},
VARBINARY("")},
+ {{VARBINARY("你好HELLO"), std::int32_t(100), std::int32_t(5)},
VARBINARY("")},
+ {{VARBINARY("你好HELLO"), std::int32_t(100), std::int32_t(-1)},
VARBINARY("")},
+ {{VARBINARY("你好HELLO"), std::int32_t(100), std::int32_t(100)},
VARBINARY("")},
+ {{VARBINARY("你好HELLO"), std::int32_t(100), Null()}, Null()},
+ {{VARBINARY("你好HELLO"), Null(), std::int32_t(1)}, Null()},
+ {{VARBINARY("你好HELLO"), Null(), std::int32_t(5)}, Null()},
+ {{VARBINARY("你好HELLO"), Null(), std::int32_t(-1)}, Null()},
+ {{VARBINARY("你好HELLO"), Null(), std::int32_t(100)}, Null()},
+ {{VARBINARY("你好HELLO"), Null(), Null()}, Null()},
+ {{VARBINARY("123ABC_"), std::int32_t(1), std::int32_t(1)},
VARBINARY("1")},
+ {{VARBINARY("123ABC_"), std::int32_t(1), std::int32_t(5)},
VARBINARY("123AB")},
+ {{VARBINARY("123ABC_"), std::int32_t(1), std::int32_t(-1)},
VARBINARY("")},
+ {{VARBINARY("123ABC_"), std::int32_t(1), std::int32_t(100)},
VARBINARY("123ABC_")},
+ {{VARBINARY("123ABC_"), std::int32_t(1), Null()}, Null()},
+ {{VARBINARY("123ABC_"), std::int32_t(5), std::int32_t(1)},
VARBINARY("B")},
+ {{VARBINARY("123ABC_"), std::int32_t(5), std::int32_t(5)},
VARBINARY("BC_")},
+ {{VARBINARY("123ABC_"), std::int32_t(5), std::int32_t(-1)},
VARBINARY("")},
+ {{VARBINARY("123ABC_"), std::int32_t(5), std::int32_t(100)},
VARBINARY("BC_")},
+ {{VARBINARY("123ABC_"), std::int32_t(5), Null()}, Null()},
+ {{VARBINARY("123ABC_"), std::int32_t(-1), std::int32_t(1)},
VARBINARY("_")},
+ {{VARBINARY("123ABC_"), std::int32_t(-1), std::int32_t(5)},
VARBINARY("_")},
+ {{VARBINARY("123ABC_"), std::int32_t(-1), std::int32_t(-1)},
VARBINARY("")},
+ {{VARBINARY("123ABC_"), std::int32_t(-1), std::int32_t(100)},
VARBINARY("_")},
+ {{VARBINARY("123ABC_"), std::int32_t(-1), Null()}, Null()},
+ {{VARBINARY("123ABC_"), std::int32_t(100), std::int32_t(1)},
VARBINARY("")},
+ {{VARBINARY("123ABC_"), std::int32_t(100), std::int32_t(5)},
VARBINARY("")},
+ {{VARBINARY("123ABC_"), std::int32_t(100), std::int32_t(-1)},
VARBINARY("")},
+ {{VARBINARY("123ABC_"), std::int32_t(100), std::int32_t(100)},
VARBINARY("")},
+ {{VARBINARY("123ABC_"), std::int32_t(100), Null()}, Null()},
+ {{VARBINARY("123ABC_"), Null(), std::int32_t(1)}, Null()},
+ {{VARBINARY("123ABC_"), Null(), std::int32_t(5)}, Null()},
+ {{VARBINARY("123ABC_"), Null(), std::int32_t(-1)}, Null()},
+ {{VARBINARY("123ABC_"), Null(), std::int32_t(100)}, Null()},
+ {{VARBINARY("123ABC_"), Null(), Null()}, Null()},
+ {{VARBINARY("MYtestSTR"), std::int32_t(1), std::int32_t(1)},
VARBINARY("M")},
+ {{VARBINARY("MYtestSTR"), std::int32_t(1), std::int32_t(5)},
VARBINARY("MYtes")},
+ {{VARBINARY("MYtestSTR"), std::int32_t(1), std::int32_t(-1)},
VARBINARY("")},
+ {{VARBINARY("MYtestSTR"), std::int32_t(1), std::int32_t(100)},
+ VARBINARY("MYtestSTR")},
+ {{VARBINARY("MYtestSTR"), std::int32_t(1), Null()}, Null()},
+ {{VARBINARY("MYtestSTR"), std::int32_t(5), std::int32_t(1)},
VARBINARY("s")},
+ {{VARBINARY("MYtestSTR"), std::int32_t(5), std::int32_t(5)},
VARBINARY("stSTR")},
+ {{VARBINARY("MYtestSTR"), std::int32_t(5), std::int32_t(-1)},
VARBINARY("")},
+ {{VARBINARY("MYtestSTR"), std::int32_t(5), std::int32_t(100)},
VARBINARY("stSTR")},
+ {{VARBINARY("MYtestSTR"), std::int32_t(5), Null()}, Null()},
+ {{VARBINARY("MYtestSTR"), std::int32_t(-1), std::int32_t(1)},
VARBINARY("R")},
+ {{VARBINARY("MYtestSTR"), std::int32_t(-1), std::int32_t(5)},
VARBINARY("R")},
+ {{VARBINARY("MYtestSTR"), std::int32_t(-1), std::int32_t(-1)},
VARBINARY("")},
+ {{VARBINARY("MYtestSTR"), std::int32_t(-1),
std::int32_t(100)}, VARBINARY("R")},
+ {{VARBINARY("MYtestSTR"), std::int32_t(-1), Null()}, Null()},
+ {{VARBINARY("MYtestSTR"), std::int32_t(100), std::int32_t(1)},
VARBINARY("")},
+ {{VARBINARY("MYtestSTR"), std::int32_t(100), std::int32_t(5)},
VARBINARY("")},
+ {{VARBINARY("MYtestSTR"), std::int32_t(100),
std::int32_t(-1)}, VARBINARY("")},
+ {{VARBINARY("MYtestSTR"), std::int32_t(100),
std::int32_t(100)}, VARBINARY("")},
+ {{VARBINARY("MYtestSTR"), std::int32_t(100), Null()}, Null()},
+ {{VARBINARY("MYtestSTR"), Null(), std::int32_t(1)}, Null()},
+ {{VARBINARY("MYtestSTR"), Null(), std::int32_t(5)}, Null()},
+ {{VARBINARY("MYtestSTR"), Null(), std::int32_t(-1)}, Null()},
+ {{VARBINARY("MYtestSTR"), Null(), std::int32_t(100)}, Null()},
+ {{VARBINARY("MYtestSTR"), Null(), Null()}, Null()},
+ {{VARBINARY(""), std::int32_t(1), std::int32_t(1)},
VARBINARY("")},
+ {{VARBINARY(""), std::int32_t(1), std::int32_t(5)},
VARBINARY("")},
+ {{VARBINARY(""), std::int32_t(1), std::int32_t(-1)},
VARBINARY("")},
+ {{VARBINARY(""), std::int32_t(1), std::int32_t(100)},
VARBINARY("")},
+ {{VARBINARY(""), std::int32_t(1), Null()}, Null()},
+ {{VARBINARY(""), std::int32_t(5), std::int32_t(1)},
VARBINARY("")},
+ {{VARBINARY(""), std::int32_t(5), std::int32_t(5)},
VARBINARY("")},
+ {{VARBINARY(""), std::int32_t(5), std::int32_t(-1)},
VARBINARY("")},
+ {{VARBINARY(""), std::int32_t(5), std::int32_t(100)},
VARBINARY("")},
+ {{VARBINARY(""), std::int32_t(5), Null()}, Null()},
+ {{VARBINARY(""), std::int32_t(-1), std::int32_t(1)},
VARBINARY("")},
+ {{VARBINARY(""), std::int32_t(-1), std::int32_t(5)},
VARBINARY("")},
+ {{VARBINARY(""), std::int32_t(-1), std::int32_t(-1)},
VARBINARY("")},
+ {{VARBINARY(""), std::int32_t(-1), std::int32_t(100)},
VARBINARY("")},
+ {{VARBINARY(""), std::int32_t(-1), Null()}, Null()},
+ {{VARBINARY(""), std::int32_t(100), std::int32_t(1)},
VARBINARY("")},
+ {{VARBINARY(""), std::int32_t(100), std::int32_t(5)},
VARBINARY("")},
+ {{VARBINARY(""), std::int32_t(100), std::int32_t(-1)},
VARBINARY("")},
+ {{VARBINARY(""), std::int32_t(100), std::int32_t(100)},
VARBINARY("")},
+ {{VARBINARY(""), std::int32_t(100), Null()}, Null()},
+ {{VARBINARY(""), Null(), std::int32_t(1)}, Null()},
+ {{VARBINARY(""), Null(), std::int32_t(5)}, Null()},
+ {{VARBINARY(""), Null(), std::int32_t(-1)}, Null()},
+ {{VARBINARY(""), Null(), std::int32_t(100)}, Null()},
+ {{VARBINARY(""), Null(), Null()}, Null()},
+ {{Null(), std::int32_t(1), std::int32_t(1)}, Null()},
+ {{Null(), std::int32_t(1), std::int32_t(5)}, Null()},
+ {{Null(), std::int32_t(1), std::int32_t(-1)}, Null()},
+ {{Null(), std::int32_t(1), std::int32_t(100)}, Null()},
+ {{Null(), std::int32_t(1), Null()}, Null()},
+ {{Null(), std::int32_t(5), std::int32_t(1)}, Null()},
+ {{Null(), std::int32_t(5), std::int32_t(5)}, Null()},
+ {{Null(), std::int32_t(5), std::int32_t(-1)}, Null()},
+ {{Null(), std::int32_t(5), std::int32_t(100)}, Null()},
+ {{Null(), std::int32_t(5), Null()}, Null()},
+ {{Null(), std::int32_t(-1), std::int32_t(1)}, Null()},
+ {{Null(), std::int32_t(-1), std::int32_t(5)}, Null()},
+ {{Null(), std::int32_t(-1), std::int32_t(-1)}, Null()},
+ {{Null(), std::int32_t(-1), std::int32_t(100)}, Null()},
+ {{Null(), std::int32_t(-1), Null()}, Null()},
+ {{Null(), std::int32_t(100), std::int32_t(1)}, Null()},
+ {{Null(), std::int32_t(100), std::int32_t(5)}, Null()},
+ {{Null(), std::int32_t(100), std::int32_t(-1)}, Null()},
+ {{Null(), std::int32_t(100), std::int32_t(100)}, Null()},
+ {{Null(), std::int32_t(100), Null()}, Null()},
+ {{Null(), Null(), std::int32_t(1)}, Null()},
+ {{Null(), Null(), std::int32_t(5)}, Null()},
+ {{Null(), Null(), std::int32_t(-1)}, Null()},
+ {{Null(), Null(), std::int32_t(100)}, Null()},
+ {{Null(), Null(), Null()}, Null()},
+ {{VARBINARY("A,b,C,D,_E"), std::int32_t(1), std::int32_t(1)},
VARBINARY("A")},
+ {{VARBINARY("A,b,C,D,_E"), std::int32_t(1), std::int32_t(5)},
VARBINARY("A,b,C")},
+ {{VARBINARY("A,b,C,D,_E"), std::int32_t(1), std::int32_t(-1)},
VARBINARY("")},
+ {{VARBINARY("A,b,C,D,_E"), std::int32_t(1), std::int32_t(100)},
+ VARBINARY("A,b,C,D,_E")},
+ {{VARBINARY("A,b,C,D,_E"), std::int32_t(1), Null()}, Null()},
+ {{VARBINARY("A,b,C,D,_E"), std::int32_t(5), std::int32_t(1)},
VARBINARY("C")},
+ {{VARBINARY("A,b,C,D,_E"), std::int32_t(5), std::int32_t(5)},
VARBINARY("C,D,_")},
+ {{VARBINARY("A,b,C,D,_E"), std::int32_t(5), std::int32_t(-1)},
VARBINARY("")},
+ {{VARBINARY("A,b,C,D,_E"), std::int32_t(5), std::int32_t(100)},
+ VARBINARY("C,D,_E")},
+ {{VARBINARY("A,b,C,D,_E"), std::int32_t(5), Null()}, Null()},
+ {{VARBINARY("A,b,C,D,_E"), std::int32_t(-1), std::int32_t(1)},
VARBINARY("E")},
+ {{VARBINARY("A,b,C,D,_E"), std::int32_t(-1), std::int32_t(5)},
VARBINARY("E")},
+ {{VARBINARY("A,b,C,D,_E"), std::int32_t(-1),
std::int32_t(-1)}, VARBINARY("")},
+ {{VARBINARY("A,b,C,D,_E"), std::int32_t(-1),
std::int32_t(100)}, VARBINARY("E")},
+ {{VARBINARY("A,b,C,D,_E"), std::int32_t(-1), Null()}, Null()},
+ {{VARBINARY("A,b,C,D,_E"), std::int32_t(100),
std::int32_t(1)}, VARBINARY("")},
+ {{VARBINARY("A,b,C,D,_E"), std::int32_t(100),
std::int32_t(5)}, VARBINARY("")},
+ {{VARBINARY("A,b,C,D,_E"), std::int32_t(100),
std::int32_t(-1)}, VARBINARY("")},
+ {{VARBINARY("A,b,C,D,_E"), std::int32_t(100),
std::int32_t(100)}, VARBINARY("")},
+ {{VARBINARY("A,b,C,D,_E"), std::int32_t(100), Null()}, Null()},
+ {{VARBINARY("A,b,C,D,_E"), Null(), std::int32_t(1)}, Null()},
+ {{VARBINARY("A,b,C,D,_E"), Null(), std::int32_t(5)}, Null()},
+ {{VARBINARY("A,b,C,D,_E"), Null(), std::int32_t(-1)}, Null()},
+ {{VARBINARY("A,b,C,D,_E"), Null(), std::int32_t(100)}, Null()},
+ {{VARBINARY("A,b,C,D,_E"), Null(), Null()}, Null()},
+ {{VARBINARY("1234321312312"), std::int32_t(1),
std::int32_t(1)}, VARBINARY("1")},
+ {{VARBINARY("1234321312312"), std::int32_t(1),
std::int32_t(5)},
+ VARBINARY("12343")},
+ {{VARBINARY("1234321312312"), std::int32_t(1),
std::int32_t(-1)}, VARBINARY("")},
+ {{VARBINARY("1234321312312"), std::int32_t(1),
std::int32_t(100)},
+ VARBINARY("1234321312312")},
+ {{VARBINARY("1234321312312"), std::int32_t(1), Null()},
Null()},
+ {{VARBINARY("1234321312312"), std::int32_t(5),
std::int32_t(1)}, VARBINARY("3")},
+ {{VARBINARY("1234321312312"), std::int32_t(5),
std::int32_t(5)},
+ VARBINARY("32131")},
+ {{VARBINARY("1234321312312"), std::int32_t(5),
std::int32_t(-1)}, VARBINARY("")},
+ {{VARBINARY("1234321312312"), std::int32_t(5),
std::int32_t(100)},
+ VARBINARY("321312312")},
+ {{VARBINARY("1234321312312"), std::int32_t(5), Null()},
Null()},
+ {{VARBINARY("1234321312312"), std::int32_t(-1),
std::int32_t(1)}, VARBINARY("2")},
+ {{VARBINARY("1234321312312"), std::int32_t(-1),
std::int32_t(5)}, VARBINARY("2")},
+ {{VARBINARY("1234321312312"), std::int32_t(-1),
std::int32_t(-1)}, VARBINARY("")},
+ {{VARBINARY("1234321312312"), std::int32_t(-1),
std::int32_t(100)}, VARBINARY("2")},
+ {{VARBINARY("1234321312312"), std::int32_t(-1), Null()},
Null()},
+ {{VARBINARY("1234321312312"), std::int32_t(100),
std::int32_t(1)}, VARBINARY("")},
+ {{VARBINARY("1234321312312"), std::int32_t(100),
std::int32_t(5)}, VARBINARY("")},
+ {{VARBINARY("1234321312312"), std::int32_t(100),
std::int32_t(-1)}, VARBINARY("")},
+ {{VARBINARY("1234321312312"), std::int32_t(100),
std::int32_t(100)}, VARBINARY("")},
+ {{VARBINARY("1234321312312"), std::int32_t(100), Null()},
Null()},
+ {{VARBINARY("1234321312312"), Null(), std::int32_t(1)},
Null()},
+ {{VARBINARY("1234321312312"), Null(), std::int32_t(5)},
Null()},
+ {{VARBINARY("1234321312312"), Null(), std::int32_t(-1)},
Null()},
+ {{VARBINARY("1234321312312"), Null(), std::int32_t(100)},
Null()},
+ {{VARBINARY("1234321312312"), Null(), Null()}, Null()},
+ {{VARBINARY("heh1h2_!u@_u@i$o%ll_"), std::int32_t(1),
std::int32_t(1)},
+ VARBINARY("h")},
+ {{VARBINARY("heh1h2_!u@_u@i$o%ll_"), std::int32_t(1),
std::int32_t(5)},
+ VARBINARY("heh1h")},
+ {{VARBINARY("heh1h2_!u@_u@i$o%ll_"), std::int32_t(1),
std::int32_t(-1)},
+ VARBINARY("")},
+ {{VARBINARY("heh1h2_!u@_u@i$o%ll_"), std::int32_t(1),
std::int32_t(100)},
+ VARBINARY("heh1h2_!u@_u@i$o%ll_")},
+ {{VARBINARY("heh1h2_!u@_u@i$o%ll_"), std::int32_t(1), Null()},
Null()},
+ {{VARBINARY("heh1h2_!u@_u@i$o%ll_"), std::int32_t(5),
std::int32_t(1)},
+ VARBINARY("h")},
+ {{VARBINARY("heh1h2_!u@_u@i$o%ll_"), std::int32_t(5),
std::int32_t(5)},
+ VARBINARY("h2_!u")},
+ {{VARBINARY("heh1h2_!u@_u@i$o%ll_"), std::int32_t(5),
std::int32_t(-1)},
+ VARBINARY("")},
+ {{VARBINARY("heh1h2_!u@_u@i$o%ll_"), std::int32_t(5),
std::int32_t(100)},
+ VARBINARY("h2_!u@_u@i$o%ll_")},
+ {{VARBINARY("heh1h2_!u@_u@i$o%ll_"), std::int32_t(5), Null()},
Null()},
+ {{VARBINARY("heh1h2_!u@_u@i$o%ll_"), std::int32_t(-1),
std::int32_t(1)},
+ VARBINARY("_")},
+ {{VARBINARY("heh1h2_!u@_u@i$o%ll_"), std::int32_t(-1),
std::int32_t(5)},
+ VARBINARY("_")},
+ {{VARBINARY("heh1h2_!u@_u@i$o%ll_"), std::int32_t(-1),
std::int32_t(-1)},
+ VARBINARY("")},
+ {{VARBINARY("heh1h2_!u@_u@i$o%ll_"), std::int32_t(-1),
std::int32_t(100)},
+ VARBINARY("_")},
+ {{VARBINARY("heh1h2_!u@_u@i$o%ll_"), std::int32_t(-1),
Null()}, Null()},
+ {{VARBINARY("heh1h2_!u@_u@i$o%ll_"), std::int32_t(100),
std::int32_t(1)},
+ VARBINARY("")},
+ {{VARBINARY("heh1h2_!u@_u@i$o%ll_"), std::int32_t(100),
std::int32_t(5)},
+ VARBINARY("")},
+ {{VARBINARY("heh1h2_!u@_u@i$o%ll_"), std::int32_t(100),
std::int32_t(-1)},
+ VARBINARY("")},
+ {{VARBINARY("heh1h2_!u@_u@i$o%ll_"), std::int32_t(100),
std::int32_t(100)},
+ VARBINARY("")},
+ {{VARBINARY("heh1h2_!u@_u@i$o%ll_"), std::int32_t(100),
Null()}, Null()},
+ {{VARBINARY("heh1h2_!u@_u@i$o%ll_"), Null(), std::int32_t(1)},
Null()},
+ {{VARBINARY("heh1h2_!u@_u@i$o%ll_"), Null(), std::int32_t(5)},
Null()},
+ {{VARBINARY("heh1h2_!u@_u@i$o%ll_"), Null(),
std::int32_t(-1)}, Null()},
+ {{VARBINARY("heh1h2_!u@_u@i$o%ll_"), Null(),
std::int32_t(100)}, Null()},
+ {{VARBINARY("heh1h2_!u@_u@i$o%ll_"), Null(), Null()}, Null()},
+ };
+
+ check_function_all_arg_comb<DataTypeVarbinary, true>(func_name,
input_types, data_set);
+ }
+}
+
+TEST(function_binary_test, function_to_binary_test) {
+ std::string func_name = "to_binary";
+ InputTypeSet input_types = {PrimitiveType::TYPE_VARCHAR};
+
+ DataSet data_set = {
+ {{std::string("48656c6c6f")}, VARBINARY("Hello")},
+ {{std::string("0001")}, VARBINARY(std::string_view("\x00\x01",
2))},
+ {{std::string("aaff")}, VARBINARY("\xAA\xFF")},
+ {{std::string("aGVsbG8gd29ybGQ")}, Null()},
+ {{std::string("a")}, Null()},
+ {{std::string("__123hehe1")}, Null()},
+ {{std::string("")}, Null()},
+ {{Null()}, Null()},
+ };
+
+ check_function_all_arg_comb<DataTypeVarbinary, true>(func_name,
input_types, data_set);
+}
+
+} // namespace doris::vectorized
diff --git
a/fe/fe-core/src/main/java/org/apache/doris/catalog/BuiltinScalarFunctions.java
b/fe/fe-core/src/main/java/org/apache/doris/catalog/BuiltinScalarFunctions.java
index d69322818a2..3074cd112dc 100644
---
a/fe/fe-core/src/main/java/org/apache/doris/catalog/BuiltinScalarFunctions.java
+++
b/fe/fe-core/src/main/java/org/apache/doris/catalog/BuiltinScalarFunctions.java
@@ -210,6 +210,7 @@ import
org.apache.doris.nereids.trees.expressions.functions.scalar.FormatNumber;
import org.apache.doris.nereids.trees.expressions.functions.scalar.FormatRound;
import org.apache.doris.nereids.trees.expressions.functions.scalar.Fpow;
import org.apache.doris.nereids.trees.expressions.functions.scalar.FromBase64;
+import
org.apache.doris.nereids.trees.expressions.functions.scalar.FromBase64Binary;
import org.apache.doris.nereids.trees.expressions.functions.scalar.FromBinary;
import org.apache.doris.nereids.trees.expressions.functions.scalar.FromDays;
import
org.apache.doris.nereids.trees.expressions.functions.scalar.FromIso8601Date;
@@ -463,6 +464,7 @@ import
org.apache.doris.nereids.trees.expressions.functions.scalar.StrToDate;
import org.apache.doris.nereids.trees.expressions.functions.scalar.StrToMap;
import org.apache.doris.nereids.trees.expressions.functions.scalar.Strcmp;
import
org.apache.doris.nereids.trees.expressions.functions.scalar.StructElement;
+import org.apache.doris.nereids.trees.expressions.functions.scalar.SubBinary;
import org.apache.doris.nereids.trees.expressions.functions.scalar.SubBitmap;
import org.apache.doris.nereids.trees.expressions.functions.scalar.SubReplace;
import org.apache.doris.nereids.trees.expressions.functions.scalar.Substring;
@@ -474,6 +476,7 @@ import
org.apache.doris.nereids.trees.expressions.functions.scalar.TimeDiff;
import org.apache.doris.nereids.trees.expressions.functions.scalar.TimeToSec;
import org.apache.doris.nereids.trees.expressions.functions.scalar.Timestamp;
import org.apache.doris.nereids.trees.expressions.functions.scalar.ToBase64;
+import
org.apache.doris.nereids.trees.expressions.functions.scalar.ToBase64Binary;
import org.apache.doris.nereids.trees.expressions.functions.scalar.ToBinary;
import org.apache.doris.nereids.trees.expressions.functions.scalar.ToBitmap;
import
org.apache.doris.nereids.trees.expressions.functions.scalar.ToBitmapWithCheck;
@@ -719,6 +722,7 @@ public class BuiltinScalarFunctions implements
FunctionHelper {
scalar(FormatNumber.class, "format_number"),
scalar(Fpow.class, "fpow"),
scalar(FromBase64.class, "from_base64"),
+ scalar(FromBase64Binary.class, "from_base64_binary"),
scalar(FromBinary.class, "from_binary", "from_hex"),
scalar(FromDays.class, "from_days"),
scalar(FromIso8601Date.class, "from_iso8601_date"),
@@ -979,6 +983,7 @@ public class BuiltinScalarFunctions implements
FunctionHelper {
scalar(Strcmp.class, "strcmp"),
scalar(StrToDate.class, "str_to_date"),
scalar(StrToMap.class, "str_to_map"),
+ scalar(SubBinary.class, "sub_binary"),
scalar(SubBitmap.class, "sub_bitmap"),
scalar(SubReplace.class, "sub_replace"),
scalar(Substring.class, "substr", "substring", "mid"),
@@ -990,6 +995,7 @@ public class BuiltinScalarFunctions implements
FunctionHelper {
scalar(TimeToSec.class, "time_to_sec"),
scalar(Timestamp.class, "timestamp"),
scalar(ToBase64.class, "to_base64"),
+ scalar(ToBase64Binary.class, "to_base64_binary"),
scalar(ToBinary.class, "to_binary", "to_hex"),
scalar(ToBitmap.class, "to_bitmap"),
scalar(ToBitmapWithCheck.class, "to_bitmap_with_check"),
diff --git
a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/scalar/Length.java
b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/scalar/FromBase64Binary.java
similarity index 74%
copy from
fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/scalar/Length.java
copy to
fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/scalar/FromBase64Binary.java
index 6bb8bc9c3dd..81b858b63f8 100644
---
a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/scalar/Length.java
+++
b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/scalar/FromBase64Binary.java
@@ -19,13 +19,13 @@ 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.functions.PropagateNullable;
+import
org.apache.doris.nereids.trees.expressions.functions.PropagateNullLiteral;
import org.apache.doris.nereids.trees.expressions.shape.UnaryExpression;
import org.apache.doris.nereids.trees.expressions.visitor.ExpressionVisitor;
-import org.apache.doris.nereids.types.IntegerType;
import org.apache.doris.nereids.types.StringType;
-import org.apache.doris.nereids.types.VarcharType;
+import org.apache.doris.nereids.types.VarBinaryType;
import com.google.common.base.Preconditions;
import com.google.common.collect.ImmutableList;
@@ -33,25 +33,22 @@ import com.google.common.collect.ImmutableList;
import java.util.List;
/**
- * ScalarFunction 'length'. This class is generated by GenerateFunction.
+ * ScalarFunction 'from_base64_binary'.
*/
-public class Length extends ScalarFunction
- implements UnaryExpression, ExplicitlyCastableSignature,
PropagateNullable {
-
+public class FromBase64Binary extends ScalarFunction
+ implements UnaryExpression, ExplicitlyCastableSignature,
AlwaysNullable, PropagateNullLiteral {
public static final List<FunctionSignature> SIGNATURES = ImmutableList.of(
-
FunctionSignature.ret(IntegerType.INSTANCE).args(VarcharType.SYSTEM_DEFAULT),
-
FunctionSignature.ret(IntegerType.INSTANCE).args(StringType.INSTANCE)
- );
+
FunctionSignature.ret(VarBinaryType.INSTANCE).args(StringType.INSTANCE));
/**
* constructor with 1 argument.
*/
- public Length(Expression arg) {
- super("length", arg);
+ public FromBase64Binary(Expression arg) {
+ super("from_base64_binary", arg);
}
/** constructor for withChildren and reuse signature */
- private Length(ScalarFunctionParams functionParams) {
+ private FromBase64Binary(ScalarFunctionParams functionParams) {
super(functionParams);
}
@@ -59,9 +56,9 @@ public class Length extends ScalarFunction
* withChildren.
*/
@Override
- public Length withChildren(List<Expression> children) {
+ public FromBase64Binary withChildren(List<Expression> children) {
Preconditions.checkArgument(children.size() == 1);
- return new Length(getFunctionParams(children));
+ return new FromBase64Binary(getFunctionParams(children));
}
@Override
@@ -71,6 +68,7 @@ public class Length extends ScalarFunction
@Override
public <R, C> R accept(ExpressionVisitor<R, C> visitor, C context) {
- return visitor.visitLength(this, context);
+ return visitor.visitFromBase64Binary(this, context);
}
+
}
diff --git
a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/scalar/Length.java
b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/scalar/Length.java
index 6bb8bc9c3dd..35fc1b49aef 100644
---
a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/scalar/Length.java
+++
b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/scalar/Length.java
@@ -25,6 +25,7 @@ import
org.apache.doris.nereids.trees.expressions.shape.UnaryExpression;
import org.apache.doris.nereids.trees.expressions.visitor.ExpressionVisitor;
import org.apache.doris.nereids.types.IntegerType;
import org.apache.doris.nereids.types.StringType;
+import org.apache.doris.nereids.types.VarBinaryType;
import org.apache.doris.nereids.types.VarcharType;
import com.google.common.base.Preconditions;
@@ -40,8 +41,8 @@ public class Length extends ScalarFunction
public static final List<FunctionSignature> SIGNATURES = ImmutableList.of(
FunctionSignature.ret(IntegerType.INSTANCE).args(VarcharType.SYSTEM_DEFAULT),
-
FunctionSignature.ret(IntegerType.INSTANCE).args(StringType.INSTANCE)
- );
+
FunctionSignature.ret(IntegerType.INSTANCE).args(StringType.INSTANCE),
+
FunctionSignature.ret(IntegerType.INSTANCE).args(VarBinaryType.INSTANCE));
/**
* constructor with 1 argument.
diff --git
a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/scalar/Length.java
b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/scalar/SubBinary.java
similarity index 55%
copy from
fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/scalar/Length.java
copy to
fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/scalar/SubBinary.java
index 6bb8bc9c3dd..5fc67aca98e 100644
---
a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/scalar/Length.java
+++
b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/scalar/SubBinary.java
@@ -21,47 +21,65 @@ import org.apache.doris.catalog.FunctionSignature;
import org.apache.doris.nereids.trees.expressions.Expression;
import
org.apache.doris.nereids.trees.expressions.functions.ExplicitlyCastableSignature;
import org.apache.doris.nereids.trees.expressions.functions.PropagateNullable;
-import org.apache.doris.nereids.trees.expressions.shape.UnaryExpression;
+import org.apache.doris.nereids.trees.expressions.literal.Literal;
import org.apache.doris.nereids.trees.expressions.visitor.ExpressionVisitor;
import org.apache.doris.nereids.types.IntegerType;
-import org.apache.doris.nereids.types.StringType;
-import org.apache.doris.nereids.types.VarcharType;
+import org.apache.doris.nereids.types.VarBinaryType;
import com.google.common.base.Preconditions;
import com.google.common.collect.ImmutableList;
import java.util.List;
+import java.util.Optional;
/**
- * ScalarFunction 'length'. This class is generated by GenerateFunction.
+ * ScalarFunction 'sub_binary'.
*/
-public class Length extends ScalarFunction
- implements UnaryExpression, ExplicitlyCastableSignature,
PropagateNullable {
-
+public class SubBinary extends ScalarFunction
+ implements ExplicitlyCastableSignature, PropagateNullable {
public static final List<FunctionSignature> SIGNATURES = ImmutableList.of(
-
FunctionSignature.ret(IntegerType.INSTANCE).args(VarcharType.SYSTEM_DEFAULT),
-
FunctionSignature.ret(IntegerType.INSTANCE).args(StringType.INSTANCE)
- );
+
FunctionSignature.ret(VarBinaryType.INSTANCE).args(VarBinaryType.INSTANCE,
IntegerType.INSTANCE),
+ FunctionSignature.ret(VarBinaryType.INSTANCE)
+ .args(VarBinaryType.INSTANCE, IntegerType.INSTANCE,
IntegerType.INSTANCE));
+
+ /**
+ * constructor with 2 arguments.
+ */
+ public SubBinary(Expression arg0, Expression arg1) {
+ super("sub_binary", arg0, arg1, Literal.of(Integer.MAX_VALUE));
+ }
/**
- * constructor with 1 argument.
+ * constructor with 3 arguments.
*/
- public Length(Expression arg) {
- super("length", arg);
+ public SubBinary(Expression arg0, Expression arg1, Expression arg2) {
+ super("sub_binary", arg0, arg1, arg2);
}
/** constructor for withChildren and reuse signature */
- private Length(ScalarFunctionParams functionParams) {
+ private SubBinary(ScalarFunctionParams functionParams) {
super(functionParams);
}
+ public Expression getSource() {
+ return child(0);
+ }
+
+ public Expression getPosition() {
+ return child(1);
+ }
+
+ public Optional<Expression> getLength() {
+ return arity() == 3 ? Optional.of(child(2)) : Optional.empty();
+ }
+
/**
* withChildren.
*/
@Override
- public Length withChildren(List<Expression> children) {
- Preconditions.checkArgument(children.size() == 1);
- return new Length(getFunctionParams(children));
+ public SubBinary withChildren(List<Expression> children) {
+ Preconditions.checkArgument(children.size() == 2 || children.size() ==
3);
+ return new SubBinary(getFunctionParams(children));
}
@Override
@@ -71,6 +89,6 @@ public class Length extends ScalarFunction
@Override
public <R, C> R accept(ExpressionVisitor<R, C> visitor, C context) {
- return visitor.visitLength(this, context);
+ return visitor.visitSubBinary(this, context);
}
}
diff --git
a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/scalar/Length.java
b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/scalar/ToBase64Binary.java
similarity index 75%
copy from
fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/scalar/Length.java
copy to
fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/scalar/ToBase64Binary.java
index 6bb8bc9c3dd..fe07fecff0c 100644
---
a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/scalar/Length.java
+++
b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/scalar/ToBase64Binary.java
@@ -23,9 +23,8 @@ import
org.apache.doris.nereids.trees.expressions.functions.ExplicitlyCastableSi
import org.apache.doris.nereids.trees.expressions.functions.PropagateNullable;
import org.apache.doris.nereids.trees.expressions.shape.UnaryExpression;
import org.apache.doris.nereids.trees.expressions.visitor.ExpressionVisitor;
-import org.apache.doris.nereids.types.IntegerType;
import org.apache.doris.nereids.types.StringType;
-import org.apache.doris.nereids.types.VarcharType;
+import org.apache.doris.nereids.types.VarBinaryType;
import com.google.common.base.Preconditions;
import com.google.common.collect.ImmutableList;
@@ -33,25 +32,23 @@ import com.google.common.collect.ImmutableList;
import java.util.List;
/**
- * ScalarFunction 'length'. This class is generated by GenerateFunction.
+ * ScalarFunction 'to_base64_binary'.
*/
-public class Length extends ScalarFunction
+public class ToBase64Binary extends ScalarFunction
implements UnaryExpression, ExplicitlyCastableSignature,
PropagateNullable {
public static final List<FunctionSignature> SIGNATURES = ImmutableList.of(
-
FunctionSignature.ret(IntegerType.INSTANCE).args(VarcharType.SYSTEM_DEFAULT),
-
FunctionSignature.ret(IntegerType.INSTANCE).args(StringType.INSTANCE)
- );
+
FunctionSignature.ret(StringType.INSTANCE).args(VarBinaryType.INSTANCE));
/**
* constructor with 1 argument.
*/
- public Length(Expression arg) {
- super("length", arg);
+ public ToBase64Binary(Expression arg) {
+ super("to_base64_binary", arg);
}
/** constructor for withChildren and reuse signature */
- private Length(ScalarFunctionParams functionParams) {
+ private ToBase64Binary(ScalarFunctionParams functionParams) {
super(functionParams);
}
@@ -59,9 +56,9 @@ public class Length extends ScalarFunction
* withChildren.
*/
@Override
- public Length withChildren(List<Expression> children) {
+ public ToBase64Binary withChildren(List<Expression> children) {
Preconditions.checkArgument(children.size() == 1);
- return new Length(getFunctionParams(children));
+ return new ToBase64Binary(getFunctionParams(children));
}
@Override
@@ -71,6 +68,6 @@ public class Length extends ScalarFunction
@Override
public <R, C> R accept(ExpressionVisitor<R, C> visitor, C context) {
- return visitor.visitLength(this, context);
+ return visitor.visitToBase64Binary(this, context);
}
}
diff --git
a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/visitor/ScalarFunctionVisitor.java
b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/visitor/ScalarFunctionVisitor.java
index fbfa0d5bce2..8ce00fc6f1f 100644
---
a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/visitor/ScalarFunctionVisitor.java
+++
b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/visitor/ScalarFunctionVisitor.java
@@ -220,6 +220,7 @@ import
org.apache.doris.nereids.trees.expressions.functions.scalar.FormatNumber;
import org.apache.doris.nereids.trees.expressions.functions.scalar.FormatRound;
import org.apache.doris.nereids.trees.expressions.functions.scalar.Fpow;
import org.apache.doris.nereids.trees.expressions.functions.scalar.FromBase64;
+import
org.apache.doris.nereids.trees.expressions.functions.scalar.FromBase64Binary;
import org.apache.doris.nereids.trees.expressions.functions.scalar.FromBinary;
import org.apache.doris.nereids.trees.expressions.functions.scalar.FromDays;
import
org.apache.doris.nereids.trees.expressions.functions.scalar.FromIso8601Date;
@@ -463,6 +464,7 @@ import
org.apache.doris.nereids.trees.expressions.functions.scalar.StrToDate;
import org.apache.doris.nereids.trees.expressions.functions.scalar.StrToMap;
import org.apache.doris.nereids.trees.expressions.functions.scalar.Strcmp;
import
org.apache.doris.nereids.trees.expressions.functions.scalar.StructElement;
+import org.apache.doris.nereids.trees.expressions.functions.scalar.SubBinary;
import org.apache.doris.nereids.trees.expressions.functions.scalar.SubBitmap;
import org.apache.doris.nereids.trees.expressions.functions.scalar.SubReplace;
import org.apache.doris.nereids.trees.expressions.functions.scalar.Substring;
@@ -473,6 +475,7 @@ import
org.apache.doris.nereids.trees.expressions.functions.scalar.Time;
import org.apache.doris.nereids.trees.expressions.functions.scalar.TimeDiff;
import org.apache.doris.nereids.trees.expressions.functions.scalar.Timestamp;
import org.apache.doris.nereids.trees.expressions.functions.scalar.ToBase64;
+import
org.apache.doris.nereids.trees.expressions.functions.scalar.ToBase64Binary;
import org.apache.doris.nereids.trees.expressions.functions.scalar.ToBinary;
import org.apache.doris.nereids.trees.expressions.functions.scalar.ToBitmap;
import
org.apache.doris.nereids.trees.expressions.functions.scalar.ToBitmapWithCheck;
@@ -1313,6 +1316,10 @@ public interface ScalarFunctionVisitor<R, C> {
return visitScalarFunction(fromBase64, context);
}
+ default R visitFromBase64Binary(FromBase64Binary fromBase64Binary, C
context) {
+ return visitScalarFunction(fromBase64Binary, context);
+ }
+
default R visitFromBinary(FromBinary fromBinary, C context) {
return visitScalarFunction(fromBinary, context);
}
@@ -2205,6 +2212,10 @@ public interface ScalarFunctionVisitor<R, C> {
return visitScalarFunction(stringRegexPredicate, context);
}
+ default R visitSubBinary(SubBinary subBinary, C context) {
+ return visitScalarFunction(subBinary, context);
+ }
+
default R visitSubBitmap(SubBitmap subBitmap, C context) {
return visitScalarFunction(subBitmap, context);
}
@@ -2257,6 +2268,10 @@ public interface ScalarFunctionVisitor<R, C> {
return visitScalarFunction(toBase64, context);
}
+ default R visitToBase64Binary(ToBase64Binary toBase64Binary, C context) {
+ return visitScalarFunction(toBase64Binary, context);
+ }
+
default R visitToBinary(ToBinary toBinary, C context) {
return visitScalarFunction(toBinary, context);
}
diff --git
a/regression-test/suites/query_p0/sql_functions/binary_functions/test_binary_function.groovy
b/regression-test/suites/query_p0/sql_functions/binary_functions/test_binary_function.groovy
new file mode 100644
index 00000000000..0959adefea1
--- /dev/null
+++
b/regression-test/suites/query_p0/sql_functions/binary_functions/test_binary_function.groovy
@@ -0,0 +1,128 @@
+// 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.
+
+suite("test_binary_function",
"p0,external,mysql,external_docker,external_docker_mysql") {
+ String enabled = context.config.otherConfigs.get("enableJdbcTest")
+
+ if (enabled != null && enabled.equalsIgnoreCase("true")) {
+ String externalEnvIp = context.config.otherConfigs.get("externalEnvIp")
+ String s3_endpoint = getS3Endpoint()
+ String bucket = getS3BucketName()
+ String driver_url =
"https://${bucket}.${s3_endpoint}/regression/jdbc_driver/mysql-connector-java-8.0.25.jar"
+ String catalog_name = "mysql_varbinary_catalog";
+ String ex_db_name = "doris_test";
+ String mysql_port = context.config.otherConfigs.get("mysql_57_port");
+ String test_table = "binary_test";
+
+
+
+ sql """drop catalog if exists ${catalog_name}"""
+
+ sql """create catalog if not exists ${catalog_name} properties(
+ "type"="jdbc",
+ "user"="root",
+ "password"="123456",
+ "jdbc_url" =
"jdbc:mysql://${externalEnvIp}:${mysql_port}/doris_test?useSSL=false",
+ "driver_url" = "${driver_url}",
+ "driver_class" = "com.mysql.cj.jdbc.Driver"
+ );"""
+
+ connect("root", "123456",
"jdbc:mysql://${externalEnvIp}:${mysql_port}/doris_test?useSSL=false") {
+ try_sql """DROP TABLE IF EXISTS ${test_table}"""
+
+ sql """CREATE TABLE ${test_table} (
+ id int,
+ vb varbinary(100),
+ vc VARCHAR(100)
+ )"""
+
+ sql """INSERT INTO ${test_table} VALUES
+ (1, 'hello world', 'hello world'),
+ (2, '', ''),
+ (3, 'special chars: !@#%', 'special chars: !@#%'),
+ (4, '__123hehe1', '__123hehe1'),
+ (5, 'ABB', 'ABB'),
+ (6, '5ZWK5ZOI5ZOI5ZOI8J+YhCDjgILigJTigJQh',
'5ZWK5ZOI5ZOI5ZOI8J+YhCDjgILigJTigJQh'),
+ (7, 'SEVMTE8sIV4l', 'SEVMTE8sIV4l')
+ """
+ }
+
+ sql """switch ${catalog_name}"""
+ sql """use ${ex_db_name}"""
+
+ def length_result = sql """select id, length(vb), length(vc) from
${test_table} order by id"""
+ for (int i = 0; i < length_result.size(); i++) {
+ assertTrue(length_result[i][1] == length_result[i][2],
+ "length mismatch for row ${length_result[i][0]}:
VarBinary=${length_result[i][1]}, VARCHAR=${length_result[i][2]}")
+ }
+
+ def from_base64_result = sql """select id,
from_binary(from_base64_binary(vc)), hex(from_base64(vc)) from ${test_table}
order by id"""
+ for (int i = 0; i < from_base64_result.size(); i++) {
+ def bin = from_base64_result[i][1]
+ def str = from_base64_result[i][2]
+ assertTrue(bin == str,
+ "from_base64 mismatch for row ${from_base64_result[i][0]}:
VarBinary=${bin}, VARCHAR=${str}")
+ }
+
+ def to_base64_result = sql """select id, to_base64_binary(vb),
to_base64(vc) from ${test_table} order by id"""
+ for (int i = 0; i < to_base64_result.size(); i++) {
+ assertTrue(to_base64_result[i][1] == to_base64_result[i][2],
+ "to_base64 mismatch for row ${to_base64_result[i][0]}:
VarBinary=${to_base64_result[i][1]}, VARCHAR=${to_base64_result[i][2]}")
+ }
+
+ def sub_binary_3args_result = sql """select id,
from_binary(sub_binary(vb, 1, 5)), hex(substr(vc, 1, 5)) from ${test_table}
order by id"""
+ for (int i = 0; i < sub_binary_3args_result.size(); i++) {
+ def bin = sub_binary_3args_result[i][1]
+ def str = sub_binary_3args_result[i][2]
+ assertTrue(bin == str,
+ "sub_binary_3args mismatch for row
${sub_binary_3args_result[i][0]}: VarBinary=${bin}, VARCHAR=${str}")
+ }
+
+ def sub_binary_3args_result_2 = sql """select id,
from_binary(sub_binary(vb, -1, 5)), hex(substr(vc, -1, 5)) from ${test_table}
order by id"""
+ for (int i = 0; i < sub_binary_3args_result_2.size(); i++) {
+ def bin = sub_binary_3args_result_2[i][1]
+ def str = sub_binary_3args_result_2[i][2]
+ assertTrue(bin == str,
+ "sub_binary_3args_2 mismatch for row
${sub_binary_3args_result_2[i][0]}: VarBinary=${bin}, VARCHAR=${str}")
+ }
+
+ def sub_binary_2args_result = sql """select id,
from_binary(sub_binary(vb, 1)), hex(substr(vc, 1)) from ${test_table} order by
id"""
+ for (int i = 0; i < sub_binary_2args_result.size(); i++) {
+ def bin = sub_binary_2args_result[i][1]
+ def str = sub_binary_2args_result[i][2]
+ assertTrue(bin == str,
+ "sub_binary_2args mismatch for row
${sub_binary_2args_result[i][0]}: VarBinary=${bin}, VARCHAR=${str}")
+ }
+
+ def sub_binary_2args_result_2 = sql """select id,
from_binary(sub_binary(vb, -1)), hex(substr(vc, -1)) from ${test_table} order
by id"""
+ for (int i = 0; i < sub_binary_2args_result_2.size(); i++) {
+ def bin = sub_binary_2args_result_2[i][1]
+ def str = sub_binary_2args_result_2[i][2]
+ assertTrue(bin == str,
+ "sub_binary_2args_2 mismatch for row
${sub_binary_2args_result_2[i][0]}: VarBinary=${bin}, VARCHAR=${str}")
+ }
+
+ def sub_binary_nest_2args_result = sql """select id,
from_binary(sub_binary(sub_binary(vb, 1), 1)), hex(substr(substr(vc, 1), 1))
from ${test_table} order by id"""
+ for (int i = 0; i < sub_binary_nest_2args_result.size(); i++) {
+ def bin = sub_binary_nest_2args_result[i][1]
+ def str = sub_binary_nest_2args_result[i][2]
+ assertTrue(bin == str,
+ "sub_binary_nest_2args mismatch for row
${sub_binary_nest_2args_result[i][0]}: VarBinary=${bin}, VARCHAR=${str}")
+ }
+
+ }
+}
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]