2525
2626#include " iceberg/exception.h"
2727#include " iceberg/type_fwd.h"
28+ #include " iceberg/util/macros.h"
2829
2930namespace iceberg {
3031
@@ -102,7 +103,10 @@ Result<Literal> LiteralCaster::CastFromInt(
102103 return Literal::Double (static_cast <double >(int_val));
103104 case TypeId::kDate :
104105 return Literal::Date (int_val);
105- // TODO(Li Feiyang): Implement cast from Int to decimal
106+ case TypeId::kDecimal : {
107+ auto decimal_type = std::static_pointer_cast<DecimalType>(target_type);
108+ return Literal::Decimal (int_val, decimal_type->precision (), decimal_type->scale ());
109+ }
106110 default :
107111 return NotSupported (" Cast from Int to {} is not implemented" ,
108112 target_type->ToString ());
@@ -143,7 +147,10 @@ Result<Literal> LiteralCaster::CastFromLong(
143147 return Literal::Timestamp (long_val);
144148 case TypeId::kTimestampTz :
145149 return Literal::TimestampTz (long_val);
146- // TODO(Li Feiyang): Implement cast from Long to decimal, TimestampNs and
150+ case TypeId::kDecimal : {
151+ auto decimal_type = std::static_pointer_cast<DecimalType>(target_type);
152+ return Literal::Decimal (long_val, decimal_type->precision (), decimal_type->scale ());
153+ }
147154 default :
148155 return NotSupported (" Cast from Long to {} is not supported" ,
149156 target_type->ToString ());
@@ -157,7 +164,21 @@ Result<Literal> LiteralCaster::CastFromFloat(
157164 switch (target_type->type_id ()) {
158165 case TypeId::kDouble :
159166 return Literal::Double (static_cast <double >(float_val));
160- // TODO(Li Feiyang): Implement cast from Float to decimal
167+ case TypeId::kDecimal : {
168+ auto decimal_type = std::static_pointer_cast<DecimalType>(target_type);
169+ std::string float_str = std::to_string (float_val);
170+
171+ iceberg::Decimal parsed_val;
172+ int32_t parsed_scale = 0 ;
173+ ICEBERG_ASSIGN_OR_RAISE (
174+ parsed_val, iceberg::Decimal::FromString (float_str, nullptr , &parsed_scale));
175+ iceberg::Decimal rescaled_val;
176+ ICEBERG_ASSIGN_OR_RAISE (rescaled_val,
177+ parsed_val.Rescale (parsed_scale, decimal_type->scale ()));
178+
179+ return Literal::Decimal (rescaled_val.value (), decimal_type->precision (),
180+ decimal_type->scale ());
181+ }
161182 default :
162183 return NotSupported (" Cast from Float to {} is not supported" ,
163184 target_type->ToString ());
@@ -178,6 +199,21 @@ Result<Literal> LiteralCaster::CastFromDouble(
178199 }
179200 return Literal::Float (static_cast <float >(double_val));
180201 }
202+ case TypeId::kDecimal : {
203+ auto decimal_type = std::static_pointer_cast<DecimalType>(target_type);
204+ std::string double_str = std::to_string (double_val);
205+
206+ iceberg::Decimal parsed_val;
207+ int32_t parsed_scale = 0 ;
208+ ICEBERG_ASSIGN_OR_RAISE (
209+ parsed_val, iceberg::Decimal::FromString (double_str, nullptr , &parsed_scale));
210+ iceberg::Decimal rescaled_val;
211+ ICEBERG_ASSIGN_OR_RAISE (rescaled_val,
212+ parsed_val.Rescale (parsed_scale, decimal_type->scale ()));
213+
214+ return Literal::Decimal (rescaled_val.value (), decimal_type->precision (),
215+ decimal_type->scale ());
216+ }
181217 default :
182218 return NotSupported (" Cast from Double to {} is not supported" ,
183219 target_type->ToString ());
@@ -193,9 +229,16 @@ Result<Literal> LiteralCaster::CastFromString(
193229 case TypeId::kTime :
194230 case TypeId::kTimestamp :
195231 case TypeId::kTimestampTz :
232+ case TypeId::kUuid :
196233 return NotImplemented (" Cast from String to {} is not implemented yet" ,
197234 target_type->ToString ());
198- // TODO(Li Feiyang): Implement cast from String to uuid and decimal
235+ case TypeId::kDecimal : {
236+ auto decimal_type = std::static_pointer_cast<DecimalType>(target_type);
237+ iceberg::Decimal dec_val;
238+ ICEBERG_ASSIGN_OR_RAISE (dec_val, iceberg::Decimal::FromString (str_val));
239+ return Literal::Decimal (dec_val.value (), decimal_type->precision (),
240+ decimal_type->scale ());
241+ }
199242
200243 default :
201244 return NotSupported (" Cast from String to {} is not supported" ,
@@ -407,14 +450,25 @@ std::partial_ordering Literal::operator<=>(const Literal& other) const {
407450 return this_val <=> other_val;
408451 }
409452
453+ case TypeId::kDecimal : {
454+ auto this_val = std::get<int128_t >(value_);
455+ auto other_val = std::get<int128_t >(other.value_ );
456+ return this_val <=> other_val;
457+ }
458+
410459 default :
411460 // For unsupported types, return unordered
412461 return std::partial_ordering::unordered;
413462 }
414463}
415464
416465std::string Literal::ToString () const {
417- auto invalid_ = [this ]() { return std::format (" = {}" , type_->ToString ()); };
466+ auto unsupported_error = [this ]() {
467+ return std::format (" ToString not supported for type: {}" , type_->ToString ());
468+ };
469+ auto invalid_argument = [this ]() {
470+ return std::format (" Invalid argument for type: {}" , type_->ToString ());
471+ };
418472
419473 if (std::holds_alternative<BelowMin>(value_)) {
420474 return " belowMin" ;
@@ -443,7 +497,7 @@ std::string Literal::ToString() const {
443497 return std::to_string (std::get<double >(value_));
444498 }
445499 case TypeId::kString : {
446- return std::get<std::string>(value_);
500+ return " \" " + std::get<std::string>(value_) + " \" " ;
447501 }
448502 case TypeId::kBinary :
449503 case TypeId::kFixed : {
@@ -475,13 +529,10 @@ std::string Literal::ToString() const {
475529 if (str_res.has_value ()) {
476530 return str_res.value ();
477531 }
478- return
479- }
480- case TypeId::kUuid : {
481- return {" kDecimal and kUuid are not implemented yet" };
532+ return invalid_argument ();
482533 }
483534 default : {
484- throw IcebergError ( " Unknown type: " + type_-> ToString () );
535+ return unsupported_error ( );
485536 }
486537 }
487538}
@@ -513,6 +564,9 @@ Result<Literal> LiteralCaster::CastTo(const Literal& literal,
513564
514565 // Delegate to specific cast functions based on source type
515566 switch (source_type_id) {
567+ case TypeId::kBoolean :
568+ // No casts defined for Boolean, other than to itself.
569+ break ;
516570 case TypeId::kInt :
517571 return CastFromInt (literal, target_type);
518572 case TypeId::kLong :
@@ -531,12 +585,11 @@ Result<Literal> LiteralCaster::CastTo(const Literal& literal,
531585 return CastFromTimestamp (literal, target_type);
532586 case TypeId::kTimestampTz :
533587 return CastFromTimestampTz (literal, target_type);
534- case TypeId::kBoolean :
535588 default :
536589 break ;
537590 }
538591
539- return NotSupported (" Cast from {} to {} is not implemented " , literal.type_ ->ToString (),
592+ return NotSupported (" Cast from {} to {} is not supported " , literal.type_ ->ToString (),
540593 target_type->ToString ());
541594}
542595
0 commit comments