Skip to content

Commit a171977

Browse files
ARROW-46531: [C++] Add type_singleton utility function and corresponding tests
1 parent 8dd9eba commit a171977

File tree

3 files changed

+140
-0
lines changed

3 files changed

+140
-0
lines changed

cpp/src/arrow/type_test.cc

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,10 +32,12 @@
3232
#include "arrow/memory_pool.h"
3333
#include "arrow/table.h"
3434
#include "arrow/testing/gtest_util.h"
35+
#include "arrow/testing/matchers.h"
3536
#include "arrow/testing/random.h"
3637
#include "arrow/testing/util.h"
3738
#include "arrow/type.h"
3839
#include "arrow/type_traits.h"
40+
#include "arrow/util/logging.h"
3941
#include "arrow/util/checked_cast.h"
4042
#include "arrow/util/key_value_metadata.h"
4143

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

54+
TEST(TestTypeSingleton, ParameterFreeTypes) {
55+
// Test successful cases - parameter-free types
56+
std::vector<std::pair<Type::type, std::shared_ptr<DataType>>> cases = {
57+
{Type::NA, null()},
58+
{Type::BOOL, boolean()},
59+
{Type::INT8, int8()},
60+
{Type::INT16, int16()},
61+
{Type::INT32, int32()},
62+
{Type::INT64, int64()},
63+
{Type::UINT8, uint8()},
64+
{Type::UINT16, uint16()},
65+
{Type::UINT32, uint32()},
66+
{Type::UINT64, uint64()},
67+
{Type::HALF_FLOAT, float16()},
68+
{Type::FLOAT, float32()},
69+
{Type::DOUBLE, float64()},
70+
{Type::STRING, utf8()},
71+
{Type::BINARY, binary()},
72+
{Type::LARGE_STRING, large_utf8()},
73+
{Type::LARGE_BINARY, large_binary()},
74+
{Type::DATE32, date32()},
75+
};
76+
77+
for (const auto& test_case : cases) {
78+
SCOPED_TRACE("Testing type: " + std::to_string(static_cast<int>(test_case.first)));
79+
auto result = type_singleton(test_case.first);
80+
ASSERT_OK_AND_ASSIGN(auto type, result);
81+
ASSERT_TRUE(type->Equals(*test_case.second))
82+
<< "Failed on type " << test_case.first << ". Expected "
83+
<< test_case.second->ToString() << " but got " << type->ToString();
84+
}
85+
}
86+
87+
TEST(TestTypeSingleton, ParameterizedTypes) {
88+
// Test error cases - parameterized types
89+
std::vector<Type::type> parameterized_types = {
90+
Type::TIMESTAMP, Type::TIME32, Type::TIME64,
91+
Type::DURATION, Type::FIXED_SIZE_BINARY, Type::DECIMAL128,
92+
Type::LIST, Type::LARGE_LIST, Type::FIXED_SIZE_LIST,
93+
Type::STRUCT, Type::DICTIONARY, Type::MAP,
94+
Type::EXTENSION
95+
};
96+
97+
for (const auto type_id : parameterized_types) {
98+
SCOPED_TRACE("Testing type: " + std::to_string(static_cast<int>(type_id)));
99+
auto result = type_singleton(type_id);
100+
ASSERT_FALSE(result.ok());
101+
const auto& status = result.status();
102+
EXPECT_THAT(status.message(), testing::HasSubstr("is not a parameter-free singleton type"));
103+
}
104+
}
105+
106+
TEST(TestTypeSingleton, InvalidType) {
107+
// Test with an invalid type ID
108+
auto result = type_singleton(static_cast<Type::type>(9999));
109+
ASSERT_FALSE(result.ok());
110+
const auto& status = result.status();
111+
EXPECT_THAT(status.message(), testing::HasSubstr("requires parameters or is not supported"));
112+
}
113+
52114
template <typename ReprFunc>
53115
void CheckTypeIdReprs(ReprFunc&& repr_func, bool expect_uppercase) {
54116
std::unordered_set<std::string> unique_reprs;

cpp/src/arrow/type_traits.cc

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,10 +17,73 @@
1717

1818
#include "arrow/type_traits.h"
1919

20+
#include "arrow/result.h"
21+
#include "arrow/status.h"
22+
#include "arrow/type.h"
2023
#include "arrow/util/logging_internal.h"
2124

2225
namespace arrow {
2326

27+
Result<std::shared_ptr<DataType>> type_singleton(Type::type id) {
28+
switch (id) {
29+
case Type::NA:
30+
return null();
31+
case Type::BOOL:
32+
return boolean();
33+
case Type::INT8:
34+
return int8();
35+
case Type::INT16:
36+
return int16();
37+
case Type::INT32:
38+
return int32();
39+
case Type::INT64:
40+
return int64();
41+
case Type::UINT8:
42+
return uint8();
43+
case Type::UINT16:
44+
return uint16();
45+
case Type::UINT32:
46+
return uint32();
47+
case Type::UINT64:
48+
return uint64();
49+
case Type::HALF_FLOAT:
50+
return float16();
51+
case Type::FLOAT:
52+
return float32();
53+
case Type::DOUBLE:
54+
return float64();
55+
case Type::STRING:
56+
return utf8();
57+
case Type::BINARY:
58+
return binary();
59+
case Type::LARGE_STRING:
60+
return large_utf8();
61+
case Type::LARGE_BINARY:
62+
return large_binary();
63+
case Type::DATE32:
64+
return date32();
65+
66+
// Explicitly handle known parameterized types
67+
case Type::TIMESTAMP:
68+
case Type::TIME32:
69+
case Type::TIME64:
70+
case Type::DURATION:
71+
case Type::FIXED_SIZE_BINARY:
72+
case Type::DECIMAL128:
73+
case Type::LIST:
74+
case Type::LARGE_LIST:
75+
case Type::FIXED_SIZE_LIST:
76+
case Type::STRUCT:
77+
case Type::DICTIONARY:
78+
case Type::MAP:
79+
case Type::EXTENSION:
80+
return Status::Invalid("Type ", id, " is not a parameter-free singleton type.");
81+
82+
default:
83+
return Status::Invalid("Type ", id, " requires parameters or is not supported");
84+
}
85+
}
86+
2487
int RequiredValueAlignmentForBuffer(Type::type type_id, int buffer_index) {
2588
if (buffer_index == 2 && type_id == Type::DENSE_UNION) {
2689
// A dense union array is the only array (so far) that requires alignment

cpp/src/arrow/type_traits.h

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,8 +22,10 @@
2222
#include <type_traits>
2323
#include <vector>
2424

25+
#include "arrow/result.h"
2526
#include "arrow/type.h"
2627
#include "arrow/util/bit_util.h"
28+
#include "arrow/util/macros.h"
2729

2830
namespace arrow {
2931

@@ -596,6 +598,19 @@ struct TypeTraits<ExtensionType> {
596598
};
597599
/// @}
598600

601+
/// \brief Create a data type instance from a type ID for parameter-free types
602+
///
603+
/// This function creates a data type instance for types that don't require
604+
/// additional parameters (where TypeTraits<T>::is_parameter_free is true).
605+
/// For types that require parameters (like TimestampType or ListType),
606+
/// this function will return an error.
607+
///
608+
/// \param[in] id The type ID to create a type instance for
609+
/// \return Result with a shared pointer to the created DataType instance,
610+
/// or an error if the type requires parameters
611+
ARROW_EXPORT
612+
Result<std::shared_ptr<DataType>> type_singleton(Type::type id);
613+
599614
namespace internal {
600615

601616
template <typename... Ts>

0 commit comments

Comments
 (0)