@@ -1456,6 +1456,85 @@ TEST_F(UpdateSchemaTest, DeleteRenameConflict) {
14561456 EXPECT_THAT (result, HasErrorMessage (" Cannot rename a column that will be deleted" ));
14571457}
14581458
1459+ // Test case insensitive add then update
1460+ TEST_F (UpdateSchemaTest, CaseInsensitiveAddThenUpdate) {
1461+ ICEBERG_UNWRAP_OR_FAIL (auto update, table_->NewUpdateSchema ());
1462+ update->CaseSensitive (false )
1463+ .AddColumn (" Foo" , int32 (), " A column with uppercase name" )
1464+ .UpdateColumn (" foo" , int64 ()); // Update using lowercase
1465+
1466+ ICEBERG_UNWRAP_OR_FAIL (auto result, update->Apply ());
1467+
1468+ // Verify the column was added and updated
1469+ ICEBERG_UNWRAP_OR_FAIL (auto field_opt, result.schema ->FindFieldByName (" Foo" , false ));
1470+ ASSERT_TRUE (field_opt.has_value ());
1471+ EXPECT_EQ (*field_opt->get ().type (), *int64 ()); // Type should be updated to int64
1472+ }
1473+
1474+ // Test case insensitive add then rename
1475+ TEST_F (UpdateSchemaTest, CaseInsensitiveAddThenRename) {
1476+ ICEBERG_UNWRAP_OR_FAIL (auto update, table_->NewUpdateSchema ());
1477+ update->CaseSensitive (false )
1478+ .AddColumn (" Foo" , string (), " A column with uppercase name" )
1479+ .RenameColumn (" foo" , " Bar" ); // Rename using lowercase
1480+
1481+ ICEBERG_UNWRAP_OR_FAIL (auto result, update->Apply ());
1482+
1483+ // Verify the column was renamed
1484+ ICEBERG_UNWRAP_OR_FAIL (auto foo_opt, result.schema ->FindFieldByName (" Foo" , false ));
1485+ ICEBERG_UNWRAP_OR_FAIL (auto bar_opt, result.schema ->FindFieldByName (" Bar" , false ));
1486+ EXPECT_FALSE (foo_opt.has_value ());
1487+ ASSERT_TRUE (bar_opt.has_value ());
1488+ EXPECT_EQ (*bar_opt->get ().type (), *string ());
1489+ }
1490+
1491+ // Test case insensitive add then update doc
1492+ TEST_F (UpdateSchemaTest, CaseInsensitiveAddThenUpdateDoc) {
1493+ ICEBERG_UNWRAP_OR_FAIL (auto update, table_->NewUpdateSchema ());
1494+ update->CaseSensitive (false )
1495+ .AddColumn (" Foo" , int32 (), " original doc" )
1496+ .UpdateColumnDoc (" foo" , " updated doc" ); // Update doc using lowercase
1497+
1498+ ICEBERG_UNWRAP_OR_FAIL (auto result, update->Apply ());
1499+
1500+ // Verify the doc was updated
1501+ ICEBERG_UNWRAP_OR_FAIL (auto field_opt, result.schema ->FindFieldByName (" Foo" , false ));
1502+ ASSERT_TRUE (field_opt.has_value ());
1503+ EXPECT_EQ (field_opt->get ().doc (), " updated doc" );
1504+ }
1505+
1506+ // Test case insensitive add then make optional
1507+ TEST_F (UpdateSchemaTest, CaseInsensitiveAddThenMakeOptional) {
1508+ ICEBERG_UNWRAP_OR_FAIL (auto update, table_->NewUpdateSchema ());
1509+ update->CaseSensitive (false )
1510+ .AllowIncompatibleChanges ()
1511+ .AddRequiredColumn (" Foo" , int32 (), " required column" )
1512+ .MakeColumnOptional (" foo" ); // Make optional using lowercase
1513+
1514+ ICEBERG_UNWRAP_OR_FAIL (auto result, update->Apply ());
1515+
1516+ // Verify the column is now optional
1517+ ICEBERG_UNWRAP_OR_FAIL (auto field_opt, result.schema ->FindFieldByName (" Foo" , false ));
1518+ ASSERT_TRUE (field_opt.has_value ());
1519+ EXPECT_TRUE (field_opt->get ().optional ());
1520+ }
1521+
1522+ // Test case insensitive add then require
1523+ TEST_F (UpdateSchemaTest, CaseInsensitiveAddThenRequire) {
1524+ ICEBERG_UNWRAP_OR_FAIL (auto update, table_->NewUpdateSchema ());
1525+ update->CaseSensitive (false )
1526+ .AllowIncompatibleChanges ()
1527+ .AddColumn (" Foo" , int32 (), " optional column" )
1528+ .RequireColumn (" foo" ); // Require using lowercase
1529+
1530+ ICEBERG_UNWRAP_OR_FAIL (auto result, update->Apply ());
1531+
1532+ // Verify the column is now required
1533+ ICEBERG_UNWRAP_OR_FAIL (auto field_opt, result.schema ->FindFieldByName (" Foo" , false ));
1534+ ASSERT_TRUE (field_opt.has_value ());
1535+ EXPECT_FALSE (field_opt->get ().optional ());
1536+ }
1537+
14591538// Test mixed changes - comprehensive test combining multiple operations
14601539TEST_F (UpdateSchemaTest, MixedChanges) {
14611540 // First, create a complex schema similar to Java's SCHEMA constant
0 commit comments