talatuyarer commented on code in PR #14266:
URL: https://github.com/apache/iceberg/pull/14266#discussion_r2408948602


##########
core/src/main/java/org/apache/iceberg/SchemaUpdate.java:
##########
@@ -281,7 +297,7 @@ public UpdateSchema updateColumn(String name, 
Type.PrimitiveType newType) {
     }
 
     Preconditions.checkArgument(
-        TypeUtil.isPromotionAllowed(field.type(), newType),
+        TypeUtil.isPromotionAllowed(field.type(), newType, formatVersion),

Review Comment:
   You need to add Partition Field Validation too. [According to 
spec](https://iceberg.apache.org/spec/#:~:text=Type%20promotion%20is,timestamp%20or%20timestamp_ns)
  `Type promotion is not allowed for a field that is referenced by source-id or 
source-ids of a partition field if the partition transform would produce a 
different value after promoting the type.`



##########
api/src/main/java/org/apache/iceberg/types/TypeUtil.java:
##########
@@ -400,13 +400,31 @@ public static Type find(Type type, Predicate<Type> 
predicate) {
   }
 
   public static boolean isPromotionAllowed(Type from, Type.PrimitiveType to) {
+    return TypeUtil.isPromotionAllowed(from, to, 2);
+  }
+
+  public static boolean isPromotionAllowed(
+      Type from, Type.PrimitiveType to, Integer formatVersion) {
     // Warning! Before changing this function, make sure that the type change 
doesn't introduce
     // compatibility problems in partitioning.
     if (from.equals(to)) {
       return true;
     }
 
     switch (from.typeId()) {
+      case DATE:
+        if (formatVersion < 3) {
+          return false;
+        } else if (to.typeId() == Type.TypeID.TIMESTAMP) {
+          // Timezone types cannot be promoted.
+          Types.TimestampType toTs = (Types.TimestampType) to;
+          return Types.TimestampType.withoutZone().equals(toTs);
+        } else if (to.typeId() == Type.TypeID.TIMESTAMP_NANO) {
+          // Timezone types cannot be promoted.
+          Types.TimestampNanoType toTs = (Types.TimestampNanoType) to;
+          return Types.TimestampNanoType.withoutZone().equals(toTs);
+        }
+        // fall through

Review Comment:
   You did not cover `Date → anything else` case. IMHO You should return false 
explicitly for any non applicable case.  



##########
api/src/main/java/org/apache/iceberg/types/CheckCompatibility.java:
##########
@@ -38,7 +38,20 @@ public class CheckCompatibility extends 
TypeUtil.CustomOrderSchemaVisitor<List<S
    * @return a list of error details, or an empty list if there are no 
compatibility problems
    */
   public static List<String> writeCompatibilityErrors(Schema readSchema, 
Schema writeSchema) {
-    return writeCompatibilityErrors(readSchema, writeSchema, true);
+    return writeCompatibilityErrors(readSchema, writeSchema, true, 2);
+  }
+
+  /**
+   * Returns a list of compatibility errors for writing with the given write 
schema. This includes
+   * nullability: writing optional (nullable) values to a required field is an 
error.
+   *
+   * @param readSchema a read schema
+   * @param writeSchema a write schema
+   * @return a list of error details, or an empty list if there are no 
compatibility problems
+   */
+  public static List<String> writeCompatibilityErrors(
+      Schema readSchema, Schema writeSchema, int formatVersion) {
+    return writeCompatibilityErrors(readSchema, writeSchema, true, 
formatVersion);

Review Comment:
   Please update javadoc whereever you add formatversion. 



##########
core/src/test/java/org/apache/iceberg/TestSchemaUpdate.java:
##########
@@ -2204,8 +2222,7 @@ public void 
testDeleteContainingNestedIdentifierFieldColumnsFails() {
                 new SchemaUpdate(newSchema, SCHEMA_LAST_COLUMN_ID + 
2).deleteColumn("out").apply())
         .isInstanceOf(IllegalArgumentException.class)
         .hasMessage(
-            "Cannot delete field 24: out: required struct<25: nested: required 
string> "
-                + "as it will delete nested identifier field 25: nested: 
required string");
+            "Cannot delete field 26: out: required struct<27: nested: required 
string> as it will delete nested identifier field 27: nested: required string");
   }
 

Review Comment:
   You introduce new functionally which should be covered by new test cases. At 
least this can be good cases to start :
   
   - v2 tables rejecting date→timestamp promotion
   - v3 tables rejecting date→timestamptz promotion
   - Partitioned date fields rejecting promotion



##########
api/src/test/java/org/apache/iceberg/types/TestReadabilityChecks.java:
##########
@@ -70,7 +70,7 @@ public void testPrimitiveTypes() {
             CheckCompatibility.writeCompatibilityErrors(
                 new Schema(required(1, "to_field", to)), fromSchema);
 
-        if (TypeUtil.isPromotionAllowed(from, to)) {
+        if (TypeUtil.isPromotionAllowed(from, to, 2)) {

Review Comment:
   This means date promotions will fail in this test (as expected). But should 
there be a v3-specific test showing date promotions work?



-- 
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