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