Hi Gabor,

Thanks for the detailed example.

I agree with Steven that Option 2 seems reasonable. I will add a section to
the design doc regarding equality delete handling, and we can discuss this
further during our meeting on Tuesday.

~Anurag

On Fri, Feb 6, 2026 at 7:08 AM Steven Wu <[email protected]> wrote:

> > 1) When deleting with eq-deletes: If there is a column update on the
> equality-filed ID we use for the delete, reject deletion
> > 2) When adding a column update on a column that is part of the equality
> field IDs in some delete, we reject the column update
>
> Gabor, this is a good scenario. The 2nd option makes sense to me, since
> equality ids are like primary key fields. If we have the 2nd rule enforced,
> the first option is not applicable anymore.
>
> On Fri, Feb 6, 2026 at 3:13 AM Gábor Kaszab <[email protected]>
> wrote:
>
>> Hey,
>>
>> Thank you for the proposal, Anurag! I made a pass recently and I think
>> there is some interference between column updates and equality deletes. Let
>> me describe below:
>>
>> Steps:
>>
>> CREATE TABLE tbl (int a, int b);
>>
>> INSERT INTO tbl VALUES (1, 11), (2, 22);  -- creates the base data file
>>
>> DELETE FROM tbl WHERE b=11;               -- creates an equality delete
>> file
>>
>> UPDATE tbl SET b=11;                                   -- writes column
>> update
>>
>>
>>
>> SELECT * FROM tbl;
>>
>> Expected result:
>>
>> (2, 11)
>>
>>
>>
>> Data and metadata created after the above steps:
>>
>> Base file
>>
>> (1, 11), (2, 22),
>>
>> seqnum=1
>>
>> EQ-delete
>>
>> b=11
>>
>> seqnum=2
>>
>> Column update
>>
>> Field ids: [field_id_for_col_b]
>>
>> seqnum=3
>>
>> Data file content: (dummy_value),(11)
>>
>>
>>
>> Read steps:
>>
>>    1. Stitch base file with column updates in reader:
>>
>> Rows: (1,dummy_value), (2,11) (Note, dummy value can be either null, or
>> 11, see the proposal for more details)
>>
>> Seqnum for base file=1
>>
>> Seqnum for column update=3
>>
>>    2. Apply eq-delete b=11, seqnum=3 on the stitched result
>>    3. Query result depends on which seqnum we carry forward to compare
>>    with the eq-delete's seqnum, but it's not correct in any of the cases
>>       1. Use seqnum from base file: we get either an empty result if
>>       'dummy_value' is 11 or we get (1, null) otherwise
>>       2. Use seqnum from last update file: don't delete any rows, result
>>       set is (1, dummy_value),(2,11)
>>
>>
>>
>> Problem:
>>
>> EQ-delete should be applied midway applying the column updates to the
>> base file based on sequence number, during the stitching process. If I'm
>> not mistaken, this is not feasible with the way readers work.
>>
>>
>> Proposal:
>>
>> Don't allow equality deletes together with column updates.
>>
>>   1) When deleting with eq-deletes: If there is a column update on the
>> equality-filed ID we use for the delete, reject deletion
>>
>>   2) When adding a column update on a column that is part of the equality
>> field IDs in some delete, we reject the column update
>>
>> Alternatively, column updates could be controlled by a property of the
>> table (immutable), and reject eq-deletes if the property indicates column
>> updates are turned on for the table
>>
>>
>> Let me know what you think!
>>
>> Best Regards,
>>
>> Gabor
>>
>> Anurag Mantripragada <[email protected]> ezt írta (időpont: 2026.
>> jan. 28., Sze, 3:31):
>>
>>> Thank you everyone for the initial review comments. It is exciting to
>>> see so much interest in this proposal.
>>>
>>> I am currently reviewing and responding to each comment. The general
>>> themes of the feedback so far include:
>>> - Including partial updates (column updates on a subset of rows in a
>>> table).
>>> - Adding details on how SQL engines will write the update files.
>>> - Adding details on split planning and row alignment for update files.
>>>
>>> I will think through these points and update the design accordingly.
>>>
>>> Best
>>> Anurag
>>>
>>> On Tue, Jan 27, 2026 at 6:25 PM Anurag Mantripragada <
>>> [email protected]> wrote:
>>>
>>>> Hi Xiangin,
>>>>
>>>> Happy to learn from your experience in supporting backfill use-cases.
>>>> Please feel free to review the proposal and add your comments. I will wait
>>>> for a couple of days more to ensure everyone has a chance to review the
>>>> proposal.
>>>>
>>>> ~ Anurag
>>>>
>>>> On Tue, Jan 27, 2026 at 6:42 AM Xianjin Ye <[email protected]> wrote:
>>>>
>>>>> Hi Anurag and Peter,
>>>>>
>>>>> It’s great to see the partial column update has gained great interest
>>>>> in the community. I internally built a BackfillColumns action to
>>>>> efficiently backfill columns(by writing the partial columns only and 
>>>>> copies
>>>>> the binary data of other columns into a new DataFile). The speedup could 
>>>>> be
>>>>> 10x for wide tables but the write amplification is still there. I would be
>>>>> happy to collaborate on the work and eliminate the write amplification.
>>>>>
>>>>> On 2026/01/27 10:12:54 Péter Váry wrote:
>>>>> > Hi Anurag,
>>>>> >
>>>>> > It’s great to see how much interest there is in the community around
>>>>> this
>>>>> > potential new feature. Gábor and I have actually submitted an Iceberg
>>>>> > Summit talk proposal on this topic, and we would be very happy to
>>>>> > collaborate on the work. I was mainly waiting for the File Format
>>>>> API to be
>>>>> > finalized, as I believe this feature should build on top of it.
>>>>> >
>>>>> > For reference, our related work includes:
>>>>> >
>>>>> >    - *Dev list thread:*
>>>>> >    https://lists.apache.org/thread/h0941sdq9jwrb6sj0pjfjjxov8tx7ov9
>>>>> >    - *Proposal document:*
>>>>> >
>>>>> https://docs.google.com/document/d/1OHuZ6RyzZvCOQ6UQoV84GzwVp3UPiu_cfXClsOi03ww
>>>>> >    (not shared widely yet)
>>>>> >    - *Performance testing PR for readers and writers:*
>>>>> >    https://github.com/apache/iceberg/pull/13306
>>>>> >
>>>>> > During earlier discussions about possible metadata changes, another
>>>>> option
>>>>> > came up that hasn’t been documented yet: separating planner metadata
>>>>> from
>>>>> > reader metadata. Since the planner does not need to know about the
>>>>> actual
>>>>> > files, we could store the file composition in a separate file
>>>>> (potentially
>>>>> > a Puffin file). This file could hold the column_files metadata,
>>>>> while the
>>>>> > manifest would reference the Puffin file and blob position instead
>>>>> of the
>>>>> > data filename.
>>>>> > This approach has the advantage of keeping the existing metadata
>>>>> largely
>>>>> > intact, and it could also give us a natural place later to add
>>>>> file-level
>>>>> > indexes or Bloom filters for use during reads or secondary
>>>>> filtering. The
>>>>> > downsides are the additional files and the increased complexity of
>>>>> > identifying files that are no longer referenced by the table, so
>>>>> this may
>>>>> > not be an ideal solution.
>>>>> >
>>>>> > I do have some concerns about the MoR metadata proposal described in
>>>>> the
>>>>> > document. At first glance, it seems to complicate distributed
>>>>> planning, as
>>>>> > all entries for a given file would need to be collected and merged to
>>>>> > provide the information required by both the planner and the reader.
>>>>> > Additionally, when a new column is added or updated, we would still
>>>>> need to
>>>>> > add a new metadata entry for every existing data file. If we
>>>>> immediately
>>>>> > write out the merged metadata, the total number of entries remains
>>>>> the
>>>>> > same. The main benefit is avoiding rewriting statistics, which can be
>>>>> > significant, but this comes at the cost of increased planning
>>>>> complexity.
>>>>> > If we choose to store the merged statistics in the column_families
>>>>> entry, I
>>>>> > don’t see much benefit in excluding the rest of the metadata,
>>>>> especially
>>>>> > since including it would simplify the planning process.
>>>>> >
>>>>> > As Anton already pointed out, we should also discuss how this change
>>>>> would
>>>>> > affect split handling, particularly how to avoid double reads when
>>>>> row
>>>>> > groups are not aligned between the original data files and the new
>>>>> column
>>>>> > files.
>>>>> >
>>>>> > Finally, I’d like to see some discussion around the Java API
>>>>> implications.
>>>>> > In particular, what API changes are required, and how SQL engines
>>>>> would
>>>>> > perform updates. Since the new column files must have the same
>>>>> number of
>>>>> > rows as the original data files, with a strict one-to-one
>>>>> relationship, SQL
>>>>> > engines would need access to the source filename, position, and
>>>>> deletion
>>>>> > status in the DataFrame in order to generate the new files. This is
>>>>> more
>>>>> > involved than a simple update and deserves some explicit
>>>>> consideration.
>>>>> >
>>>>> > Looking forward to your thoughts.
>>>>> > Best regards,
>>>>> > Peter
>>>>> >
>>>>> > On Tue, Jan 27, 2026, 03:58 Anurag Mantripragada <
>>>>> [email protected]>
>>>>> > wrote:
>>>>> >
>>>>> > > Thanks Anton and others, for providing some initial feedback. I
>>>>> will
>>>>> > > address all your comments soon.
>>>>> > >
>>>>> > > On Mon, Jan 26, 2026 at 11:10 AM Anton Okolnychyi <
>>>>> [email protected]>
>>>>> > > wrote:
>>>>> > >
>>>>> > >> I had a chance to see the proposal before it landed and I think
>>>>> it is a
>>>>> > >> cool idea and both presented approaches would likely work. I am
>>>>> looking
>>>>> > >> forward to discussing the tradeoffs and would encourage everyone
>>>>> to
>>>>> > >> push/polish each approach to see what issues can be mitigated and
>>>>> what are
>>>>> > >> fundamental.
>>>>> > >>
>>>>> > >> [1] Iceberg-native approach: better visibility into column files
>>>>> from the
>>>>> > >> metadata, potentially better concurrency for non-overlapping
>>>>> column
>>>>> > >> updates, no dep on Parquet.
>>>>> > >> [2] Parquet-native approach: almost no changes to the table format
>>>>> > >> metadata beyond tracking of base files.
>>>>> > >>
>>>>> > >> I think [1] sounds a bit better on paper but I am worried about
>>>>> the
>>>>> > >> complexity in writers and readers (especially around keeping row
>>>>> groups
>>>>> > >> aligned and split planning). It would be great to cover this in
>>>>> detail in
>>>>> > >> the proposal.
>>>>> > >>
>>>>> > >> пн, 26 січ. 2026 р. о 09:00 Anurag Mantripragada <
>>>>> > >> [email protected]> пише:
>>>>> > >>
>>>>> > >>> Hi all,
>>>>> > >>>
>>>>> > >>> "Wide tables" with thousands of columns present significant
>>>>> challenges
>>>>> > >>> for AI/ML workloads, particularly when only a subset of columns
>>>>> needs to be
>>>>> > >>> added or updated. Current Copy-on-Write (COW) and Merge-on-Read
>>>>> (MOR)
>>>>> > >>> operations in Iceberg apply at the row level, which leads to
>>>>> substantial
>>>>> > >>> write amplification in scenarios such as:
>>>>> > >>>
>>>>> > >>>    - Feature Backfilling & Column Updates: Adding new feature
>>>>> columns
>>>>> > >>>    (e.g., model embeddings) to petabyte-scale tables.
>>>>> > >>>    - Model Score Updates: Refresh prediction scores after
>>>>> retraining.
>>>>> > >>>    - Embedding Refresh: Updating vector embeddings, which
>>>>> currently
>>>>> > >>>    triggers a rewrite of the entire row.
>>>>> > >>>    - Incremental Feature Computation: Daily updates to a small
>>>>> fraction
>>>>> > >>>    of features in wide tables.
>>>>> > >>>
>>>>> > >>> With the Iceberg V4 proposal introducing single-file commits and
>>>>> column
>>>>> > >>> stats improvements, this is an ideal time to address
>>>>> column-level updates
>>>>> > >>> to better support these use cases.
>>>>> > >>>
>>>>> > >>> I have drafted a proposal that explores both table-format
>>>>> enhancements
>>>>> > >>> and file-format (Parquet) changes to enable more efficient
>>>>> updates.
>>>>> > >>>
>>>>> > >>> Proposal Details:
>>>>> > >>> - GitHub Issue: #15146 <
>>>>> https://github.com/apache/iceberg/issues/15146>
>>>>> > >>> - Design Document: Efficient Column Updates in Iceberg
>>>>> > >>> <
>>>>> https://docs.google.com/document/d/1Bd7JVzgajA8-DozzeEE24mID_GLuz6iwj0g4TlcVJcs/edit?tab=t.0
>>>>> >
>>>>> > >>>
>>>>> > >>> Next Steps:
>>>>> > >>> I plan to create POCs to benchmark the approaches described in
>>>>> the
>>>>> > >>> document.
>>>>> > >>>
>>>>> > >>> Please review the proposal and share your feedback.
>>>>> > >>>
>>>>> > >>> Thanks,
>>>>> > >>> Anurag
>>>>> > >>>
>>>>> > >>
>>>>> >
>>>>>
>>>>

Reply via email to