This is an automated email from the ASF dual-hosted git repository.

amoghj pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/iceberg.git


The following commit(s) were added to refs/heads/main by this push:
     new 19b4bd0244 Core: Disallow encryption table properties in v1 and v2 
(#14668)
19b4bd0244 is described below

commit 19b4bd024486d9d516d0e547e273419c1bc7074e
Author: Yuya Ebihara <[email protected]>
AuthorDate: Mon Dec 8 14:01:06 2025 +0900

    Core: Disallow encryption table properties in v1 and v2 (#14668)
---
 .../java/org/apache/iceberg/TableMetadata.java     |  3 +++
 .../apache/iceberg/encryption/EncryptionUtil.java  | 22 ++++++++++++++++++++++
 .../java/org/apache/iceberg/TestTableMetadata.java | 19 +++++++++++++++++++
 .../iceberg/spark/sql/TestCTASEncryption.java      |  2 +-
 .../iceberg/spark/sql/TestTableEncryption.java     |  2 +-
 5 files changed, 46 insertions(+), 2 deletions(-)

diff --git a/core/src/main/java/org/apache/iceberg/TableMetadata.java 
b/core/src/main/java/org/apache/iceberg/TableMetadata.java
index 3c2a3eb9b7..7dac5d401a 100644
--- a/core/src/main/java/org/apache/iceberg/TableMetadata.java
+++ b/core/src/main/java/org/apache/iceberg/TableMetadata.java
@@ -31,6 +31,7 @@ import java.util.function.Predicate;
 import java.util.stream.Collectors;
 import java.util.stream.Stream;
 import org.apache.iceberg.encryption.EncryptedKey;
+import org.apache.iceberg.encryption.EncryptionUtil;
 import org.apache.iceberg.exceptions.ValidationException;
 import org.apache.iceberg.relocated.com.google.common.base.MoreObjects;
 import org.apache.iceberg.relocated.com.google.common.base.Objects;
@@ -140,6 +141,8 @@ public class TableMetadata implements Serializable {
 
     PropertyUtil.validateCommitProperties(properties);
 
+    EncryptionUtil.checkCompatibility(properties, formatVersion);
+
     return new Builder()
         .setInitialFormatVersion(formatVersion)
         .setCurrentSchema(freshSchema, lastColumnId.get())
diff --git 
a/core/src/main/java/org/apache/iceberg/encryption/EncryptionUtil.java 
b/core/src/main/java/org/apache/iceberg/encryption/EncryptionUtil.java
index fe228fae93..1f0461bc4d 100644
--- a/core/src/main/java/org/apache/iceberg/encryption/EncryptionUtil.java
+++ b/core/src/main/java/org/apache/iceberg/encryption/EncryptionUtil.java
@@ -22,16 +22,24 @@ import java.nio.ByteBuffer;
 import java.nio.charset.StandardCharsets;
 import java.util.List;
 import java.util.Map;
+import java.util.Set;
 import org.apache.iceberg.CatalogProperties;
 import org.apache.iceberg.ManifestListFile;
 import org.apache.iceberg.TableProperties;
 import org.apache.iceberg.common.DynConstructors;
 import org.apache.iceberg.io.OutputFile;
 import org.apache.iceberg.relocated.com.google.common.base.Preconditions;
+import org.apache.iceberg.relocated.com.google.common.collect.ImmutableSet;
+import org.apache.iceberg.relocated.com.google.common.collect.Sets;
 import org.apache.iceberg.util.ByteBuffers;
 import org.apache.iceberg.util.PropertyUtil;
 
 public class EncryptionUtil {
+  private static final Set<String> ENCRYPTION_TABLE_PROPERTIES =
+      ImmutableSet.<String>builder()
+          .add(TableProperties.ENCRYPTION_TABLE_KEY)
+          .add(TableProperties.ENCRYPTION_DEK_LENGTH)
+          .build();
 
   private EncryptionUtil() {}
 
@@ -182,4 +190,18 @@ public class EncryptionUtil {
 
     return ByteBuffer.wrap(encryptedKeyMetadata);
   }
+
+  public static void checkCompatibility(Map<String, String> tableProperties, 
int formatVersion) {
+    if (formatVersion >= 3) {
+      return;
+    }
+
+    Set<String> encryptionProperties =
+        Sets.intersection(ENCRYPTION_TABLE_PROPERTIES, 
tableProperties.keySet());
+    Preconditions.checkArgument(
+        encryptionProperties.isEmpty(),
+        "Invalid properties for v%s: %s",
+        formatVersion,
+        encryptionProperties);
+  }
 }
diff --git a/core/src/test/java/org/apache/iceberg/TestTableMetadata.java 
b/core/src/test/java/org/apache/iceberg/TestTableMetadata.java
index 345f506fa9..ed7b630f60 100644
--- a/core/src/test/java/org/apache/iceberg/TestTableMetadata.java
+++ b/core/src/test/java/org/apache/iceberg/TestTableMetadata.java
@@ -72,6 +72,7 @@ import org.junit.jupiter.api.io.TempDir;
 import org.junit.jupiter.params.ParameterizedTest;
 import org.junit.jupiter.params.provider.Arguments;
 import org.junit.jupiter.params.provider.MethodSource;
+import org.junit.jupiter.params.provider.ValueSource;
 
 public class TestTableMetadata {
   private static final String TEST_LOCATION = "s3://bucket/test/location";
@@ -1094,6 +1095,24 @@ public class TestTableMetadata {
         .isNotNull();
   }
 
+  @ParameterizedTest
+  @ValueSource(ints = {1, 2})
+  void testEncryptionVersionValidation(int formatVersion) {
+    assertThatThrownBy(
+            () ->
+                TableMetadata.newTableMetadata(
+                    TEST_SCHEMA,
+                    PartitionSpec.unpartitioned(),
+                    SortOrder.unsorted(),
+                    TEST_LOCATION,
+                    ImmutableMap.of("encryption.key-id", "test", 
"encryption.data-key-length", "5"),
+                    formatVersion))
+        .isInstanceOf(IllegalArgumentException.class)
+        .hasMessage(
+            "Invalid properties for v%s: [encryption.key-id, 
encryption.data-key-length]",
+            formatVersion);
+  }
+
   @Test
   public void testParserVersionValidation() throws Exception {
     String supportedVersion1 = 
readTableMetadataInputFile("TableMetadataV1Valid.json");
diff --git 
a/spark/v4.0/spark/src/test/java/org/apache/iceberg/spark/sql/TestCTASEncryption.java
 
b/spark/v4.0/spark/src/test/java/org/apache/iceberg/spark/sql/TestCTASEncryption.java
index 6094ab0ccc..3dee6e1e1d 100644
--- 
a/spark/v4.0/spark/src/test/java/org/apache/iceberg/spark/sql/TestCTASEncryption.java
+++ 
b/spark/v4.0/spark/src/test/java/org/apache/iceberg/spark/sql/TestCTASEncryption.java
@@ -71,7 +71,7 @@ public class TestCTASEncryption extends CatalogTestBase {
     sql(
         "CREATE TABLE %s USING iceberg "
             + "TBLPROPERTIES ( "
-            + "'encryption.key-id'='%s')"
+            + "'encryption.key-id'='%s', 'format-version'='3')"
             + " AS SELECT * from %s",
         tableName, UnitestKMS.MASTER_KEY_NAME1, tableName + "1");
   }
diff --git 
a/spark/v4.0/spark/src/test/java/org/apache/iceberg/spark/sql/TestTableEncryption.java
 
b/spark/v4.0/spark/src/test/java/org/apache/iceberg/spark/sql/TestTableEncryption.java
index 8f0552a378..e35ebf71b5 100644
--- 
a/spark/v4.0/spark/src/test/java/org/apache/iceberg/spark/sql/TestTableEncryption.java
+++ 
b/spark/v4.0/spark/src/test/java/org/apache/iceberg/spark/sql/TestTableEncryption.java
@@ -78,7 +78,7 @@ public class TestTableEncryption extends CatalogTestBase {
     sql(
         "CREATE TABLE %s (id bigint, data string, float float) USING iceberg "
             + "TBLPROPERTIES ( "
-            + "'encryption.key-id'='%s')",
+            + "'encryption.key-id'='%s', 'format-version'='3')",
         tableName, UnitestKMS.MASTER_KEY_NAME1);
 
     sql("INSERT INTO %s VALUES (1, 'a', 1.0), (2, 'b', 2.0), (3, 'c', 
float('NaN'))", tableName);

Reply via email to