Skip to content

Commit 6627ed4

Browse files
committed
reject out-of-range decimal scale before rescaling integer literals
1 parent 86dbd7d commit 6627ed4

2 files changed

Lines changed: 13 additions & 1 deletion

File tree

src/iceberg/expression/literal.cc

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -102,9 +102,16 @@ Literal LiteralCaster::AboveMaxLiteral(std::shared_ptr<PrimitiveType> type) {
102102
Result<Literal> LiteralCaster::CastIntegerToDecimal(
103103
int64_t value, const std::shared_ptr<PrimitiveType>& target_type) {
104104
const auto& decimal_type = internal::checked_cast<const DecimalType&>(*target_type);
105+
const int32_t scale = decimal_type.scale();
106+
// DecimalType does not bound its scale, but Rescale indexes a powers-of-ten table sized
107+
// for [0, kMaxScale]; reject an out-of-range scale here rather than reading past it.
108+
if (scale < 0 || scale > Decimal::kMaxScale) {
109+
return InvalidArgument("Cannot cast {} as a {} value", value,
110+
target_type->ToString());
111+
}
105112
// An integer has scale 0, so scaling it to the target scale multiplies the unscaled
106113
// 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()));
114+
ICEBERG_ASSIGN_OR_RAISE(auto decimal, Decimal(value).Rescale(0, scale));
108115
if (!decimal.FitsInPrecision(decimal_type.precision())) {
109116
return InvalidArgument("Cannot cast {} as a {} value", value,
110117
target_type->ToString());

src/iceberg/test/literal_test.cc

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -166,6 +166,11 @@ TEST(LiteralTest, IntegerCastToDecimal) {
166166
IsError(ErrorKind::kInvalidArgument));
167167
EXPECT_THAT(Literal::Long(int64_t{100}).CastTo(decimal(4, 2)),
168168
IsError(ErrorKind::kInvalidArgument));
169+
170+
// A scale beyond the decimal powers-of-ten table is rejected rather than read past it
171+
// (DecimalType does not bound its scale on construction).
172+
EXPECT_THAT(Literal::Int(1).CastTo(std::make_shared<DecimalType>(9, 40)),
173+
IsError(ErrorKind::kInvalidArgument));
169174
}
170175

171176
// Error cases for casts

0 commit comments

Comments
 (0)