blob: abdc7576a598a86489281380421dcc254b32578d [file]
// 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 <memory>
#include <string>
#include <vector>
#include "core/block/block.h"
#include "core/column/column_const.h"
#include "core/data_type/data_type_array.h"
#include "core/data_type/data_type_nullable.h"
#include "core/data_type/data_type_number.h"
#include "core/data_type/data_type_string.h"
#include "exprs/function/function_test_util.h"
#include "exprs/function/simple_function_factory.h"
namespace doris {
namespace {
void check_array_except_all(const DataTypePtr& array_type, const TestArray& left,
const TestArray& right, const TestArray& expected, bool left_const,
bool right_const) {
MutableColumnPtr left_column = array_type->create_column();
ASSERT_TRUE(insert_cell(left_column, array_type, left));
MutableColumnPtr right_column = array_type->create_column();
ASSERT_TRUE(insert_cell(right_column, array_type, right));
constexpr size_t row_count = 1;
if (left_const) {
left_column = ColumnConst::create(std::move(left_column), row_count);
}
if (right_const) {
right_column = ColumnConst::create(std::move(right_column), row_count);
}
Block block;
block.insert({std::move(left_column), array_type, "left"});
block.insert({std::move(right_column), array_type, "right"});
auto function = SimpleFunctionFactory::instance().get_function(
"array_except_all", block.get_columns_with_type_and_name(), array_type);
ASSERT_NE(function, nullptr);
FunctionUtils function_utils(array_type, {array_type, array_type}, false);
auto* context = function_utils.get_fn_ctx();
ASSERT_TRUE(function->open(context, FunctionContext::FRAGMENT_LOCAL).ok());
ASSERT_TRUE(function->open(context, FunctionContext::THREAD_LOCAL).ok());
block.insert({nullptr, array_type, "result"});
ASSERT_TRUE(function->execute(context, block, {0, 1}, 2, row_count).ok());
ASSERT_TRUE(function->close(context, FunctionContext::THREAD_LOCAL).ok());
ASSERT_TRUE(function->close(context, FunctionContext::FRAGMENT_LOCAL).ok());
MutableColumnPtr expected_column = array_type->create_column();
ASSERT_TRUE(insert_cell(expected_column, array_type, expected));
Field actual_value;
block.get_by_position(2).column->get(0, actual_value);
Field expected_value;
expected_column->get(0, expected_value);
EXPECT_EQ(actual_value, expected_value);
}
} // namespace
TEST(function_array_except_all_test, integer_multiset_semantics) {
auto array_type =
std::make_shared<DataTypeArray>(make_nullable(std::make_shared<DataTypeInt32>()));
check_array_except_all(array_type, {Int32(1), Int32(1), Int32(2)}, {Int32(1)},
{Int32(1), Int32(2)}, false, false);
check_array_except_all(array_type, {Int32(1), Int32(1)}, {Int32(1), Int32(1), Int32(1)}, {},
true, false);
check_array_except_all(array_type, {Int32(1), Int32(2)}, {}, {Int32(1), Int32(2)}, false, true);
}
TEST(function_array_except_all_test, null_and_string_counts) {
auto integer_array_type =
std::make_shared<DataTypeArray>(make_nullable(std::make_shared<DataTypeInt32>()));
check_array_except_all(integer_array_type, {Null(), Null(), Int32(1)}, {Null()},
{Null(), Int32(1)}, false, false);
check_array_except_all(integer_array_type, {Null()}, {Null(), Null()}, {}, false, false);
auto string_array_type =
std::make_shared<DataTypeArray>(make_nullable(std::make_shared<DataTypeString>()));
check_array_except_all(string_array_type,
{std::string("a"), std::string("a"), std::string("b")},
{std::string("a")}, {std::string("a"), std::string("b")}, false, false);
}
} // namespace doris