blob: e53b01c4b0b72b5af434fa4ff1e3696c237044c0 [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 "paimon/testing/utils/dict_array_converter.h"
#include "arrow/ipc/json_simple.h"
#include "gtest/gtest.h"
#include "paimon/testing/utils/testharness.h"
namespace paimon::test {
TEST(DictArrayConverterTest, TestNestedBinaryDictionary) {
const std::string bytes("a\0\xff\x80", 4);
arrow::BinaryBuilder builder;
ASSERT_TRUE(builder.Append(bytes).ok());
ASSERT_TRUE(builder.Append("").ok());
ASSERT_TRUE(builder.AppendNull().ok());
std::shared_ptr<arrow::Array> binary_dictionary;
ASSERT_TRUE(builder.Finish(&binary_dictionary).ok());
for (const auto& value_type : {arrow::binary(), arrow::large_binary()}) {
SCOPED_TRACE(value_type->ToString());
ASSERT_OK_AND_ASSIGN(
std::shared_ptr<arrow::Array> dictionary,
CastingUtils::Cast(binary_dictionary, value_type, arrow::compute::CastOptions::Safe(),
arrow::default_memory_pool()));
auto indices =
arrow::ipc::internal::json::ArrayFromJSON(arrow::int16(), "[1, 0, null, 1, 2, 0]")
.ValueOrDie();
auto encoded =
arrow::DictionaryArray::FromArrays(indices, dictionary).ValueOrDie()->Slice(1);
auto offsets =
arrow::ipc::internal::json::ArrayFromJSON(arrow::int32(), "[0, 2, 2, 5]").ValueOrDie();
auto list = arrow::ListArray::FromArrays(*offsets, *encoded).ValueOrDie();
auto keys =
arrow::ipc::internal::json::ArrayFromJSON(arrow::utf8(), R"(["a", "b", "c", "d", "e"])")
.ValueOrDie();
auto map = arrow::MapArray::FromArrays(offsets, keys, encoded).ValueOrDie();
auto array =
arrow::StructArray::Make({list, map}, std::vector<std::string>({"list", "map"}))
.ValueOrDie();
ASSERT_OK_AND_ASSIGN(
std::shared_ptr<arrow::Array> result,
DictArrayConverter::ConvertDictArray(array, arrow::default_memory_pool()));
ASSERT_TRUE(result->ValidateFull().ok());
auto decoded_struct = checked_pointer_cast<arrow::StructArray>(result);
auto decoded_list = checked_pointer_cast<arrow::ListArray>(decoded_struct->field(0));
auto decoded_map = checked_pointer_cast<arrow::MapArray>(decoded_struct->field(1));
ASSERT_TRUE(decoded_list->value_type()->Equals(value_type));
ASSERT_TRUE(decoded_map->items()->type()->Equals(value_type));
ASSERT_TRUE(decoded_list->values()->Equals(decoded_map->items()));
auto values = decoded_list->values();
ASSERT_TRUE(values->IsNull(1));
ASSERT_TRUE(values->IsNull(3));
auto check_values = [&](const auto& typed) {
ASSERT_EQ(bytes, typed->GetView(0));
ASSERT_EQ("", typed->GetView(2));
ASSERT_EQ(bytes, typed->GetView(4));
};
if (value_type->id() == arrow::Type::BINARY) {
check_values(checked_pointer_cast<arrow::BinaryArray>(values));
} else {
check_values(checked_pointer_cast<arrow::LargeBinaryArray>(values));
}
}
}
} // namespace paimon::test