Skip to content

Commit 165a962

Browse files
committed
fix: check type for transform literal to human string
1 parent 7fedb11 commit 165a962

File tree

3 files changed

+66
-7
lines changed

3 files changed

+66
-7
lines changed

src/iceberg/test/transform_human_string_test.cc

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -130,6 +130,36 @@ class TimestampHumanStringTest : public ::testing::TestWithParam<HumanStringTest
130130
Transform::Year(), Transform::Month(), Transform::Day(), Transform::Hour()};
131131
};
132132

133+
TEST_F(TimestampHumanStringTest, InvalidType) {
134+
ICEBERG_UNWRAP_OR_FAIL(auto above_max,
135+
Literal::Long(std::numeric_limits<int64_t>::max())
136+
.CastTo(std::make_shared<IntType>()));
137+
ICEBERG_UNWRAP_OR_FAIL(auto below_min,
138+
Literal::Long(std::numeric_limits<int64_t>::min())
139+
.CastTo(std::make_shared<IntType>()));
140+
141+
auto unmatch_type_literal = Literal::Long(std::numeric_limits<int64_t>::max());
142+
143+
for (const auto& transform : transforms_) {
144+
auto result = transform->ToHumanString(above_max);
145+
EXPECT_THAT(result, IsError(ErrorKind::kNotSupported));
146+
EXPECT_THAT(result,
147+
HasErrorMessage("Cannot transfrom human string for value: aboveMax"));
148+
149+
result = transform->ToHumanString(below_min);
150+
EXPECT_THAT(result, IsError(ErrorKind::kNotSupported));
151+
EXPECT_THAT(result,
152+
HasErrorMessage("Cannot transfrom human string for value: belowMin"));
153+
154+
result = transform->ToHumanString(unmatch_type_literal);
155+
EXPECT_THAT(result, IsError(ErrorKind::kNotSupported));
156+
EXPECT_THAT(result, HasErrorMessage(std::format(
157+
"Transfrom human {} from type {} is not supported",
158+
TransformTypeToString(transform->transform_type()),
159+
unmatch_type_literal.type()->ToString())));
160+
}
161+
}
162+
133163
TEST_P(TimestampHumanStringTest, ToHumanString) {
134164
const auto& param = GetParam();
135165
for (uint32_t i = 0; i < transforms_.size(); i++) {

src/iceberg/transform.cc

Lines changed: 34 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -372,16 +372,44 @@ Result<std::string> Transform::ToHumanString(const Literal& value) {
372372
return "null";
373373
}
374374

375+
if (value.IsAboveMax() || value.IsBelowMin()) [[unlikely]] {
376+
return NotSupported("Cannot transfrom human string for value: {}", value.ToString());
377+
}
378+
375379
switch (transform_type_) {
376-
case TransformType::kYear:
380+
case TransformType::kYear: {
381+
if (!std::holds_alternative<int32_t>(value.value())) [[unlikely]] {
382+
return NotSupported("Transfrom human year from type {} is not supported",
383+
value.type()->ToString());
384+
}
377385
return TransformUtil::HumanYear(std::get<int32_t>(value.value()));
378-
case TransformType::kMonth:
386+
}
387+
case TransformType::kMonth: {
388+
if (!std::holds_alternative<int32_t>(value.value())) [[unlikely]] {
389+
return NotSupported("Transfrom human month from type {} is not supported",
390+
value.type()->ToString());
391+
}
379392
return TransformUtil::HumanMonth(std::get<int32_t>(value.value()));
380-
case TransformType::kDay:
393+
}
394+
case TransformType::kDay: {
395+
if (!std::holds_alternative<int32_t>(value.value())) [[unlikely]] {
396+
return NotSupported("Transfrom human day from type {} is not supported",
397+
value.type()->ToString());
398+
}
381399
return TransformUtil::HumanDay(std::get<int32_t>(value.value()));
382-
case TransformType::kHour:
400+
}
401+
case TransformType::kHour: {
402+
if (!std::holds_alternative<int32_t>(value.value())) [[unlikely]] {
403+
return NotSupported("Transfrom human hour from type {} is not supported",
404+
value.type()->ToString());
405+
}
383406
return TransformUtil::HumanHour(std::get<int32_t>(value.value()));
384-
default: {
407+
}
408+
case TransformType::kIdentity:
409+
case TransformType::kBucket:
410+
case TransformType::kTruncate:
411+
case TransformType::kUnknown:
412+
case TransformType::kVoid: {
385413
switch (value.type()->type_id()) {
386414
case TypeId::kDate:
387415
return TransformUtil::HumanDay(std::get<int32_t>(value.value()));
@@ -409,6 +437,7 @@ Result<std::string> Transform::ToHumanString(const Literal& value) {
409437
}
410438
}
411439
}
440+
std::unreachable();
412441
}
413442

414443
bool TransformFunction::Equals(const TransformFunction& other) const {

src/iceberg/transform.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -194,10 +194,10 @@ class ICEBERG_EXPORT Transform : public util::Formattable {
194194
Result<std::unique_ptr<UnboundPredicate>> ProjectStrict(
195195
std::string_view name, const std::shared_ptr<BoundPredicate>& predicate);
196196

197-
/// \brief Returns a human-readable String representation of a transformed value.
197+
/// \brief Returns a human-readable string representation of a transformed value.
198198
///
199199
/// \param value The literal value to be transformed.
200-
/// \return A human-readable String representation of the value
200+
/// \return A human-readable string representation of the value
201201
Result<std::string> ToHumanString(const Literal& value);
202202

203203
/// \brief Returns a string representation of this transform (e.g., "bucket[16]").

0 commit comments

Comments
 (0)