Skip to content

Commit 8e8abdc

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

3 files changed

Lines changed: 140 additions & 0 deletions

File tree

cpp/src/arrow/type_test.cc

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,10 +33,12 @@
3333
#include "arrow/memory_pool.h"
3434
#include "arrow/table.h"
3535
#include "arrow/testing/gtest_util.h"
36+
#include "arrow/testing/matchers.h"
3637
#include "arrow/testing/random.h"
3738
#include "arrow/testing/util.h"
3839
#include "arrow/type.h"
3940
#include "arrow/type_traits.h"
41+
#include "arrow/util/logging.h"
4042
#include "arrow/util/checked_cast.h"
4143
#include "arrow/util/key_value_metadata.h"
4244

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

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