Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
62 changes: 62 additions & 0 deletions cpp/src/arrow/type_test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -32,10 +32,12 @@
#include "arrow/memory_pool.h"
#include "arrow/table.h"
#include "arrow/testing/gtest_util.h"
#include "arrow/testing/matchers.h"
#include "arrow/testing/random.h"
#include "arrow/testing/util.h"
#include "arrow/type.h"
#include "arrow/type_traits.h"
#include "arrow/util/logging.h"
#include "arrow/util/checked_cast.h"
#include "arrow/util/key_value_metadata.h"

Expand All @@ -49,6 +51,66 @@ TEST(TestTypeId, AllTypeIds) {
ASSERT_EQ(static_cast<int>(all_ids.size()), Type::MAX_ID);
}

TEST(TestTypeSingleton, ParameterFreeTypes) {
// Test successful cases - parameter-free types
std::vector<std::pair<Type::type, std::shared_ptr<DataType>>> cases = {
{Type::NA, null()},
{Type::BOOL, boolean()},
{Type::INT8, int8()},
{Type::INT16, int16()},
{Type::INT32, int32()},
{Type::INT64, int64()},
{Type::UINT8, uint8()},
{Type::UINT16, uint16()},
{Type::UINT32, uint32()},
{Type::UINT64, uint64()},
{Type::HALF_FLOAT, float16()},
{Type::FLOAT, float32()},
{Type::DOUBLE, float64()},
{Type::STRING, utf8()},
{Type::BINARY, binary()},
{Type::LARGE_STRING, large_utf8()},
{Type::LARGE_BINARY, large_binary()},
{Type::DATE32, date32()},
};

for (const auto& test_case : cases) {
SCOPED_TRACE("Testing type: " + std::to_string(static_cast<int>(test_case.first)));
auto result = type_singleton(test_case.first);
ASSERT_OK_AND_ASSIGN(auto type, result);
ASSERT_TRUE(type->Equals(*test_case.second))
<< "Failed on type " << test_case.first << ". Expected "
<< test_case.second->ToString() << " but got " << type->ToString();
}
}

TEST(TestTypeSingleton, ParameterizedTypes) {
// Test error cases - parameterized types
std::vector<Type::type> parameterized_types = {
Type::TIMESTAMP, Type::TIME32, Type::TIME64,
Type::DURATION, Type::FIXED_SIZE_BINARY, Type::DECIMAL128,
Type::LIST, Type::LARGE_LIST, Type::FIXED_SIZE_LIST,
Type::STRUCT, Type::DICTIONARY, Type::MAP,
Type::EXTENSION
};

for (const auto type_id : parameterized_types) {
SCOPED_TRACE("Testing type: " + std::to_string(static_cast<int>(type_id)));
auto result = type_singleton(type_id);
ASSERT_FALSE(result.ok());
const auto& status = result.status();
EXPECT_THAT(status.message(), testing::HasSubstr("is not a parameter-free singleton type"));
}
}

TEST(TestTypeSingleton, InvalidType) {
// Test with an invalid type ID
auto result = type_singleton(static_cast<Type::type>(9999));
ASSERT_FALSE(result.ok());
const auto& status = result.status();
EXPECT_THAT(status.message(), testing::HasSubstr("requires parameters or is not supported"));
}

template <typename ReprFunc>
void CheckTypeIdReprs(ReprFunc&& repr_func, bool expect_uppercase) {
std::unordered_set<std::string> unique_reprs;
Expand Down
63 changes: 63 additions & 0 deletions cpp/src/arrow/type_traits.cc
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,73 @@

#include "arrow/type_traits.h"

#include "arrow/result.h"
#include "arrow/status.h"
#include "arrow/type.h"
#include "arrow/util/logging_internal.h"

namespace arrow {

Result<std::shared_ptr<DataType>> type_singleton(Type::type id) {
switch (id) {
case Type::NA:
return null();
case Type::BOOL:
return boolean();
case Type::INT8:
return int8();
case Type::INT16:
return int16();
case Type::INT32:
return int32();
case Type::INT64:
return int64();
case Type::UINT8:
return uint8();
case Type::UINT16:
return uint16();
case Type::UINT32:
return uint32();
case Type::UINT64:
return uint64();
case Type::HALF_FLOAT:
return float16();
case Type::FLOAT:
return float32();
case Type::DOUBLE:
return float64();
case Type::STRING:
return utf8();
case Type::BINARY:
return binary();
case Type::LARGE_STRING:
return large_utf8();
case Type::LARGE_BINARY:
return large_binary();
case Type::DATE32:
return date32();

// Explicitly handle known parameterized types
case Type::TIMESTAMP:
case Type::TIME32:
case Type::TIME64:
case Type::DURATION:
case Type::FIXED_SIZE_BINARY:
case Type::DECIMAL128:
case Type::LIST:
case Type::LARGE_LIST:
case Type::FIXED_SIZE_LIST:
case Type::STRUCT:
case Type::DICTIONARY:
case Type::MAP:
case Type::EXTENSION:
return Status::Invalid("Type ", id, " is not a parameter-free singleton type.");

default:
return Status::Invalid("Type ", id, " requires parameters or is not supported");
}
}

int RequiredValueAlignmentForBuffer(Type::type type_id, int buffer_index) {
if (buffer_index == 2 && type_id == Type::DENSE_UNION) {
// A dense union array is the only array (so far) that requires alignment
Expand Down
15 changes: 15 additions & 0 deletions cpp/src/arrow/type_traits.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,10 @@
#include <type_traits>
#include <vector>

#include "arrow/result.h"
#include "arrow/type.h"
#include "arrow/util/bit_util.h"
#include "arrow/util/macros.h"

namespace arrow {

Expand Down Expand Up @@ -596,6 +598,19 @@ struct TypeTraits<ExtensionType> {
};
/// @}

/// \brief Create a data type instance from a type ID for parameter-free types
///
/// This function creates a data type instance for types that don't require
/// additional parameters (where TypeTraits<T>::is_parameter_free is true).
/// For types that require parameters (like TimestampType or ListType),
/// this function will return an error.
///
/// \param[in] id The type ID to create a type instance for
/// \return Result with a shared pointer to the created DataType instance,
/// or an error if the type requires parameters
ARROW_EXPORT
Result<std::shared_ptr<DataType>> type_singleton(Type::type id);

namespace internal {

template <typename... Ts>
Expand Down
Loading