huan233usc commented on code in PR #809:
URL: https://github.com/apache/iceberg-cpp/pull/809#discussion_r3624631069


##########
src/iceberg/schema_field.cc:
##########
@@ -168,6 +170,18 @@ Status ValidateDefault(const SchemaField& field, const 
Literal& value,
     return InvalidSchema("{} of field {} has type {} but expected {}", kind, 
field.name(),
                          *value.type(), *field.type());
   }
+  // A decimal literal carries a precision in its type but stores only an 
unscaled value,
+  // so a value that does not fit the field precision would pass the type 
check above yet
+  // be rejected when the metadata is parsed back. Reject it here to keep the 
default
+  // consistent with what the reader accepts.
+  if (field.type()->type_id() == TypeId::kDecimal &&
+      std::holds_alternative<Decimal>(value.value())) {
+    const auto& decimal_type = internal::checked_cast<const 
DecimalType&>(*field.type());
+    if 
(!std::get<Decimal>(value.value()).FitsInPrecision(decimal_type.precision())) {
+      return InvalidSchema("{} of field {} does not fit precision {}", kind, 
field.name(),
+                           decimal_type.precision());
+    }
+  }

Review Comment:
   Fixed in 33dddddc: switched to `std::get_if<Decimal>` so we only touch the 
variant once (also covers @WZhuo's suggestion).



##########
src/iceberg/test/schema_field_test.cc:
##########
@@ -170,4 +172,22 @@ TEST(SchemaFieldTest, CastDefaultValue) {
   }
 }
 
+TEST(SchemaFieldTest, ValidateRejectsDecimalDefaultExceedingPrecision) {
+  // A decimal default whose unscaled value needs more digits than the field 
precision has
+  // the matching literal type (decimal(2, 1)) but does not fit; Validate must 
reject it
+  // so it is never serialized to metadata the reader would later refuse to 
parse.
+  SchemaField field(/*field_id=*/1, /*name=*/"d", decimal(2, 1),
+                    /*optional=*/true, /*doc=*/"",
+                    std::make_shared<const Literal>(Literal::Decimal(999, 2, 
1)));
+  EXPECT_THAT(field.Validate(), IsError(ErrorKind::kInvalidSchema));
+  EXPECT_THAT(field.Validate(), HasErrorMessage("does not fit precision"));

Review Comment:
   Fixed in 33dddddc: validate once and assert on the captured `Status`.



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to