Skip to content

Check add_files duplicates against the target branch - #4347

Open
rahulsmahadev wants to merge 1 commit into
apache:mainfrom
rahulsmahadev:rahul/add-files-branch-duplicate-check
Open

rahulsmahadev wants to merge 1 commit into
apache:mainfrom
rahulsmahadev:rahul/add-files-branch-duplicate-check

Conversation

@rahulsmahadev

Copy link
Copy Markdown
Contributor

Rationale for this change

Transaction.add_files(..., branch=...) checks for already-referenced files only against the current snapshot (main), not against the target branch. Adding the same file to a branch twice is therefore not rejected, and reading the branch returns the file's rows twice:

tbl.append(main_rows)
tbl.manage_snapshots().create_branch(snapshot_id=tbl.metadata.current_snapshot_id, branch_name="b").commit()
tbl.add_files([path], branch="b")
tbl.add_files([path], branch="b")  # should raise "already referenced by table"; it commits a second copy

The second call succeeds, and the branch holds two live entries for path. The same second call on main is rejected. #3287 describes this as a pre-existing inconsistency and preserved it.

This change makes the check cover the target branch's snapshot as well as the current snapshot. The existing main check stays, and a file the branch already references is now rejected too. Snapshots and manifests shared by both are read once.

Related: #3287

Are these changes tested?

Yes. The tests are in tests/integration/test_add_files.py and run against the memory and SQL catalogs. test_add_files_to_branch_rejects_file_already_referenced_by_branch and test_add_files_to_branch_rejects_file_added_earlier_in_transaction fail without this change (the second add is not rejected) and pass with it. test_add_files_to_branch_accepts_distinct_file_with_same_rows adds a different path with the same rows and passes both ways. test_add_files_to_branch_rejects_file_referenced_only_by_main passes both ways and pins that files referenced by main are still rejected on a branch.

Are there any user-facing changes?

Yes: add_files with a non-main branch now also rejects files that the branch already references. Files referenced by main are still rejected, and the check_duplicate_files docs mention the target branch.

This pull request and its description were written by Isaac.

add_files(branch=...) checked duplicates only against the current
snapshot, so adding a file to a branch twice committed it again and
doubled the rows. The check now also covers the target branch's
snapshot, reading shared snapshots and manifests once.

Co-authored-by: Isaac <no-reply@databricks.com>
@rahulsmahadev

Copy link
Copy Markdown
Contributor Author

@kevinjqliu @laichunpongben could you take a look when you have a chance? It closes the branch gap in the add_files duplicate check that #3287 called out.

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

Verified locally (Windows, Python 3.12):

  • The four new tests/integration/test_add_files.py branch tests pass on this branch across all three catalog fixtures (12 passed), and the two rejection tests fail on pre-change code (6 failed with main's source swapped in) — exactly the claimed fail-first behavior. The distinct-file-with-same-rows and referenced-only-by-main tests pass both ways, pinning that legitimate adds stay allowed and the main check is preserved.
  • Read the diff: the snapshot set dedupes by snapshot_id and the manifest set by manifest_path, so shared manifests are scanned once; snapshot_by_name(None) returns None (refs.get(None)), so the no-branch path collapses to exactly the old single-snapshot check. The executor/path_filter machinery is unchanged — the only behavioral delta is the wider candidate set, which matches the description.

Nice find — the inconsistency #3287 describes was easy to hit on branch workflows, and the fix is minimal while keeping the shared-scan cost at one read.

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants