|
27 | 27 |
|
28 | 28 | namespace iceberg { |
29 | 29 |
|
30 | | -TypeId BooleanType::type_id() const { return TypeId::kBoolean; } |
31 | | -std::string BooleanType::ToString() const { return "boolean"; } |
32 | | -bool BooleanType::Equals(const Type& other) const { |
33 | | - return other.type_id() == TypeId::kBoolean; |
34 | | -} |
35 | | - |
36 | | -TypeId IntType::type_id() const { return TypeId::kInt; } |
37 | | -std::string IntType::ToString() const { return "int"; } |
38 | | -bool IntType::Equals(const Type& other) const { return other.type_id() == TypeId::kInt; } |
39 | | - |
40 | | -TypeId LongType::type_id() const { return TypeId::kLong; } |
41 | | -std::string LongType::ToString() const { return "long"; } |
42 | | -bool LongType::Equals(const Type& other) const { |
43 | | - return other.type_id() == TypeId::kLong; |
44 | | -} |
45 | | - |
46 | | -TypeId FloatType::type_id() const { return TypeId::kFloat; } |
47 | | -std::string FloatType::ToString() const { return "float"; } |
48 | | -bool FloatType::Equals(const Type& other) const { |
49 | | - return other.type_id() == TypeId::kFloat; |
50 | | -} |
51 | | - |
52 | | -TypeId DoubleType::type_id() const { return TypeId::kDouble; } |
53 | | -std::string DoubleType::ToString() const { return "double"; } |
54 | | -bool DoubleType::Equals(const Type& other) const { |
55 | | - return other.type_id() == TypeId::kDouble; |
56 | | -} |
| 30 | +StructType::StructType(std::vector<SchemaField> fields) : fields_(std::move(fields)) { |
| 31 | + size_t index = 0; |
| 32 | + for (const auto& field : fields_) { |
| 33 | + auto [it, inserted] = field_id_to_index_.try_emplace(field.field_id(), index); |
| 34 | + if (!inserted) { |
| 35 | + throw std::runtime_error( |
| 36 | + std::format("StructType: duplicate field ID {} (field indices {} and {})", |
| 37 | + field.field_id(), it->second, index)); |
| 38 | + } |
57 | 39 |
|
58 | | -DecimalType::DecimalType(int32_t precision, int32_t scale) |
59 | | - : precision_(precision), scale_(scale) { |
60 | | - if (precision < 0 || precision > kMaxPrecision) { |
61 | | - throw std::runtime_error( |
62 | | - std::format("DecimalType: precision must be in [0, 38], was {}", precision)); |
| 40 | + ++index; |
63 | 41 | } |
64 | 42 | } |
65 | 43 |
|
66 | | -int32_t DecimalType::precision() const { return precision_; } |
67 | | -int32_t DecimalType::scale() const { return scale_; } |
68 | | -TypeId DecimalType::type_id() const { return TypeId::kDecimal; } |
69 | | -std::string DecimalType::ToString() const { |
70 | | - return std::format("decimal({}, {})", precision_, scale_); |
71 | | -} |
72 | | -bool DecimalType::Equals(const Type& other) const { |
73 | | - if (other.type_id() != TypeId::kDecimal) { |
74 | | - return false; |
| 44 | +TypeId StructType::type_id() const { return TypeId::kStruct; } |
| 45 | +std::string StructType::ToString() const { |
| 46 | + std::string repr = "struct<\n"; |
| 47 | + for (const auto& field : fields_) { |
| 48 | + std::format_to(std::back_inserter(repr), " {}\n", field); |
75 | 49 | } |
76 | | - const auto& decimal = static_cast<const DecimalType&>(other); |
77 | | - return precision_ == decimal.precision_ && scale_ == decimal.scale_; |
78 | | -} |
79 | | - |
80 | | -TypeId TimeType::type_id() const { return TypeId::kTime; } |
81 | | -std::string TimeType::ToString() const { return "time"; } |
82 | | -bool TimeType::Equals(const Type& other) const { |
83 | | - return other.type_id() == TypeId::kTime; |
84 | | -} |
85 | | - |
86 | | -TypeId DateType::type_id() const { return TypeId::kDate; } |
87 | | -std::string DateType::ToString() const { return "date"; } |
88 | | -bool DateType::Equals(const Type& other) const { |
89 | | - return other.type_id() == TypeId::kDate; |
90 | | -} |
91 | | - |
92 | | -bool TimestampType::is_zoned() const { return false; } |
93 | | -TimeUnit TimestampType::time_unit() const { return TimeUnit::kMicrosecond; } |
94 | | -TypeId TimestampType::type_id() const { return TypeId::kTimestamp; } |
95 | | -std::string TimestampType::ToString() const { return "timestamp"; } |
96 | | -bool TimestampType::Equals(const Type& other) const { |
97 | | - return other.type_id() == TypeId::kTimestamp; |
98 | | -} |
99 | | - |
100 | | -bool TimestampTzType::is_zoned() const { return true; } |
101 | | -TimeUnit TimestampTzType::time_unit() const { return TimeUnit::kMicrosecond; } |
102 | | -TypeId TimestampTzType::type_id() const { return TypeId::kTimestampTz; } |
103 | | -std::string TimestampTzType::ToString() const { return "timestamptz"; } |
104 | | -bool TimestampTzType::Equals(const Type& other) const { |
105 | | - return other.type_id() == TypeId::kTimestampTz; |
| 50 | + repr += ">"; |
| 51 | + return repr; |
106 | 52 | } |
107 | | - |
108 | | -TypeId BinaryType::type_id() const { return TypeId::kBinary; } |
109 | | -std::string BinaryType::ToString() const { return "binary"; } |
110 | | -bool BinaryType::Equals(const Type& other) const { |
111 | | - return other.type_id() == TypeId::kBinary; |
| 53 | +std::span<const SchemaField> StructType::fields() const { return fields_; } |
| 54 | +std::optional<std::reference_wrapper<const SchemaField>> StructType::GetFieldById( |
| 55 | + int32_t field_id) const { |
| 56 | + auto it = field_id_to_index_.find(field_id); |
| 57 | + if (it == field_id_to_index_.end()) return std::nullopt; |
| 58 | + return fields_[it->second]; |
112 | 59 | } |
113 | | - |
114 | | -TypeId StringType::type_id() const { return TypeId::kString; } |
115 | | -std::string StringType::ToString() const { return "string"; } |
116 | | -bool StringType::Equals(const Type& other) const { |
117 | | - return other.type_id() == TypeId::kString; |
| 60 | +std::optional<std::reference_wrapper<const SchemaField>> StructType::GetFieldByIndex( |
| 61 | + int32_t index) const { |
| 62 | + if (index < 0 || index >= static_cast<int>(fields_.size())) { |
| 63 | + return std::nullopt; |
| 64 | + } |
| 65 | + return fields_[index]; |
118 | 66 | } |
119 | | - |
120 | | -FixedType::FixedType(int32_t length) : length_(length) { |
121 | | - if (length < 0) { |
122 | | - throw std::runtime_error( |
123 | | - std::format("FixedType: length must be >= 0, was {}", length)); |
| 67 | +std::optional<std::reference_wrapper<const SchemaField>> StructType::GetFieldByName( |
| 68 | + std::string_view name) const { |
| 69 | + // TODO: what is the right behavior if there are duplicate names? (Are |
| 70 | + // duplicate names permitted?) |
| 71 | + for (const auto& field : fields_) { |
| 72 | + if (field.name() == name) { |
| 73 | + return field; |
| 74 | + } |
124 | 75 | } |
| 76 | + return std::nullopt; |
125 | 77 | } |
126 | | - |
127 | | -int32_t FixedType::length() const { return length_; } |
128 | | -TypeId FixedType::type_id() const { return TypeId::kFixed; } |
129 | | -std::string FixedType::ToString() const { return std::format("fixed({})", length_); } |
130 | | -bool FixedType::Equals(const Type& other) const { |
131 | | - if (other.type_id() != TypeId::kFixed) { |
| 78 | +bool StructType::Equals(const Type& other) const { |
| 79 | + if (other.type_id() != TypeId::kStruct) { |
132 | 80 | return false; |
133 | 81 | } |
134 | | - const auto& fixed = static_cast<const FixedType&>(other); |
135 | | - return length_ == fixed.length_; |
136 | | -} |
137 | | - |
138 | | -TypeId UuidType::type_id() const { return TypeId::kUuid; } |
139 | | -std::string UuidType::ToString() const { return "uuid"; } |
140 | | -bool UuidType::Equals(const Type& other) const { |
141 | | - return other.type_id() == TypeId::kUuid; |
| 82 | + const auto& struct_ = static_cast<const StructType&>(other); |
| 83 | + return fields_ == struct_.fields_; |
142 | 84 | } |
143 | 85 |
|
144 | 86 | ListType::ListType(SchemaField element) : element_(std::move(element)) { |
@@ -253,60 +195,118 @@ bool MapType::Equals(const Type& other) const { |
253 | 195 | return fields_ == map.fields_; |
254 | 196 | } |
255 | 197 |
|
256 | | -StructType::StructType(std::vector<SchemaField> fields) : fields_(std::move(fields)) { |
257 | | - size_t index = 0; |
258 | | - for (const auto& field : fields_) { |
259 | | - auto [it, inserted] = field_id_to_index_.try_emplace(field.field_id(), index); |
260 | | - if (!inserted) { |
261 | | - throw std::runtime_error( |
262 | | - std::format("StructType: duplicate field ID {} (field indices {} and {})", |
263 | | - field.field_id(), it->second, index)); |
264 | | - } |
| 198 | +TypeId BooleanType::type_id() const { return TypeId::kBoolean; } |
| 199 | +std::string BooleanType::ToString() const { return "boolean"; } |
| 200 | +bool BooleanType::Equals(const Type& other) const { |
| 201 | + return other.type_id() == TypeId::kBoolean; |
| 202 | +} |
265 | 203 |
|
266 | | - ++index; |
267 | | - } |
| 204 | +TypeId IntType::type_id() const { return TypeId::kInt; } |
| 205 | +std::string IntType::ToString() const { return "int"; } |
| 206 | +bool IntType::Equals(const Type& other) const { return other.type_id() == TypeId::kInt; } |
| 207 | + |
| 208 | +TypeId LongType::type_id() const { return TypeId::kLong; } |
| 209 | +std::string LongType::ToString() const { return "long"; } |
| 210 | +bool LongType::Equals(const Type& other) const { |
| 211 | + return other.type_id() == TypeId::kLong; |
268 | 212 | } |
269 | 213 |
|
270 | | -TypeId StructType::type_id() const { return TypeId::kStruct; } |
271 | | -std::string StructType::ToString() const { |
272 | | - std::string repr = "struct<\n"; |
273 | | - for (const auto& field : fields_) { |
274 | | - std::format_to(std::back_inserter(repr), " {}\n", field); |
| 214 | +TypeId FloatType::type_id() const { return TypeId::kFloat; } |
| 215 | +std::string FloatType::ToString() const { return "float"; } |
| 216 | +bool FloatType::Equals(const Type& other) const { |
| 217 | + return other.type_id() == TypeId::kFloat; |
| 218 | +} |
| 219 | + |
| 220 | +TypeId DoubleType::type_id() const { return TypeId::kDouble; } |
| 221 | +std::string DoubleType::ToString() const { return "double"; } |
| 222 | +bool DoubleType::Equals(const Type& other) const { |
| 223 | + return other.type_id() == TypeId::kDouble; |
| 224 | +} |
| 225 | + |
| 226 | +DecimalType::DecimalType(int32_t precision, int32_t scale) |
| 227 | + : precision_(precision), scale_(scale) { |
| 228 | + if (precision < 0 || precision > kMaxPrecision) { |
| 229 | + throw std::runtime_error( |
| 230 | + std::format("DecimalType: precision must be in [0, 38], was {}", precision)); |
275 | 231 | } |
276 | | - repr += ">"; |
277 | | - return repr; |
278 | 232 | } |
279 | | -std::span<const SchemaField> StructType::fields() const { return fields_; } |
280 | | -std::optional<std::reference_wrapper<const SchemaField>> StructType::GetFieldById( |
281 | | - int32_t field_id) const { |
282 | | - auto it = field_id_to_index_.find(field_id); |
283 | | - if (it == field_id_to_index_.end()) return std::nullopt; |
284 | | - return fields_[it->second]; |
| 233 | + |
| 234 | +int32_t DecimalType::precision() const { return precision_; } |
| 235 | +int32_t DecimalType::scale() const { return scale_; } |
| 236 | +TypeId DecimalType::type_id() const { return TypeId::kDecimal; } |
| 237 | +std::string DecimalType::ToString() const { |
| 238 | + return std::format("decimal({}, {})", precision_, scale_); |
285 | 239 | } |
286 | | -std::optional<std::reference_wrapper<const SchemaField>> StructType::GetFieldByIndex( |
287 | | - int32_t index) const { |
288 | | - if (index < 0 || index >= static_cast<int>(fields_.size())) { |
289 | | - return std::nullopt; |
| 240 | +bool DecimalType::Equals(const Type& other) const { |
| 241 | + if (other.type_id() != TypeId::kDecimal) { |
| 242 | + return false; |
290 | 243 | } |
291 | | - return fields_[index]; |
| 244 | + const auto& decimal = static_cast<const DecimalType&>(other); |
| 245 | + return precision_ == decimal.precision_ && scale_ == decimal.scale_; |
292 | 246 | } |
293 | | -std::optional<std::reference_wrapper<const SchemaField>> StructType::GetFieldByName( |
294 | | - std::string_view name) const { |
295 | | - // TODO: what is the right behavior if there are duplicate names? (Are |
296 | | - // duplicate names permitted?) |
297 | | - for (const auto& field : fields_) { |
298 | | - if (field.name() == name) { |
299 | | - return field; |
300 | | - } |
| 247 | + |
| 248 | +TypeId DateType::type_id() const { return TypeId::kDate; } |
| 249 | +std::string DateType::ToString() const { return "date"; } |
| 250 | +bool DateType::Equals(const Type& other) const { |
| 251 | + return other.type_id() == TypeId::kDate; |
| 252 | +} |
| 253 | + |
| 254 | +TypeId TimeType::type_id() const { return TypeId::kTime; } |
| 255 | +std::string TimeType::ToString() const { return "time"; } |
| 256 | +bool TimeType::Equals(const Type& other) const { |
| 257 | + return other.type_id() == TypeId::kTime; |
| 258 | +} |
| 259 | + |
| 260 | +bool TimestampType::is_zoned() const { return false; } |
| 261 | +TimeUnit TimestampType::time_unit() const { return TimeUnit::kMicrosecond; } |
| 262 | +TypeId TimestampType::type_id() const { return TypeId::kTimestamp; } |
| 263 | +std::string TimestampType::ToString() const { return "timestamp"; } |
| 264 | +bool TimestampType::Equals(const Type& other) const { |
| 265 | + return other.type_id() == TypeId::kTimestamp; |
| 266 | +} |
| 267 | + |
| 268 | +bool TimestampTzType::is_zoned() const { return true; } |
| 269 | +TimeUnit TimestampTzType::time_unit() const { return TimeUnit::kMicrosecond; } |
| 270 | +TypeId TimestampTzType::type_id() const { return TypeId::kTimestampTz; } |
| 271 | +std::string TimestampTzType::ToString() const { return "timestamptz"; } |
| 272 | +bool TimestampTzType::Equals(const Type& other) const { |
| 273 | + return other.type_id() == TypeId::kTimestampTz; |
| 274 | +} |
| 275 | + |
| 276 | +TypeId StringType::type_id() const { return TypeId::kString; } |
| 277 | +std::string StringType::ToString() const { return "string"; } |
| 278 | +bool StringType::Equals(const Type& other) const { |
| 279 | + return other.type_id() == TypeId::kString; |
| 280 | +} |
| 281 | + |
| 282 | +TypeId UuidType::type_id() const { return TypeId::kUuid; } |
| 283 | +std::string UuidType::ToString() const { return "uuid"; } |
| 284 | +bool UuidType::Equals(const Type& other) const { |
| 285 | + return other.type_id() == TypeId::kUuid; |
| 286 | +} |
| 287 | + |
| 288 | +FixedType::FixedType(int32_t length) : length_(length) { |
| 289 | + if (length < 0) { |
| 290 | + throw std::runtime_error( |
| 291 | + std::format("FixedType: length must be >= 0, was {}", length)); |
301 | 292 | } |
302 | | - return std::nullopt; |
303 | 293 | } |
304 | | -bool StructType::Equals(const Type& other) const { |
305 | | - if (other.type_id() != TypeId::kStruct) { |
| 294 | + |
| 295 | +int32_t FixedType::length() const { return length_; } |
| 296 | +TypeId FixedType::type_id() const { return TypeId::kFixed; } |
| 297 | +std::string FixedType::ToString() const { return std::format("fixed({})", length_); } |
| 298 | +bool FixedType::Equals(const Type& other) const { |
| 299 | + if (other.type_id() != TypeId::kFixed) { |
306 | 300 | return false; |
307 | 301 | } |
308 | | - const auto& struct_ = static_cast<const StructType&>(other); |
309 | | - return fields_ == struct_.fields_; |
| 302 | + const auto& fixed = static_cast<const FixedType&>(other); |
| 303 | + return length_ == fixed.length_; |
| 304 | +} |
| 305 | + |
| 306 | +TypeId BinaryType::type_id() const { return TypeId::kBinary; } |
| 307 | +std::string BinaryType::ToString() const { return "binary"; } |
| 308 | +bool BinaryType::Equals(const Type& other) const { |
| 309 | + return other.type_id() == TypeId::kBinary; |
310 | 310 | } |
311 | 311 |
|
312 | 312 | } // namespace iceberg |
0 commit comments