From 39f5a8e6a08021e49e15f907c920fd528fe20a42 Mon Sep 17 00:00:00 2001 From: Peter Vary Date: Mon, 16 Feb 2026 13:40:00 +0100 Subject: [PATCH 1/5] Data: Moving GenericFileWriterFactory to the new FormatModel API --- .../iceberg/data/BaseFileWriterFactory.java | 15 +- .../data/GenericFileWriterFactory.java | 170 +++++++++++++--- .../data/RegistryBasedFileWriterFactory.java | 182 ++++++++++++++++++ 3 files changed, 336 insertions(+), 31 deletions(-) create mode 100644 data/src/main/java/org/apache/iceberg/data/RegistryBasedFileWriterFactory.java diff --git a/data/src/main/java/org/apache/iceberg/data/BaseFileWriterFactory.java b/data/src/main/java/org/apache/iceberg/data/BaseFileWriterFactory.java index 55f3b5701e0b..486ea99f7aa6 100644 --- a/data/src/main/java/org/apache/iceberg/data/BaseFileWriterFactory.java +++ b/data/src/main/java/org/apache/iceberg/data/BaseFileWriterFactory.java @@ -40,7 +40,13 @@ import org.apache.iceberg.parquet.Parquet; import org.apache.iceberg.relocated.com.google.common.collect.ImmutableMap; -/** A base writer factory to be extended by query engine integrations. */ +/** + * A base writer factory to be extended by query engine integrations. + * + * @deprecated deprecated as of version 1.11.0 and will be removed in 1.12.0. Use {@link + * RegistryBasedFileWriterFactory} + */ +@Deprecated public abstract class BaseFileWriterFactory implements FileWriterFactory, Serializable { private final Table table; private final FileFormat dataFileFormat; @@ -75,13 +81,6 @@ protected BaseFileWriterFactory( this.positionDeleteRowSchema = null; } - /** - * @deprecated This constructor is deprecated as of version 1.11.0 and will be removed in 1.12.0. - * Position deletes that include row data are no longer supported. Use {@link - * #BaseFileWriterFactory(Table, FileFormat, Schema, SortOrder, FileFormat, int[], Schema, - * SortOrder, Map)} instead. - */ - @Deprecated protected BaseFileWriterFactory( Table table, FileFormat dataFileFormat, diff --git a/data/src/main/java/org/apache/iceberg/data/GenericFileWriterFactory.java b/data/src/main/java/org/apache/iceberg/data/GenericFileWriterFactory.java index e6872cc6e136..04ade3597a0d 100644 --- a/data/src/main/java/org/apache/iceberg/data/GenericFileWriterFactory.java +++ b/data/src/main/java/org/apache/iceberg/data/GenericFileWriterFactory.java @@ -22,21 +22,36 @@ import static org.apache.iceberg.TableProperties.DEFAULT_FILE_FORMAT_DEFAULT; import static org.apache.iceberg.TableProperties.DELETE_DEFAULT_FILE_FORMAT; +import java.io.IOException; +import java.io.UncheckedIOException; import java.util.Map; import org.apache.iceberg.FileFormat; +import org.apache.iceberg.MetricsConfig; +import org.apache.iceberg.PartitionSpec; import org.apache.iceberg.Schema; import org.apache.iceberg.SortOrder; +import org.apache.iceberg.StructLike; import org.apache.iceberg.Table; import org.apache.iceberg.avro.Avro; import org.apache.iceberg.data.avro.DataWriter; import org.apache.iceberg.data.orc.GenericOrcWriter; import org.apache.iceberg.data.parquet.GenericParquetWriter; +import org.apache.iceberg.deletes.PositionDeleteWriter; +import org.apache.iceberg.encryption.EncryptedOutputFile; +import org.apache.iceberg.formats.FormatModelRegistry; import org.apache.iceberg.orc.ORC; import org.apache.iceberg.parquet.Parquet; import org.apache.iceberg.relocated.com.google.common.base.Preconditions; import org.apache.iceberg.relocated.com.google.common.collect.ImmutableMap; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; -public class GenericFileWriterFactory extends BaseFileWriterFactory { +public class GenericFileWriterFactory extends RegistryBasedFileWriterFactory { + private static final Logger LOG = LoggerFactory.getLogger(GenericFileWriterFactory.class); + + private Table table; + private FileFormat format; + private Schema positionDeleteRowSchema; GenericFileWriterFactory( Table table, @@ -50,13 +65,16 @@ public class GenericFileWriterFactory extends BaseFileWriterFactory { super( table, dataFileFormat, + Record.class, dataSchema, dataSortOrder, deleteFileFormat, equalityFieldIds, equalityDeleteRowSchema, equalityDeleteSortOrder, - ImmutableMap.of()); + ImmutableMap.of(), + null, + null); } /** @@ -80,14 +98,19 @@ public class GenericFileWriterFactory extends BaseFileWriterFactory { super( table, dataFileFormat, + Record.class, dataSchema, dataSortOrder, deleteFileFormat, equalityFieldIds, equalityDeleteRowSchema, equalityDeleteSortOrder, - positionDeleteRowSchema, - writerProperties); + writerProperties, + null, + null); + this.table = table; + this.format = dataFileFormat; + this.positionDeleteRowSchema = positionDeleteRowSchema; } /** @@ -107,62 +130,163 @@ public class GenericFileWriterFactory extends BaseFileWriterFactory { super( table, dataFileFormat, + Record.class, dataSchema, dataSortOrder, deleteFileFormat, equalityFieldIds, equalityDeleteRowSchema, equalityDeleteSortOrder, - positionDeleteRowSchema); + ImmutableMap.of(), + dataSchema, + equalityDeleteRowSchema); + this.table = table; + this.format = dataFileFormat; + this.positionDeleteRowSchema = positionDeleteRowSchema; } static Builder builderFor(Table table) { return new Builder(table); } - @Override + /** + * @deprecated Since 1.10.0, will be removed in 1.11.0. It won't be called starting 1.10.0 as the + * configuration is done by the {@link FormatModelRegistry}. + */ + @Deprecated protected void configureDataWrite(Avro.DataWriteBuilder builder) { - builder.createWriterFunc(DataWriter::create); + throwUnsupportedOperationException(); } - @Override + /** + * @deprecated Since 1.10.0, will be removed in 1.11.0. It won't be called starting 1.10.0 as the + * configuration is done by the {@link FormatModelRegistry}. + */ + @Deprecated protected void configureEqualityDelete(Avro.DeleteWriteBuilder builder) { - builder.createWriterFunc(DataWriter::create); + throwUnsupportedOperationException(); } - @Override + /** + * @deprecated Since 1.10.0, will be removed in 1.11.0. It won't be called starting 1.10.0 as the + * configuration is done by the {@link FormatModelRegistry}. + */ + @Deprecated protected void configurePositionDelete(Avro.DeleteWriteBuilder builder) { - builder.createWriterFunc(DataWriter::create); + throwUnsupportedOperationException(); } - @Override + /** + * @deprecated Since 1.10.0, will be removed in 1.11.0. It won't be called starting 1.10.0 as the + * configuration is done by the {@link FormatModelRegistry}. + */ + @Deprecated protected void configureDataWrite(Parquet.DataWriteBuilder builder) { - builder.createWriterFunc(GenericParquetWriter::create); + throwUnsupportedOperationException(); } - @Override + /** + * @deprecated Since 1.10.0, will be removed in 1.11.0. It won't be called starting 1.10.0 as the + * configuration is done by the {@link FormatModelRegistry}. + */ + @Deprecated protected void configureEqualityDelete(Parquet.DeleteWriteBuilder builder) { - builder.createWriterFunc(GenericParquetWriter::create); + throwUnsupportedOperationException(); } - @Override + /** + * @deprecated Since 1.10.0, will be removed in 1.11.0. It won't be called starting 1.10.0 as the + * configuration is done by the {@link FormatModelRegistry}. + */ + @Deprecated protected void configurePositionDelete(Parquet.DeleteWriteBuilder builder) { - builder.createWriterFunc(GenericParquetWriter::create); + throwUnsupportedOperationException(); } - @Override + /** + * @deprecated Since 1.10.0, will be removed in 1.11.0. It won't be called starting 1.10.0 as the + * configuration is done by the {@link FormatModelRegistry}. + */ + @Deprecated protected void configureDataWrite(ORC.DataWriteBuilder builder) { - builder.createWriterFunc(GenericOrcWriter::buildWriter); + throwUnsupportedOperationException(); } - @Override + /** + * @deprecated Since 1.10.0, will be removed in 1.11.0. It won't be called starting 1.10.0 as the + * configuration is done by the {@link FormatModelRegistry}. + */ + @Deprecated protected void configureEqualityDelete(ORC.DeleteWriteBuilder builder) { - builder.createWriterFunc(GenericOrcWriter::buildWriter); + throwUnsupportedOperationException(); } - @Override + /** + * @deprecated Since 1.10.0, will be removed in 1.11.0. It won't be called starting 1.10.0 as the + * configuration is done by the {@link FormatModelRegistry}. + */ + @Deprecated protected void configurePositionDelete(ORC.DeleteWriteBuilder builder) { - builder.createWriterFunc(GenericOrcWriter::buildWriter); + throwUnsupportedOperationException(); + } + + private void throwUnsupportedOperationException() { + throw new UnsupportedOperationException( + "Method is deprecated and should not be called. " + + "Configuration is already done by the registry."); + } + + @Override + public PositionDeleteWriter newPositionDeleteWriter( + EncryptedOutputFile file, PartitionSpec spec, StructLike partition) { + if (positionDeleteRowSchema == null) { + return super.newPositionDeleteWriter(file, spec, partition); + } else { + LOG.info( + "Deprecated feature used. Position delete row schema is used to create the position delete writer."); + MetricsConfig metricsConfig = + table != null + ? MetricsConfig.forPositionDelete(table) + : MetricsConfig.fromProperties(ImmutableMap.of()); + + try { + return switch (format) { + case AVRO -> + Avro.writeDeletes(file) + .createWriterFunc(DataWriter::create) + .withPartition(partition) + .overwrite() + .rowSchema(positionDeleteRowSchema) + .withSpec(spec) + .withKeyMetadata(file.keyMetadata()) + .buildPositionWriter(); + case ORC -> + ORC.writeDeletes(file) + .createWriterFunc(GenericOrcWriter::buildWriter) + .withPartition(partition) + .overwrite() + .rowSchema(positionDeleteRowSchema) + .withSpec(spec) + .withKeyMetadata(file.keyMetadata()) + .buildPositionWriter(); + case PARQUET -> + Parquet.writeDeletes(file) + .createWriterFunc(GenericParquetWriter::create) + .withPartition(partition) + .overwrite() + .metricsConfig(metricsConfig) + .rowSchema(positionDeleteRowSchema) + .withSpec(spec) + .withKeyMetadata(file.keyMetadata()) + .buildPositionWriter(); + default -> + throw new UnsupportedOperationException( + "Cannot write pos-deletes for unsupported file format: " + format); + }; + } catch (IOException e) { + throw new UncheckedIOException("Failed to create new position delete writer", e); + } + } } public static class Builder { diff --git a/data/src/main/java/org/apache/iceberg/data/RegistryBasedFileWriterFactory.java b/data/src/main/java/org/apache/iceberg/data/RegistryBasedFileWriterFactory.java new file mode 100644 index 000000000000..3d0e2e8fb030 --- /dev/null +++ b/data/src/main/java/org/apache/iceberg/data/RegistryBasedFileWriterFactory.java @@ -0,0 +1,182 @@ +/* + * 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.data; + +import java.io.IOException; +import java.io.Serializable; +import java.io.UncheckedIOException; +import java.util.Map; +import org.apache.iceberg.FileFormat; +import org.apache.iceberg.MetricsConfig; +import org.apache.iceberg.PartitionSpec; +import org.apache.iceberg.Schema; +import org.apache.iceberg.SortOrder; +import org.apache.iceberg.StructLike; +import org.apache.iceberg.Table; +import org.apache.iceberg.deletes.EqualityDeleteWriter; +import org.apache.iceberg.deletes.PositionDeleteWriter; +import org.apache.iceberg.encryption.EncryptedOutputFile; +import org.apache.iceberg.encryption.EncryptionKeyMetadata; +import org.apache.iceberg.formats.FileWriterBuilder; +import org.apache.iceberg.formats.FormatModelRegistry; +import org.apache.iceberg.io.DataWriter; +import org.apache.iceberg.io.FileWriterFactory; +import org.apache.iceberg.relocated.com.google.common.base.Preconditions; +import org.apache.iceberg.relocated.com.google.common.collect.ImmutableMap; + +/** + * A base writer factory to be extended by query engine integrations. + * + * @param row type + */ +public abstract class RegistryBasedFileWriterFactory + implements FileWriterFactory, Serializable { + private final Table table; + private final FileFormat dataFileFormat; + private final Class inputType; + private final Schema dataSchema; + private final SortOrder dataSortOrder; + private final FileFormat deleteFileFormat; + private final int[] equalityFieldIds; + private final Schema equalityDeleteRowSchema; + private final SortOrder equalityDeleteSortOrder; + private final Map writerProperties; + private final S inputSchema; + private final S equalityDeleteInputSchema; + + protected RegistryBasedFileWriterFactory( + Table table, + FileFormat dataFileFormat, + Class inputType, + Schema dataSchema, + SortOrder dataSortOrder, + FileFormat deleteFileFormat, + int[] equalityFieldIds, + Schema equalityDeleteRowSchema, + SortOrder equalityDeleteSortOrder, + Map writerProperties, + S inputSchema, + S equalityDeleteInputSchema) { + this.table = table; + this.dataFileFormat = dataFileFormat; + this.inputType = inputType; + this.dataSchema = dataSchema; + this.dataSortOrder = dataSortOrder; + this.deleteFileFormat = deleteFileFormat; + this.equalityFieldIds = equalityFieldIds; + this.equalityDeleteRowSchema = equalityDeleteRowSchema; + this.equalityDeleteSortOrder = equalityDeleteSortOrder; + this.writerProperties = writerProperties != null ? writerProperties : ImmutableMap.of(); + this.inputSchema = inputSchema; + this.equalityDeleteInputSchema = equalityDeleteInputSchema; + } + + protected S inputSchema() { + return inputSchema; + } + + protected S equalityDeleteInputSchema() { + return equalityDeleteInputSchema; + } + + @Override + public DataWriter newDataWriter( + EncryptedOutputFile file, PartitionSpec spec, StructLike partition) { + Preconditions.checkNotNull(dataSchema, "Data schema must not be null"); + EncryptionKeyMetadata keyMetadata = file.keyMetadata(); + Map properties = table != null ? table.properties() : ImmutableMap.of(); + MetricsConfig metricsConfig = + table != null ? MetricsConfig.forTable(table) : MetricsConfig.getDefault(); + + try { + FileWriterBuilder, S> builder = + FormatModelRegistry.dataWriteBuilder(dataFileFormat, inputType, file); + return builder + .schema(dataSchema) + .engineSchema(inputSchema()) + .setAll(properties) + .setAll(writerProperties) + .metricsConfig(metricsConfig) + .spec(spec) + .partition(partition) + .keyMetadata(keyMetadata) + .sortOrder(dataSortOrder) + .overwrite() + .build(); + } catch (IOException e) { + throw new UncheckedIOException("Failed to create new data writer", e); + } + } + + @Override + public EqualityDeleteWriter newEqualityDeleteWriter( + EncryptedOutputFile file, PartitionSpec spec, StructLike partition) { + Preconditions.checkNotNull(equalityDeleteRowSchema, "Equality delete schema must not be null"); + + EncryptionKeyMetadata keyMetadata = file.keyMetadata(); + Map properties = table != null ? table.properties() : ImmutableMap.of(); + MetricsConfig metricsConfig = + table != null ? MetricsConfig.forTable(table) : MetricsConfig.getDefault(); + + try { + FileWriterBuilder, S> builder = + FormatModelRegistry.equalityDeleteWriteBuilder(deleteFileFormat, inputType, file); + return builder + .setAll(properties) + .setAll(writerProperties) + .metricsConfig(metricsConfig) + .schema(equalityDeleteRowSchema) + .engineSchema(equalityDeleteInputSchema()) + .equalityFieldIds(equalityFieldIds) + .spec(spec) + .partition(partition) + .keyMetadata(keyMetadata) + .sortOrder(equalityDeleteSortOrder) + .overwrite() + .build(); + } catch (IOException e) { + throw new UncheckedIOException("Failed to create new equality delete writer", e); + } + } + + @Override + public PositionDeleteWriter newPositionDeleteWriter( + EncryptedOutputFile file, PartitionSpec spec, StructLike partition) { + EncryptionKeyMetadata keyMetadata = file.keyMetadata(); + Map properties = table != null ? table.properties() : ImmutableMap.of(); + MetricsConfig metricsConfig = + table != null ? MetricsConfig.forPositionDelete(table) : MetricsConfig.forPositionDelete(); + + try { + FileWriterBuilder, ?> builder = + FormatModelRegistry.positionDeleteWriteBuilder(deleteFileFormat, file); + return builder + .setAll(properties) + .setAll(writerProperties) + .metricsConfig(metricsConfig) + .spec(spec) + .partition(partition) + .keyMetadata(keyMetadata) + .overwrite() + .build(); + } catch (IOException e) { + throw new UncheckedIOException("Failed to create new position delete writer", e); + } + } +} From 91c331f6ed7da02c8d478a1d90191e741c3eaa98 Mon Sep 17 00:00:00 2001 From: Peter Vary Date: Mon, 16 Feb 2026 21:07:38 +0100 Subject: [PATCH 2/5] Eduard's comments --- .../iceberg/data/BaseFileWriterFactory.java | 2 +- .../data/GenericFileWriterFactory.java | 44 ++++++++----------- 2 files changed, 20 insertions(+), 26 deletions(-) diff --git a/data/src/main/java/org/apache/iceberg/data/BaseFileWriterFactory.java b/data/src/main/java/org/apache/iceberg/data/BaseFileWriterFactory.java index 486ea99f7aa6..444c0d0226bd 100644 --- a/data/src/main/java/org/apache/iceberg/data/BaseFileWriterFactory.java +++ b/data/src/main/java/org/apache/iceberg/data/BaseFileWriterFactory.java @@ -43,7 +43,7 @@ /** * A base writer factory to be extended by query engine integrations. * - * @deprecated deprecated as of version 1.11.0 and will be removed in 1.12.0. Use {@link + * @deprecated since version 1.11.0 and will be removed in 1.12.0. Use {@link * RegistryBasedFileWriterFactory} */ @Deprecated diff --git a/data/src/main/java/org/apache/iceberg/data/GenericFileWriterFactory.java b/data/src/main/java/org/apache/iceberg/data/GenericFileWriterFactory.java index 04ade3597a0d..91a0bd66dd53 100644 --- a/data/src/main/java/org/apache/iceberg/data/GenericFileWriterFactory.java +++ b/data/src/main/java/org/apache/iceberg/data/GenericFileWriterFactory.java @@ -150,90 +150,84 @@ static Builder builderFor(Table table) { } /** - * @deprecated Since 1.10.0, will be removed in 1.11.0. It won't be called starting 1.10.0 as the + * @deprecated Since 1.11.0, will be removed in 1.12.0. It won't be called starting 1.11.0 as the * configuration is done by the {@link FormatModelRegistry}. */ @Deprecated protected void configureDataWrite(Avro.DataWriteBuilder builder) { - throwUnsupportedOperationException(); + builder.createWriterFunc(DataWriter::create); } /** - * @deprecated Since 1.10.0, will be removed in 1.11.0. It won't be called starting 1.10.0 as the + * @deprecated Since 1.11.0, will be removed in 1.12.0. It won't be called starting 1.11.0 as the * configuration is done by the {@link FormatModelRegistry}. */ @Deprecated protected void configureEqualityDelete(Avro.DeleteWriteBuilder builder) { - throwUnsupportedOperationException(); + builder.createWriterFunc(DataWriter::create); } /** - * @deprecated Since 1.10.0, will be removed in 1.11.0. It won't be called starting 1.10.0 as the + * @deprecated Since 1.11.0, will be removed in 1.12.0. It won't be called starting 1.11.0 as the * configuration is done by the {@link FormatModelRegistry}. */ @Deprecated protected void configurePositionDelete(Avro.DeleteWriteBuilder builder) { - throwUnsupportedOperationException(); + builder.createWriterFunc(DataWriter::create); } /** - * @deprecated Since 1.10.0, will be removed in 1.11.0. It won't be called starting 1.10.0 as the + * @deprecated Since 1.11.0, will be removed in 1.12.0. It won't be called starting 1.11.0 as the * configuration is done by the {@link FormatModelRegistry}. */ @Deprecated protected void configureDataWrite(Parquet.DataWriteBuilder builder) { - throwUnsupportedOperationException(); + builder.createWriterFunc(GenericParquetWriter::create); } /** - * @deprecated Since 1.10.0, will be removed in 1.11.0. It won't be called starting 1.10.0 as the + * @deprecated Since 1.11.0, will be removed in 1.12.0. It won't be called starting 1.11.0 as the * configuration is done by the {@link FormatModelRegistry}. */ @Deprecated protected void configureEqualityDelete(Parquet.DeleteWriteBuilder builder) { - throwUnsupportedOperationException(); + builder.createWriterFunc(GenericParquetWriter::create); } /** - * @deprecated Since 1.10.0, will be removed in 1.11.0. It won't be called starting 1.10.0 as the + * @deprecated Since 1.11.0, will be removed in 1.12.0. It won't be called starting 1.11.0 as the * configuration is done by the {@link FormatModelRegistry}. */ @Deprecated protected void configurePositionDelete(Parquet.DeleteWriteBuilder builder) { - throwUnsupportedOperationException(); + builder.createWriterFunc(GenericParquetWriter::create); } /** - * @deprecated Since 1.10.0, will be removed in 1.11.0. It won't be called starting 1.10.0 as the + * @deprecated Since 1.11.0, will be removed in 1.12.0. It won't be called starting 1.11.0 as the * configuration is done by the {@link FormatModelRegistry}. */ @Deprecated protected void configureDataWrite(ORC.DataWriteBuilder builder) { - throwUnsupportedOperationException(); + builder.createWriterFunc(GenericOrcWriter::buildWriter); } /** - * @deprecated Since 1.10.0, will be removed in 1.11.0. It won't be called starting 1.10.0 as the + * @deprecated Since 1.11.0, will be removed in 1.12.0. It won't be called starting 1.11.0 as the * configuration is done by the {@link FormatModelRegistry}. */ @Deprecated protected void configureEqualityDelete(ORC.DeleteWriteBuilder builder) { - throwUnsupportedOperationException(); + builder.createWriterFunc(GenericOrcWriter::buildWriter); } /** - * @deprecated Since 1.10.0, will be removed in 1.11.0. It won't be called starting 1.10.0 as the + * @deprecated Since 1.11.0, will be removed in 1.12.0. It won't be called starting 1.11.0 as the * configuration is done by the {@link FormatModelRegistry}. */ @Deprecated protected void configurePositionDelete(ORC.DeleteWriteBuilder builder) { - throwUnsupportedOperationException(); - } - - private void throwUnsupportedOperationException() { - throw new UnsupportedOperationException( - "Method is deprecated and should not be called. " - + "Configuration is already done by the registry."); + builder.createWriterFunc(GenericOrcWriter::buildWriter); } @Override @@ -242,7 +236,7 @@ public PositionDeleteWriter newPositionDeleteWriter( if (positionDeleteRowSchema == null) { return super.newPositionDeleteWriter(file, spec, partition); } else { - LOG.info( + LOG.warn( "Deprecated feature used. Position delete row schema is used to create the position delete writer."); MetricsConfig metricsConfig = table != null From 05c4db70d4fcfffffd269d6d9924c3c78d0fdb29 Mon Sep 17 00:00:00 2001 From: Peter Vary Date: Tue, 17 Feb 2026 08:17:51 +0100 Subject: [PATCH 3/5] Eduard's second batch of comments --- .../data/GenericFileWriterFactory.java | 38 +++++++++---------- .../data/RegistryBasedFileWriterFactory.java | 4 +- 2 files changed, 21 insertions(+), 21 deletions(-) diff --git a/data/src/main/java/org/apache/iceberg/data/GenericFileWriterFactory.java b/data/src/main/java/org/apache/iceberg/data/GenericFileWriterFactory.java index 91a0bd66dd53..b689f80545ec 100644 --- a/data/src/main/java/org/apache/iceberg/data/GenericFileWriterFactory.java +++ b/data/src/main/java/org/apache/iceberg/data/GenericFileWriterFactory.java @@ -150,8 +150,8 @@ static Builder builderFor(Table table) { } /** - * @deprecated Since 1.11.0, will be removed in 1.12.0. It won't be called starting 1.11.0 as the - * configuration is done by the {@link FormatModelRegistry}. + * @deprecated Since 1.11.0, will be removed in 1.12.0. It won't be called starting in 1.11.0 as + * the configuration is done by the {@link FormatModelRegistry}. */ @Deprecated protected void configureDataWrite(Avro.DataWriteBuilder builder) { @@ -159,8 +159,8 @@ protected void configureDataWrite(Avro.DataWriteBuilder builder) { } /** - * @deprecated Since 1.11.0, will be removed in 1.12.0. It won't be called starting 1.11.0 as the - * configuration is done by the {@link FormatModelRegistry}. + * @deprecated Since 1.11.0, will be removed in 1.12.0. It won't be called starting in 1.11.0 as + * the configuration is done by the {@link FormatModelRegistry}. */ @Deprecated protected void configureEqualityDelete(Avro.DeleteWriteBuilder builder) { @@ -168,8 +168,8 @@ protected void configureEqualityDelete(Avro.DeleteWriteBuilder builder) { } /** - * @deprecated Since 1.11.0, will be removed in 1.12.0. It won't be called starting 1.11.0 as the - * configuration is done by the {@link FormatModelRegistry}. + * @deprecated Since 1.11.0, will be removed in 1.12.0. It won't be called starting in 1.11.0 as + * the configuration is done by the {@link FormatModelRegistry}. */ @Deprecated protected void configurePositionDelete(Avro.DeleteWriteBuilder builder) { @@ -177,8 +177,8 @@ protected void configurePositionDelete(Avro.DeleteWriteBuilder builder) { } /** - * @deprecated Since 1.11.0, will be removed in 1.12.0. It won't be called starting 1.11.0 as the - * configuration is done by the {@link FormatModelRegistry}. + * @deprecated Since 1.11.0, will be removed in 1.12.0. It won't be called starting in 1.11.0 as + * the configuration is done by the {@link FormatModelRegistry}. */ @Deprecated protected void configureDataWrite(Parquet.DataWriteBuilder builder) { @@ -186,8 +186,8 @@ protected void configureDataWrite(Parquet.DataWriteBuilder builder) { } /** - * @deprecated Since 1.11.0, will be removed in 1.12.0. It won't be called starting 1.11.0 as the - * configuration is done by the {@link FormatModelRegistry}. + * @deprecated Since 1.11.0, will be removed in 1.12.0. It won't be called starting in 1.11.0 as + * the configuration is done by the {@link FormatModelRegistry}. */ @Deprecated protected void configureEqualityDelete(Parquet.DeleteWriteBuilder builder) { @@ -195,8 +195,8 @@ protected void configureEqualityDelete(Parquet.DeleteWriteBuilder builder) { } /** - * @deprecated Since 1.11.0, will be removed in 1.12.0. It won't be called starting 1.11.0 as the - * configuration is done by the {@link FormatModelRegistry}. + * @deprecated Since 1.11.0, will be removed in 1.12.0. It won't be called starting in 1.11.0 as + * the configuration is done by the {@link FormatModelRegistry}. */ @Deprecated protected void configurePositionDelete(Parquet.DeleteWriteBuilder builder) { @@ -204,8 +204,8 @@ protected void configurePositionDelete(Parquet.DeleteWriteBuilder builder) { } /** - * @deprecated Since 1.11.0, will be removed in 1.12.0. It won't be called starting 1.11.0 as the - * configuration is done by the {@link FormatModelRegistry}. + * @deprecated Since 1.11.0, will be removed in 1.12.0. It won't be called starting in 1.11.0 as + * the configuration is done by the {@link FormatModelRegistry}. */ @Deprecated protected void configureDataWrite(ORC.DataWriteBuilder builder) { @@ -213,8 +213,8 @@ protected void configureDataWrite(ORC.DataWriteBuilder builder) { } /** - * @deprecated Since 1.11.0, will be removed in 1.12.0. It won't be called starting 1.11.0 as the - * configuration is done by the {@link FormatModelRegistry}. + * @deprecated Since 1.11.0, will be removed in 1.12.0. It won't be called starting in 1.11.0 as + * the configuration is done by the {@link FormatModelRegistry}. */ @Deprecated protected void configureEqualityDelete(ORC.DeleteWriteBuilder builder) { @@ -222,8 +222,8 @@ protected void configureEqualityDelete(ORC.DeleteWriteBuilder builder) { } /** - * @deprecated Since 1.11.0, will be removed in 1.12.0. It won't be called starting 1.11.0 as the - * configuration is done by the {@link FormatModelRegistry}. + * @deprecated Since 1.11.0, will be removed in 1.12.0. It won't be called starting in 1.11.0 as + * the configuration is done by the {@link FormatModelRegistry}. */ @Deprecated protected void configurePositionDelete(ORC.DeleteWriteBuilder builder) { @@ -241,7 +241,7 @@ public PositionDeleteWriter newPositionDeleteWriter( MetricsConfig metricsConfig = table != null ? MetricsConfig.forPositionDelete(table) - : MetricsConfig.fromProperties(ImmutableMap.of()); + : MetricsConfig.forPositionDelete(); try { return switch (format) { diff --git a/data/src/main/java/org/apache/iceberg/data/RegistryBasedFileWriterFactory.java b/data/src/main/java/org/apache/iceberg/data/RegistryBasedFileWriterFactory.java index 3d0e2e8fb030..868b41f5840b 100644 --- a/data/src/main/java/org/apache/iceberg/data/RegistryBasedFileWriterFactory.java +++ b/data/src/main/java/org/apache/iceberg/data/RegistryBasedFileWriterFactory.java @@ -98,7 +98,7 @@ protected S equalityDeleteInputSchema() { @Override public DataWriter newDataWriter( EncryptedOutputFile file, PartitionSpec spec, StructLike partition) { - Preconditions.checkNotNull(dataSchema, "Data schema must not be null"); + Preconditions.checkArgument(dataSchema != null, "Invalid data schema: null"); EncryptionKeyMetadata keyMetadata = file.keyMetadata(); Map properties = table != null ? table.properties() : ImmutableMap.of(); MetricsConfig metricsConfig = @@ -127,7 +127,7 @@ public DataWriter newDataWriter( @Override public EqualityDeleteWriter newEqualityDeleteWriter( EncryptedOutputFile file, PartitionSpec spec, StructLike partition) { - Preconditions.checkNotNull(equalityDeleteRowSchema, "Equality delete schema must not be null"); + Preconditions.checkArgument(equalityDeleteRowSchema != null, "Invalid delete schema: null"); EncryptionKeyMetadata keyMetadata = file.keyMetadata(); Map properties = table != null ? table.properties() : ImmutableMap.of(); From a8c8500127af243bfb1fff129d04300568698e4f Mon Sep 17 00:00:00 2001 From: Peter Vary Date: Tue, 17 Feb 2026 10:25:14 +0100 Subject: [PATCH 4/5] Set metrics config and writer configurations in the fallback path --- .../iceberg/data/GenericFileWriterFactory.java | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/data/src/main/java/org/apache/iceberg/data/GenericFileWriterFactory.java b/data/src/main/java/org/apache/iceberg/data/GenericFileWriterFactory.java index b689f80545ec..8b53ebbe2bf5 100644 --- a/data/src/main/java/org/apache/iceberg/data/GenericFileWriterFactory.java +++ b/data/src/main/java/org/apache/iceberg/data/GenericFileWriterFactory.java @@ -52,6 +52,7 @@ public class GenericFileWriterFactory extends RegistryBasedFileWriterFactory writerProperties; GenericFileWriterFactory( Table table, @@ -111,6 +112,7 @@ public class GenericFileWriterFactory extends RegistryBasedFileWriterFactory newPositionDeleteWriter( } else { LOG.warn( "Deprecated feature used. Position delete row schema is used to create the position delete writer."); + Map properties = table == null ? ImmutableMap.of() : table.properties(); MetricsConfig metricsConfig = - table != null - ? MetricsConfig.forPositionDelete(table) - : MetricsConfig.forPositionDelete(); + table == null + ? MetricsConfig.forPositionDelete() + : MetricsConfig.forPositionDelete(table); try { return switch (format) { case AVRO -> Avro.writeDeletes(file) + .setAll(properties) + .setAll(writerProperties) + .metricsConfig(metricsConfig) .createWriterFunc(DataWriter::create) .withPartition(partition) .overwrite() @@ -256,6 +262,9 @@ public PositionDeleteWriter newPositionDeleteWriter( .buildPositionWriter(); case ORC -> ORC.writeDeletes(file) + .setAll(properties) + .setAll(writerProperties) + .metricsConfig(metricsConfig) .createWriterFunc(GenericOrcWriter::buildWriter) .withPartition(partition) .overwrite() @@ -265,6 +274,9 @@ public PositionDeleteWriter newPositionDeleteWriter( .buildPositionWriter(); case PARQUET -> Parquet.writeDeletes(file) + .setAll(properties) + .setAll(writerProperties) + .metricsConfig(metricsConfig) .createWriterFunc(GenericParquetWriter::create) .withPartition(partition) .overwrite() From 9c3d1443b3e8901161051827e20965b380644558 Mon Sep 17 00:00:00 2001 From: Peter Vary Date: Tue, 17 Feb 2026 11:25:20 +0100 Subject: [PATCH 5/5] dedup metricsConfig set --- .../java/org/apache/iceberg/data/GenericFileWriterFactory.java | 1 - 1 file changed, 1 deletion(-) diff --git a/data/src/main/java/org/apache/iceberg/data/GenericFileWriterFactory.java b/data/src/main/java/org/apache/iceberg/data/GenericFileWriterFactory.java index 8b53ebbe2bf5..1e75b9eda961 100644 --- a/data/src/main/java/org/apache/iceberg/data/GenericFileWriterFactory.java +++ b/data/src/main/java/org/apache/iceberg/data/GenericFileWriterFactory.java @@ -280,7 +280,6 @@ public PositionDeleteWriter newPositionDeleteWriter( .createWriterFunc(GenericParquetWriter::create) .withPartition(partition) .overwrite() - .metricsConfig(metricsConfig) .rowSchema(positionDeleteRowSchema) .withSpec(spec) .withKeyMetadata(file.keyMetadata())