Skip to content

direct: collapse block+leaf overlap to one level in the plan - #6624

Open
denik wants to merge 4 commits into
mainfrom
denik/plan-one-level
Open

direct: collapse block+leaf overlap to one level in the plan#6624
denik wants to merge 4 commits into
mainfrom
denik/plan-one-level

Conversation

@denik

@denik denik commented Sep 11, 2026

Copy link
Copy Markdown
Contributor

Changes

When a whole block is added or removed on one side, structdiff records a single block-level change while the other diff descends to the inner fields, producing an overlap (e.g. schedule and schedule.timezone_id). prepareChanges now drops any change that has an ancestor change in the same resource, so the plan carries one level per subtree (block wins).

config-remote-sync produces identical config from the result. Postgres rebuilds its update_mask from the plan, so collectUpdatePathsWithPrefix re-diffs each block change to recover the changed leaves — masking the whole message is rejected by the API.

Follows #6589.

Tests

Existing acceptance tests, regenerated.

@eng-dev-ecosystem-bot

eng-dev-ecosystem-bot commented Sep 11, 2026

Copy link
Copy Markdown
Collaborator

Integration test report

Commit: 84317dc

Run: 34847450431

Env 💚​RECOVERED ✅​pass 🙈​skip Time
💚​ aws linux 1 295 18 11:54
💚​ aws windows 1 289 18 9:23
💚​ azure linux 1 282 21 9:39
💚​ azure windows 1 276 21 6:32
💚​ gcp linux 1 283 21 12:12
💚​ gcp windows 1 277 21 6:04
Test Name aws linux aws windows azure linux azure windows gcp linux gcp windows
💚​ TestAccept 💚​R 💚​R 💚​R 💚​R 💚​R 💚​R
Top 16 slowest tests (at least 2 minutes):
duration env testname
4:28 gcp windows TestAccept
4:07 aws windows TestAccept/bundle/resources/postgres_roles/update/DATABRICKS_BUNDLE_ENGINE=terraform/DMS=
4:00 gcp linux TestAccept
3:57 aws linux TestAccept
3:50 azure linux TestAccept
3:27 azure windows TestAccept
3:08 aws windows TestAccept
2:37 aws windows TestAccept/bundle/resources/postgres_endpoints/update_pg_settings/DATABRICKS_BUNDLE_ENGINE=direct/DMS=true
2:28 aws linux TestAccept/bundle/resources/postgres_projects/update_default_endpoint_suspend/DATABRICKS_BUNDLE_ENGINE=terraform/DMS=
2:28 aws linux TestAccept/bundle/resources/postgres_roles/update/DATABRICKS_BUNDLE_ENGINE=terraform/DMS=
2:24 gcp linux TestAccept/bundle/config-remote-sync/config_edits/DATABRICKS_BUNDLE_ENGINE=terraform/DMS=
2:12 aws windows TestAccept/bundle/resources/postgres_roles/update/DATABRICKS_BUNDLE_ENGINE=direct/DMS=true
2:10 aws linux TestAccept/bundle/resources/postgres_roles/update/DATABRICKS_BUNDLE_ENGINE=direct/DMS=
2:08 aws windows TestAccept/bundle/resources/postgres_projects/update_default_endpoint_suspend/DATABRICKS_BUNDLE_ENGINE=terraform/DMS=
2:03 aws windows TestAccept/bundle/resources/postgres_endpoints/update_pg_settings/DATABRICKS_BUNDLE_ENGINE=terraform/DMS=
2:03 aws windows TestAccept/bundle/resources/postgres_roles/update/DATABRICKS_BUNDLE_ENGINE=direct/DMS=

@denik
denik force-pushed the denik/plan-one-level branch from 8231aa8 to 5e1db42 Compare September 11, 2026 12:02
@denik denik changed the title Investigate: collapse block+leaf overlap to one level in bundle plan output direct: collapse block+leaf overlap to one level in the plan Sep 11, 2026
@denik
denik force-pushed the denik/plan-one-level branch 3 times, most recently from 3ac9325 to 21b9b66 Compare September 14, 2026 09:41
@denik
denik marked this pull request as ready for review September 14, 2026 10:35
@denik
denik requested review from ilyakuz-db and janniklasrose and removed request for janniklasrose September 14, 2026 10:35
@github-actions

Copy link
Copy Markdown
Contributor

Approval status: pending

/acceptance/bundle/ - needs approval

9 files changed
Suggested: @pietern
Also eligible: @andrewnester, @janniklasrose, @shreyas-goenka, @anton-107, @lennartkats-db

/bundle/ - needs approval

4 files changed
Suggested: @pietern
Also eligible: @andrewnester, @janniklasrose, @shreyas-goenka, @anton-107, @lennartkats-db

Any maintainer (@andrewnester, @anton-107, @pietern, @shreyas-goenka, @simonfaltum, @renaudhartert-db, @janniklasrose, @lennartkats-db, @rugpanov, @rclarey) can approve all areas.
See OWNERS for ownership rules.

@@ -28,3 +28,2 @@
clusters:
- label: maintenance
- num_workers: 3

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.

This one looks like a regression due to less granular updates? Cluster is defined in 2 places. Previously, we were able to detect the change and remove

Not sure though what is desired behavior here

denik and others added 4 commits September 14, 2026 15:07
When a whole block is added/removed on one side it is recorded as a single
block-level change, and the other diff may also descend to inner fields of the
same subtree. prepareChanges now drops any change that has an ancestor change in
the map, so the plan carries one level per subtree.

config-remote-sync consumes these changes and produces identical config
(verified: config_edits/multiple_files write the same YAML, only the redundant
child op drops from the op-list; split/positional shifts its documented
positional gap).

update_mask is intentionally not addressed here (postgres default_endpoint_settings
still masks the enclosing message); that is handled by the parallel static-mask work.

Co-authored-by: Isaac <no-reply@databricks.com>
Block-wins collapses an edited block to a single block-level plan entry,
but the update_mask must still name the changed leaves: masking the whole
message makes the API require every field under it in the request body.
collectUpdatePathsWithPrefix now re-diffs each block change's Old against
New to recover those leaves; a whole add/remove (one side nil) does not
descend and masks as the block, matching prior behavior.

Co-authored-by: Isaac <no-reply@databricks.com>
The block+leaf overlap collapse dropped a leaf against its block ancestor
in prepareChanges, before classification. For a missing-in-remote block
(e.g. job_runs' local-only lifecycle fingerprint) the remote diff always
emits a whole-block change that the resource then drops (ReasonDrop),
while the real recreate rides on the leaf. Collapsing first dropped the
leaf, then the ancestor was dropped too, so on_bundle_deploy/on_file_change
no longer re-fired the run.

Move the collapse to keepOneLevelPerSubtree, run after addPerFieldActions
on the classified, drop-pruned map. A dropped ancestor is already gone and
can no longer shadow a real leaf; a surviving block ancestor still inherits
a descendant's recreate via findMatchingRuleBidirectional, so the genuine
overlap cases (config-remote-sync, postgres update_mask) are unchanged.

Co-authored-by: Isaac <no-reply@databricks.com>
These goldens track the plan's per-field op list, which the one-level
collapse trims: a redundant child op under a block op is dropped
(email_notifications.on_failure[0], tasks[...].new_cluster,
config.env[0].value), and split/positional shows its documented
positional remnant. The written config is otherwise unchanged.

Co-authored-by: Isaac <no-reply@databricks.com>
@denik
denik force-pushed the denik/plan-one-level branch from 21b9b66 to 84317dc Compare September 14, 2026 13:08
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.

3 participants