Skip to content

Core: Add Eager fetch to parquet read path - #17284

Merged
RussellSpitzer merged 11 commits into
apache:mainfrom
varun-lakhyani:manifest-eagerinputfile
Sep 1, 2026
Merged

RussellSpitzer merged 11 commits into
apache:mainfrom
varun-lakhyani:manifest-eagerinputfile

Conversation

@varun-lakhyani

@varun-lakhyani varun-lakhyani commented Jul 18, 2026 •

Copy link
Copy Markdown
Contributor

Summary

Wire Eager Fetch (EagerInputFile/EagerInputStream) into Parquet read path so any Parquet read (Manifest, Datafile etc) ≤ 1 MB are read in a single S3 GET instead of three (footer length → footer → row group).

EagerInputFile Implementation #16729
It trusts the supplied (recorded) file length for paruqet - breaks when it doesn't match the real length.

Behavior change for HadoopFileIO

For Parquet reads through HadoopFileIO, files at or below the 1 MiB eager fetch threshold now trust and use the length reported by InputFile.getLength(), which may have been initialized from Iceberg metadata rather than retrieving the physical file size through HadoopInputFile.getStat().

Previously, Hadoop backed reads could tolerate an incorrect metadata length because the physical file size was returned by getStat(). Other implementations such as S3InputFile already trust the metadata provided length when available. This change makes the eager Hadoop path consistent with all those implementations but an incorrect metadata length can now cause the eager read to fail - Eager checks if reported length is equal to actual, if not fails at EagerInputFile.newStream for both cases( file is longer/shorter than reported length).

Why

Detailed Benchmark setup and results comment below

  • S3 GET requests from 3 → 1 per manifest read
  • Improves manifest read by ~25–41% for Parquet manifests
  • ~55% reduction in read time (Benchmarked independently by @vaquarkhan)

Benchmark methodology, JMH output, raw S3 access logs - https://github.com/varun-lakhyani/iceberg-manifest-eagerpath-benchmark/blob/main/README.md

Benchmark for parquet datafile read

Reproducing

Fork this branch - change only the S3 location/region.
(Integration here is little different than actual as benchmark is using flag and just manifest rather than overall)

Run EagerFetchScalingBenchmark or ManifestBenchmark

@github-actions github-actions Bot added the core label Jul 18, 2026
@varun-lakhyani varun-lakhyani changed the title Use EagerInputFile in Manifest reader path Core: Use EagerInputFile in Manifest reader path Jul 18, 2026
@varun-lakhyani

varun-lakhyani commented Jul 20, 2026 •

Copy link
Copy Markdown
Contributor Author

Benchmark Setup (JMH)

Machine: AWS EC2 (same region as the S3 bucket to minimize network latency)

Property Value
Instance type r5.4xlarge
vCPUs 16
Memory 128 GB
Network Up to 10 Gbps
Storage 50 GB gp3 EBS
AMI Amazon Linux 2023
Region ap-south-1 (Mumbai)

Benchmark: ManifestBenchmark

  • Warmup iterations: 6
  • Measurement iterations: 10
  • Entry Counts: 37500

Results

Parquet v4 (Non-Partitioned)

Number of Columns Default (s/op) Eager Fetch (s/op) Latency Reduction
10 0.142 0.100 29.6%
50 0.134 0.100 25.4%
100 0.138 0.101 26.8%

Parquet v4 (Partitioned)

Number of Columns Default (s/op) Eager Fetch (s/op) Latency Reduction
10 0.161 0.094 41.6%
50 0.170 0.100 41.2%
100 0.134 0.096 28.4%

AVRO v4 (Non-Partitioned)

Number of Columns Default (s/op) Eager Fetch (s/op) Latency Reduction
10 0.086 0.095 -10.5%
50 0.086 0.082 4.7%
100 0.080 0.076 5.0%

AVRO v4 (Partitioned)

Number of Columns Default (s/op) Eager Fetch (s/op) Latency Reduction
10 0.092 0.095 -3.3%
50 0.086 0.086 0.0%
100 0.094 0.088 6.4%

Graphical Comparison

manifest_grouped_bars

S3 Request Analysis

S3 access logs confirm 3 GETs/read (default) → 1 GET/read (eager)

@varun-lakhyani varun-lakhyani changed the title Core: Use EagerInputFile in Manifest reader path Core: Add EagerInputFile in Manifest reader path Jul 20, 2026
return contentCache(io).tryCache(input);
}

if (eagerFetchEnabled(io)) {

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's get some integration tests on this to make sure that when our parameter is enabled it is actually using eager

@varun-lakhyani varun-lakhyani Jul 28, 2026 •

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added in TestManifestReader - 2 tests

  • verifies it routes to EagerInputFile based on flag and size threshold (required making newInputFile package-private)
  • verifies manifest entries are read back correctly when eager fetch is enabled

*/
public static final String IO_MANIFEST_EAGER_FETCH_ENABLED = "io.manifest.eager-fetch-enabled";

public static final boolean IO_MANIFEST_EAGER_FETCH_ENABLED_DEFAULT = false;

@varun-lakhyani varun-lakhyani Jul 28, 2026 •

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we can make this default true, It would be great improvement for v4 parquet manifest.
I would love to hear thoughts on this.

@vaquarkhan

vaquarkhan commented Jul 29, 2026 •

Copy link
Copy Markdown

Thanks @varun-lakhyani for the thorough benchmark, the graph, and especially the S3 GET breakdown (3 -> 1). That
request count is the strongest part of the story since it does not depend on the machine.

I reproduced this on my own account (EC2 r7i.2xlarge, us-east-1, S3, JDK 17, same JMH warmup and measurement settings) and the direction holds cleanly:

  • Parquet v4, numCols=50, non-partitioned: 0.141 -> 0.063 s/op with eager on.
  • Avro v4: 0.060 -> 0.061 s/op, no change.

My baseline matches yours closely (0.141 vs your 0.134). My eager number is lower (0.063 vs 0.100),most likely because of the newer instance: the eager path reads the whole file into memory and serves from RAM, so it gains from faster CPU and memory, while the network-bound default path stays about the same. Different hardware, same conclusion.

image

I also ran one extra benchmark, same read path, adding a local filesystem and a size sweep across the 1 MB threshold:

  1. Local filesystem: eager gives no benefit, and for a small Parquet manifest it looked slightly slower (within noise). No round trip to collapse locally, so this is expected. This is why I would keep it behind the flag rather than always on.

  2. Size sweep: below 1 MB the S3 Parquet win holds (~52-53%); above 1 MB it correctly does not fire.
    The 1 MB cap behaves as intended.

  3. Avro vs Parquet baseline (eager off): on S3, a Parquet manifest read is about 1.9x-2.4x slower than an Avro manifest of the same size (non-overlapping error bars). On local disk there is no such gap. With eager on, the S3 Parquet read comes back down close to Avro. So eager fetch is really closing the object-store Parquet penalty, which lines up with your 3 -> 1 GET result.

image

Net: a solid win for Parquet manifests on object storage under the 1 MB cap, little or nothing for Avro or on local storage. I would keep the default off, or scope any future default to object store plus Parquet under the cap, rather than always on.

One reproducibility note: the benchmark branch did not build/run for me as-is. The iceberg-core jmh source set has no iceberg-aws dependency and the AWS SDK is compile-only, so :iceberg-core:jmh fails to compile and then at runtime with missing AWS classes. I added iceberg-aws plus the SDK to the jmh classpath to get it running; might be worth including so others can reproduce.

I'll share a Google Doc with the full numbers and charts, this weekend

vaquarkhan added a commit to vaquarkhan/iceberg that referenced this pull request Jul 29, 2026
Add a JMH benchmark that extends the manifest EagerInputFile work in PR apache#17284
with two dimensions the existing benchmark does not cover:
- storage: local filesystem (HadoopFileIO) vs S3 (S3FileIO)
- manifest size: a sweep that straddles the fixed 1 MB eager-fetch gate

It uses the real read path (io.manifest.eager-fetch-enabled set on the FileIO,
so ManifestFiles.read wraps the InputFile in EagerInputFile) and reuses
ManifestBenchmarkUtil to build the manifests. The measured manifest byte size
is printed per trial so the size-to-gate mapping is verified, not assumed.

Add iceberg-aws and the AWS SDK to the iceberg-core jmh classpath so the
S3FileIO-based manifest benchmarks compile and run.
@vaquarkhan

Copy link
Copy Markdown

Quick follow-up: @varun-lakhyani I pushed that extra benchmark as a commit here (EagerFetchScalingBenchmark plus the small build.gradle change so the jmh module picks up the AWS SDK). It reuses your ManifestBenchmarkUtil and the same read path.

I should have checked with you first before pushing, apologies if I got ahead of it.

Totally your call: keep it in this PR, or I can pull it out and send it as a separate follow-up PR, whichever you prefer. Full results and charts in a shared doc this weekend.

@RussellSpitzer

Copy link
Copy Markdown
Member

@vaquarkhan Thanks for the review here. I'd like to get more community feedback here but I'm thinking we should just have this default to always on with these kind of results. Right now it only applies for parquet manifests in V4 so we may want to disable it for V3 and below or check whether the file is parquet first? I'm not sure if that complexity really makes a difference though.

@vaquarkhan

Copy link
Copy Markdown

@RussellSpitzer , This makes sense. One observation from the numbers: as written the gate is size-based (<=1 MB),
not format-based, so "always on" would also wrap Avro and local-filesystem reads, where I saw no benefit and it still buffers the whole manifest into memory during planning. So our "check whether it's Parquet first" is the right call and matches the data.

That Parquet check also covers V3 and below on its own, since those are Avro-only, and it handles mixed manifests in a V4 table correctly, so I don't think a separate version check is needed.

Only caution: local filesystem showed no gain even for Parquet, and my numbers are single-shot on one instance, so a slightly broader run would be worth it before flipping the default. Happy to help validate.

varun-lakhyani pushed a commit to varun-lakhyani/iceberg that referenced this pull request Jul 30, 2026
Add a JMH benchmark that extends the manifest EagerInputFile work in PR apache#17284
with two dimensions the existing benchmark does not cover:
- storage: local filesystem (HadoopFileIO) vs S3 (S3FileIO)
- manifest size: a sweep that straddles the fixed 1 MB eager-fetch gate

It uses the real read path (io.manifest.eager-fetch-enabled set on the FileIO,
so ManifestFiles.read wraps the InputFile in EagerInputFile) and reuses
ManifestBenchmarkUtil to build the manifests. The measured manifest byte size
is printed per trial so the size-to-gate mapping is verified, not assumed.

Add iceberg-aws and the AWS SDK to the iceberg-core jmh classpath so the
S3FileIO-based manifest benchmarks compile and run.
@varun-lakhyani

varun-lakhyani commented Jul 30, 2026 •

Copy link
Copy Markdown
Contributor Author

Thanks @vaquarkhan for the review and extensive Benchmark run.
Agreed! numbers are almost similar to my run, although I ran for v1-v4 Avro and v4 Parquet but not for local.
I posted my JMH results and s3 bucket logs which conclusively shows 3 -> 1 GET calls on S3 for reference https://github.com/varun-lakhyani/iceberg-manifest-eagerpath-benchmark/blob/main/README.md

I am hoping the see community's view on keeping it default true.
Avro path showed no benefit as expected and local run also showed no result or little overhead as expected.
Let's see if we need some checks along with flag so it doesn't use this eagerPath in local or for Avro

Also, I pushed your commit to the benchmark branch anyone can fork it and run the benchmark as is, included the aws dependencies so its easy for folks to just run the benchmarks as is. Thanks

@kevinjqliu
kevinjqliu self-requested a review August 3, 2026 16:14
@RussellSpitzer RussellSpitzer added this to the Iceberg 1.12.0 milestone Aug 10, 2026

@anoopj anoopj left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please note that v4 manifest readers don't follow the ManifestFiles path, so the PR description is incorrect. We can add this to the v4 reader when #17541 is merged.

@RussellSpitzer

Copy link
Copy Markdown
Member

Please note that v4 manifest readers don't follow the ManifestFiles path, so the PR description is incorrect. We can add this to the v4 reader when #17541 is merged.

We had a discussion on the mailing list, and we are going to rework this to apply at the Parquet File Reader level so it just applies to all Parquet reads so the title will need a bit more reworking but we'll also cover everything.

@varun-lakhyani varun-lakhyani changed the title Core: Add EagerInputFile in Manifest reader path Core: Add Eager fetch to parquet read path Aug 13, 2026
@varun-lakhyani varun-lakhyani changed the title Core: Add Eager fetch to parquet read path [WIP] Core: Add Eager fetch to parquet read path Aug 13, 2026
@varun-lakhyani varun-lakhyani changed the title [WIP] Core: Add Eager fetch to parquet read path Core: [WIP] Add Eager fetch to parquet read path Aug 13, 2026
@varun-lakhyani

varun-lakhyani commented Aug 13, 2026 •

Copy link
Copy Markdown
Contributor Author

Yes a bit delay from my end, Updated title and description.
I am working on it, will update as soon I finish and push the changes, mostly 1-2 days.

@RussellSpitzer

Copy link
Copy Markdown
Member

There are some weird failures in https://github.com/apache/iceberg/actions/runs/31809741067/job/94797306211?pr=17284

I'm worried this is a downstream effect of our changes, Can you please check those our @varun-lakhyani

@@ -144,6 +145,12 @@ private Parquet() {}
"parquet.read.support.class",
"parquet.crypto.factory.class");

/*
* Size threshold (bytes) at or below which a Parquet file is fetched eagerly on the first read.
* Fixed at 1 MB - not user configurable

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This line of the comment isn't really needed :)

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fixed

@varun-lakhyani

Copy link
Copy Markdown
Contributor Author

There are some weird failures in https://github.com/apache/iceberg/actions/runs/31809741067/job/94797306211?pr=17284

I'm worried this is a downstream effect of our changes, Can you please check those our @varun-lakhyani

yes working on it.

@eymetmaria-ops

eymetmaria-ops commented Aug 24, 2026 via email

Copy link
Copy Markdown

@varun-lakhyani
varun-lakhyani force-pushed the manifest-eagerinputfile branch from ab310ab to ca3bf41 Compare August 26, 2026 13:13
@varun-lakhyani
varun-lakhyani force-pushed the manifest-eagerinputfile branch from ca3bf41 to 2cce30c Compare August 26, 2026 13:50
@RussellSpitzer

Copy link
Copy Markdown
Member

@kevinjqliu I see you self asked for a review, did you still want to take a pass?

private ReadBuilder(InputFile file) {
this.file = file;
long fileLength = file.getLength();
this.file = canEagerFetch(fileLength) ? EagerInputFile.of(file, fileLength) : file;

@kevinjqliu kevinjqliu Aug 26, 2026 •

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Codex helped me flag this issue. In summary, S3/GCS/ADLS already accepts and use the (potentially staled) length. Hadoop was using getStat() to get the length directly. So this is a new regression for Hadoop.

Details

For small Hadoop-backed Parquet reads, file.getLength() may come from the manifest-list entry and can be stale. Previously, Hadoop reads obtained the physical size through:

HadoopInputFile.fromStatus(hfile.getStat(), hfile.getConf());

See ParquetIO.file().

This PR wraps files up to 1 MiB using the reported length:

long fileLength = file.getLength();
this.file = canEagerFetch(fileLength) ? EagerInputFile.of(file, fileLength) : file;

The eager reader then reads exactly that many bytes:

byte[] bytes = new byte[(int) length];
IOUtil.readFully(src, bytes, 0, bytes.length);

If the recorded length is smaller than the physical file, the buffer excludes the real Parquet footer and trailing PAR1 magic:

java.lang.RuntimeException: ... is not a Parquet file.
Expected magic number at tail, but found [0, 80, 65, 82]
  at org.apache.parquet.hadoop.ParquetFileReader.readFooter(ParquetFileReader.java:622)
  at org.apache.iceberg.parquet.ReadConf.newReader(ReadConf.java:194)
  at org.apache.iceberg.parquet.ParquetReader.init(ParquetReader.java:74)

If the recorded length is larger, readFully attempts to read past EOF.

#16910 corrects new complete rewrites, but it does not repair existing affected manifest-list entries and still preserves source lengths for manifests carried over by incremental rewrites.

This PR therefore removes Hadoop's existing protection against stale lengths by wrapping HadoopInputFile before ParquetIO can call getStat(). Other input implementations already trusted their reported lengths and are not newly broken.

Please preserve the physical Hadoop FileStatus length before eager wrapping and add a stale-length regression test.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hadoop should not be protecting against this :) Honestly I think this is a misfeature. It exists to cover for bad implementations which store the wrong length, but leads to even weirder situations where HadoopFileIO would work reading a file via S3A that would fail through S3FileIO

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since all the other FileIO implementations already trust the supplied length, I think its reasonable for HadoopFileIO to do this.

I think its worth calling that out, perhaps in the PR description. And perhaps with a unit test

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also to note, this doesn't apply to manfiest-lists written for any currently valid tables since they are all using Avro for manifest list and manifests which do not break on the wrong length regardless

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

updated PR description to include this change for Hadoop and mentioned the trusting length part

@kevinjqliu kevinjqliu left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM! thanks for working on this.

private ReadBuilder(InputFile file) {
this.file = file;
long fileLength = file.getLength();
this.file = canEagerFetch(fileLength) ? EagerInputFile.of(file, fileLength) : file;

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since all the other FileIO implementations already trust the supplied length, I think its reasonable for HadoopFileIO to do this.

I think its worth calling that out, perhaps in the PR description. And perhaps with a unit test

@anuragmantri anuragmantri left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I did a final pass and LGTM. Thanks @varun-lakhyani

@kevinjqliu

Copy link
Copy Markdown
Contributor

nit: how about something like this in the pr description? I want to make sure others (and perhaps myself) reading this PR in the future can quickly understand the behavior change.

Behavior change for HadoopFileIO

This PR changes small Parquet reads through HadoopFileIO to use the length reported by InputFile.getLength()—which may have been initialized from Iceberg metadata—rather than retrieving the physical file size through HadoopInputFile.getStat().

Previously, Hadoop-backed reads could tolerate an incorrect metadata length because getStat() returned the physical file size. Other implementations, such as S3InputFile, already use the metadata-provided length when available.

With eager fetching, files at or below the 1 MiB threshold use the reported length to size the read buffer, including files backed by HadoopInputFile. This makes Hadoop consistent with other InputFile implementations, but an incorrect metadata length that previously succeeded through HadoopFileIO may now cause the read to fail.

@varun-lakhyani

varun-lakhyani commented Aug 27, 2026 •

Copy link
Copy Markdown
Contributor Author

nit: how about something like this in the pr description? I want to make sure others (and perhaps myself) reading this PR in the future can quickly understand the behavior change.

Behavior change for HadoopFileIO

Updated the description - I believe it shows the change clearly now

Comment thread core/src/main/java/org/apache/iceberg/io/EagerInputFile.java
IOUtil.readFully(src, bytes, 0, bytes.length);
// reads from the already open stream; no additional request
if (src.read() != -1) {
throw new IOException("Did not reach the end of stream after reading " + length + " bytes");

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit on this, the exception is not clear why this is an issue. "Incorrect length provided for file %x, given a length of %d and did not reach the end of stream."

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done

super(delegate, length);
Preconditions.checkArgument(
delegate instanceof HadoopConfigurable,
"Cannot create a Hadoop configurable eager input file from %s",

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Need to explain why we can't create "Cannot create Hadoop Configurable Eager Input File because %s does not implement HadoopConfigurable" or whatever

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

donw

@RussellSpitzer RussellSpitzer left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good call, waiting on @danielcweeks to make sure we covered the extra long files. I think it's a safe check that was added so I'm +1

@RussellSpitzer
RussellSpitzer merged commit 86da2dc into apache:main Sep 1, 2026
39 checks passed
@RussellSpitzer

Copy link
Copy Markdown
Member

Merged! Thanks @varun-lakhyani for all your work in this space and for helping us with your GSoC project. Thank you to all the folks who helped review this change, @danielcweeks , @anuragmantri , @kevinjqliu and @vaquarkhan

@varun-lakhyani

Copy link
Copy Markdown
Contributor Author

Thanks @RussellSpitzer , @danielcweeks , @anuragmantri , @kevinjqliu , @vaquarkhan for taking part in this change.

robert3005 added a commit to spiraldb/iceberg that referenced this pull request Sep 16, 2026
* Build: Bump actions/stale from 10.4.0 to 11.0.0 (#17576)

Bumps [actions/stale](https://github.com/actions/stale) from 10.4.0 to 11.0.0.
- [Release notes](https://github.com/actions/stale/releases)
- [Changelog](https://github.com/actions/stale/blob/main/CHANGELOG.md)
- [Commits](https://github.com/actions/stale/compare/1e223db275d687790206a7acac4d1a11bd6fe629...4391f3da665fdf50b6810c1a66712fb9ba21aa93)

---
updated-dependencies:
- dependency-name: actions/stale
  dependency-version: 11.0.0
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>

* Build: Bump zizmorcore/zizmor-action from 0.6.1 to 0.6.2 (#17575)

Bumps [zizmorcore/zizmor-action](https://github.com/zizmorcore/zizmor-action) from 0.6.1 to 0.6.2.
- [Release notes](https://github.com/zizmorcore/zizmor-action/releases)
- [Commits](https://github.com/zizmorcore/zizmor-action/compare/6fc4b006235f201fdab3722e17240ab420d580e5...3dc1ecc9bcb9e94e9b2c709687979e1298497054)

---
updated-dependencies:
- dependency-name: zizmorcore/zizmor-action
  dependency-version: 0.6.2
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>

* Build: Bump gradle/actions/setup-gradle from 6.2.0 to 6.3.0 (#17574)

Bumps [gradle/actions/setup-gradle](https://github.com/gradle/actions) from 6.2.0 to 6.3.0.
- [Release notes](https://github.com/gradle/actions/releases)
- [Commits](https://github.com/gradle/actions/compare/3f131e8634966bd73d06cc69884922b02e6faf92...9c971963bec38e04b3d30dcc455b5382be2fdbfb)

---
updated-dependencies:
- dependency-name: gradle/actions/setup-gradle
  dependency-version: 6.3.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>

* Build: Bump actions/setup-java from 5.6.0 to 5.7.0 (#17573)

Bumps [actions/setup-java](https://github.com/actions/setup-java) from 5.6.0 to 5.7.0.
- [Release notes](https://github.com/actions/setup-java/releases)
- [Commits](https://github.com/actions/setup-java/compare/03ad4de0992f5dab5e18fcb136590ce7c4a0ac95...b6effb05e454b25005698d916606bdc6ffcbf961)

---
updated-dependencies:
- dependency-name: actions/setup-java
  dependency-version: 5.7.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>

* Build: Bump com.diffplug.spotless:spotless-plugin-gradle from 8.8.0 to 8.9.0 (#17569)

Build: Bump com.diffplug.spotless:spotless-plugin-gradle

Bumps [com.diffplug.spotless:spotless-plugin-gradle](https://github.com/diffplug/spotless) from 8.8.0 to 8.9.0.
- [Release notes](https://github.com/diffplug/spotless/releases)
- [Changelog](https://github.com/diffplug/spotless/blob/main/CHANGES.md)
- [Commits](https://github.com/diffplug/spotless/compare/gradle/8.8.0...gradle/8.9.0)

---
updated-dependencies:
- dependency-name: com.diffplug.spotless:spotless-plugin-gradle
  dependency-version: 8.9.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>

* Build: Bump the codeql-action group with 3 updates (#17572)

Bumps the codeql-action group with 3 updates: [github/codeql-action/init](https://github.com/github/codeql-action), [github/codeql-action/analyze](https://github.com/github/codeql-action) and [github/codeql-action/upload-sarif](https://github.com/github/codeql-action).


Updates `github/codeql-action/init` from 4.37.3 to 4.37.4
- [Release notes](https://github.com/github/codeql-action/releases)
- [Changelog](https://github.com/github/codeql-action/blob/main/CHANGELOG.md)
- [Commits](https://github.com/github/codeql-action/compare/e4fba868fa4b1b91e1fdab776edc8cfbe6e9fb81...f205ea1c3313d32999d8d6a48b4f6530d4437b38)

Updates `github/codeql-action/analyze` from 4.37.3 to 4.37.4
- [Release notes](https://github.com/github/codeql-action/releases)
- [Changelog](https://github.com/github/codeql-action/blob/main/CHANGELOG.md)
- [Commits](https://github.com/github/codeql-action/compare/e4fba868fa4b1b91e1fdab776edc8cfbe6e9fb81...f205ea1c3313d32999d8d6a48b4f6530d4437b38)

Updates `github/codeql-action/upload-sarif` from 4.37.3 to 4.37.4
- [Release notes](https://github.com/github/codeql-action/releases)
- [Changelog](https://github.com/github/codeql-action/blob/main/CHANGELOG.md)
- [Commits](https://github.com/github/codeql-action/compare/e4fba868fa4b1b91e1fdab776edc8cfbe6e9fb81...f205ea1c3313d32999d8d6a48b4f6530d4437b38)

---
updated-dependencies:
- dependency-name: github/codeql-action/init
  dependency-version: 4.37.4
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: codeql-action
- dependency-name: github/codeql-action/analyze
  dependency-version: 4.37.4
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: codeql-action
- dependency-name: github/codeql-action/upload-sarif
  dependency-version: 4.37.4
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: codeql-action
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>

* Data, Spark: Support byte[] binary values in InternalRowConverter (#17482)

* Flink: Reuse the catalog in the dynamic sink serializer cache (#17437)

* Flink: Fix read split table properties being ignored (#17445)

* Flink: Remove unused logger in TestIcebergCommitter (#17587)

* Flink: Backport dynamic sink serializer cache catalog reuse to 2.0 and 1.20 (#17437) (#17590)

* Flink: Avoid per-row field getter allocation in RowDataWrapper (#16789)

* Flink: Backport read split table properties fix to 2.0 and 1.20 (#17445) (#17591)

* Flink: Backport avoid per-row field getter allocation in RowDataWrapper (#17606)

Backports #16789

* Core, REST: Fix delete file references for DVs in the same Puffin file (#17497)

Motivation: Scan planning responses index delete files by position in the delete-files array.
The index map was keyed on the delete file location alone, but a single Puffin file can hold a deletion vector for each of several data files. Every DV in that file shares a location, so each new DV entry overwrote the previous one and every task referencing a DV in that Puffin file resolved to the same last index.

Changes: Extract DeleteFileSet's private wrapper into a public DeleteFileWrapper, mirroring CharSequenceWrapper, and key the index map on it so serialization uses the same delete file identity that builds the delete-files array.
Fail with a clear message when a task references a delete file that is not in that array.

* Docs: Document missing read table properties in configuration (#17554)

Add read.split.adaptive-size.enabled, read.data-planning-mode, and read.delete-planning-mode to the read properties table with their defaults and accepted values.

* Core: Support metrics with nested field in AppendBenchmark and FileGenerationUtil (#17391)

* Core: Add nested field traversal in AppendBenchmark and FileGenerationUtil

* expand testBoundsForNestedTypes to cover all metricsMode

* Core: Resolve metrics mode by field id in FileGenerationUtil

Use MetricsConfig.columnMode(int) instead of manually resolving the
column name via Schema.findColumnName. The int overload performs the
same id-to-name lookup internally and correctly handles column aliases,
removing duplicated logic across the generator and its test.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* fix schema used in UT

---------

Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* Core: Include CRC values in DV deserialization error message (#17393)

* Site: Add blog post introducing the Variant type (#17537)

* Core: Add max-file-group-input-files to valid rewrite options (#17544)

max-file-group-input-files is read and validated by
SizeBasedFileRewritePlanner but was missing from validOptions(), so
RewriteDataFilesSparkAction rejected it with "Cannot use options
[max-file-group-input-files]". Flink exposes the option through
RewriteDataFiles.maxFileGroupInputFiles() where it works, while Spark
rejected it. The option was added in #14837 without updating validOptions().

Add the option to validOptions() and cover it with a rewrite that sets it,
which fails without this change, plus a planner test that it caps the number
of input files per group.

* API: Respect plaintext files in EncryptingFileIO bulkDecrypt (#17592)

* Respect plaintext files in EncyptingFileIO bulkDecrypt

* unit tests

---------

Co-authored-by: Thomas Powell <tpowell@palantir.com>

* Core: Fix AvroEncoderUtil header error printing literal %02X (#17125)

AvroEncoderUtil.decode validated the magic bytes with
Preconditions.checkState(cond, "Unrecognized header bytes: 0x%02X 0x%02X",
header0, header1). Guava's Preconditions formats messages with
Strings.lenientFormat, which only understands the %s placeholder, so the
%02X specifiers were emitted verbatim and the two byte arguments were
appended as decimal in a trailing bracket. A mismatched header therefore
reported "Unrecognized header bytes: 0x%02X 0x%02X [16, 32]" instead of the
intended hex, obscuring the actual bytes.

* Flink: Remove deprecated RewriteDataFiles.Builder.filter(Expression) (#17624)

* Core: Fix Z-order byte encoding for floating-point values (#17071)

Thanks @eye-gu for the Fix!

* Parquet: Fix notNaN for columns missing from files (#17633)

* Spark: Remove deprecated and unused methods in SparkRead/WriteConf and SparkSchemaUtil (#17626)

Spark: Remove deprecated methods scheduled for 1.12.0 removal

- SparkSchemaUtil.convertWithFreshIds(Schema, StructType) and
  prune(Schema, StructType, List<Expression>) in Spark 4.0 and 4.1
- SparkReadConf/SparkWriteConf constructors taking an unused branch
  argument in Spark 4.1

Spark 3.5 is unaffected: these overloads were never deprecated there.

* Site: Update the variant blog with Apache Arrow variant support (#17640)

* Data: Add Variant Support for file format tck (#17617)

* Core: Call close on iterables returned by ManifestReader.liveEntries() in ManifestFilterManager (#15713)

* Parquet, Spark, Flink: Type uniformity for variant shredding (#17424)

* API: Avoid intermediate collections in IN predicate metrics evaluation (#17659)

* Core: Always track null count in content stats, add evaluator (#17413)

* API: Avoid intermediate collections in NOT IN strict metrics evaluation (#17661)

* Core: Use TrackedFile constants for partition and content_stats fields (#17649)

Replace the duplicated field ID and name literals with the constants that
TrackedFile already declares, which both files use elsewhere.

* Kafka Connect: Remove deprecated TableReference and IcebergWriterResult members (#17623)

Deprecated for removal in 1.12.0:
- TableReference.of(String, TableIdentifier) and the
  TableReference(String, List<String>, String) constructor
- IcebergWriterResult(TableIdentifier, List, List, StructType) and
  IcebergWriterResult.tableIdentifier()

Callers now construct a TableReference with an explicit table UUID; the
two tests pass null to preserve their previous behavior.

* BigQuery: Remove deprecated catalog property constants (#17625)

PROJECT_ID, GCP_LOCATION and LIST_ALL_TABLES on
BigQueryMetastoreCatalog were deprecated for removal in 1.12.0 in favor
of the equivalents on BigQueryProperties. No remaining callers.

* API: Add Javadoc for the Metrics constructor parameters (#17608)

* API: Add Javadoc for the Metrics constructor parameters

Document each parameter of the canonical Metrics constructor, including that the maps and counts may be null when unknown.

* Update api/src/main/java/org/apache/iceberg/Metrics.java

Co-authored-by: Anoop Johnson <git@anoopjohnson.com>

* Fix format

* Followup changes

---------

Co-authored-by: Anoop Johnson <git@anoopjohnson.com>

* Build: Bump datamodel-code-generator from 0.71.0 to 0.72.2 (#17673)

Bumps [datamodel-code-generator](https://github.com/koxudaxi/datamodel-code-generator) from 0.71.0 to 0.72.2.
- [Release notes](https://github.com/koxudaxi/datamodel-code-generator/releases)
- [Changelog](https://github.com/koxudaxi/datamodel-code-generator/blob/main/CHANGELOG.md)
- [Commits](https://github.com/koxudaxi/datamodel-code-generator/compare/0.71.0...0.72.2)

---
updated-dependencies:
- dependency-name: datamodel-code-generator
  dependency-version: 0.72.2
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>

* Build: Bump org.apache.httpcomponents.client5:httpclient5 from 5.6.3 to 5.6.4 (#17674)

Build: Bump org.apache.httpcomponents.client5:httpclient5

Bumps [org.apache.httpcomponents.client5:httpclient5](https://github.com/apache/httpcomponents-client) from 5.6.3 to 5.6.4.
- [Changelog](https://github.com/apache/httpcomponents-client/blob/rel/v5.6.4/RELEASE_NOTES.txt)
- [Commits](https://github.com/apache/httpcomponents-client/compare/rel/v5.6.3...rel/v5.6.4)

---
updated-dependencies:
- dependency-name: org.apache.httpcomponents.client5:httpclient5
  dependency-version: 5.6.4
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>

* Build: Bump at.yawk.lz4:lz4-java from 1.11.1 to 1.11.2 (#17675)

Bumps [at.yawk.lz4:lz4-java](https://github.com/yawkat/lz4-java) from 1.11.1 to 1.11.2.
- [Release notes](https://github.com/yawkat/lz4-java/releases)
- [Changelog](https://github.com/yawkat/lz4-java/blob/main/CHANGES.md)
- [Commits](https://github.com/yawkat/lz4-java/compare/v1.11.1...v1.11.2)

---
updated-dependencies:
- dependency-name: at.yawk.lz4:lz4-java
  dependency-version: 1.11.2
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>

* Build: Bump org.roaringbitmap:RoaringBitmap from 1.6.18 to 1.6.20 (#17677)

Bumps [org.roaringbitmap:RoaringBitmap](https://github.com/RoaringBitmap/RoaringBitmap) from 1.6.18 to 1.6.20.
- [Release notes](https://github.com/RoaringBitmap/RoaringBitmap/releases)
- [Commits](https://github.com/RoaringBitmap/RoaringBitmap/commits)

---
updated-dependencies:
- dependency-name: org.roaringbitmap:RoaringBitmap
  dependency-version: 1.6.20
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>

* Build: Bump jetty from 12.1.11 to 12.1.12 (#17678)

Bumps `jetty` from 12.1.11 to 12.1.12.

Updates `org.eclipse.jetty.compression:jetty-compression-server` from 12.1.11 to 12.1.12

Updates `org.eclipse.jetty.compression:jetty-compression-gzip` from 12.1.11 to 12.1.12

Updates `org.eclipse.jetty.ee10:jetty-ee10-servlet` from 12.1.11 to 12.1.12

---
updated-dependencies:
- dependency-name: org.eclipse.jetty.compression:jetty-compression-server
  dependency-version: 12.1.12
  dependency-type: direct:production
  update-type: version-update:semver-patch
- dependency-name: org.eclipse.jetty.compression:jetty-compression-gzip
  dependency-version: 12.1.12
  dependency-type: direct:production
  update-type: version-update:semver-patch
- dependency-name: org.eclipse.jetty.ee10:jetty-ee10-servlet
  dependency-version: 12.1.12
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>

* Build: Bump io.netty:netty-buffer from 4.2.16.Final to 4.2.17.Final (#17679)

Bumps [io.netty:netty-buffer](https://github.com/netty/netty) from 4.2.16.Final to 4.2.17.Final.
- [Release notes](https://github.com/netty/netty/releases)
- [Commits](https://github.com/netty/netty/compare/netty-4.2.16.Final...netty-4.2.17.Final)

---
updated-dependencies:
- dependency-name: io.netty:netty-buffer
  dependency-version: 4.2.17.Final
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>

* Build: Bump the codeql-action group with 3 updates (#17681)

Bumps the codeql-action group with 3 updates: [github/codeql-action/init](https://github.com/github/codeql-action), [github/codeql-action/analyze](https://github.com/github/codeql-action) and [github/codeql-action/upload-sarif](https://github.com/github/codeql-action).


Updates `github/codeql-action/init` from 4.37.4 to 4.37.6
- [Release notes](https://github.com/github/codeql-action/releases)
- [Changelog](https://github.com/github/codeql-action/blob/main/CHANGELOG.md)
- [Commits](https://github.com/github/codeql-action/compare/f205ea1c3313d32999d8d6a48b4f6530d4437b38...5595ccaf912efad79be6eef63a5619ff05969be3)

Updates `github/codeql-action/analyze` from 4.37.4 to 4.37.6
- [Release notes](https://github.com/github/codeql-action/releases)
- [Changelog](https://github.com/github/codeql-action/blob/main/CHANGELOG.md)
- [Commits](https://github.com/github/codeql-action/compare/f205ea1c3313d32999d8d6a48b4f6530d4437b38...5595ccaf912efad79be6eef63a5619ff05969be3)

Updates `github/codeql-action/upload-sarif` from 4.37.4 to 4.37.6
- [Release notes](https://github.com/github/codeql-action/releases)
- [Changelog](https://github.com/github/codeql-action/blob/main/CHANGELOG.md)
- [Commits](https://github.com/github/codeql-action/compare/f205ea1c3313d32999d8d6a48b4f6530d4437b38...5595ccaf912efad79be6eef63a5619ff05969be3)

---
updated-dependencies:
- dependency-name: github/codeql-action/init
  dependency-version: 4.37.6
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: codeql-action
- dependency-name: github/codeql-action/analyze
  dependency-version: 4.37.6
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: codeql-action
- dependency-name: github/codeql-action/upload-sarif
  dependency-version: 4.37.6
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: codeql-action
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>

* Docs: Update Apache Fluss documentation link to correct path (#17647)

* Arrow: Fix direct memory leak in row lineage vectorized readers (#17296)

Co-authored-by: Angel Conde <acmanjon@amazon.com>

* Build: Bump software.amazon.awssdk:bom from 2.50.2 to 2.51.3 (#17686)

Bumps software.amazon.awssdk:bom from 2.50.2 to 2.51.3.

---
updated-dependencies:
- dependency-name: software.amazon.awssdk:bom
  dependency-version: 2.51.3
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>

* Build: Bump com.google.cloud.gcs.analytics:gcs-analytics-core from 1.4.0 to 1.5.0 (#17687)

Build: Bump com.google.cloud.gcs.analytics:gcs-analytics-core

Bumps [com.google.cloud.gcs.analytics:gcs-analytics-core](https://github.com/GoogleCloudPlatform/gcs-analytics-core) from 1.4.0 to 1.5.0.
- [Release notes](https://github.com/GoogleCloudPlatform/gcs-analytics-core/releases)
- [Changelog](https://github.com/GoogleCloudPlatform/gcs-analytics-core/blob/main/CHANGELOG.md)
- [Commits](https://github.com/GoogleCloudPlatform/gcs-analytics-core/compare/v1.4.0...v1.5.0)

---
updated-dependencies:
- dependency-name: com.google.cloud.gcs.analytics:gcs-analytics-core
  dependency-version: 1.5.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>

* Parquet: Fix notStartsWith skipping row groups with null values (#17656)

The dictionary row group filter only sees non-null values, so a column whose
  dictionary entries all start with the prefix was reported as unmatchable even
  when the column contained nulls. Null values match notStartsWith, so those row
  groups were skipped and their rows dropped from scan results.

* API: Extract superclass from StrictMetricsEvaluator (#17511)

Extract the strict evaluation logic from StrictMetricsEvaluator into a new
superclass, StrictEvalVisitor. StrictMetricsEvaluator now uses the visitor
superclass and implements methods to access metrics by ID. This is in
preparation for adding a strict stats visitor that consumes ContentStats
directly.

* Core: Preserve snapshot pruning when ignoring residuals in AllManifestsTable (#17522)

* Core: Simplify PartitionData.hashCode to avoid per-call allocations (#17666)

* Core: Simplify list handling in manifest read and write paths (#17581)

* Spark: Remove deprecated SparkFilters (#17702)

SparkFilters converted Spark DSv1 filters into Iceberg expressions and was
deprecated as a class for removal in 1.12.0 in favor of SparkV2Filters,
which converts DSv2 predicates.

Nothing uses it. The only remaining references were its own test,
TestSparkFilters, which is removed with it, and a TODO comment in
TestRewriteDataFilesProcedure that named the class; that comment now points
at SparkV2Filters.

Applies to Spark 3.5, 4.0 and 4.1.

* Docs: Align Flink docs with current engine (#17695)

* Data: Remove deprecated GenericAppenderFactory and BaseFileWriterFactory (#17696)

* Spark: Reduce TestRewriteDataFilesAction data volume to speed up CI (#16565)

* Build: Remove unused Avro dependency from iceberg-orc (#17694)

* Core: Treat path prefixes as literals in RewriteTablePathUtil.replacePaths (#17521)

* Spark 4.0/4.1: Remove deprecated SparkTableUtil methods (#17703)

* Docs: Fix "refer" grammar in maintenance, AWS, and Nessie docs (#17580)

* Data, Kafka Connect: Enable Parquet variant shredding for Kafka Connect and generic Record writes (#17520)

* Core: Remove deprecated methods and fields scheduled for 1.12.0 removal (#17700)

* Core: Remove deprecated methods and fields scheduled for 1.12.0 removal

Removes the remaining core API marked for removal in 1.12.0 that has no
callers left:

- SystemProperties (class) -> SystemConfigs
- ThreadPools.newWorkerPool(String) and newWorkerPool(String, int) ->
  newExitingWorkerPool or newFixedThreadPool depending on pool lifetime
- ContentCache.invalidateAll(), which was only best-effort and racy
- TableProperties.MANIFEST_LISTS_ENABLED and MANIFEST_LISTS_ENABLED_DEFAULT;
  writing manifest lists is always enabled
- AvroSchemaUtil.pruneColumns(Schema, Set, NameMapping) -> applyNameMapping
  plus pruneColumns(Schema, Set)
- SnapshotUtil.newFiles and newFilesBetween -> SnapshotChanges with
  ancestorsBetween
- TableScanUtil.hasDeletes(CombinedScanTask) and hasEqDeletes(CombinedScanTask)
- StandardEncryptionManager(String, int, KeyManagementClient), wrapKey and
  unwrapKey
- ManifestFiles.read(ManifestFile, FileIO), readPaths(ManifestFile, FileIO)
  and open(ManifestFile, FileIO) -> the overloads taking a specs map
- BaseScan.io() -> table().io(); DataScan and BaseDistributedDataScan are
  migrated to call table().io() directly

Generated-by: Claude Code

* rename unit test in TestManifestReader

* Docs: Align Spark docs with current engine (#17688)

* AWS: Remove deprecated S3 signer classes and properties (#17627)

AWS: Remove deprecated S3 signer request/response classes

These five classes were deprecated for removal in 1.12.0 and are now
orphaned: they reference only each other and have no remaining callers
in main or test sources. S3V4RestSignerClient uses the RemoteSign*
equivalents.

- S3SignRequest, S3SignResponse
- S3SignRequestParser, S3SignResponseParser
- S3ObjectMapper

* Build: Fix OpenAPI test fixtures runtime dependency (#17519)

* Core: Remove deprecated DataReader in favor of PlannedDataReader (#17699)

DataReader was deprecated for removal in 1.12.0; PlannedDataReader is the
replacement. Also removes the deprecated RawDecoder constructor that took
a read schema and reader function, superseded by
RawDecoder.create(Schema, Function, Schema).

No remaining references to either. TestDataReader is removed along with
the class it covered; PlannedDataReader has its own coverage in
TestPlannedDataReader.

* API: Add tests for BinaryUtil (#17692)

* API: Add tests for BinaryUtil

Cover truncateBinary (partial, full, zero-length, and negative-length guard), the previously untested truncateBinaryUnsafe view, and truncateBinaryMax including the all-bytes-overflow case.

* More changes

* Arrow: Fix vectorized read of all-null DELTA-encoded Parquet pages (#17017)

An all-null page decodes to a length stream with totalValueCount 0, so
readValues wrote firstValue into a zero-length array.

* Data: Split BaseFormatModelTests into read and read-write test classes (#17711)

* AWS, Core: Implement RemoteSigningConfig  (#17709)

* Core, REST, AWS: Implement RemoteSigningConfig

* Flink: Support variant for Avro readers and writers (#17737)

* Docs: Fix duplicated word in Spark merge-schema description (#17746)

* Core: Remove deprecated REST namespace encoding helpers (#17697)

* Core: Remove deprecated REST namespace encoding helpers

Removes REST API deprecated for removal in 1.12.0:

- RESTUtil.NAMESPACE_JOINER / NAMESPACE_SPLITTER, superseded by
  namespaceToQueryParam(Namespace) / namespaceFromQueryParam(String)
- RESTUtil.encodeNamespace(Namespace) / decodeNamespace(String), superseded
  by the two-arg overloads that take an explicit separator
- RESTSessionCatalog.REST_PAGE_SIZE, superseded by
  RESTCatalogProperties.PAGE_SIZE
- CatalogHandlers.loadTable(Catalog, TableIdentifier), superseded by the
  overload taking a SnapshotMode

Javadoc on namespaceToQueryParam and encodeNamespace no longer cross-links
the removed single-arg encodeNamespace; the wording now describes the raw
versus percent-encoded separator directly.

* Core: Remove deprecated public ResourcePaths(String) constructor

The deprecation notice said this constructor would be made private in
1.12.0. It had no callers anywhere in the repo, so making it private
would leave an unused private constructor; remove it instead. Removal
and privatization are indistinguishable to external callers.

* Core: Address review feedback on deprecated REST API removal

Review feedback from nastra and singhpk234:

- Keep the decode separator in encodeAsOldClientAndDecodeAsNewServer
  hardcoded as "%2E". The test only needs a separator that differs from
  the legacy one; it does not have to be the one RESTCatalogAdapter
  advertises.
- Use "Removed deprecated functionality scheduled for removal in 1.12.0"
  as the revapi justification for all seven accepted breaks. The previous
  text claimed every break was part of the namespace encoding API, which
  was not true for REST_PAGE_SIZE, CatalogHandlers.loadTable and the
  ResourcePaths constructor.
- Drop the javadoc note on namespaceToQueryParam(Namespace, String). The
  separator is an explicit argument there, so warning that it differs from
  encodeNamespace adds nothing.
- Keep the note on the no-arg namespaceToQueryParam, which hides the
  separator, but point it at the surviving encodeNamespace(Namespace,
  String) overload. The distinction it warns about is real:
  namespaceToQueryParam joins raw levels, while encodeNamespace
  URL-encodes each level.

* Core: Use transaction metadata for post-commit file cleanup (#17708)

BaseTransaction resolved its newly committed snapshots through
ops.current(), a catalog re-read that can be stale when the catalog
caches table pointers. A missing snapshot made committedFiles return
null, skipping clean-up of all uncommitted files and leaking one stale
manifest list per commit retry attempt. The transaction's own committed
metadata always contains the new snapshots, so resolve them there.

* Core: Fail scans when position deletes/DVs don't match data file partition (#16957)

* Build: Bump mkdocs-exclude-search from 0.6.6 to 0.6.7 (#17775)

Bumps [mkdocs-exclude-search](https://github.com/chrieke/mkdocs-exclude-search) from 0.6.6 to 0.6.7.
- [Release notes](https://github.com/chrieke/mkdocs-exclude-search/releases)
- [Changelog](https://github.com/chrieke/mkdocs-exclude-search/blob/main/CHANGELOG.md)
- [Commits](https://github.com/chrieke/mkdocs-exclude-search/compare/0.6.6...0.6.7)

---
updated-dependencies:
- dependency-name: mkdocs-exclude-search
  dependency-version: 0.6.7
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>

* Build: Bump datamodel-code-generator from 0.72.2 to 0.73.0 (#17776)

Bumps [datamodel-code-generator](https://github.com/koxudaxi/datamodel-code-generator) from 0.72.2 to 0.73.0.
- [Release notes](https://github.com/koxudaxi/datamodel-code-generator/releases)
- [Changelog](https://github.com/koxudaxi/datamodel-code-generator/blob/main/CHANGELOG.md)
- [Commits](https://github.com/koxudaxi/datamodel-code-generator/compare/0.72.2...0.73.0)

---
updated-dependencies:
- dependency-name: datamodel-code-generator
  dependency-version: 0.73.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>

* Build: Bump io.delta:delta-standalone_2.12 from 3.3.2 to 3.3.3 (#17779)

Bumps [io.delta:delta-standalone_2.12](https://github.com/delta-io/delta) from 3.3.2 to 3.3.3.
- [Release notes](https://github.com/delta-io/delta/releases)
- [Commits](https://github.com/delta-io/delta/compare/v3.3.2...v3.3.3)

---
updated-dependencies:
- dependency-name: io.delta:delta-standalone_2.12
  dependency-version: 3.3.3
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>

* Build: Bump astral-sh/setup-uv from 9.0.0 to 10.0.1 (#17782)

Bumps [astral-sh/setup-uv](https://github.com/astral-sh/setup-uv) from 9.0.0 to 10.0.1.
- [Release notes](https://github.com/astral-sh/setup-uv/releases)
- [Commits](https://github.com/astral-sh/setup-uv/compare/c771a70e6277c0a99b617c7a806ffedaca235ff9...20cfd1bf945f4377ade1205e4dbc17946fc9a30d)

---
updated-dependencies:
- dependency-name: astral-sh/setup-uv
  dependency-version: 10.0.1
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>

* Build: Bump the codeql-action group with 3 updates (#17781)

Bumps the codeql-action group with 3 updates: [github/codeql-action/init](https://github.com/github/codeql-action), [github/codeql-action/analyze](https://github.com/github/codeql-action) and [github/codeql-action/upload-sarif](https://github.com/github/codeql-action).


Updates `github/codeql-action/init` from 4.37.6 to 4.37.7
- [Release notes](https://github.com/github/codeql-action/releases)
- [Changelog](https://github.com/github/codeql-action/blob/main/CHANGELOG.md)
- [Commits](https://github.com/github/codeql-action/compare/5595ccaf912efad79be6eef63a5619ff05969be3...ff2f1c621b7f889edc0d3c761ac2e6a3f8cdb0dd)

Updates `github/codeql-action/analyze` from 4.37.6 to 4.37.7
- [Release notes](https://github.com/github/codeql-action/releases)
- [Changelog](https://github.com/github/codeql-action/blob/main/CHANGELOG.md)
- [Commits](https://github.com/github/codeql-action/compare/5595ccaf912efad79be6eef63a5619ff05969be3...ff2f1c621b7f889edc0d3c761ac2e6a3f8cdb0dd)

Updates `github/codeql-action/upload-sarif` from 4.37.6 to 4.37.7
- [Release notes](https://github.com/github/codeql-action/releases)
- [Changelog](https://github.com/github/codeql-action/blob/main/CHANGELOG.md)
- [Commits](https://github.com/github/codeql-action/compare/5595ccaf912efad79be6eef63a5619ff05969be3...ff2f1c621b7f889edc0d3c761ac2e6a3f8cdb0dd)

---
updated-dependencies:
- dependency-name: github/codeql-action/init
  dependency-version: 4.37.7
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: codeql-action
- dependency-name: github/codeql-action/analyze
  dependency-version: 4.37.7
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: codeql-action
- dependency-name: github/codeql-action/upload-sarif
  dependency-version: 4.37.7
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: codeql-action
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>

* Build: Bump io.delta:delta-spark_2.12 from 3.3.2 to 3.3.3 (#17780)

Bumps [io.delta:delta-spark_2.12](https://github.com/delta-io/delta) from 3.3.2 to 3.3.3.
- [Release notes](https://github.com/delta-io/delta/releases)
- [Commits](https://github.com/delta-io/delta/compare/v3.3.2...v3.3.3)

---
updated-dependencies:
- dependency-name: io.delta:delta-spark_2.12
  dependency-version: 3.3.3
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>

* Parquet: Make createStructReader with fieldId abstract (#17698)

createStructReader(List, StructType) was deprecated for removal in 1.12.0
in favor of createStructReader(List, StructType, Integer). The 2-arg form
threw UnsupportedOperationException and the 3-arg form defaulted to
delegating to it, so neither was usable without an override.

Remove the 2-arg method and make the 3-arg form abstract. Both subclasses
(GenericParquetReaders, InternalReader) already override it, and
BaseParquetReaders is package-private so no other subclass can exist.

* Flink: Avoid per-record Set allocation in the dynamic sink forward check (#17618)

* Core: Include valid range in BasePartitionStatistics position error (#17546)

* Core: Include valid range in BasePartitionStatistics position error

Add the expected position range to the "Unknown position" errors thrown by getByPos and internalSet so the message points to the cause.

* Address review

* Build: Bump software.amazon.awssdk:bom from 2.51.3 to 2.53.1 (#17787)

Bumps software.amazon.awssdk:bom from 2.51.3 to 2.53.1.

---
updated-dependencies:
- dependency-name: software.amazon.awssdk:bom
  dependency-version: 2.53.1
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>

* Docs: Add MinIO AIStor to vendors.md (#17760)

* Add MinIO AIStor section to vendors documentation

Added information about MinIO AIStor as a software-defined object store with Apache Iceberg support.

* Docs: note OAuth2 and credential vending in MinIO AIStor entry

* Docs: Add OptimaFlo to vendors.md (#17725)

Signed-off-by: evro <evandanrosa@gmail.com>

* Core: Remove deprecated HadoopFileIO(SerializableSupplier) constructor (#17704)

The constructor taking a SerializableSupplier<Configuration> was
deprecated for removal in 1.12.0 in favor of HadoopFileIO(Configuration),
and has no remaining callers. Since it was the delegation target, its body
is inlined into the Configuration constructor.

Also drops @Deprecated from serializeConfWith. That method is declared by
the HadoopConfigurable interface, which is not deprecated, and it has five
live consumers: SerializationUtil, IcebergInputFormat (mr) and
SerializableFileIOWithSize in Spark 3.5, 4.0 and 4.1. Marking an override
of a supported interface method as deprecated is misleading, so the
annotation is removed rather than the method.

* Connect: Fix idColumns are not read correctly from table config (#17152)

* Site: Expand Variant intro blog with Iceberg table-level details (#17705)

* API, Core, Spark: Add Hilbert-curve clustering strategy for `rewrite_data_files` (#16827)

* Core, Spark: Fix stale manifest_length in rewrite_table_path manifest lists (#16910)

* Parquet: Fix misleading AlwaysFalse placeholder exception message (#17816)

* Core: Add dv_count column to PartitionsTable metadata table (#16125)

* ORC: Fix timestamp nano predicate pushdown (#17750)

Co-authored-by: Vova Kolmakov <wombatukun@gmail.com>

* Revert "Core: Add dv_count column to PartitionsTable metadata table" (#17825)

Revert "Core: Add dv_count column to PartitionsTable metadata table (#16125)"

This reverts commit 68a7f2767b8da025a2663e67fc5321febf3c8dd1.

* Core: Reduce visibility on scan planning response builder for specsById and deleteFiles (#17638)

* Core: Add geometry bounds builder (#17509)

* API: Add a builder usage example to PartitionSpec Javadoc (#17747)

* Build: Clean up shaded-jar LICENSE/NOTICE and add missing third-party notices (#16543)

* Spark: Make the view stored-schema cast configurable (#17499)

* Core, Data, Spark, Flink: Remove of position delete files with row data (#17706)

* Spec: Clarify content file uniqueness within a snapshot (#17198)

* Core: Preserve trailing slash on table location in V4 manifest reader (#17807)

The V4 manifest reader stripped a trailing slash from the table location
before resolving relative file locations against it. Remove the strip
as it should be done by the catalog during table creation. It is not
the reader's responsibility

* Spark: Backport view schema binding mode to Spark 3.5 and 4.0 (#17838)

* API, Core, Parquet: Carry avg value sizes for v4 content stats (#17451)

* API, AWS, Azure, GCP: Track read metrics for positioned, vectored, and accelerated reads (#17236)

* Docs: Flink DDL documentation correction (#17854)

Flink DDL documentation correction: Expand `ALTER TABLE` section to include support for adding, dropping, renaming, and modifying columns, along with clarifications on partition changes. Update Flink overview table to reflect these capabilities.

* Flink: Copy Flink v2.1 to v2.3 directory

* Flink: Add v2.2 directory

* Flink: Adjust build scripts for Flink 2.2 and 2.3

* Flink: Code changes for Flink 2.2 and 2.3

* Flink: Remove support for Flink 2.0

* Flink: Catalog type refactor in Test and add support for REST catalog in CatalogTestBase (#17861)

* Build: Add descriptions to OpenAPI spec validation tasks (#17799)

* Core: Read delete manifests correctly during snapshot expiration (#17763)

* Spark: Fix map value decoding in test helpers (#17721)

Generated-by: Codex

* Docs: Update documentation Flink versions and Flink lifecycle maintenance. (#17869)

* Flink: Backport CatalogType test refactor to 1.20

* Flink: Backport REST catalog support in CatalogTestBase to 1.20

* Flink: Forward-port CatalogType test refactor to 2.3

* Flink: Forward-port REST catalog support in CatalogTestBase to 2.3

* Flink: Forward-port CatalogType test refactor to 2.2

* Flink: Forward-port REST catalog support in CatalogTestBase to 2.2

* Flink: Fix deleted rows reappearing after a failed eq-delete conversion cycle (#17630)

* Build: Bump Avro Version to Avro 1.12.2 (#17188)

* Build: Bump Avro Version to Avro 1.12.2

This is a smoke test PR against the staging RC1 artifacts

Change-Id: I1954fdf77da9cb6b48b8f6eae9ac8536d852366f

* Remove Apache staging repository from repositories


Removed Apache staging repository from build.gradle as there's a full release now (same artifact tested against before)

* Docs: Fix Nessie Flink Python example (#17091)

* Flink: Backport eq-delete conversion replan reindex fix to 1.20 and 2.2 (#17630)

* Flink: Forward-port eq-delete conversion replan reindex fix to 2.3 (#17630)

* Build: Bump software.amazon.awssdk:bom from 2.53.1 to 2.54.2 (#17887)

Bumps software.amazon.awssdk:bom from 2.53.1 to 2.54.2.

---
updated-dependencies:
- dependency-name: software.amazon.awssdk:bom
  dependency-version: 2.54.2
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>

* Build: Bump docker/setup-buildx-action from 4.2.0 to 4.3.0 (#17886)

Bumps [docker/setup-buildx-action](https://github.com/docker/setup-buildx-action) from 4.2.0 to 4.3.0.
- [Release notes](https://github.com/docker/setup-buildx-action/releases)
- [Commits](https://github.com/docker/setup-buildx-action/compare/bb05f3f5519dd87d3ba754cc423b652a5edd6d2c...37fe631027851001ddb9b187196cc803df7f5f0e)

---
updated-dependencies:
- dependency-name: docker/setup-buildx-action
  dependency-version: 4.3.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>

* Build: Bump com.diffplug.spotless:spotless-plugin-gradle from 8.9.0 to 8.10.0 (#17883)

Build: Bump com.diffplug.spotless:spotless-plugin-gradle

Bumps [com.diffplug.spotless:spotless-plugin-gradle](https://github.com/diffplug/spotless) from 8.9.0 to 8.10.0.
- [Release notes](https://github.com/diffplug/spotless/releases)
- [Changelog](https://github.com/diffplug/spotless/blob/main/CHANGES.md)
- [Commits](https://github.com/diffplug/spotless/compare/gradle/8.9.0...gradle/8.10.0)

---
updated-dependencies:
- dependency-name: com.diffplug.spotless:spotless-plugin-gradle
  dependency-version: 8.10.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>

* Build: Bump the codeql-action group with 3 updates (#17885)

Bumps the codeql-action group with 3 updates: [github/codeql-action/init](https://github.com/github/codeql-action), [github/codeql-action/analyze](https://github.com/github/codeql-action) and [github/codeql-action/upload-sarif](https://github.com/github/codeql-action).


Updates `github/codeql-action/init` from 4.37.7 to 4.37.8
- [Release notes](https://github.com/github/codeql-action/releases)
- [Changelog](https://github.com/github/codeql-action/blob/main/CHANGELOG.md)
- [Commits](https://github.com/github/codeql-action/compare/ff2f1c621b7f889edc0d3c761ac2e6a3f8cdb0dd...db488ddef3bf6cb639b32c2e9a7c0a7ea8271d28)

Updates `github/codeql-action/analyze` from 4.37.7 to 4.37.8
- [Release notes](https://github.com/github/codeql-action/releases)
- [Changelog](https://github.com/github/codeql-action/blob/main/CHANGELOG.md)
- [Commits](https://github.com/github/codeql-action/compare/ff2f1c621b7f889edc0d3c761ac2e6a3f8cdb0dd...db488ddef3bf6cb639b32c2e9a7c0a7ea8271d28)

Updates `github/codeql-action/upload-sarif` from 4.37.7 to 4.37.8
- [Release notes](https://github.com/github/codeql-action/releases)
- [Changelog](https://github.com/github/codeql-action/blob/main/CHANGELOG.md)
- [Commits](https://github.com/github/codeql-action/compare/ff2f1c621b7f889edc0d3c761ac2e6a3f8cdb0dd...db488ddef3bf6cb639b32c2e9a7c0a7ea8271d28)

---
updated-dependencies:
- dependency-name: github/codeql-action/init
  dependency-version: 4.37.8
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: codeql-action
- dependency-name: github/codeql-action/analyze
  dependency-version: 4.37.8
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: codeql-action
- dependency-name: github/codeql-action/upload-sarif
  dependency-version: 4.37.8
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: codeql-action
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>

* Build: Bump datamodel-code-generator from 0.73.0 to 0.74.0 (#17880)

Bumps [datamodel-code-generator](https://github.com/koxudaxi/datamodel-code-generator) from 0.73.0 to 0.74.0.
- [Release notes](https://github.com/koxudaxi/datamodel-code-generator/releases)
- [Changelog](https://github.com/koxudaxi/datamodel-code-generator/blob/main/CHANGELOG.md)
- [Commits](https://github.com/koxudaxi/datamodel-code-generator/compare/0.73.0...0.74.0)

---
updated-dependencies:
- dependency-name: datamodel-code-generator
  dependency-version: 0.74.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>

* Build: Bump jackson-bom from 2.22.1 to 2.22.2 (#17881)

Bumps `jackson-bom` from 2.22.1 to 2.22.2.

Updates `com.fasterxml.jackson:jackson-bom` from 2.22.1 to 2.22.2
- [Commits](https://github.com/FasterXML/jackson-bom/compare/jackson-bom-2.22.1...jackson-bom-2.22.2)

Updates `com.fasterxml.jackson.core:jackson-core` from 2.22.1 to 2.22.2
- [Commits](https://github.com/FasterXML/jackson-core/compare/jackson-core-2.22.1...jackson-core-2.22.2)

Updates `com.fasterxml.jackson.core:jackson-databind` from 2.22.1 to 2.22.2
- [Commits](https://github.com/FasterXML/jackson-databind/compare/jackson-databind-2.22.1...jackson-databind-2.22.2)

---
updated-dependencies:
- dependency-name: com.fasterxml.jackson:jackson-bom
  dependency-version: 2.22.2
  dependency-type: direct:production
  update-type: version-update:semver-patch
- dependency-name: com.fasterxml.jackson.core:jackson-core
  dependency-version: 2.22.2
  dependency-type: direct:production
  update-type: version-update:semver-patch
- dependency-name: com.fasterxml.jackson.core:jackson-databind
  dependency-version: 2.22.2
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>

* API, Core: Fix typos in test comments (#17889)

Fix a duplicated "the", "overriden" -> "overridden", and "doesnt" -> "doesn't" in
test comments. Comment-only changes, no behavior change.

* Docs, Core, AWS, BigQuery, Flink: Fix miscellaneous typos in comments and docs (#17898)

* Docs: Run `generateRuntimeDeps` on all modules (#17323)

Updated comments for clarity on Gradle commands.

* Docs: Fix grammatical typo in Spark module description (#17897)

'submodules for each spark versions' -> 'submodules for each Spark version'
(number agreement + capitalization, consistent with Flink/Hive naming nearby)

* Core: Fix geo bounds in v4 legacy stat maps (#17493)

* Spark 4.1: Mark overrides of deprecated Spark API as deprecated (#16028)

* Core: Remove ThreadPools.WORKER_THREAD_POOL_SIZE_PROP update warning log message (#17812)

* Core: Remove ThreadPools.WORKER_THREAD_POOL_SIZE_PROP and correct manifest spec fallback removal version

Resolves the two remaining deprecation markers in iceberg-core that
promised action "in 1.12.0" but were missed by the removal PRs.

Remove ThreadPools.WORKER_THREAD_POOL_SIZE_PROP. The field was
deprecated in #5659 in favor of SystemConfigs.WORKER_THREAD_POOL_SIZE
and retargeted from 2.0.0 to 1.12.0 by #14392. It had no callers
anywhere in the repository outside its own declaration and no
references in the docs, and it was the only survivor of #14392's
13-file batch after #17700 removed the rest. The corresponding
java.field.removed break is recorded in .palantir/revapi.yml under the
1.11.0 baseline.

Correct the ManifestReader warning for the partition-spec-from-file-
metadata fallback to say 2.0.0 rather than 1.12.0. The fallback cannot
be honored in 1.12.0 because its only production caller is
BaseSnapshot:276, which passes a null spec map while serving
Snapshot.addedDeleteFiles(FileIO) and removedDeleteFiles(FileIO).
Those accessors are themselves already marked "@deprecated will be
removed in 2.0.0; use SnapshotChanges#builderFor(Table) instead", and
because they receive only a FileIO they structurally cannot supply a
spec map. The fallback must therefore outlive 1.12.0, and 2.0.0 aligns
its removal with that of its last caller.

* reword revapi change

* Dell: Preserve known ECS input file lengths (#17870)

* Dell: Preserve known ECS input file lengths

Carry known lengths into ECS input files so scan planning avoids redundant object metadata requests.

Generated-by: Codex

* Dell: Verify known lengths avoid metadata requests

Use a mock ECS client and assert that reading a supplied file length performs no client interaction.

Generated-by: Codex

* Core: Add Eager fetch to parquet read path (#17284)

* Spark 4.1: Add rewrite option to enable executor cache for delete files (#17868)

* Spark 4.0: Add rewrite option to enable executor cache for delete files (#17907)

* Spark 3.5: Add rewrite option to enable executor cache for delete files (#17909)

* Core: Clean up TestTrackingBuilder (#17145)

* Core, API, Parquet: Collapse redundant nested if statements (#17905)

* Docs: Add max-file-group-input-files to rewrite options tables in spark-procedures.md (#17707)

* Docs: Bump site Flink version to 2.3 (#17936)

* Docs: Fix wrong config keys in Flink maintenance docs (#17935)

* Core, Open-API, Spark, Flink: Use String.replace for literal replacements (#17484)

* API: Add Javadoc for Transforms.fromString (#17693)

* Spec: Add finer grained read restrictions as part of loadTable (#13879)

Add an optional read-restrictions field to LoadTableResult so a catalog
can return the result of evaluating fine grained access policies for the
calling user. The restrictions are enforced by the client, which
requires a trust relationship between the engine and the catalog; how
that trust is established is out of scope for this change.

ReadRestrictions carries two optional fields:

- required-column-projections: a list of Action objects, each naming a
  column by field-id along with the transformation to apply. Action uses
  a discriminator on the action property, with mask-alphanum,
  mask-to-fixed-value, replace-with-null, show-first-4, show-last-4,
  truncate-to-year, truncate-to-month, sha-256-global and
  sha-256-query-local defined. Each action produces a value of the same
  type as the input column.

- required-row-filter: an Expression evaluated against original,
  untransformed column values. Projections are applied to the rows that
  survive the filter.

Enforcement is fail-closed. A reader that supports read restrictions
must fail any read it cannot satisfy in full, including unrecognized
action or expression types and actions that cannot be loaded, parsed, or
evaluated, and must not silently return raw, partial, or empty results.
The restrictions apply to every read performed with a given response,
including subsequent planTableScan and fetchScanTasks calls, and may
differ between requests or between authentication scopes. A missing or
empty ReadRestrictions object imposes no restrictions.

Approved on the dev list with 8 binding +1 votes and no -1 votes:
https://lists.apache.org/thread/0zloqhp8wkgyn04yg69j71cwcg5n7g74

* Build: Bump mkdocs-material from 9.7.5 to 9.7.7 in /site (#17942)

Bumps [mkdocs-material](https://github.com/squidfunk/mkdocs-material) from 9.7.5 to 9.7.7.
- [Release notes](https://github.com/squidfunk/mkdocs-material/releases)
- [Changelog](https://github.com/squidfunk/mkdocs-material/blob/master/CHANGELOG)
- [Commits](https://github.com/squidfunk/mkdocs-material/compare/9.7.5...9.7.7)

---
updated-dependencies:
- dependency-name: mkdocs-material
  dependency-version: 9.7.7
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>

* API: Fix grammatical typos in UpdatePartitionSpec Javadoc (#17941)

Correct "the a" / "the an" to "a" / "an" in the @throws documentation of addField and removeField.

* Core, Hive, Spark: Auto close JsonGenerator using try-with-resources (#17931)

* Core, Hive, Spark: Close JsonGenerator instead of only flushing it

Ten sites created a JsonGenerator, called flush(), and left it unclosed.
flush() pushes buffered content to the target and flushes the target itself,
so the output was correct, but only close() returns the generator's char
buffers to the thread's BufferRecycler (_releaseBuffers) and returns the
recycler to the pool (IOContext.close). Without it, every serialization
allocates a fresh char[4000] concat buffer instead of reusing one.

Each generator now joins its enclosing try-with-resources so it closes
before its target. The explicit flush() remains only where a value is read
off the target inside the try: JsonUtil.generate and
TableMetadataParser.toJson read StringWriter.toString(), and
HMSTablePropertyHelper.hashOf reads HashWriter.getHash(). The last is
ordering-sensitive, since AUTO_CLOSE_TARGET makes closing the generator
close the HashWriter, and a closed HashWriter rejects getHash().

A JMH benchmark over TableMetadataParser measured a fixed 8,016 B/op
allocation reduction independent of document size, which is one char[4000]
plus its object header. For a ~1 KB document that is 10,616 -> 2,600 B/op
and 0.860 -> 0.730 us/op; for ~41 KB it is 49,680 -> 41,664 B/op.

On a failure mid-serialization, close() now auto-completes open contexts
(AUTO_CLOSE_JSON_CONTENT) and flushes partial content, where the flush()
was previously skipped. The resulting metadata file is orphaned either way
because the commit fails.

* Restore explicit generator.flush() calls

Review feedback: relying on close() to flush is correct but implicit, and it
contradicts JsonUtil.generate, which was cited as the pattern this change
follows and which does call flush().

Restoring the calls keeps this change to a single concern: adding the
generator to the enclosing try-with-resources so it is closed. The
buffer-recycling win comes entirely from close() releasing the char buffer
to the BufferRecycler, not from dropping the flush, so nothing measured is
lost. The flush is now redundant with close() at these sites, which costs
one extra flush() on the underlying stream per write.

* Core, OpenAPI: Preserve avg value sizes in REST JSON (#17855)

* Core, Flink, Spark, Build: Replace Guava Queues with plain JDK and bump guava from 33.6.0-jre to 33.7.1-jre  (#17888)

* Replace Guava Queues with plain JDK

* Build: Bump guava from 33.6.0-jre to 33.7.1-jre

Bumps `guava` from 33.6.0-jre to 33.7.1-jre.

Updates `com.google.guava:guava` from 33.6.0-jre to 33.7.1-jre
- [Release notes](https://github.com/google/guava/releases)
- [Commits](https://github.com/google/guava/commits)

Updates `com.google.guava:guava-testlib` from 33.6.0-jre to 33.7.1-jre
- [Release notes](https://github.com/google/guava/releases)
- [Commits](https://github.com/google/guava/commits)

---
updated-dependencies:
- dependency-name: com.google.guava:guava
  dependency-version: 33.7.1-jre
  dependency-type: direct:production
  update-type: version-update:semver-minor
- dependency-name: com.google.guava:guava-testlib
  dependency-version: 33.7.1-jre
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>

---------

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>

* Core: Fix commit validation when a data file has multiple DVs across snapshots (#17764)

* API, Core: Expose co-located deletion vector through DataFile (#17928)

V4 co-locates a data file's deletion vector on the data entry.
Add DataFile.deletionVector() returning the DV as a DeleteFile.

Related discussion thread:
https://github.com/apache/iceberg/pull/17541/changes#r3787760198

* API: Add contextual load apis (#15895)

* API: Adds contextual load APIs and LoadContext

Co-authored-by: Prashant Singh <prashant.singh@snowflake.com>

* Spark: Add support for 4.2.0 (#14984)

* Spark 4.2: Fix build failures from missed cleanups (#17952)

* Docs: Note that REST catalog credentials should be redacted by engines (#17920)

* Core: Avoid per-row path rehashing in toPositionIndexes (#17864)

* Core: Avoid per-row path rehashing in toPositionIndexes

Signed-off-by: Sergei Nikolaev <kinolaev@gmail.com>

* Core: Compare paths by content when building pos delete indexes + tests

Signed-off-by: Sergei Nikolaev <kinolaev@gmail.com>
Co-authored-by: Anurag Mantripragada <amantripragada@apple.com>

* Core: Fix Deletes.toPositionIndexes with interleaved paths test

Signed-off-by: Sergei Nikolaev <kinolaev@gmail.com>

* Core: Fix test names, improve assertion in TestDeletes

Signed-off-by: Sergei Nikolaev <kinolaev@gmail.com>

---------

Signed-off-by: Sergei Nikolaev <kinolaev@gmail.com>
Co-authored-by: Anurag Mantripragada <amantripragada@apple.com>

* API, Core: Add ManifestFile adapter for v4 tracked files (#17932)

Reintroduces the ManifestFile adapter closed in #16867, which stalled because ManifestFile had no way to represent a manifest deletion vector. The V4 scan task planner (#17541) plans over manifests through the ManifestFile API, so this adds ManifestFile.manifestDeletionVector() and has the adapter expose the tracked file's manifest DV.

* Build: Bump zizmorcore/zizmor-action from 0.6.2 to 0.6.3 (#17976)

Bumps [zizmorcore/zizmor-action](https://github.com/zizmorcore/zizmor-action) from 0.6.2 to 0.6.3.
- [Release notes](https://github.com/zizmorcore/zizmor-action/releases)
- [Commits](https://github.com/zizmorcore/zizmor-action/compare/3dc1ecc9bcb9e94e9b2c709687979e1298497054...70fb788f84895a7701f5643d103d587e460b5c99)

---
updated-dependencies:
- dependency-name: zizmorcore/zizmor-action
  dependency-version: 0.6.3
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>

* Build: Bump actions/setup-java from 5.7.0 to 6.0.0 (#17975)

Bumps [actions/setup-java](https://github.com/actions/setup-java) from 5.7.0 to 6.0.0.
- [Release notes](https://github.com/actions/setup-java/releases)
- [Commits](https://github.com/actions/setup-java/compare/b6effb05e454b25005698d916606bdc6ffcbf961...dd06d9cba3e5552c54d9f8ea23572deb30010f7c)

---
updated-dependencies:
- dependency-name: actions/setup-java
  dependency-version: 6.0.0
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>

* Build: Bump the codeql-action group with 3 updates (#17974)

Bumps the codeql-action group with 3 updates: [github/codeql-action/init](https://github.com/github/codeql-action), [github/codeql-action/analyze](https://github.com/github/codeql-action) and [github/codeql-action/upload-sarif](https://github.com/github/codeql-action).


Updates `github/codeql-action/init` from 4.37.8 to 4.37.9
- [Release notes](https://github.com/github/codeql-action/releases)
- [Changelog](https://github.com/github/codeql-action/blob/main/CHANGELOG.md)
- [Commits](https://github.com/github/codeql-action/compare/db488ddef3bf6cb639b32c2e9a7c0a7ea8271d28...cdf488f595d80d6e07e03d4674febd5ab45fa938)

Updates `github/codeql-action/analyze` from 4.37.8 to 4.37.9
- [Release notes](https://github.com/github/codeql-action/releases)
- [Changelog](https://github.com/github/codeql-action/blob/main/CHANGELOG.md)
- [Commits](https://github.com/github/codeql-action/compare/db488ddef3bf6cb639b32c2e9a7c0a7ea8271d28...cdf488f595d80d6e07e03d4674febd5ab45fa938)

Updates `github/codeql-action/upload-sarif` from 4.37.8 to 4.37.9
- [Release notes](https://github.com/github/codeql-action/releases)
- [Changelog](https://github.com/github/codeql-action/blob/main/CHANGELOG.md)
- [Commits](https://github.com/github/codeql-action/compare/db488ddef3bf6cb639b32c2e9a7c0a7ea8271d28...cdf488f595d80d6e07e03d4674febd5ab45fa938)

---
updated-dependencies:
- dependency-name: github/codeql-action/init
  dependency-version: 4.37.9
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: codeql-action
- dependency-name: github/codeql-action/analyze
  dependency-version: 4.37.9
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: codeql-action
- dependency-name: github/codeql-action/upload-sarif
  dependency-version: 4.37.9
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: codeql-action
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>

* Build: Bump org.openapitools:openapi-generator-gradle-plugin from 7.24.0 to 7.25.0 (#17973)

Build: Bump org.openapitools:openapi-generator-gradle-plugin

Bumps [org.openapitools:openapi-generator-gradle-plugin](https://github.com/OpenAPITools/openapi-generator) from 7.24.0 to 7.25.0.
- [Release notes](https://github.com/OpenAPITools/openapi-generator/releases)
- [Changelog](https://github.com/OpenAPITools/openapi-generator/blob/master/docs/release-summary.md)
- [Commits](https://github.com/OpenAPITools/openapi-generator/compare/v7.24.0...v7.25.0)

---
updated-dependencies:
- dependency-name: org.openapitools:openapi-generator-gradle-plugin
  dependency-version: 7.25.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>

* Build: Bump org.xerial:sqlite-jdbc from 3.53.2.1 to 3.53.4.0 (#17972)

Bumps [org.xerial:sqlite-jdbc](https://github.com/xerial/sqlite-jdbc) from 3.53.2.1 to 3.53.4.0.
- [Release notes](https://github.com/xerial/sqlite-jdbc/releases)
- [Changelog](https://github.com/xerial/sqlite-jdbc/blob/master/CHANGELOG)
- [Commits](https://github.com/xerial/sqlite-jdbc/compare/3.53.2.1...3.53.4.0)

---
updated-dependencies:
- dependency-name: org.xerial:sqlite-jdbc
  dependency-version: 3.53.4.0
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>

* Build: Bump com.diffplug.spotless:spotless-plugin-gradle from 8.10.0 to 8.10.1 (#17970)

Build: Bump com.diffplug.spotless:spotless-plugin-gradle

Bumps [com.diffplug.spotless:spotless-plugin-gradle](https://github.com/diffplug/spotless) from 8.10.0 to 8.10.1.
- [Release notes](https://github.com/diffplug/spotless/releases)
- [Changelog](https://github.com/diffplug/spotless/blob/main/CHANGES.md)
- [Commits](https://github.com/diffplug/spotless/compare/gradle/8.10.0...gradle/8.10.1)

---
updated-dependencies:
- dependency-name: com.diffplug.spotless:spotless-plugin-gradle
  dependency-version: 8.10.1
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>

* Build: Bump software.amazon.awssdk:bom from 2.54.2 to 2.54.7 (#17969)

Bumps software.amazon.awssdk:bom from 2.54.2 to 2.54.7.

---
updated-dependencies:
- dependency-name: software.amazon.awssdk:bom
  dependency-version: 2.54.7
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>

* Build: Bump datamodel-code-generator from 0.74.0 to 0.76.0 (#17968)

Bumps [datamodel-code-generator](https://github.com/koxudaxi/datamodel-code-generator) from 0.74.0 to 0.76.0.
- [Release notes](https://github.com/koxudaxi/datamodel-code-generator/releases)
- [Changelog](https://github.com/koxudaxi/datamodel-code-generator/blob/main/CHANGELOG.md)
- [Commits](https://github.com/koxudaxi/datamodel-code-generator/compare/0.74.0...0.76.0)

---
updated-dependencies:
- dependency-name: datamodel-code-generator
  dependency-version: 0.76.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] …
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

8 participants