@@ -85,6 +85,10 @@ class LiteralCaster {
8585 // / Cast from Fixed type to target type.
8686 static Result<Literal> CastFromFixed (const Literal& literal,
8787 const std::shared_ptr<PrimitiveType>& target_type);
88+
89+ // / Cast an integer value (from Int or Long) to a decimal target type.
90+ static Result<Literal> CastIntegerToDecimal (
91+ int64_t value, const std::shared_ptr<PrimitiveType>& target_type);
8892};
8993
9094Literal LiteralCaster::BelowMinLiteral (std::shared_ptr<PrimitiveType> type) {
@@ -95,6 +99,20 @@ Literal LiteralCaster::AboveMaxLiteral(std::shared_ptr<PrimitiveType> type) {
9599 return Literal (Literal::AboveMax{}, std::move (type));
96100}
97101
102+ Result<Literal> LiteralCaster::CastIntegerToDecimal (
103+ int64_t value, const std::shared_ptr<PrimitiveType>& target_type) {
104+ const auto & decimal_type = internal::checked_cast<const DecimalType&>(*target_type);
105+ // An integer has scale 0, so scaling it to the target scale multiplies the unscaled
106+ // value by 10^scale; Rescale rejects a target scale that would overflow the value.
107+ ICEBERG_ASSIGN_OR_RAISE (auto decimal, Decimal (value).Rescale (0 , decimal_type.scale ()));
108+ if (!decimal.FitsInPrecision (decimal_type.precision ())) {
109+ return InvalidArgument (" Cannot cast {} as a {} value" , value,
110+ target_type->ToString ());
111+ }
112+ return Literal::Decimal (decimal.value (), decimal_type.precision (),
113+ decimal_type.scale ());
114+ }
115+
98116Result<Literal> LiteralCaster::CastFromInt (
99117 const Literal& literal, const std::shared_ptr<PrimitiveType>& target_type) {
100118 auto int_val = std::get<int32_t >(literal.value_ );
@@ -109,6 +127,8 @@ Result<Literal> LiteralCaster::CastFromInt(
109127 return Literal::Double (static_cast <double >(int_val));
110128 case TypeId::kDate :
111129 return Literal::Date (int_val);
130+ case TypeId::kDecimal :
131+ return CastIntegerToDecimal (static_cast <int64_t >(int_val), target_type);
112132 default :
113133 return NotSupported (" Cast from Int to {} is not implemented" ,
114134 target_type->ToString ());
@@ -153,6 +173,8 @@ Result<Literal> LiteralCaster::CastFromLong(
153173 return Literal::TimestampNs (long_val);
154174 case TypeId::kTimestampTzNs :
155175 return Literal::TimestampTzNs (long_val);
176+ case TypeId::kDecimal :
177+ return CastIntegerToDecimal (long_val, target_type);
156178 default :
157179 return NotSupported (" Cast from Long to {} is not supported" ,
158180 target_type->ToString ());
0 commit comments