Repository navigation
AddFiles: Add dry_run - #40167
Merged
Merged
AddFiles: Add dry_run#40167
Conversation
claudevdm
force-pushed
the
addfiles-dry-run
branch
from
September 18, 2026 03:43
49f0b21 to
f436398
Compare
Collaborator
Author
|
R: @ahmedabu98 |
Contributor
|
Stopping reviewer notifications for this pull request: review requested by someone other than the bot, ceding control. If you'd like to restart, comment |
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## master #40167 +/- ##
============================================
- Coverage 58.47% 58.46% -0.01%
+ Complexity 13593 13591 -2
============================================
Files 2576 2576
Lines 269266 269266
Branches 11079 11079
============================================
- Hits 157441 157427 -14
- Misses 105863 105871 +8
- Partials 5962 5968 +6
Flags with carried forward coverage won't be shown. Click here to find out more. ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
…ommitting or registering
SchemaEvolutionConfig.setDryRun(true) (provider key dry_run) turns
AddFiles into a report-only transform: the read side runs as usual
(footers, distinct schemas), then DryRunReport emits one Row per
distinct schema plus one summary row on a new output, dry_run_report.
Why: before enabling evolution on a large import, a user wants to know
what the options would do to the table and which files would be
refused, without touching anything. Running the real transform under
FAIL_PIPELINE answers only "would it fail", and only for the first
failure.
The verdicts come from CommitSchemaUnion.plan, the one step that
decides everything a commit does before writing anything. A Plan says
which distinct file schemas are merged (SchemaToMerge), which are
refused and why (IncompatibleSchema), and the schema the table ends
with. It is an EvolutionPlan against an existing table (base schema
snapshot, name-mapping repair) or a CreationPlan when the table is
missing (partition spec and sort order resolved against the union, or
the problem that blocks creation). commitOnce dispatches to evolve or
create, which fail or warn under the handling mode and then write; the
dry run turns the same plan into rows, so a check added to the plan
reaches both and the report cannot drift from the commit. A schema that
is fine against the table but conflicts with another schema of the
input is therefore reported with the blame a real run assigns.
Real-run changes that come with planning first: partition or sort
fields that do not fit the union fail with a message naming them,
before any catalog write and under either handling (the per-file
fallback creation throws the same error, so it could never be routed);
problems are reported before the transaction is opened; every
transaction is checked against the one base snapshot; planning retries
like committing; a window without schemas plans nothing. Settings
(config, the handling resolved for the mode, NewTableSettings) replaces
the three loose arguments both DoFns carried.
Report rows (REPORT_SCHEMA), told apart by row_type:
row_type schema | create | unreadable | unchecked | summary
schema_key short murmur3 key of the schema JSON on schema rows
schema the canonical schema JSON; on the create row, the
union the table would be created with
num_files files the row covers
changes ARRAY<STRING>: the SchemaDelta descriptions on schema
rows; "create <optional|required> <name> <type>" per
column on the create row (pins shown required); the
totals line and table-level changes on the summary
allowed whether a real run would accept it
reason why not, else ""; the consequence on the summary
would_create_table false whenever a real run would not create the
table, including when it would fail first
Provider: the dry_run_report output only exists when dry_run is set,
so existing YAML pipelines that enumerate outputs are unaffected.
claudevdm
force-pushed
the
addfiles-dry-run
branch
from
September 21, 2026 03:46
f436398 to
2d2d5de
Compare
ahmedabu98
reviewed
Sep 21, 2026
ahmedabu98
left a comment
Contributor
There was a problem hiding this comment.
Left some comments.
Really cool to see how it looks like in the YAML test
ahmedabu98
approved these changes
Sep 22, 2026
ahmedabu98
left a comment
Contributor
There was a problem hiding this comment.
Just some doc nits. Everything else LGTM, thanks!
Amar3tto
pushed a commit
that referenced
this pull request
Sep 24, 2026
* AddFiles: dry_run reports what the schema pre-pass would do without committing or registering
SchemaEvolutionConfig.setDryRun(true) (provider key dry_run) turns
AddFiles into a report-only transform: the read side runs as usual
(footers, distinct schemas), then DryRunReport emits one Row per
distinct schema plus one summary row on a new output, dry_run_report.
Why: before enabling evolution on a large import, a user wants to know
what the options would do to the table and which files would be
refused, without touching anything. Running the real transform under
FAIL_PIPELINE answers only "would it fail", and only for the first
failure.
The verdicts come from CommitSchemaUnion.plan, the one step that
decides everything a commit does before writing anything. A Plan says
which distinct file schemas are merged (SchemaToMerge), which are
refused and why (IncompatibleSchema), and the schema the table ends
with. It is an EvolutionPlan against an existing table (base schema
snapshot, name-mapping repair) or a CreationPlan when the table is
missing (partition spec and sort order resolved against the union, or
the problem that blocks creation). commitOnce dispatches to evolve or
create, which fail or warn under the handling mode and then write; the
dry run turns the same plan into rows, so a check added to the plan
reaches both and the report cannot drift from the commit. A schema that
is fine against the table but conflicts with another schema of the
input is therefore reported with the blame a real run assigns.
Real-run changes that come with planning first: partition or sort
fields that do not fit the union fail with a message naming them,
before any catalog write and under either handling (the per-file
fallback creation throws the same error, so it could never be routed);
problems are reported before the transaction is opened; every
transaction is checked against the one base snapshot; planning retries
like committing; a window without schemas plans nothing. Settings
(config, the handling resolved for the mode, NewTableSettings) replaces
the three loose arguments both DoFns carried.
Report rows (REPORT_SCHEMA), told apart by row_type:
row_type schema | create | unreadable | unchecked | summary
schema_key short murmur3 key of the schema JSON on schema rows
schema the canonical schema JSON; on the create row, the
union the table would be created with
num_files files the row covers
changes ARRAY<STRING>: the SchemaDelta descriptions on schema
rows; "create <optional|required> <name> <type>" per
column on the create row (pins shown required); the
totals line and table-level changes on the summary
allowed whether a real run would accept it
reason why not, else ""; the consequence on the summary
would_create_table false whenever a real run would not create the
table, including when it would fail first
Provider: the dry_run_report output only exists when dry_run is set,
so existing YAML pipelines that enumerate outputs are unaffected.
* improve retry
* comments
* add untracked file
* move tests
* track file
* comments
Amar3tto
added a commit
that referenced
this pull request
Sep 24, 2026
Cherry pick AddFiles: Add dry_run (#40167)
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
AddFiles:
dry_runreports what the schema pre-pass would doSchemaEvolutionConfig.setDryRun(true)(dry_run: truein YAML) turns AddFiles into a report-only transform. The read side runs as usual (footers, distinct schemas); instead of committing and registering, a newdry_run_reportoutput gets one row per distinct file schema plus acreaterow, marker rows for unreadable and ORC/Avro files, and a summary row, told apart by arow_typecolumn.snapshotsanderrorsare empty. The output only exists whendry_runis set, so existing YAML pipelines are unaffected.The diff has two halves. Reading them in this order is easiest.
1.
CommitSchemaUnion: the commit now plans before it writes.Everything a commit decides is pulled into a
Plan, built byplan(): which distinct file schemas get merged (SchemaToMerge), which are refused and why (IncompatibleSchema), the schema the table ends with, and any configuration problems. It is anEvolutionPlanagainst an existing table (classify and fold on scratch transactions, all against one snapshot of the table schema, plus whether the name mapping gets repaired) or aCreationPlanwhen the table is missing (fold for creation, then the partition spec and sort order resolved against the union, or the problem that blocks creation).commitOnceonly dispatches toevolveorcreate; each fails or warns under the handling mode first, then writes.DryRunReportturns the same plan into rows. A check added to the plan reaches both, so the report cannot drift from the commit. In particular a schema that is fine against the table but conflicts with another schema of the input is reported with the blame a real run assigns.Because these types are now shared with the report, some merged code was renamed and tidied:
Acceptedis nowSchemaToMergeandIncompatibleis nowIncompatibleSchema(each is a whole distinct file schema, not a column change);TableCreationis nowNewTableSettings;reportIncompatibleis nowfailOrWarnOnIncompatibleSchemas, since it can end the run.Settings(the config, the handling resolved for the pipeline mode, the new-table settings) replaces the three loose arguments thatcommit,CommitSchemaOnceand nowDryRunReportcarried.Verdictsholder tracks where each schema stands, and staging returns theConflictit found.2. The dry run itself.
DryRunReport(new), theexpandwiring inAddFiles, thedry_runknob inSchemaEvolutionConfigand the YAML provider, the marker keys inReadFooterSchema, the transform-level tests inAddFilesTest, and a YAML fixture that runs a dry run against a missing table, writes the report to JSON and asserts the full rows.Report rows
row_typeschema,create,unreadable,uncheckedorsummaryschema_keyschemarows, to group by; empty on the othersschemacreaterow, the union the table would be created with; empty on the othersnum_fileschangesSchemaDeltadescriptions onschemarows; onecreate optional <name> <type>per column on thecreaterow; the totals line plus any table-level change (name mapping) on the summaryallowedreasonwould_create_tablePart of #40144
Thank you for your contribution! Follow this checklist to help us incorporate your contribution quickly and easily:
addresses #123), if applicable. This will automatically add a link to the pull request in the issue. If you would like the issue to automatically close on merging the pull request, commentfixes #<ISSUE NUMBER>instead.CHANGES.mdwith noteworthy changes.See the Contributor Guide for more tips on how to make review process smoother.
To check the build health, please visit https://github.com/apache/beam/blob/master/.test-infra/BUILD_STATUS.md
GitHub Actions Tests Status (on master branch)
See CI.md for more information about GitHub Actions CI or the workflows README to see a list of phrases to trigger workflows.