blob: 6ef4894cab1172ab9eb4cffb9e8e6d4155aea9ac [file] [log] [blame]
// 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 <cstdint>
#include <memory>
#include <variant>
#include <vector>
#include "cast_test.h"
#include "runtime/define_primitive_type.h"
#include "runtime/primitive_type.h"
#include "testutil/column_helper.h"
#include "vec/columns/column_array.h"
#include "vec/core/field.h"
#include "vec/data_types/data_type_nullable.h"
#include "vec/data_types/data_type_number.h"
#include "vec/data_types/data_type_string.h"
#include "vec/functions/cast/cast_base.h"
namespace doris::vectorized {
using namespace ut_type;
template <typename DataType>
struct ColumnArrayBuilder {
using FieldType = typename DataType::FieldType;
using Ty = std::variant<FieldType, NullTag>;
void add(const std::vector<Ty>& values) {
for (const auto& value : values) {
if (std::holds_alternative<FieldType>(value)) {
nested_values.push_back(std::get<FieldType>(value));
nested_null_map.push_back(false);
} else {
nested_values.push_back(FieldType {});
nested_null_map.push_back(true);
}
}
size += values.size();
null_map.push_back(0);
offsets.push_back(size);
}
ColumnWithTypeAndName build() {
auto nested_column =
ColumnHelper::create_nullable_column<DataType>(nested_values, nested_null_map);
auto offsets_column = ColumnHelper::create_column_offsets<TYPE_UINT64>(offsets);
auto col_array = ColumnArray::create(std::move(nested_column), offsets_column);
auto col_null_map = ColumnHelper::create_column<DataTypeUInt8>(null_map);
auto col_nullable = ColumnNullable::create(std::move(col_array), std::move(col_null_map));
auto data_type = std::make_shared<DataTypeNullable>(std::make_shared<DataTypeArray>(
std::make_shared<DataTypeNullable>(std::make_shared<DataType>())));
return ColumnWithTypeAndName(std::move(col_nullable), data_type, "column");
}
void add_null() {
null_map.push_back(1);
offsets.push_back(size);
}
int size = 0;
std::vector<FieldType> nested_values;
std::vector<DataTypeUInt8::FieldType> nested_null_map;
std::vector<uint64_t> offsets;
std::vector<DataTypeUInt8::FieldType> null_map;
};
TEST_F(FunctionCastTest, test_from_string_to_array_int) {
ColumnArrayBuilder<DataTypeInt32> builder;
std::vector<std::string> from_str;
from_str.push_back(R"([123,456])");
builder.add({123, 456});
from_str.push_back(R"([789, 101112])");
builder.add({789, 101112});
from_str.push_back(R"([1, 2, 3])");
builder.add({1, 2, 3});
from_str.push_back(R"([abc, 101112])");
builder.add({NullTag {}, 101112});
from_str.push_back(R"([1, 2, 3, 4])");
builder.add({1, 2, 3, 4});
from_str.push_back(R"([)");
builder.add_null();
check_cast(ColumnWithTypeAndName(ColumnHelper::create_column<DataTypeString>(from_str),
std::make_shared<DataTypeString>(), "from"),
builder.build(), false);
}
TEST_F(FunctionCastTest, test_from_string_to_array_double) {
ColumnArrayBuilder<DataTypeFloat64> builder;
std::vector<std::string> from_str;
from_str.push_back(R"([123.456, 789.101])");
builder.add({123.456, 789.101});
from_str.push_back(R"([1.2, 3.4, 5.6])");
builder.add({1.2, 3.4, 5.6});
from_str.push_back(R"(["1.2", '3.4', "5.6"])");
builder.add({1.2, 3.4, 5.6});
from_str.push_back(R"([abc, 101112])");
builder.add({NullTag {}, 101112.0});
from_str.push_back(R"([1.2, 3.4, 5.6, 7.8])");
builder.add({1.2, 3.4, 5.6, 7.8});
from_str.push_back(R"([)");
builder.add_null();
from_str.push_back(R"([])");
builder.add({});
from_str.push_back(R"([ ])");
builder.add({NullTag {}});
from_str.push_back(R"([123;123])");
builder.add({NullTag {}});
check_cast(ColumnWithTypeAndName(ColumnHelper::create_column<DataTypeString>(from_str),
std::make_shared<DataTypeString>(), "from"),
builder.build(), false);
}
TEST_F(FunctionCastTest, test_from_string_to_array_string) {
ColumnArrayBuilder<DataTypeString> builder;
std::vector<std::string> from_str;
from_str.push_back(R"([123,456])");
builder.add({"123", "456"});
from_str.push_back(R"([789, 101112])");
builder.add({"789", "101112"});
from_str.push_back(R"([1, 2, 3])");
builder.add({"1", "2", "3"});
from_str.push_back(R"([abc, 101112])");
builder.add({"abc", "101112"});
from_str.push_back(R"([1, 2, 3, 4])");
builder.add({"1", "2", "3", "4"});
from_str.push_back(R"([)");
builder.add_null();
from_str.push_back(R"([])");
builder.add({});
from_str.push_back(R"([ ])");
builder.add({""});
check_cast(ColumnWithTypeAndName(ColumnHelper::create_column<DataTypeString>(from_str),
std::make_shared<DataTypeString>(), "from"),
builder.build(), false);
}
TEST_F(FunctionCastTest, test_from_string_to_array_bool) {
ColumnArrayBuilder<DataTypeBool> builder;
std::vector<std::string> from_str;
from_str.push_back(R"([true, false])");
builder.add({true, false});
from_str.push_back(R"([1, 0])");
builder.add({true, false});
from_str.push_back(R"(['true', "0", "false"])");
builder.add({true, false, false});
from_str.push_back(R"([abc, 101112])");
builder.add({NullTag {}, NullTag {}});
check_cast(ColumnWithTypeAndName(ColumnHelper::create_column<DataTypeString>(from_str),
std::make_shared<DataTypeString>(), "from"),
builder.build(), false);
}
} // namespace doris::vectorized