diff --git a/api/src/main/java/org/apache/iceberg/FileContent.java b/api/src/main/java/org/apache/iceberg/FileContent.java index f977b02a9426..1ee1d290b767 100644 --- a/api/src/main/java/org/apache/iceberg/FileContent.java +++ b/api/src/main/java/org/apache/iceberg/FileContent.java @@ -26,6 +26,8 @@ public enum FileContent { DATA_MANIFEST(3), DELETE_MANIFEST(4); + private static final FileContent[] VALUES = FileContent.values(); + private final int id; FileContent(int id) { @@ -35,4 +37,8 @@ public enum FileContent { public int id() { return id; } + + public static FileContent fromId(int id) { + return VALUES[id]; + } } diff --git a/api/src/test/java/org/apache/iceberg/TestFileContent.java b/api/src/test/java/org/apache/iceberg/TestFileContent.java new file mode 100644 index 000000000000..bd5e44ed3cf3 --- /dev/null +++ b/api/src/test/java/org/apache/iceberg/TestFileContent.java @@ -0,0 +1,48 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.iceberg; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatThrownBy; + +import java.util.stream.IntStream; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.EnumSource; +import org.junit.jupiter.params.provider.MethodSource; + +class TestFileContent { + + @ParameterizedTest + @EnumSource(FileContent.class) + void fromId(FileContent content) { + assertThat(FileContent.fromId(content.id())).isEqualTo(content); + } + + static IntStream invalidContentTypeIds() { + return IntStream.of(-1, FileContent.values().length); + } + + @ParameterizedTest + @MethodSource("invalidContentTypeIds") + void fromIdInvalid(int id) { + assertThatThrownBy(() -> FileContent.fromId(id)) + .isInstanceOf(ArrayIndexOutOfBoundsException.class) + .hasMessageContaining(String.valueOf(id)); + } +} diff --git a/core/src/main/java/org/apache/iceberg/BaseFile.java b/core/src/main/java/org/apache/iceberg/BaseFile.java index a02e0eff55a2..3c31c50f099f 100644 --- a/core/src/main/java/org/apache/iceberg/BaseFile.java +++ b/core/src/main/java/org/apache/iceberg/BaseFile.java @@ -45,7 +45,7 @@ abstract class BaseFile extends SupportsIndexProjection StructLike, SpecificData.SchemaConstructable, Serializable { - private static final FileContent[] FILE_CONTENT_VALUES = FileContent.values(); + static final Types.StructType EMPTY_STRUCT_TYPE = Types.StructType.of(); static final PartitionData EMPTY_PARTITION_DATA = new PartitionData(EMPTY_STRUCT_TYPE) { @@ -316,7 +316,7 @@ public void put(int i, Object value) { protected void internalSet(int pos, T value) { switch (pos) { case 0: - this.content = value != null ? FILE_CONTENT_VALUES[(Integer) value] : FileContent.DATA; + this.content = value != null ? FileContent.fromId((Integer) value) : FileContent.DATA; return; case 1: // always coerce to String for Serializable diff --git a/spark/v3.4/spark/src/main/java/org/apache/iceberg/spark/SparkContentFile.java b/spark/v3.4/spark/src/main/java/org/apache/iceberg/spark/SparkContentFile.java index bad31d8d85f4..78d69eeaaf61 100644 --- a/spark/v3.4/spark/src/main/java/org/apache/iceberg/spark/SparkContentFile.java +++ b/spark/v3.4/spark/src/main/java/org/apache/iceberg/spark/SparkContentFile.java @@ -35,8 +35,6 @@ public abstract class SparkContentFile implements ContentFile { - private static final FileContent[] FILE_CONTENT_VALUES = FileContent.values(); - private final int fileContentPosition; private final int filePathPosition; private final int fileFormatPosition; @@ -139,7 +137,7 @@ public FileContent content() { if (wrapped.isNullAt(fileContentPosition)) { return null; } - return FILE_CONTENT_VALUES[wrapped.getInt(fileContentPosition)]; + return FileContent.fromId(wrapped.getInt(fileContentPosition)); } @Override diff --git a/spark/v3.5/spark/src/main/java/org/apache/iceberg/spark/SparkContentFile.java b/spark/v3.5/spark/src/main/java/org/apache/iceberg/spark/SparkContentFile.java index bad31d8d85f4..78d69eeaaf61 100644 --- a/spark/v3.5/spark/src/main/java/org/apache/iceberg/spark/SparkContentFile.java +++ b/spark/v3.5/spark/src/main/java/org/apache/iceberg/spark/SparkContentFile.java @@ -35,8 +35,6 @@ public abstract class SparkContentFile implements ContentFile { - private static final FileContent[] FILE_CONTENT_VALUES = FileContent.values(); - private final int fileContentPosition; private final int filePathPosition; private final int fileFormatPosition; @@ -139,7 +137,7 @@ public FileContent content() { if (wrapped.isNullAt(fileContentPosition)) { return null; } - return FILE_CONTENT_VALUES[wrapped.getInt(fileContentPosition)]; + return FileContent.fromId(wrapped.getInt(fileContentPosition)); } @Override diff --git a/spark/v4.0/spark/src/main/java/org/apache/iceberg/spark/SparkContentFile.java b/spark/v4.0/spark/src/main/java/org/apache/iceberg/spark/SparkContentFile.java index bad31d8d85f4..78d69eeaaf61 100644 --- a/spark/v4.0/spark/src/main/java/org/apache/iceberg/spark/SparkContentFile.java +++ b/spark/v4.0/spark/src/main/java/org/apache/iceberg/spark/SparkContentFile.java @@ -35,8 +35,6 @@ public abstract class SparkContentFile implements ContentFile { - private static final FileContent[] FILE_CONTENT_VALUES = FileContent.values(); - private final int fileContentPosition; private final int filePathPosition; private final int fileFormatPosition; @@ -139,7 +137,7 @@ public FileContent content() { if (wrapped.isNullAt(fileContentPosition)) { return null; } - return FILE_CONTENT_VALUES[wrapped.getInt(fileContentPosition)]; + return FileContent.fromId(wrapped.getInt(fileContentPosition)); } @Override diff --git a/spark/v4.1/spark/src/main/java/org/apache/iceberg/spark/SparkContentFile.java b/spark/v4.1/spark/src/main/java/org/apache/iceberg/spark/SparkContentFile.java index bad31d8d85f4..78d69eeaaf61 100644 --- a/spark/v4.1/spark/src/main/java/org/apache/iceberg/spark/SparkContentFile.java +++ b/spark/v4.1/spark/src/main/java/org/apache/iceberg/spark/SparkContentFile.java @@ -35,8 +35,6 @@ public abstract class SparkContentFile implements ContentFile { - private static final FileContent[] FILE_CONTENT_VALUES = FileContent.values(); - private final int fileContentPosition; private final int filePathPosition; private final int fileFormatPosition; @@ -139,7 +137,7 @@ public FileContent content() { if (wrapped.isNullAt(fileContentPosition)) { return null; } - return FILE_CONTENT_VALUES[wrapped.getInt(fileContentPosition)]; + return FileContent.fromId(wrapped.getInt(fileContentPosition)); } @Override