Skip to content

Fix whole-block plan misclassification via bidirectional rule matching - #6589

Draft
denik wants to merge 1 commit into
mainfrom
denik/diff-whole-block-fix
Draft

Fix whole-block plan misclassification via bidirectional rule matching#6589
denik wants to merge 1 commit into
mainfrom
denik/diff-whole-block-fix

Conversation

@denik

@denik denik commented Sep 9, 2026

Copy link
Copy Markdown
Contributor

Follow-up to #6566 (the reproducer tests, now merged).

Fixes the "whole block" plan issues without touching structdiff, so configsync and most goldens are unaffected.

structdiff keeps emitting one change at the block level when a nested struct is nil on one side — the right granularity for a whole add/remove. The fix is in the two bundle-plan consumers:

  • Bidirectional rule matching (findMatchingRulematchesFieldRule): a rule on foo.bar now also matches a change recorded at foo. So adding/removing a whole block that contains an immutable field (ingestion_definition.connection_name) is classified recreate instead of update.
  • One level per subtree (prepareChanges): when one diff descended to a leaf while the other stayed at the block, the block-level entry wins and inner-field entries are dropped — the plan no longer carries both a block and its children.

update_mask is intentionally left alone (minimal change), so the postgres default_endpoint_settings message-mask case stays a documented bug rather than being fixed here.

Test flips (reproducers from #6566):

  • pipelines/recreate-{add,remove}-whole-blockrecreate on both engines.
  • jobs/whole-block-overlapchanges collapses to the single schedule block.
  • postgres_projects/add_default_endpoint_settings → unchanged (still documents the mask bug).

Incidental golden updates (apps/config-drift-stopped, job_runs/on_bundle_deploy, model_serving .../telemetry_config_unmanaged) are the overlap collapsing to one level; resource-level actions are unchanged.

Note: broad golden regeneration was interrupted; CI (and a follow-up commit) will land any remaining goldens.

This pull request and its description were written by Isaac.

Keep structdiff emitting whole-block changes: when a nested struct is nil on one
side it is one change at the block level, which is the right granularity for a
whole add/remove. Fix the two bundle-plan consumers that need to relate a rule to
such a change:

- findMatchingRule is now bidirectional (matchesFieldRule): a rule on foo.bar
  matches a change at foo, so adding/removing a whole block that contains an
  immutable field recreates instead of updating.
- prepareChanges keeps one level per subtree: when one diff descended to a leaf
  while the other stayed at the block, the block-level entry wins and inner-field
  entries are dropped.

update_mask is left alone, so the postgres default_endpoint_settings message-mask
case stays a documented bug. structdiff and configsync are unchanged, so there is
no empty-parent regression.

Co-authored-by: Isaac <no-reply@databricks.com>
@eng-dev-ecosystem-bot

Copy link
Copy Markdown
Collaborator

Integration test report

Commit: 2170b36

Run: 34371816920

Env 🔄​flaky 💚​RECOVERED ✅​pass 🙈​skip Time
💚​ aws linux 1 275 21 12:33
🔄​ aws windows 1 1 276 19 10:05
🔄​ azure linux 2 1 272 21 13:08
💚​ azure windows 1 276 19 7:54
🔄​ gcp linux 1 1 274 21 13:19
🔄​ gcp windows 1 1 276 19 12:16
Test Name aws linux aws windows azure linux azure windows gcp linux gcp windows
💚​ TestAccept 💚​R 💚​R 💚​R 💚​R 💚​R 💚​R
🔄​ TestSyncIncrementalFileOverwritesFolder ✅​p 🔄​f ✅​p ✅​p 🔄​f ✅​p
🔄​ TestSyncIncrementalFileSync ✅​p ✅​p 🔄​f ✅​p ✅​p ✅​p
🔄​ TestSyncIncrementalSyncFileToPythonNotebook ✅​p ✅​p ✅​p ✅​p ✅​p 🔄​f
🔄​ TestSyncNestedSpacePlusAndHashAreEscapedSync ✅​p ✅​p 🔄​f ✅​p ✅​p ✅​p
Top 22 slowest tests (at least 2 minutes):
duration env testname
3:48 aws windows TestAccept
3:40 azure windows TestAccept
3:40 gcp windows TestAccept
3:28 aws windows TestFilerRecursiveDelete/workspace_files
3:23 gcp linux TestFilerWorkspaceFilesExtensionsRead
3:01 gcp windows TestFilerRecursiveDelete/workspace_files_extensions
2:57 aws linux TestFilerRecursiveDelete/workspace_files
2:44 gcp windows TestImportDir
2:32 aws windows TestFilerWorkspaceFilesExtensionsStat
2:30 gcp windows TestImportDirWithOverwriteFlag
2:28 aws linux TestFilerRecursiveDelete/workspace_files_extensions
2:26 gcp windows TestFilerWorkspaceFilesExtensionsStat
2:23 aws linux TestImportDirWithOverwriteFlag
2:15 azure windows TestFilerWorkspaceFilesExtensionsReadDir
2:09 aws linux TestAccept
2:09 gcp windows TestFilerRecursiveDelete/workspace_files
2:07 gcp linux TestLock
2:05 gcp linux TestWorkspaceFilesExtensions_ExportFormatIsPreserved/source_scala
2:05 gcp windows TestWorkpaceExportPrintsContents
2:04 azure linux TestAccept
2:04 gcp windows TestFilerWorkspaceFilesExtensionsReadDir
2:03 gcp linux TestAccept

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