Skip to content

[AURON #2434] Support full-data-file Iceberg changelog deletes - #2435

Open
weimingdiit wants to merge 3 commits into
apache:masterfrom
weimingdiit:feat/iceberg-changelog-full-file-delete
Open

[AURON #2434] Support full-data-file Iceberg changelog deletes#2435
weimingdiit wants to merge 3 commits into
apache:masterfrom
weimingdiit:feat/iceberg-changelog-full-file-delete

Conversation

@weimingdiit

Copy link
Copy Markdown
Contributor

Which issue does this PR close?
Closes #2434

Rationale for this change
Auron native Iceberg changelog scan currently supports insert-only changelog tasks.

Full-data-file delete changelog tasks can be executed natively without row-level delete-file handling. Auron can scan the deleted data file directly and materialize changelog metadata from the Iceberg changelog task.

Supporting this case improves native Iceberg changelog scan coverage while keeping more complex delete and update semantics on Spark's reader.

What changes are included in this PR?
Allows native Iceberg changelog scan to accept DeletedDataFileScanTask when:

  • the changelog operation is DELETE
  • existingDeletes() is empty

Keeps existing native support for AddedRowsScanTask when:

  • the changelog operation is INSERT
  • deletes() is empty

Keeps fallback behavior for unsupported changelog tasks, including row-level deletes, position/equality deletes, update changelog tasks, mixed file formats, and delete tasks with existing delete files.

Adds coverage for:

  • full-data-file delete changelog native scan
  • a changelog range that contains both insert tasks and full-data-file delete tasks

Are there any user-facing changes?
No user-facing API changes. More Iceberg changelog scans can now be executed natively by Auron.

How was this patch tested?
UT.

Allow native Iceberg changelog scan to handle DeletedDataFileScanTask
when the task represents a DELETE operation and has no existing delete
files.

Keep existing support for insert changelog tasks and continue falling
back for row-level deletes, position/equality deletes, update changelog
tasks, mixed file formats, and delete tasks with existing deletes.

Add tests for full-data-file delete changelog scans and mixed
insert/delete changelog ranges.

Signed-off-by: weimingdiit <weimingdiit@gmail.com>

@merrily01 merrily01 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.

@weimingdiit Thanks for the contribution. The implementation looks correct to me, just a few comments inline.

test("iceberg changelog scan falls back when delete changes exist") {
withTable("local.db.t_changelog_delete") {
withTempView("t_changelog_delete_changes") {
test("iceberg native scan supports mixed insert and full-data-file delete changelog scan") {

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 replaces the previous falls back when delete changes exist test, which covered row-level deletes. Could we keep a dedicated fallback test (e.g. non-partitioned table with a position delete, or a DeletedDataFileScanTask with non-empty existingDeletes())? It would help guard against regressions on the row-level delete / update paths.

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.

Thanks for pointing this out. I rechecked the behavior of the replaced test and Iceberg 1.10.1.

The replaced test did not actually exercise a row-level delete. In the CI run, the insert produced two data files and the DELETE removed one complete data file, so it covered a DeletedDataFileScanTask with empty existingDeletes(), which is the case this PR now makes native.

A genuine position-delete changelog case cannot currently reach Auron's fallback guard. BaseIncrementalChangelogScan rejects any snapshot in the changelog range that contains delete manifests before Auron receives the planned tasks. In addition, Iceberg 1.10.1's CreateDataFileChangeTasks constructs both AddedRowsScanTask and DeletedDataFileScanTask with NO_DELETES, so a DeletedDataFileScanTask with non-empty existingDeletes() cannot be produced through the public changelog planner.

The existing "iceberg scan falls back when delete files exist" test still covers position-delete fallback for regular Iceberg scans. It explicitly creates a position delete, verifies that the planned FileScanTask contains deletes, and checks that NativeIcebergTableScan is not used.

Given these limitations, I have not added a changelog integration test that would either fail inside Iceberg before reaching Auron or not exercise the intended guard. If useful, I can add a focused synthetic task-level test for the existingDeletes() guard instead.

deletesEmpty(added.deletes()) =>
Some(NativeChangelogDataFileTask(added.file(), added.start(), added.length(), added))
case deleted: DeletedDataFileScanTask
if deleted.operation() == ChangelogOperation.DELETE &&

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: deleted.operation() == ChangelogOperation.DELETE is always true. How about dropping it or adding a comment for clarity?

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.

Agreed. DeletedDataFileScanTask already defines the operation as DELETE, so I removed the redundant operation check and kept only the existingDeletes() guard.

Signed-off-by: weimingdiit <weimingdiit@gmail.com>
Signed-off-by: weimingdiit <weimingdiit@gmail.com>

Copilot AI 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.

🟡 Not ready to approve

The native-acceptance guard for DeletedDataFileScanTask does not enforce the PR’s stated operation == DELETE constraint, risking incorrect native execution for non-DELETE changelog tasks.

Once you've addressed the issues Copilot identified, you can request another Copilot review.

This review doesn't count toward merge requirements. Sign up for the private preview to control whether Copilot approvals count.

Pull request overview

This PR expands Auron’s native Iceberg changelog scan support to include full-data-file delete changelog tasks (while keeping row-level delete semantics on Spark’s reader), improving native coverage for simple DELETE changelog ranges.

Changes:

  • Extend native changelog planning to accept DeletedDataFileScanTask when it can be handled by scanning the data file directly.
  • Refactor changelog task handling to a unified “native changelog data-file task” representation used for native scan task construction.
  • Add integration tests covering full-data-file delete changelog scans and mixed insert + full-data-file delete ranges.
File summaries
File Description
thirdparty/auron-iceberg/src/main/scala/org/apache/spark/sql/auron/iceberg/IcebergScanSupport.scala Adds native handling for full-data-file delete changelog tasks by mapping supported changelog tasks into native scan tasks.
thirdparty/auron-iceberg/src/test/scala/org/apache/auron/iceberg/AuronIcebergIntegrationSuite.scala Adds integration coverage for native execution of delete-only and mixed insert+delete changelog ranges.
Review details
  • Files reviewed: 2/2 changed files
  • Comments generated: 2
  • Review effort level: Lite

We're testing this review assessment. Please use 👍 or 👎 to tell us if it's correct.

Comment on lines +560 to +573
private def toNativeChangelogDataFileTask(
task: ChangelogScanTask): Option[NativeChangelogDataFileTask] = {
task match {
case added: AddedRowsScanTask
if added.operation() == ChangelogOperation.INSERT &&
deletesEmpty(added.deletes()) =>
Some(NativeChangelogDataFileTask(added.file(), added.start(), added.length(), added))
case deleted: DeletedDataFileScanTask if deletesEmpty(deleted.existingDeletes()) =>
Some(
NativeChangelogDataFileTask(deleted.file(), deleted.start(), deleted.length(), deleted))
case _ =>
None
}
}
Comment on lines +745 to +749
test("iceberg native scan supports mixed insert and full-data-file delete changelog scan") {
withTable("local.db.t_changelog_mixed_delete") {
withTempView("t_changelog_mixed_delete_changes") {
sql("""
|create table local.db.t_changelog_delete (id int, v string)
|create table local.db.t_changelog_mixed_delete (id int, v string, p int)
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.

Support full-data-file delete Iceberg changelog tasks in native scan

3 participants