2727
2828namespace iceberg {
2929
30- // Constructor
31- PrimitiveLiteral::PrimitiveLiteral (PrimitiveLiteralValue value,
32- std::shared_ptr<PrimitiveType> type)
33- : value_(std::move(value)), type_(std::move(type)) {}
34-
35- // Factory methods
36- PrimitiveLiteral PrimitiveLiteral::Boolean (bool value) {
37- return {PrimitiveLiteralValue{value}, std::make_shared<BooleanType>()};
38- }
39-
40- PrimitiveLiteral PrimitiveLiteral::Int (int32_t value) {
41- return {PrimitiveLiteralValue{value}, std::make_shared<IntType>()};
42- }
43-
44- PrimitiveLiteral PrimitiveLiteral::Long (int64_t value) {
45- return {PrimitiveLiteralValue{value}, std::make_shared<LongType>()};
46- }
47-
48- PrimitiveLiteral PrimitiveLiteral::Float (float value) {
49- return {PrimitiveLiteralValue{value}, std::make_shared<FloatType>()};
50- }
51-
52- PrimitiveLiteral PrimitiveLiteral::Double (double value) {
53- return {PrimitiveLiteralValue{value}, std::make_shared<DoubleType>()};
30+ // / \brief PrimitiveLiteralCaster handles type casting operations for PrimitiveLiteral.
31+ // / This is an internal implementation class.
32+ class PrimitiveLiteralCaster {
33+ public:
34+ // / Cast a PrimitiveLiteral to the target type.
35+ static Result<PrimitiveLiteral> CastTo (
36+ const PrimitiveLiteral& literal, const std::shared_ptr<PrimitiveType>& target_type);
37+
38+ // / Create a literal representing a value below the minimum for the given type.
39+ static PrimitiveLiteral BelowMinLiteral (std::shared_ptr<PrimitiveType> type);
40+
41+ // / Create a literal representing a value above the maximum for the given type.
42+ static PrimitiveLiteral AboveMaxLiteral (std::shared_ptr<PrimitiveType> type);
43+
44+ private:
45+ // / Cast from Int type to target type.
46+ static Result<PrimitiveLiteral> CastFromInt (
47+ const PrimitiveLiteral& literal, const std::shared_ptr<PrimitiveType>& target_type);
48+
49+ // / Cast from Long type to target type.
50+ static Result<PrimitiveLiteral> CastFromLong (
51+ const PrimitiveLiteral& literal, const std::shared_ptr<PrimitiveType>& target_type);
52+
53+ // / Cast from Float type to target type.
54+ static Result<PrimitiveLiteral> CastFromFloat (
55+ const PrimitiveLiteral& literal, const std::shared_ptr<PrimitiveType>& target_type);
56+ };
57+
58+ PrimitiveLiteral PrimitiveLiteralCaster::BelowMinLiteral (
59+ std::shared_ptr<PrimitiveType> type) {
60+ return PrimitiveLiteral (PrimitiveLiteral::BelowMin{}, std::move (type));
5461}
5562
56- PrimitiveLiteral PrimitiveLiteral::String (std::string value) {
57- return {PrimitiveLiteralValue{std::move (value)}, std::make_shared<StringType>()};
63+ PrimitiveLiteral PrimitiveLiteralCaster::AboveMaxLiteral (
64+ std::shared_ptr<PrimitiveType> type) {
65+ return PrimitiveLiteral (PrimitiveLiteral::AboveMax{}, std::move (type));
5866}
5967
60- PrimitiveLiteral PrimitiveLiteral::Binary (std::vector<uint8_t > value) {
61- return {PrimitiveLiteralValue{std::move (value)}, std::make_shared<BinaryType>()};
62- }
63-
64- PrimitiveLiteral PrimitiveLiteral::BelowMinLiteral (std::shared_ptr<PrimitiveType> type) {
65- return {PrimitiveLiteralValue{BelowMin{}}, std::move (type)};
66- }
67-
68- PrimitiveLiteral PrimitiveLiteral::AboveMaxLiteral (std::shared_ptr<PrimitiveType> type) {
69- return {PrimitiveLiteralValue{AboveMax{}}, std::move (type)};
70- }
71-
72- Result<PrimitiveLiteral> PrimitiveLiteral::Deserialize (std::span<const uint8_t > data) {
73- return NotImplemented (" Deserialization of PrimitiveLiteral is not implemented yet" );
74- }
75-
76- Result<std::vector<uint8_t >> PrimitiveLiteral::Serialize () const {
77- return NotImplemented (" Serialization of PrimitiveLiteral is not implemented yet" );
78- }
79-
80- // Getters
81-
82- const std::shared_ptr<PrimitiveType>& PrimitiveLiteral::type () const { return type_; }
83-
84- // Cast method
85- Result<PrimitiveLiteral> PrimitiveLiteral::CastTo (
86- const std::shared_ptr<PrimitiveType>& target_type) const {
87- if (*type_ == *target_type) {
88- // If types are the same, return a copy of the current literal
89- return PrimitiveLiteral (value_, target_type);
90- }
91-
92- // Handle special values
93- if (std::holds_alternative<BelowMin>(value_) ||
94- std::holds_alternative<AboveMax>(value_)) {
95- // Cannot cast type for special values
96- return NotSupported (" Cannot cast type for {}" , ToString ());
97- }
98-
99- auto source_type_id = type_->type_id ();
68+ Result<PrimitiveLiteral> PrimitiveLiteralCaster::CastFromInt (
69+ const PrimitiveLiteral& literal, const std::shared_ptr<PrimitiveType>& target_type) {
70+ auto int_val = std::get<int32_t >(literal.value_ );
10071 auto target_type_id = target_type->type_id ();
10172
102- // Delegate to specific cast functions based on source type
103- switch (source_type_id) {
104- case TypeId::kInt :
105- return CastFromInt (target_type_id);
106- case TypeId::kLong :
107- return CastFromLong (target_type_id);
108- case TypeId::kFloat :
109- return CastFromFloat (target_type_id);
110- case TypeId::kDouble :
111- case TypeId::kBoolean :
112- case TypeId::kString :
113- case TypeId::kBinary :
114- break ;
115- default :
116- break ;
117- }
118-
119- return NotSupported (" Cast from {} to {} is not implemented" , type_->ToString (),
120- target_type->ToString ());
121- }
122-
123- Result<PrimitiveLiteral> PrimitiveLiteral::CastFromInt (TypeId target_type_id) const {
124- auto int_val = std::get<int32_t >(value_);
125-
12673 switch (target_type_id) {
12774 case TypeId::kLong :
12875 return PrimitiveLiteral::Long (static_cast <int64_t >(int_val));
@@ -137,17 +84,19 @@ Result<PrimitiveLiteral> PrimitiveLiteral::CastFromInt(TypeId target_type_id) co
13784 }
13885}
13986
140- Result<PrimitiveLiteral> PrimitiveLiteral::CastFromLong (TypeId target_type_id) const {
141- auto long_val = std::get<int64_t >(value_);
87+ Result<PrimitiveLiteral> PrimitiveLiteralCaster::CastFromLong (
88+ const PrimitiveLiteral& literal, const std::shared_ptr<PrimitiveType>& target_type) {
89+ auto long_val = std::get<int64_t >(literal.value_ );
90+ auto target_type_id = target_type->type_id ();
14291
14392 switch (target_type_id) {
14493 case TypeId::kInt : {
14594 // Check for overflow
14695 if (long_val >= std::numeric_limits<int32_t >::max ()) {
147- return PrimitiveLiteral:: AboveMaxLiteral (type_ );
96+ return AboveMaxLiteral (target_type );
14897 }
14998 if (long_val <= std::numeric_limits<int32_t >::min ()) {
150- return PrimitiveLiteral:: BelowMinLiteral (type_ );
99+ return BelowMinLiteral (target_type );
151100 }
152101 return PrimitiveLiteral::Int (static_cast <int32_t >(long_val));
153102 }
@@ -161,8 +110,10 @@ Result<PrimitiveLiteral> PrimitiveLiteral::CastFromLong(TypeId target_type_id) c
161110 }
162111}
163112
164- Result<PrimitiveLiteral> PrimitiveLiteral::CastFromFloat (TypeId target_type_id) const {
165- auto float_val = std::get<float >(value_);
113+ Result<PrimitiveLiteral> PrimitiveLiteralCaster::CastFromFloat (
114+ const PrimitiveLiteral& literal, const std::shared_ptr<PrimitiveType>& target_type) {
115+ auto float_val = std::get<float >(literal.value_ );
116+ auto target_type_id = target_type->type_id ();
166117
167118 switch (target_type_id) {
168119 case TypeId::kDouble :
@@ -173,6 +124,58 @@ Result<PrimitiveLiteral> PrimitiveLiteral::CastFromFloat(TypeId target_type_id)
173124 }
174125}
175126
127+ // Constructor
128+ PrimitiveLiteral::PrimitiveLiteral (Value value, std::shared_ptr<PrimitiveType> type)
129+ : value_(std::move(value)), type_(std::move(type)) {}
130+
131+ // Factory methods
132+ PrimitiveLiteral PrimitiveLiteral::Boolean (bool value) {
133+ return {Value{value}, std::make_shared<BooleanType>()};
134+ }
135+
136+ PrimitiveLiteral PrimitiveLiteral::Int (int32_t value) {
137+ return {Value{value}, std::make_shared<IntType>()};
138+ }
139+
140+ PrimitiveLiteral PrimitiveLiteral::Long (int64_t value) {
141+ return {Value{value}, std::make_shared<LongType>()};
142+ }
143+
144+ PrimitiveLiteral PrimitiveLiteral::Float (float value) {
145+ return {Value{value}, std::make_shared<FloatType>()};
146+ }
147+
148+ PrimitiveLiteral PrimitiveLiteral::Double (double value) {
149+ return {Value{value}, std::make_shared<DoubleType>()};
150+ }
151+
152+ PrimitiveLiteral PrimitiveLiteral::String (std::string value) {
153+ return {Value{std::move (value)}, std::make_shared<StringType>()};
154+ }
155+
156+ PrimitiveLiteral PrimitiveLiteral::Binary (std::vector<uint8_t > value) {
157+ return {Value{std::move (value)}, std::make_shared<BinaryType>()};
158+ }
159+
160+ Result<PrimitiveLiteral> PrimitiveLiteral::Deserialize (
161+ std::span<const uint8_t > data, std::shared_ptr<PrimitiveType> type) {
162+ return NotImplemented (" Deserialization of PrimitiveLiteral is not implemented yet" );
163+ }
164+
165+ Result<std::vector<uint8_t >> PrimitiveLiteral::Serialize () const {
166+ return NotImplemented (" Serialization of PrimitiveLiteral is not implemented yet" );
167+ }
168+
169+ // Getters
170+
171+ const std::shared_ptr<PrimitiveType>& PrimitiveLiteral::type () const { return type_; }
172+
173+ // Cast method
174+ Result<PrimitiveLiteral> PrimitiveLiteral::CastTo (
175+ const std::shared_ptr<PrimitiveType>& target_type) const {
176+ return PrimitiveLiteralCaster::CastTo (*this , target_type);
177+ }
178+
176179// Template function for floating point comparison following Iceberg rules:
177180// -NaN < NaN, but all NaN values (qNaN, sNaN) are treated as equivalent within their sign
178181template <std::floating_point T>
@@ -205,7 +208,7 @@ std::partial_ordering PrimitiveLiteral::operator<=>(const PrimitiveLiteral& othe
205208 }
206209
207210 // If either value is AboveMax or BelowMin, comparison is unordered
208- if (isAboveMax () || isBelowMin () || other.isAboveMax () || other.isBelowMin ()) {
211+ if (IsAboveMax () || IsBelowMin () || other.IsAboveMax () || other.IsBelowMin ()) {
209212 return std::partial_ordering::unordered;
210213 }
211214
@@ -313,12 +316,51 @@ std::string PrimitiveLiteral::ToString() const {
313316 }
314317}
315318
316- bool PrimitiveLiteral::isBelowMin () const {
319+ bool PrimitiveLiteral::IsBelowMin () const {
317320 return std::holds_alternative<BelowMin>(value_);
318321}
319322
320- bool PrimitiveLiteral::isAboveMax () const {
323+ bool PrimitiveLiteral::IsAboveMax () const {
321324 return std::holds_alternative<AboveMax>(value_);
322325}
323326
327+ // PrimitiveLiteralCaster implementation
328+
329+ Result<PrimitiveLiteral> PrimitiveLiteralCaster::CastTo (
330+ const PrimitiveLiteral& literal, const std::shared_ptr<PrimitiveType>& target_type) {
331+ if (*literal.type_ == *target_type) {
332+ // If types are the same, return a copy of the current literal
333+ return PrimitiveLiteral (literal.value_ , target_type);
334+ }
335+
336+ // Handle special values
337+ if (std::holds_alternative<PrimitiveLiteral::BelowMin>(literal.value_ ) ||
338+ std::holds_alternative<PrimitiveLiteral::AboveMax>(literal.value_ )) {
339+ // Cannot cast type for special values
340+ return NotSupported (" Cannot cast type for {}" , literal.ToString ());
341+ }
342+
343+ auto source_type_id = literal.type_ ->type_id ();
344+
345+ // Delegate to specific cast functions based on source type
346+ switch (source_type_id) {
347+ case TypeId::kInt :
348+ return CastFromInt (literal, target_type);
349+ case TypeId::kLong :
350+ return CastFromLong (literal, target_type);
351+ case TypeId::kFloat :
352+ return CastFromFloat (literal, target_type);
353+ case TypeId::kDouble :
354+ case TypeId::kBoolean :
355+ case TypeId::kString :
356+ case TypeId::kBinary :
357+ break ;
358+ default :
359+ break ;
360+ }
361+
362+ return NotSupported (" Cast from {} to {} is not implemented" , literal.type_ ->ToString (),
363+ target_type->ToString ());
364+ }
365+
324366} // namespace iceberg
0 commit comments