Skip to content

Commit c9205f8

Browse files
committed
refactor: add factory functions for primitive types
1 parent c00ee8f commit c9205f8

File tree

3 files changed

+109
-44
lines changed

3 files changed

+109
-44
lines changed

src/iceberg/type.cc

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121

2222
#include <format>
2323
#include <iterator>
24+
#include <memory>
2425

2526
#include "iceberg/exception.h"
2627
#include "iceberg/util/formatter.h" // IWYU pragma: keep
@@ -286,4 +287,36 @@ TypeId BinaryType::type_id() const { return kTypeId; }
286287
std::string BinaryType::ToString() const { return "binary"; }
287288
bool BinaryType::Equals(const Type& other) const { return other.type_id() == kTypeId; }
288289

290+
// ----------------------------------------------------------------------
291+
// Factory functions for creating primitive data types
292+
293+
#define TYPE_FACTORY(NAME, KLASS) \
294+
const std::shared_ptr<KLASS>& NAME() { \
295+
static std::shared_ptr<KLASS> result = std::make_shared<KLASS>(); \
296+
return result; \
297+
}
298+
299+
TYPE_FACTORY(boolean, BooleanType)
300+
TYPE_FACTORY(int32, IntType)
301+
TYPE_FACTORY(int64, LongType)
302+
TYPE_FACTORY(float32, FloatType)
303+
TYPE_FACTORY(float64, DoubleType)
304+
TYPE_FACTORY(date, DateType)
305+
TYPE_FACTORY(time, TimeType)
306+
TYPE_FACTORY(timestamp, TimestampType)
307+
TYPE_FACTORY(timestamp_tz, TimestampTzType)
308+
TYPE_FACTORY(binary, BinaryType)
309+
TYPE_FACTORY(string, StringType)
310+
TYPE_FACTORY(uuid, UuidType)
311+
312+
#undef TYPE_FACTORY
313+
314+
std::shared_ptr<DecimalType> decimal(int32_t precision, int32_t scale) {
315+
return std::make_shared<DecimalType>(precision, scale);
316+
}
317+
318+
std::shared_ptr<FixedType> fixed(int32_t length) {
319+
return std::make_shared<FixedType>(length);
320+
}
321+
289322
} // namespace iceberg

src/iceberg/type.h

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -446,4 +446,48 @@ class ICEBERG_EXPORT UuidType : public PrimitiveType {
446446

447447
/// @}
448448

449+
/// \defgroup type-factories Factory functions for creating primitive data types
450+
///
451+
/// Factory functions for creating primitive data types
452+
/// @{
453+
454+
/// \brief Return a BooleanType instance.
455+
ICEBERG_EXPORT const std::shared_ptr<BooleanType>& boolean();
456+
/// \brief Return an IntType instance.
457+
ICEBERG_EXPORT const std::shared_ptr<IntType>& int32();
458+
/// \brief Return a LongType instance.
459+
ICEBERG_EXPORT const std::shared_ptr<LongType>& int64();
460+
/// \brief Return a FloatType instance.
461+
ICEBERG_EXPORT const std::shared_ptr<FloatType>& float32();
462+
/// \brief Return a DoubleType instance.
463+
ICEBERG_EXPORT const std::shared_ptr<DoubleType>& float64();
464+
/// \brief Return a DateType instance.
465+
ICEBERG_EXPORT const std::shared_ptr<DateType>& date();
466+
/// \brief Return a TimeType instance.
467+
ICEBERG_EXPORT const std::shared_ptr<TimeType>& time();
468+
/// \brief Return a TimestampType instance.
469+
ICEBERG_EXPORT const std::shared_ptr<TimestampType>& timestamp();
470+
/// \brief Return a TimestampTzType instance.
471+
ICEBERG_EXPORT const std::shared_ptr<TimestampTzType>& timestamp_tz();
472+
/// \brief Return a BinaryType instance.
473+
ICEBERG_EXPORT const std::shared_ptr<BinaryType>& binary();
474+
/// \brief Return a StringType instance.
475+
ICEBERG_EXPORT const std::shared_ptr<StringType>& string();
476+
/// \brief Return a UuidType instance.
477+
ICEBERG_EXPORT const std::shared_ptr<UuidType>& uuid();
478+
479+
/// \brief Create a DecimalType with the given precision and scale.
480+
/// \param precision The number of decimal digits (max 38).
481+
/// \param scale The number of decimal digits after the decimal point (0 to
482+
/// precision).
483+
/// \return A shared pointer to the DecimalType instance.
484+
ICEBERG_EXPORT std::shared_ptr<DecimalType> decimal(int32_t precision, int32_t scale);
485+
486+
/// \brief Create a FixedType with the given length.
487+
/// \param length The number of bytes to store (must be >= 0).
488+
/// \return A shared pointer to the FixedType instance.
489+
ICEBERG_EXPORT std::shared_ptr<FixedType> fixed(int32_t length);
490+
491+
/// @}
492+
449493
} // namespace iceberg

test/type_test.cc

Lines changed: 32 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,6 @@
2121

2222
#include <format>
2323
#include <memory>
24-
#include <stdexcept>
2524
#include <string>
2625

2726
#include <gmock/gmock.h>
@@ -91,112 +90,112 @@ TEST_P(TypeTest, StdFormat) {
9190
const static std::array<TypeTestCase, 16> kPrimitiveTypes = {{
9291
{
9392
.name = "boolean",
94-
.type = std::make_shared<iceberg::BooleanType>(),
93+
.type = iceberg::boolean(),
9594
.type_id = iceberg::TypeId::kBoolean,
9695
.primitive = true,
9796
.repr = "boolean",
9897
},
9998
{
10099
.name = "int",
101-
.type = std::make_shared<iceberg::IntType>(),
100+
.type = iceberg::int32(),
102101
.type_id = iceberg::TypeId::kInt,
103102
.primitive = true,
104103
.repr = "int",
105104
},
106105
{
107106
.name = "long",
108-
.type = std::make_shared<iceberg::LongType>(),
107+
.type = iceberg::int64(),
109108
.type_id = iceberg::TypeId::kLong,
110109
.primitive = true,
111110
.repr = "long",
112111
},
113112
{
114113
.name = "float",
115-
.type = std::make_shared<iceberg::FloatType>(),
114+
.type = iceberg::float32(),
116115
.type_id = iceberg::TypeId::kFloat,
117116
.primitive = true,
118117
.repr = "float",
119118
},
120119
{
121120
.name = "double",
122-
.type = std::make_shared<iceberg::DoubleType>(),
121+
.type = iceberg::float64(),
123122
.type_id = iceberg::TypeId::kDouble,
124123
.primitive = true,
125124
.repr = "double",
126125
},
127126
{
128127
.name = "decimal9_2",
129-
.type = std::make_shared<iceberg::DecimalType>(9, 2),
128+
.type = iceberg::decimal(9, 2),
130129
.type_id = iceberg::TypeId::kDecimal,
131130
.primitive = true,
132131
.repr = "decimal(9, 2)",
133132
},
134133
{
135134
.name = "decimal38_10",
136-
.type = std::make_shared<iceberg::DecimalType>(38, 10),
135+
.type = iceberg::decimal(38, 10),
137136
.type_id = iceberg::TypeId::kDecimal,
138137
.primitive = true,
139138
.repr = "decimal(38, 10)",
140139
},
141140
{
142141
.name = "date",
143-
.type = std::make_shared<iceberg::DateType>(),
142+
.type = iceberg::date(),
144143
.type_id = iceberg::TypeId::kDate,
145144
.primitive = true,
146145
.repr = "date",
147146
},
148147
{
149148
.name = "time",
150-
.type = std::make_shared<iceberg::TimeType>(),
149+
.type = iceberg::time(),
151150
.type_id = iceberg::TypeId::kTime,
152151
.primitive = true,
153152
.repr = "time",
154153
},
155154
{
156155
.name = "timestamp",
157-
.type = std::make_shared<iceberg::TimestampType>(),
156+
.type = iceberg::timestamp(),
158157
.type_id = iceberg::TypeId::kTimestamp,
159158
.primitive = true,
160159
.repr = "timestamp",
161160
},
162161
{
163162
.name = "timestamptz",
164-
.type = std::make_shared<iceberg::TimestampTzType>(),
163+
.type = iceberg::timestamp_tz(),
165164
.type_id = iceberg::TypeId::kTimestampTz,
166165
.primitive = true,
167166
.repr = "timestamptz",
168167
},
169168
{
170169
.name = "binary",
171-
.type = std::make_shared<iceberg::BinaryType>(),
170+
.type = iceberg::binary(),
172171
.type_id = iceberg::TypeId::kBinary,
173172
.primitive = true,
174173
.repr = "binary",
175174
},
176175
{
177176
.name = "string",
178-
.type = std::make_shared<iceberg::StringType>(),
177+
.type = iceberg::string(),
179178
.type_id = iceberg::TypeId::kString,
180179
.primitive = true,
181180
.repr = "string",
182181
},
183182
{
184183
.name = "fixed10",
185-
.type = std::make_shared<iceberg::FixedType>(10),
184+
.type = iceberg::fixed(10),
186185
.type_id = iceberg::TypeId::kFixed,
187186
.primitive = true,
188187
.repr = "fixed(10)",
189188
},
190189
{
191190
.name = "fixed255",
192-
.type = std::make_shared<iceberg::FixedType>(255),
191+
.type = iceberg::fixed(255),
193192
.type_id = iceberg::TypeId::kFixed,
194193
.primitive = true,
195194
.repr = "fixed(255)",
196195
},
197196
{
198197
.name = "uuid",
199-
.type = std::make_shared<iceberg::UuidType>(),
198+
.type = iceberg::uuid(),
200199
.type_id = iceberg::TypeId::kUuid,
201200
.primitive = true,
202201
.repr = "uuid",
@@ -206,41 +205,33 @@ const static std::array<TypeTestCase, 16> kPrimitiveTypes = {{
206205
const static std::array<TypeTestCase, 4> kNestedTypes = {{
207206
{
208207
.name = "list_int",
209-
.type = std::make_shared<iceberg::ListType>(
210-
1, std::make_shared<iceberg::IntType>(), true),
208+
.type = std::make_shared<iceberg::ListType>(1, iceberg::int32(), true),
211209
.type_id = iceberg::TypeId::kList,
212210
.primitive = false,
213211
.repr = "list<element (1): int (optional)>",
214212
},
215213
{
216214
.name = "list_list_int",
217215
.type = std::make_shared<iceberg::ListType>(
218-
1,
219-
std::make_shared<iceberg::ListType>(2, std::make_shared<iceberg::IntType>(),
220-
true),
221-
false),
216+
1, std::make_shared<iceberg::ListType>(2, iceberg::int32(), true), false),
222217
.type_id = iceberg::TypeId::kList,
223218
.primitive = false,
224219
.repr = "list<element (1): list<element (2): int (optional)> (required)>",
225220
},
226221
{
227222
.name = "map_int_string",
228223
.type = std::make_shared<iceberg::MapType>(
229-
iceberg::SchemaField::MakeRequired(1, "key",
230-
std::make_shared<iceberg::LongType>()),
231-
iceberg::SchemaField::MakeRequired(2, "value",
232-
std::make_shared<iceberg::StringType>())),
224+
iceberg::SchemaField::MakeRequired(1, "key", iceberg::int64()),
225+
iceberg::SchemaField::MakeRequired(2, "value", iceberg::string())),
233226
.type_id = iceberg::TypeId::kMap,
234227
.primitive = false,
235228
.repr = "map<key (1): long (required): value (2): string (required)>",
236229
},
237230
{
238231
.name = "struct",
239232
.type = std::make_shared<iceberg::StructType>(std::vector<iceberg::SchemaField>{
240-
iceberg::SchemaField::MakeRequired(1, "foo",
241-
std::make_shared<iceberg::LongType>()),
242-
iceberg::SchemaField::MakeOptional(2, "bar",
243-
std::make_shared<iceberg::StringType>()),
233+
iceberg::SchemaField::MakeRequired(1, "foo", iceberg::int64()),
234+
iceberg::SchemaField::MakeOptional(2, "bar", iceberg::string()),
244235
}),
245236
.type_id = iceberg::TypeId::kStruct,
246237
.primitive = false,
@@ -344,8 +335,8 @@ TEST(TypeTest, List) {
344335

345336
TEST(TypeTest, Map) {
346337
{
347-
iceberg::SchemaField key(5, "key", std::make_shared<iceberg::IntType>(), true);
348-
iceberg::SchemaField value(7, "value", std::make_shared<iceberg::StringType>(), true);
338+
iceberg::SchemaField key(5, "key", iceberg::int32(), true);
339+
iceberg::SchemaField value(7, "value", iceberg::string(), true);
349340
iceberg::MapType map(key, value);
350341
std::span<const iceberg::SchemaField> fields = map.fields();
351342
ASSERT_EQ(2, fields.size());
@@ -365,18 +356,16 @@ TEST(TypeTest, Map) {
365356
}
366357
ASSERT_THAT(
367358
[]() {
368-
iceberg::SchemaField key(5, "notkey", std::make_shared<iceberg::IntType>(), true);
369-
iceberg::SchemaField value(7, "value", std::make_shared<iceberg::StringType>(),
370-
true);
359+
iceberg::SchemaField key(5, "notkey", iceberg::int32(), true);
360+
iceberg::SchemaField value(7, "value", iceberg::string(), true);
371361
iceberg::MapType map(key, value);
372362
},
373363
::testing::ThrowsMessage<iceberg::IcebergError>(
374364
::testing::HasSubstr("key field name should be 'key', was 'notkey'")));
375365
ASSERT_THAT(
376366
[]() {
377-
iceberg::SchemaField key(5, "key", std::make_shared<iceberg::IntType>(), true);
378-
iceberg::SchemaField value(7, "notvalue", std::make_shared<iceberg::StringType>(),
379-
true);
367+
iceberg::SchemaField key(5, "key", iceberg::int32(), true);
368+
iceberg::SchemaField value(7, "notvalue", iceberg::string(), true);
380369
iceberg::MapType map(key, value);
381370
},
382371
::testing::ThrowsMessage<iceberg::IcebergError>(
@@ -385,8 +374,8 @@ TEST(TypeTest, Map) {
385374

386375
TEST(TypeTest, Struct) {
387376
{
388-
iceberg::SchemaField field1(5, "foo", std::make_shared<iceberg::IntType>(), true);
389-
iceberg::SchemaField field2(7, "bar", std::make_shared<iceberg::StringType>(), true);
377+
iceberg::SchemaField field1(5, "foo", iceberg::int32(), true);
378+
iceberg::SchemaField field2(7, "bar", iceberg::string(), true);
390379
iceberg::StructType struct_({field1, field2});
391380
std::span<const iceberg::SchemaField> fields = struct_.fields();
392381
ASSERT_EQ(2, fields.size());
@@ -406,9 +395,8 @@ TEST(TypeTest, Struct) {
406395
}
407396
ASSERT_THAT(
408397
[]() {
409-
iceberg::SchemaField field1(5, "foo", std::make_shared<iceberg::IntType>(), true);
410-
iceberg::SchemaField field2(5, "bar", std::make_shared<iceberg::StringType>(),
411-
true);
398+
iceberg::SchemaField field1(5, "foo", iceberg::int32(), true);
399+
iceberg::SchemaField field2(5, "bar", iceberg::string(), true);
412400
iceberg::StructType struct_({field1, field2});
413401
},
414402
::testing::ThrowsMessage<iceberg::IcebergError>(

0 commit comments

Comments
 (0)