rpuch commented on code in PR #2872:
URL: https://github.com/apache/ignite-3/pull/2872#discussion_r1405900293


##########
modules/table/src/main/java/org/apache/ignite/internal/table/distributed/replicator/SchemaCompatibilityValidator.java:
##########
@@ -259,4 +286,127 @@ void failIfRequestSchemaDiffersFromTxTs(HybridTimestamp 
txTs, int requestSchemaV
             throw new InternalSchemaVersionMismatchException();
         }
     }
+
+    private enum ValidatorVerdict {
+        COMPATIBLE, INCOMPATIBLE, DONT_CARE
+    }
+
+    @SuppressWarnings("InterfaceMayBeAnnotatedFunctional")
+    private interface ForwardCompatibilityValidator {
+        ValidatorVerdict compatible(TableDefinitionDiff diff);
+    }
+
+    private static class RenameTableValidator implements 
ForwardCompatibilityValidator {
+        @Override
+        public ValidatorVerdict compatible(TableDefinitionDiff diff) {
+            return diff.nameDiffers() ? ValidatorVerdict.INCOMPATIBLE : 
ValidatorVerdict.DONT_CARE;
+        }
+    }
+
+    private static class AddColumnsValidator implements 
ForwardCompatibilityValidator {
+        @Override
+        public ValidatorVerdict compatible(TableDefinitionDiff diff) {
+            if (diff.addedColumns().isEmpty()) {
+                return ValidatorVerdict.DONT_CARE;
+            }
+
+            for (CatalogTableColumnDescriptor column : diff.addedColumns()) {
+                if (!column.nullable() && column.defaultValue() == null) {
+                    return ValidatorVerdict.INCOMPATIBLE;
+                }
+            }
+
+            return ValidatorVerdict.COMPATIBLE;
+        }
+    }
+
+    private static class DropColumnsValidator implements 
ForwardCompatibilityValidator {
+        @Override
+        public ValidatorVerdict compatible(TableDefinitionDiff diff) {
+            return diff.removedColumns().isEmpty() ? 
ValidatorVerdict.DONT_CARE : ValidatorVerdict.INCOMPATIBLE;
+        }
+    }
+
+    @SuppressWarnings("InterfaceMayBeAnnotatedFunctional")
+    private interface ColumnChangeCompatibilityValidator {
+        ValidatorVerdict compatible(ColumnDefinitionDiff diff);
+    }
+
+    private static class ChangeColumnsValidator implements 
ForwardCompatibilityValidator {
+        private final List<ColumnChangeCompatibilityValidator> validators;
+
+        private 
ChangeColumnsValidator(List<ColumnChangeCompatibilityValidator> validators) {
+            this.validators = List.copyOf(validators);
+        }
+
+        @Override
+        public ValidatorVerdict compatible(TableDefinitionDiff diff) {
+            if (diff.changedColumns().isEmpty()) {
+                return ValidatorVerdict.DONT_CARE;
+            }
+
+            boolean accepted = false;
+
+            for (ColumnDefinitionDiff columnDiff : diff.changedColumns()) {
+                switch (compatible(columnDiff)) {
+                    case COMPATIBLE:
+                        accepted = true;
+                        break;
+                    case INCOMPATIBLE:
+                        return ValidatorVerdict.INCOMPATIBLE;
+                    default:
+                        break;
+                }
+            }
+
+            // If for some column no validator either accepts or refuses the 
change, then this
+            // is an unknown change, that we consider incompatible by default.

Review Comment:
   Only neutral votes are not ok because this means that this is an unknown 
change. I changed the code to throw an `AssertionError` if this happens as this 
means that we did not add some validator.



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

Reply via email to