Skip to content

Support schema rename and improve catalog rename - #7343

Open
denik wants to merge 34 commits into
mainfrom
denik/schemas-remove
Open

denik wants to merge 34 commits into
mainfrom
denik/schemas-remove

Conversation

@denik

@denik denik commented Nov 4, 2026 •

Copy link
Copy Markdown
Contributor

Changes

Changing a schema's name now renames it in place (PATCH new_name) instead of deleting and recreating it, so the schema and its contents survive.

UC moves the children of a renamed catalog or schema along with it. A volume in a renamed schema, or a schema in a renamed catalog (schema_name/catalog_name: ${resources.<parent>.name}), used to be planned as a recreate. Its create then failed with RESOURCE_ALREADY_EXISTS on every deploy, because the recreate had already dropped it from state. The planner now re-keys such children (update_id, reason parent_renamed) under their new parents. Catalog rename was already supported and had the same latent bug for child schemas.

A child whose only change is following its parent is planned state_only: the framework saves it under the ID the adapter's new optional IDFromState gives it, with no request. Such entries are left out of the text plan and counted as unchanged. A child with its own changes too goes through DoUpdateWithID, which addresses it at its new path.

A resource can also be missing from its recorded ID with no rename in the plan: a deploy stopped after renaming the parent, or the resource or its parent was renamed out of band. When the read at the recorded ID finds nothing, the plan reads at the IDFromState ID. It takes what it finds only if its internal ID matches the one in the state. The new internal_id_field lifecycle setting names it (schema_id, volume_id); the framework records it from the remote state on every save, and the plan skips it (reason internal_id). A different object under that name is planned as a create, which UC rejects, so it is never adopted. The plan entry's id field (declared, but never set until now) records where the resource was found, and apply addresses it there. Catalogs have no internal ID and are not looked for yet. With the new state fields, apitypes.generated.yml now maps schemas and volumes to SchemaInfo/VolumeInfo, as registered models already map to their Info type.

Stacked on #7408, which makes the test server move, delete and reject UC objects the way UC does. With #7345 and #7361 (merged), which re-key grants and permissions when their parent's ID changes, a renamed schema keeps those in sync too. Registered models and UC secrets follow parent renames in #7379 and #7381.

Tests

  • New acceptance tests, Cloud = true, passing locally and on AWS, GCP and Azure: schemas/rename, schemas/rename_with_volume, catalogs/rename (catalog → schema → volume).
  • New schemas/rename_then_change: after a parent rename, a volume update, rename and recreate all reach its new path, also after a second rename and a rename back.
  • New volumes/rename_catalog_and_schema: the catalog and the schema are renamed in one deploy, so the volume follows two parent renames at once. It gets no request and keeps its volume_id.
  • New schemas/rename_with_volume_ref: a job reading the volume's full_name, id and volume_id gets the right values after the rename.
  • New schemas/rename_with_comment, catalogs/rename_with_comment (rename and comment change go in one PATCH) and schemas/rename_case_only, volumes/rename_case_only (UC accepts the update and keeps the lowercase name; the redeploy is a no-op).
  • New schemas/rename_interrupted (local only; uses the test server's kill hook): the CLI is killed after the schema's rename is saved and before the volume's re-key. The next deploy finds the volume at its new path by volume_id. Without the fix it planned a create.
  • New schemas/recreate_interrupted (local only): the same kill during a recreate of the schema under a new name. The volume went with the old schema, so the next deploy creates a new one.
  • New out-of-band renames, Cloud = true, config renamed to match: volumes/rename_out_of_band and schemas/rename_out_of_band (found by volume_id/schema_id, deploy sends no requests); catalogs/rename_out_of_band and catalogs/rename_all_out_of_band (schema and volume found; the catalog's create fails with CATALOG_ALREADY_EXISTS).
  • New out-of-band recreates, Cloud = true: volumes/recreate_out_of_band and schemas/recreate_out_of_band. An object is found under the new name but its id differs, so the plan creates instead of adopting it.
  • grants/schemas/change_name (from Re-key grants when their parent's ID changes #7345) now shows the in-place rename; migrate/auto/schema-rename now renames; lifecycle/prevent-destroy switched its recreate lever from name to catalog_name.
  • Unit tests for followsParentRename, Changes.HasOnlySingleReason and the skipped internal-ID changes.

This pull request and its description were written by Isaac.

@github-actions github-actions Bot added the DABs DABs related issues label Nov 4, 2026
@github-actions

github-actions Bot commented Nov 4, 2026 •

Copy link
Copy Markdown
Contributor

Commit: 37e8eb365 | Workflow run

Regression test report

Selected 20 changed tests (limit=20, 21 not selected)

37 tests: regression=33 unreleased=0 coverage=4 failing=0
test branch main (77950b6) latest (v1.25.0)
TestAccept/bundle/lifecycle/prevent-destroy/DMS= ✅ ✅ ✅
TestAccept/bundle/lifecycle/prevent-destroy/DMS=true ✅ ✅ ✅
TestAccept/bundle/migrate/auto/schema-rename/DMS= ✅ ❌ ❌
TestAccept/bundle/resources/catalogs/rename/DMS= ✅ ❌ ❌
TestAccept/bundle/resources/catalogs/rename/DMS=true ✅ ❌ ❌
TestAccept/bundle/resources/catalogs/rename_all_out_of_band/DMS= ✅ ❌ ❌
TestAccept/bundle/resources/catalogs/rename_all_out_of_band/DMS=true ✅ ❌ ❌
TestAccept/bundle/resources/catalogs/rename_out_of_band/DMS= ✅ ❌ ❌
TestAccept/bundle/resources/catalogs/rename_out_of_band/DMS=true ✅ ❌ ❌
TestAccept/bundle/resources/catalogs/rename_with_comment/DMS= ✅ ✅ ✅
TestAccept/bundle/resources/catalogs/rename_with_comment/DMS=true ✅ ✅ ✅
TestAccept/bundle/resources/schemas/recreate_interrupted/DMS= ✅ ❌ ❌
TestAccept/bundle/resources/schemas/recreate_out_of_band/DMS= ✅ ❌ ❌
TestAccept/bundle/resources/schemas/recreate_out_of_band/DMS=true ✅ ❌ ❌
TestAccept/bundle/resources/schemas/rename/DMS= ✅ ❌ ❌
TestAccept/bundle/resources/schemas/rename/DMS=true ✅ ❌ ❌
TestAccept/bundle/resources/schemas/rename_case_only/DMS= ✅ ❌ ❌
TestAccept/bundle/resources/schemas/rename_case_only/DMS=true ✅ ❌ ❌
TestAccept/bundle/resources/schemas/rename_interrupted/DMS= ✅ ❌ ❌
TestAccept/bundle/resources/schemas/rename_out_of_band/DMS= ✅ ❌ ❌
TestAccept/bundle/resources/schemas/rename_out_of_band/DMS=true ✅ ❌ ❌
TestAccept/bundle/resources/schemas/rename_then_change/DMS= ✅ ❌ ❌
TestAccept/bundle/resources/schemas/rename_then_change/DMS=true ✅ ❌ ❌
TestAccept/bundle/resources/schemas/rename_with_comment/DMS= ✅ ❌ ❌
TestAccept/bundle/resources/schemas/rename_with_comment/DMS=true ✅ ❌ ❌
TestAccept/bundle/resources/schemas/rename_with_volume/DMS= ✅ ❌ ❌
TestAccept/bundle/resources/schemas/rename_with_volume/DMS=true ✅ ❌ ❌
TestAccept/bundle/resources/schemas/rename_with_volume_ref/DMS= ✅ ❌ ❌
TestAccept/bundle/resources/schemas/rename_with_volume_ref/DMS=true ✅ ❌ ❌
TestAccept/bundle/resources/volumes/recreate_out_of_band/DMS= ✅ ❌ ❌
TestAccept/bundle/resources/volumes/recreate_out_of_band/DMS=true ✅ ❌ ❌
TestAccept/bundle/resources/volumes/rename_case_only/DMS= ✅ ❌ ❌
TestAccept/bundle/resources/volumes/rename_case_only/DMS=true ✅ ❌ ❌
TestAccept/bundle/resources/volumes/rename_catalog_and_schema/DMS= ✅ ❌ ❌
TestAccept/bundle/resources/volumes/rename_catalog_and_schema/DMS=true ✅ ❌ ❌
TestAccept/bundle/resources/volumes/rename_out_of_band/DMS= ✅ ❌ ❌
TestAccept/bundle/resources/volumes/rename_out_of_band/DMS=true ✅ ❌ ❌
TestAccept/bundle/migrate/auto/schema-rename/DMS=: branch ✅ | main (77950b6) ❌ | latest (v1.25.0) ❌

main (77950b6):

acceptance_test.go:1345: Diff:
        --- bundle/migrate/auto/schema-rename/output.txt
        +++ /tmp/TestAcceptbundlemigrateautoschema-renameDMS=1573634500/002/output.txt
        @@ -4,32 +4,23 @@
         
         === Rename the schema (an updatable id field) and deploy on direct
         >>> DATABRICKS_BUNDLE_ENGINE=direct [CLI] bundle deploy
        -Warn: migration to direct: schemas.my_schema: name differs between config ("myschema-[UNIQUE_NAME]-renamed") and terraform state ("myschema-[UNIQUE_NAME]"); this resource will be renamed.
        +Warn: migration to direct: schemas.my_schema: name differs between config ("myschema-[UNIQUE_NAME]-renamed") and terraform state ("myschema-[UNIQUE_NAME]"); this resource will be recreated.
         Notice: migrating your bundle to direct deployment engine (https://github.com/databricks/cli/issues/6765).
         Uploading bundle files to /Workspace/Users/[USERNAME]/.bundle/[UNIQUE_NAME]/files...
        -Migrated 1 resource to direct deployment engine.
        -Updated schemas.my_schema
        -Files: 2 uploaded, 0 deleted
        -Resources: 0 created, 1 changed, 0 deleted, 0 unchanged
         
        -=== Redeploy on direct: the schema now matches config, so the plan is a clean no-op
        ->>> DATABRICKS_BUNDLE_ENGINE=direct [CLI] bundle deploy
        -Uploading bundle files to /Workspace/Users/[USERNAME]/.bundle/[UNIQUE_NAME]/files...
        -Files: 0 uploaded, 0 deleted
        -Resources: 0 created, 0 changed, 0 deleted, 1 unchanged
        +This action will result in the deletion or recreation of the following UC schemas. Any underlying data may be lost:
        +  recreate resources.schemas.my_schema
        +Warn: Migration not committed, keeping Terraform state
        +Error: the deployment requires destructive actions, but the current console does not support prompting.
        +Deleting data assets such as schemas, pipelines, or volumes may cause permanent data loss and should be carefully reviewed.
        +To proceed, use --auto-approve after reviewing the plan above.
         
        -=== The schema exists under the new name and the local state is direct
        ->>> [CLI] schemas get main.myschema-[UNIQUE_NAME]-renamed
        -{
        -  "full_name": "main.myschema-[UNIQUE_NAME]-renamed"
        -}
        +Files: 2 uploaded, 0 deleted
         
        ->>> find.py \.databricks/.*(\.tfstate|resources.*\.json|\.wal)
        -.databricks/bundle/default/resources.json
        -.databricks/bundle/default/terraform/terraform.tfstate.backup
        -
         === Cleanup
         >>> [CLI] bundle destroy --auto-approve
        +Warn: migration to direct: schemas.my_schema: name differs between config ("myschema-[UNIQUE_NAME]-renamed") and terraform state ("myschema-[UNIQUE_NAME]"); this resource will be recreated.
        +Notice: migrating your bundle to direct deployment engine (https://github.com/databricks/cli/issues/6765).
         The following resources will be deleted:
           delete resources.schemas.my_schema
         
        @@ -38,4 +22,7 @@
         
         All files and directories at the following location will be deleted: /Workspace/Users/[USERNAME]/.bundle/[UNIQUE_NAME]
         
        +Migrated 1 resource to direct deployment engine.
         Destroy: 1 deleted
        +
        +Exit code: 1

latest (v1.25.0): same output as main (77950b6)

TestAccept/bundle/resources/catalogs/rename/DMS=: branch ✅ | main (77950b6) ❌ | latest (v1.25.0) ❌

main (77950b6):

acceptance_test.go:1345: Diff:
        --- bundle/resources/catalogs/rename/output.txt
        +++ /tmp/TestAcceptbundleresourcescatalogsrenameDMS=2035199049/002/output.txt
        @@ -73,8 +73,7 @@
                 "label": "${resources.catalogs.catalog1.name}"
               }
             ],
        -    "action": "update_id",
        -    "state_only": true,
        +    "action": "recreate",
             "new_state": {
               "value": {
                 "catalog_name": "test_catalog_renamed_[UNIQUE_NAME]",
        @@ -93,17 +92,11 @@
             },
             "changes": {
               "catalog_name": {
        -        "action": "update_id",
        -        "reason": "parent_renamed",
        +        "action": "recreate",
        +        "reason": "id_field",
                 "old": "test_catalog_[UNIQUE_NAME]",
                 "new": "test_catalog_renamed_[UNIQUE_NAME]",
                 "remote": "test_catalog_[UNIQUE_NAME]"
        -      },
        -      "schema_id": {
        -        "action": "skip",
        -        "reason": "internal_id",
        -        "old": "[SCHEMA_ID]",
        -        "remote": "[SCHEMA_ID]"
               }
             }
           },
        @@ -118,8 +108,7 @@
                 "label": "${resources.schemas.schema1.name}"
               }
             ],
        -    "action": "update_id",
        -    "state_only": true,
        +    "action": "recreate",
             "new_state": {
               "value": {
                 "catalog_name": "test_catalog_renamed_[UNIQUE_NAME]",
        @@ -141,17 +130,11 @@
             },
             "changes": {
               "catalog_name": {
        -        "action": "update_id",
        -        "reason": "parent_renamed",
        +        "action": "recreate",
        +        "reason": "id_field",
                 "old": "test_catalog_[UNIQUE_NAME]",
                 "new": "test_catalog_renamed_[UNIQUE_NAME]",
                 "remote": "test_catalog_[UNIQUE_NAME]"
        -      },
        -      "volume_id": {
        -        "action": "skip",
        -        "reason": "internal_id",
        -        "old": "[VOLUME_ID]",
        -        "remote": "[VOLUME_ID]"
               }
             }
           }
        @@ -160,63 +140,21 @@
         === Deploy renames the catalog. UC moves the schema and the volume with it, so they get no request
         >>> [CLI] bundle deploy
         Uploading bundle files to /Workspace/Users/[USERNAME]/.bundle/test-bundle-[UNIQUE_NAME]/default/files...
        -Updated catalogs.catalog1
        -Files: 1 uploaded, 0 deleted
        -Resources: 0 created, 1 changed, 0 deleted, 2 unchanged
         
        ->>> print_requests.py //unity-catalog
        -{
        -  "method": "PATCH",
        -  "path": "/api/2.1/unity-catalog/catalogs/test_catalog_[UNIQUE_NAME]",
        -  "body": {
        -    "comment": "",
        -    "custom_max_retention_hours": 0,
        -    "new_name": "test_catalog_renamed_[UNIQUE_NAME]"
        -  }
        -}
        +This action will result in the deletion or recreation of the following UC schemas. Any underlying data may be lost:
        +  recreate resources.schemas.schema1
         
        -=== The old catalog is gone and the schema and the volume are under the new one, with their original ids
        -old catalog is gone
        +This action will result in the deletion or recreation of the following volumes.
        +For managed volumes, the files stored in the volume are also deleted from your
        +cloud tenant within 30 days. For external volumes, the metadata about the volume
        +is removed from the catalog, but the underlying files are not deleted:
        +  recreate resources.volumes.volume1
        +Error: the deployment requires destructive actions, but the current console does not support prompting.
        +Deleting data assets such as schemas, pipelines, or volumes may cause permanent data loss and should be carefully reviewed.
        +To proceed, use --auto-approve after reviewing the plan above.
         
        ->>> [CLI] schemas get test_catalog_renamed_[UNIQUE_NAME].myschema
        -{
        -  "full_name": "test_catalog_renamed_[UNIQUE_NAME].myschema",
        -  "catalog_name": "test_catalog_renamed_[UNIQUE_NAME]",
        -  "schema_id": "[SCHEMA_ID]"
        -}
        +Files: 1 uploaded, 0 deleted
         
        ->>> [CLI] volumes read test_catalog_renamed_[UNIQUE_NAME].myschema.myvolume
        -{
        -  "full_name": "test_catalog_renamed_[UNIQUE_NAME].myschema.myvolume",
        -  "catalog_name": "test_catalog_renamed_[UNIQUE_NAME]",
        -  "volume_id": "[VOLUME_ID]"
        -}
        -
        -=== The state tracks the new paths
        ->>> [CLI] bundle summary --output json
        -{
        -  "catalogs": {
        -    "catalog1": "test_catalog_renamed_[UNIQUE_NAME]"
        -  },
        -  "schemas": {
        -    "schema1": "test_catalog_renamed_[UNIQUE_NAME].myschema"
        -  },
        -  "volumes": {
        -    "volume1": "test_catalog_renamed_[UNIQUE_NAME].myschema.myvolume"
        -  }
        -}
        -
        -=== Redeploy is a no-op
        ->>> [CLI] bundle plan
        -Plan: 0 to add, 0 to change, 0 to delete, 3 unchanged
        -
        ->>> [CLI] bundle deploy
        -Uploading bundle files to /Workspace/Users/[USERNAME]/.bundle/test-bundle-[UNIQUE_NAME]/default/files...
        -Files: 0 uploaded, 0 deleted
        -Resources: 0 created, 0 changed, 0 deleted, 3 unchanged
        -
        ->>> print_requests.py //unity-catalog
        -
         >>> [CLI] bundle destroy --auto-approve
         The following resources will be deleted:
           delete resources.catalogs.catalog1
        @@ -235,3 +169,5 @@
         All files and directories at the following location will be deleted: /Workspace/Users/[USERNAME]/.bundle/test-bundle-[UNIQUE_NAME]/default
         
         Destroy: 3 deleted
        +
        +Exit code: 1
        
    acceptance_test.go:1123: 
        LOG.destroy_requests: {
        LOG.destroy_requests:   "method": "DELETE",
        LOG.destroy_requests:   "path": "/api/2.1/unity-catalog/volumes/test_catalog_hc5ewtrxtjhnpovej3zkxmbkpm.myschema.myvolume"
        LOG.destroy_requests: }
        LOG.destroy_requests: {
        LOG.destroy_requests:   "method": "DELETE",
        LOG.destroy_requests:   "path": "/api/2.1/unity-catalog/schemas/test_catalog_hc5ewtrxtjhnpovej3zkxmbkpm.myschema",
        LOG.destroy_requests:   "q": {
        LOG.destroy_requests:     "force": "true"
        LOG.destroy_requests:   }
        LOG.destroy_requests: }
        LOG.destroy_requests: {
        LOG.destroy_requests:   "method": "DELETE",
        LOG.destroy_requests:   "path": "/api/2.1/unity-catalog/catalogs/test_catalog_hc5ewtrxtjhnpovej3zkxmbkpm",
        LOG.destroy_requests:   "q": {
        LOG.destroy_requests:     "force": "true"
        LOG.destroy_requests:   }
        LOG.destroy_requests: }

latest (v1.25.0):

acceptance_test.go:1345: Diff:
        --- bundle/resources/catalogs/rename/output.txt
        +++ /tmp/TestAcceptbundleresourcescatalogsrenameDMS=2230672618/002/output.txt
        @@ -73,8 +73,7 @@
                 "label": "${resources.catalogs.catalog1.name}"
               }
             ],
        -    "action": "update_id",
        -    "state_only": true,
        +    "action": "recreate",
             "new_state": {
               "value": {
                 "catalog_name": "test_catalog_renamed_[UNIQUE_NAME]",
        @@ -93,17 +92,11 @@
             },
             "changes": {
               "catalog_name": {
        -        "action": "update_id",
        -        "reason": "parent_renamed",
        +        "action": "recreate",
        +        "reason": "id_field",
                 "old": "test_catalog_[UNIQUE_NAME]",
                 "new": "test_catalog_renamed_[UNIQUE_NAME]",
                 "remote": "test_catalog_[UNIQUE_NAME]"
        -      },
        -      "schema_id": {
        -        "action": "skip",
        -        "reason": "internal_id",
        -        "old": "[SCHEMA_ID]",
        -        "remote": "[SCHEMA_ID]"
               }
             }
           },
        @@ -118,8 +108,7 @@
                 "label": "${resources.schemas.schema1.name}"
               }
             ],
        -    "action": "update_id",
        -    "state_only": true,
        +    "action": "recreate",
             "new_state": {
               "value": {
                 "catalog_name": "test_catalog_renamed_[UNIQUE_NAME]",
        @@ -141,17 +130,11 @@
             },
             "changes": {
               "catalog_name": {
        -        "action": "update_id",
        -        "reason": "parent_renamed",
        +        "action": "recreate",
        +        "reason": "id_field",
                 "old": "test_catalog_[UNIQUE_NAME]",
                 "new": "test_catalog_renamed_[UNIQUE_NAME]",
                 "remote": "test_catalog_[UNIQUE_NAME]"
        -      },
        -      "volume_id": {
        -        "action": "skip",
        -        "reason": "internal_id",
        -        "old": "[VOLUME_ID]",
        -        "remote": "[VOLUME_ID]"
               }
             }
           }
        @@ -160,63 +140,21 @@
         === Deploy renames the catalog. UC moves the schema and the volume with it, so they get no request
         >>> [CLI] bundle deploy
         Uploading bundle files to /Workspace/Users/[USERNAME]/.bundle/test-bundle-[UNIQUE_NAME]/default/files...
        -Updated catalogs.catalog1
        -Files: 1 uploaded, 0 deleted
        -Resources: 0 created, 1 changed, 0 deleted, 2 unchanged
         
        ->>> print_requests.py //unity-catalog
        -{
        -  "method": "PATCH",
        -  "path": "/api/2.1/unity-catalog/catalogs/test_catalog_[UNIQUE_NAME]",
        -  "body": {
        -    "comment": "",
        -    "custom_max_retention_hours": 0,
        -    "new_name": "test_catalog_renamed_[UNIQUE_NAME]"
        -  }
        -}
        +This action will result in the deletion or recreation of the following UC schemas. Any underlying data may be lost:
        +  recreate resources.schemas.schema1
         
        -=== The old catalog is gone and the schema and the volume are under the new one, with their original ids
        -old catalog is gone
        +This action will result in the deletion or recreation of the following volumes.
        +For managed volumes, the files stored in the volume are also deleted from your
        +cloud tenant within 30 days. For external volumes, the metadata about the volume
        +is removed from the catalog, but the underlying files are not deleted:
        +  recreate resources.volumes.volume1
        +Error: the deployment requires destructive actions, but the current console does not support prompting.
        +Deleting data assets such as schemas, pipelines, or volumes may cause permanent data loss and should be carefully reviewed.
        +To proceed, use --auto-approve after reviewing the plan above.
         
        ->>> [CLI] schemas get test_catalog_renamed_[UNIQUE_NAME].myschema
        -{
        -  "full_name": "test_catalog_renamed_[UNIQUE_NAME].myschema",
        -  "catalog_name": "test_catalog_renamed_[UNIQUE_NAME]",
        -  "schema_id": "[SCHEMA_ID]"
        -}
        +Files: 1 uploaded, 0 deleted
         
        ->>> [CLI] volumes read test_catalog_renamed_[UNIQUE_NAME].myschema.myvolume
        -{
        -  "full_name": "test_catalog_renamed_[UNIQUE_NAME].myschema.myvolume",
        -  "catalog_name": "test_catalog_renamed_[UNIQUE_NAME]",
        -  "volume_id": "[VOLUME_ID]"
        -}
        -
        -=== The state tracks the new paths
        ->>> [CLI] bundle summary --output json
        -{
        -  "catalogs": {
        -    "catalog1": "test_catalog_renamed_[UNIQUE_NAME]"
        -  },
        -  "schemas": {
        -    "schema1": "test_catalog_renamed_[UNIQUE_NAME].myschema"
        -  },
        -  "volumes": {
        -    "volume1": "test_catalog_renamed_[UNIQUE_NAME].myschema.myvolume"
        -  }
        -}
        -
        -=== Redeploy is a no-op
        ->>> [CLI] bundle plan
        -Plan: 0 to add, 0 to change, 0 to delete, 3 unchanged
        -
        ->>> [CLI] bundle deploy
        -Uploading bundle files to /Workspace/Users/[USERNAME]/.bundle/test-bundle-[UNIQUE_NAME]/default/files...
        -Files: 0 uploaded, 0 deleted
        -Resources: 0 created, 0 changed, 0 deleted, 3 unchanged
        -
        ->>> print_requests.py //unity-catalog
        -
         >>> [CLI] bundle destroy --auto-approve
         The following resources will be deleted:
           delete resources.catalogs.catalog1
        @@ -235,3 +169,5 @@
         All files and directories at the following location will be deleted: /Workspace/Users/[USERNAME]/.bundle/test-bundle-[UNIQUE_NAME]/default
         
         Destroy: 3 deleted
        +
        +Exit code: 1
        
    acceptance_test.go:1123: 
        LOG.destroy_requests: {
        LOG.destroy_requests:   "method": "DELETE",
        LOG.destroy_requests:   "path": "/api/2.1/unity-catalog/volumes/test_catalog_n5sqengxovckbctszfsfymdofy.myschema.myvolume"
        LOG.destroy_requests: }
        LOG.destroy_requests: {
        LOG.destroy_requests:   "method": "DELETE",
        LOG.destroy_requests:   "path": "/api/2.1/unity-catalog/schemas/test_catalog_n5sqengxovckbctszfsfymdofy.myschema",
        LOG.destroy_requests:   "q": {
        LOG.destroy_requests:     "force": "true"
        LOG.destroy_requests:   }
        LOG.destroy_requests: }
        LOG.destroy_requests: {
        LOG.destroy_requests:   "method": "DELETE",
        LOG.destroy_requests:   "path": "/api/2.1/unity-catalog/catalogs/test_catalog_n5sqengxovckbctszfsfymdofy",
        LOG.destroy_requests:   "q": {
        LOG.destroy_requests:     "force": "true"
        LOG.destroy_requests:   }
        LOG.destroy_requests: }
TestAccept/bundle/resources/catalogs/rename/DMS=true: branch ✅ | main (77950b6) ❌ | latest (v1.25.0) ❌

main (77950b6):

acceptance_test.go:1345: Diff:
        --- bundle/resources/catalogs/rename/output.txt
        +++ /tmp/TestAcceptbundleresourcescatalogsrenameDMS=true566234840/002/output.txt
        @@ -73,8 +73,7 @@
                 "label": "${resources.catalogs.catalog1.name}"
               }
             ],
        -    "action": "update_id",
        -    "state_only": true,
        +    "action": "recreate",
             "new_state": {
               "value": {
                 "catalog_name": "test_catalog_renamed_[UNIQUE_NAME]",
        @@ -93,17 +92,11 @@
             },
             "changes": {
               "catalog_name": {
        -        "action": "update_id",
        -        "reason": "parent_renamed",
        +        "action": "recreate",
        +        "reason": "id_field",
                 "old": "test_catalog_[UNIQUE_NAME]",
                 "new": "test_catalog_renamed_[UNIQUE_NAME]",
                 "remote": "test_catalog_[UNIQUE_NAME]"
        -      },
        -      "schema_id": {
        -        "action": "skip",
        -        "reason": "internal_id",
        -        "old": "[SCHEMA_ID]",
        -        "remote": "[SCHEMA_ID]"
               }
             }
           },
        @@ -118,8 +108,7 @@
                 "label": "${resources.schemas.schema1.name}"
               }
             ],
        -    "action": "update_id",
        -    "state_only": true,
        +    "action": "recreate",
             "new_state": {
               "value": {
                 "catalog_name": "test_catalog_renamed_[UNIQUE_NAME]",
        @@ -141,17 +130,11 @@
             },
             "changes": {
               "catalog_name": {
        -        "action": "update_id",
        -        "reason": "parent_renamed",
        +        "action": "recreate",
        +        "reason": "id_field",
                 "old": "test_catalog_[UNIQUE_NAME]",
                 "new": "test_catalog_renamed_[UNIQUE_NAME]",
                 "remote": "test_catalog_[UNIQUE_NAME]"
        -      },
        -      "volume_id": {
        -        "action": "skip",
        -        "reason": "internal_id",
        -        "old": "[VOLUME_ID]",
        -        "remote": "[VOLUME_ID]"
               }
             }
           }
        @@ -160,63 +140,21 @@
         === Deploy renames the catalog. UC moves the schema and the volume with it, so they get no request
         >>> [CLI] bundle deploy
         Uploading bundle files to /Workspace/Users/[USERNAME]/.bundle/test-bundle-[UNIQUE_NAME]/default/files...
        -Updated catalogs.catalog1
        -Files: 1 uploaded, 0 deleted
        -Resources: 0 created, 1 changed, 0 deleted, 2 unchanged
         
        ->>> print_requests.py //unity-catalog
        -{
        -  "method": "PATCH",
        -  "path": "/api/2.1/unity-catalog/catalogs/test_catalog_[UNIQUE_NAME]",
        -  "body": {
        -    "comment": "",
        -    "custom_max_retention_hours": 0,
        -    "new_name": "test_catalog_renamed_[UNIQUE_NAME]"
        -  }
        -}
        +This action will result in the deletion or recreation of the following UC schemas. Any underlying data may be lost:
        +  recreate resources.schemas.schema1
         
        -=== The old catalog is gone and the schema and the volume are under the new one, with their original ids
        -old catalog is gone
        +This action will result in the deletion or recreation of the following volumes.
        +For managed volumes, the files stored in the volume are also deleted from your
        +cloud tenant within 30 days. For external volumes, the metadata about the volume
        +is removed from the catalog, but the underlying files are not deleted:
        +  recreate resources.volumes.volume1
        +Error: the deployment requires destructive actions, but the current console does not support prompting.
        +Deleting data assets such as schemas, pipelines, or volumes may cause permanent data loss and should be carefully reviewed.
        +To proceed, use --auto-approve after reviewing the plan above.
         
        ->>> [CLI] schemas get test_catalog_renamed_[UNIQUE_NAME].myschema
        -{
        -  "full_name": "test_catalog_renamed_[UNIQUE_NAME].myschema",
        -  "catalog_name": "test_catalog_renamed_[UNIQUE_NAME]",
        -  "schema_id": "[SCHEMA_ID]"
        -}
        +Files: 1 uploaded, 0 deleted
         
        ->>> [CLI] volumes read test_catalog_renamed_[UNIQUE_NAME].myschema.myvolume
        -{
        -  "full_name": "test_catalog_renamed_[UNIQUE_NAME].myschema.myvolume",
        -  "catalog_name": "test_catalog_renamed_[UNIQUE_NAME]",
        -  "volume_id": "[VOLUME_ID]"
        -}
        -
        -=== The state tracks the new paths
        ->>> [CLI] bundle summary --output json
        -{
        -  "catalogs": {
        -    "catalog1": "test_catalog_renamed_[UNIQUE_NAME]"
        -  },
        -  "schemas": {
        -    "schema1": "test_catalog_renamed_[UNIQUE_NAME].myschema"
        -  },
        -  "volumes": {
        -    "volume1": "test_catalog_renamed_[UNIQUE_NAME].myschema.myvolume"
        -  }
        -}
        -
        -=== Redeploy is a no-op
        ->>> [CLI] bundle plan
        -Plan: 0 to add, 0 to change, 0 to delete, 3 unchanged
        -
        ->>> [CLI] bundle deploy
        -Uploading bundle files to /Workspace/Users/[USERNAME]/.bundle/test-bundle-[UNIQUE_NAME]/default/files...
        -Files: 0 uploaded, 0 deleted
        -Resources: 0 created, 0 changed, 0 deleted, 3 unchanged
        -
        ->>> print_requests.py //unity-catalog
        -
         >>> [CLI] bundle destroy --auto-approve
         The following resources will be deleted:
           delete resources.catalogs.catalog1
        @@ -235,3 +169,5 @@
         All files and directories at the following location will be deleted: /Workspace/Users/[USERNAME]/.bundle/test-bundle-[UNIQUE_NAME]/default
         
         Destroy: 3 deleted
        +
        +Exit code: 1
        
    acceptance_test.go:1123: 
        LOG.destroy_requests: {
        LOG.destroy_requests:   "method": "DELETE",
        LOG.destroy_requests:   "path": "/api/2.1/unity-catalog/volumes/test_catalog_5adthioj4ndxvhjsirnuhl3nqq.myschema.myvolume"
        LOG.destroy_requests: }
        LOG.destroy_requests: {
        LOG.destroy_requests:   "method": "DELETE",
        LOG.destroy_requests:   "path": "/api/2.1/unity-catalog/schemas/test_catalog_5adthioj4ndxvhjsirnuhl3nqq.myschema",
        LOG.destroy_requests:   "q": {
        LOG.destroy_requests:     "force": "true"
        LOG.destroy_requests:   }
        LOG.destroy_requests: }
        LOG.destroy_requests: {
        LOG.destroy_requests:   "method": "DELETE",
        LOG.destroy_requests:   "path": "/api/2.1/unity-catalog/catalogs/test_catalog_5adthioj4ndxvhjsirnuhl3nqq",
        LOG.destroy_requests:   "q": {
        LOG.destroy_requests:     "force": "true"
        LOG.destroy_requests:   }
        LOG.destroy_requests: }
FAIL

latest (v1.25.0):

acceptance_test.go:1345: Diff:
        --- bundle/resources/catalogs/rename/output.txt
        +++ /tmp/TestAcceptbundleresourcescatalogsrenameDMS=true1058174619/002/output.txt
        @@ -73,8 +73,7 @@
                 "label": "${resources.catalogs.catalog1.name}"
               }
             ],
        -    "action": "update_id",
        -    "state_only": true,
        +    "action": "recreate",
             "new_state": {
               "value": {
                 "catalog_name": "test_catalog_renamed_[UNIQUE_NAME]",
        @@ -93,17 +92,11 @@
             },
             "changes": {
               "catalog_name": {
        -        "action": "update_id",
        -        "reason": "parent_renamed",
        +        "action": "recreate",
        +        "reason": "id_field",
                 "old": "test_catalog_[UNIQUE_NAME]",
                 "new": "test_catalog_renamed_[UNIQUE_NAME]",
                 "remote": "test_catalog_[UNIQUE_NAME]"
        -      },
        -      "schema_id": {
        -        "action": "skip",
        -        "reason": "internal_id",
        -        "old": "[SCHEMA_ID]",
        -        "remote": "[SCHEMA_ID]"
               }
             }
           },
        @@ -118,8 +108,7 @@
                 "label": "${resources.schemas.schema1.name}"
               }
             ],
        -    "action": "update_id",
        -    "state_only": true,
        +    "action": "recreate",
             "new_state": {
               "value": {
                 "catalog_name": "test_catalog_renamed_[UNIQUE_NAME]",
        @@ -141,17 +130,11 @@
             },
             "changes": {
               "catalog_name": {
        -        "action": "update_id",
        -        "reason": "parent_renamed",
        +        "action": "recreate",
        +        "reason": "id_field",
                 "old": "test_catalog_[UNIQUE_NAME]",
                 "new": "test_catalog_renamed_[UNIQUE_NAME]",
                 "remote": "test_catalog_[UNIQUE_NAME]"
        -      },
        -      "volume_id": {
        -        "action": "skip",
        -        "reason": "internal_id",
        -        "old": "[VOLUME_ID]",
        -        "remote": "[VOLUME_ID]"
               }
             }
           }
        @@ -160,63 +140,21 @@
         === Deploy renames the catalog. UC moves the schema and the volume with it, so they get no request
         >>> [CLI] bundle deploy
         Uploading bundle files to /Workspace/Users/[USERNAME]/.bundle/test-bundle-[UNIQUE_NAME]/default/files...
        -Updated catalogs.catalog1
        -Files: 1 uploaded, 0 deleted
        -Resources: 0 created, 1 changed, 0 deleted, 2 unchanged
         
        ->>> print_requests.py //unity-catalog
        -{
        -  "method": "PATCH",
        -  "path": "/api/2.1/unity-catalog/catalogs/test_catalog_[UNIQUE_NAME]",
        -  "body": {
        -    "comment": "",
        -    "custom_max_retention_hours": 0,
        -    "new_name": "test_catalog_renamed_[UNIQUE_NAME]"
        -  }
        -}
        +This action will result in the deletion or recreation of the following UC schemas. Any underlying data may be lost:
        +  recreate resources.schemas.schema1
         
        -=== The old catalog is gone and the schema and the volume are under the new one, with their original ids
        -old catalog is gone
        +This action will result in the deletion or recreation of the following volumes.
        +For managed volumes, the files stored in the volume are also deleted from your
        +cloud tenant within 30 days. For external volumes, the metadata about the volume
        +is removed from the catalog, but the underlying files are not deleted:
        +  recreate resources.volumes.volume1
        +Error: the deployment requires destructive actions, but the current console does not support prompting.
        +Deleting data assets such as schemas, pipelines, or volumes may cause permanent data loss and should be carefully reviewed.
        +To proceed, use --auto-approve after reviewing the plan above.
         
        ->>> [CLI] schemas get test_catalog_renamed_[UNIQUE_NAME].myschema
        -{
        -  "full_name": "test_catalog_renamed_[UNIQUE_NAME].myschema",
        -  "catalog_name": "test_catalog_renamed_[UNIQUE_NAME]",
        -  "schema_id": "[SCHEMA_ID]"
        -}
        +Files: 1 uploaded, 0 deleted
         
        ->>> [CLI] volumes read test_catalog_renamed_[UNIQUE_NAME].myschema.myvolume
        -{
        -  "full_name": "test_catalog_renamed_[UNIQUE_NAME].myschema.myvolume",
        -  "catalog_name": "test_catalog_renamed_[UNIQUE_NAME]",
        -  "volume_id": "[VOLUME_ID]"
        -}
        -
        -=== The state tracks the new paths
        ->>> [CLI] bundle summary --output json
        -{
        -  "catalogs": {
        -    "catalog1": "test_catalog_renamed_[UNIQUE_NAME]"
        -  },
        -  "schemas": {
        -    "schema1": "test_catalog_renamed_[UNIQUE_NAME].myschema"
        -  },
        -  "volumes": {
        -    "volume1": "test_catalog_renamed_[UNIQUE_NAME].myschema.myvolume"
        -  }
        -}
        -
        -=== Redeploy is a no-op
        ->>> [CLI] bundle plan
        -Plan: 0 to add, 0 to change, 0 to delete, 3 unchanged
        -
        ->>> [CLI] bundle deploy
        -Uploading bundle files to /Workspace/Users/[USERNAME]/.bundle/test-bundle-[UNIQUE_NAME]/default/files...
        -Files: 0 uploaded, 0 deleted
        -Resources: 0 created, 0 changed, 0 deleted, 3 unchanged
        -
        ->>> print_requests.py //unity-catalog
        -
         >>> [CLI] bundle destroy --auto-approve
         The following resources will be deleted:
           delete resources.catalogs.catalog1
        @@ -235,3 +169,5 @@
         All files and directories at the following location will be deleted: /Workspace/Users/[USERNAME]/.bundle/test-bundle-[UNIQUE_NAME]/default
         
         Destroy: 3 deleted
        +
        +Exit code: 1
        
    acceptance_test.go:1123: 
        LOG.destroy_requests: {
        LOG.destroy_requests:   "method": "DELETE",
        LOG.destroy_requests:   "path": "/api/2.1/unity-catalog/volumes/test_catalog_yqxybtewmzhpvakgbrd5a4cjxa.myschema.myvolume"
        LOG.destroy_requests: }
        LOG.destroy_requests: {
        LOG.destroy_requests:   "method": "DELETE",
        LOG.destroy_requests:   "path": "/api/2.1/unity-catalog/schemas/test_catalog_yqxybtewmzhpvakgbrd5a4cjxa.myschema",
        LOG.destroy_requests:   "q": {
        LOG.destroy_requests:     "force": "true"
        LOG.destroy_requests:   }
        LOG.destroy_requests: }
        LOG.destroy_requests: {
        LOG.destroy_requests:   "method": "DELETE",
        LOG.destroy_requests:   "path": "/api/2.1/unity-catalog/catalogs/test_catalog_yqxybtewmzhpvakgbrd5a4cjxa",
        LOG.destroy_requests:   "q": {
        LOG.destroy_requests:     "force": "true"
        LOG.destroy_requests:   }
        LOG.destroy_requests: }
FAIL
TestAccept/bundle/resources/catalogs/rename_all_out_of_band/DMS=: branch ✅ | main (77950b6) ❌ | latest (v1.25.0) ❌

main (77950b6):

acceptance_test.go:1345: Diff:
        --- bundle/resources/catalogs/rename_all_out_of_band/output.txt
        +++ /tmp/TestAcceptbundleresourcescatalogsrename_all_out_of_bandDMS=2998422903/002/output.txt
        @@ -51,56 +51,35 @@
             }
           },
           "resources.schemas.schema1": {
        -    "id": "test_catalog_renamed_[UNIQUE_NAME].myschema2",
             "depends_on": [
               {
                 "node": "resources.catalogs.catalog1",
                 "label": "${resources.catalogs.catalog1.name}"
               }
             ],
        -    "action": "update_id",
        -    "state_only": true,
        +    "action": "create",
             "new_state": {
               "value": {
                 "catalog_name": "test_catalog_renamed_[UNIQUE_NAME]",
                 "name": "myschema2"
               }
             },
        -    "remote_state": {
        -      "catalog_name": "test_catalog_renamed_[UNIQUE_NAME]",
        -      "catalog_type": "MANAGED_CATALOG",
        -      "created_at": [UNIX_TIME_MILLIS][0],
        -      "created_by": "[USERNAME]",
        -      "full_name": "test_catalog_renamed_[UNIQUE_NAME].myschema2",
        -      "name": "myschema2",
        -      "owner": "[USERNAME]",
        -      "schema_id": "[SCHEMA_ID]"
        -    },
             "changes": {
               "catalog_name": {
        -        "action": "skip",
        -        "reason": "remote_already_set",
        +        "action": "recreate",
        +        "reason": "id_field",
                 "old": "test_catalog_[UNIQUE_NAME]",
        -        "new": "test_catalog_renamed_[UNIQUE_NAME]",
        -        "remote": "test_catalog_renamed_[UNIQUE_NAME]"
        +        "new": "test_catalog_renamed_[UNIQUE_NAME]"
               },
               "name": {
        -        "action": "skip",
        -        "reason": "remote_already_set",
        +        "action": "recreate",
        +        "reason": "id_field",
                 "old": "myschema",
        -        "new": "myschema2",
        -        "remote": "myschema2"
        -      },
        -      "schema_id": {
        -        "action": "skip",
        -        "reason": "internal_id",
        -        "old": "[SCHEMA_ID]",
        -        "remote": "[SCHEMA_ID]"
        +        "new": "myschema2"
               }
             }
           },
           "resources.volumes.volume1": {
        -    "id": "test_catalog_renamed_[UNIQUE_NAME].myschema2.myvolume2",
             "depends_on": [
               {
                 "node": "resources.catalogs.catalog1",
        @@ -111,8 +68,7 @@
                 "label": "${resources.schemas.schema1.name}"
               }
             ],
        -    "action": "update_id",
        -    "state_only": true,
        +    "action": "create",
             "new_state": {
               "value": {
                 "catalog_name": "test_catalog_renamed_[UNIQUE_NAME]",
        @@ -121,44 +77,24 @@
                 "volume_type": "MANAGED"
               }
             },
        -    "remote_state": {
        -      "catalog_name": "test_catalog_renamed_[UNIQUE_NAME]",
        -      "created_at": [UNIX_TIME_MILLIS][1],
        -      "created_by": "[USERNAME]",
        -      "full_name": "test_catalog_renamed_[UNIQUE_NAME].myschema2.myvolume2",
        -      "name": "myvolume2",
        -      "owner": "[USERNAME]",
        -      "schema_name": "myschema2",
        -      "volume_id": "[VOLUME_ID]",
        -      "volume_type": "MANAGED"
        -    },
             "changes": {
               "catalog_name": {
        -        "action": "skip",
        -        "reason": "remote_already_set",
        +        "action": "recreate",
        +        "reason": "id_field",
                 "old": "test_catalog_[UNIQUE_NAME]",
        -        "new": "test_catalog_renamed_[UNIQUE_NAME]",
        -        "remote": "test_catalog_renamed_[UNIQUE_NAME]"
        +        "new": "test_catalog_renamed_[UNIQUE_NAME]"
               },
               "name": {
        -        "action": "skip",
        -        "reason": "remote_already_set",
        +        "action": "update_id",
        +        "reason": "id_changes",
                 "old": "myvolume",
        -        "new": "myvolume2",
        -        "remote": "myvolume2"
        +        "new": "myvolume2"
               },
               "schema_name": {
        -        "action": "skip",
        -        "reason": "remote_already_set",
        +        "action": "recreate",
        +        "reason": "id_field",
                 "old": "myschema",
        -        "new": "myschema2",
        -        "remote": "myschema2"
        -      },
        -      "volume_id": {
        -        "action": "skip",
        -        "reason": "internal_id",
        -        "old": "[VOLUME_ID]",
        -        "remote": "[VOLUME_ID]"
        +        "new": "myschema2"
               }
             }
           }
        @@ -174,9 +101,9 @@
         API error_code: CATALOG_ALREADY_EXISTS
         API message: Catalog 'test_catalog_renamed_[UNIQUE_NAME]' already exists
         
        -Error: cannot update_id resources.schemas.schema1: dependency failed: resources.catalogs.catalog1
        +Error: cannot create resources.schemas.schema1: dependency failed: resources.catalogs.catalog1
         
        -Error: cannot update_id resources.volumes.volume1: dependency failed: resources.catalogs.catalog1
        +Error: cannot create resources.volumes.volume1: dependency failed: resources.catalogs.catalog1
         
         Files: 3 uploaded, 0 deleted
         
        
    acceptance_test.go:1123: 
        LOG.deploy_requests: {
        LOG.deploy_requests:   "method": "POST",
        LOG.deploy_requests:   "path": "/api/2.1/unity-catalog/catalogs",
        LOG.deploy_requests:   "body": {
        LOG.deploy_requests:     "name": "test_catalog_wgs7zzs2lzg33e2y3ykdpi6opy"
        LOG.deploy_requests:   }
        LOG.deploy_requests: }
        LOG.deploy_requests: {
        LOG.deploy_requests:   "method": "POST",
        LOG.deploy_requests:   "path": "/api/2.1/unity-catalog/schemas",
        LOG.deploy_requests:   "body": {
        LOG.deploy_requests:     "catalog_name": "test_catalog_wgs7zzs2lzg33e2y3ykdpi6opy",
        LOG.deploy_requests:     "name": "myschema"
        LOG.deploy_requests:   }
        LOG.deploy_requests: }
        LOG.deploy_requests: {
        LOG.deploy_requests:   "method": "POST",
        LOG.deploy_requests:   "path": "/api/2.1/unity-catalog/volumes",
        LOG.deploy_requests:   "body": {
        LOG.deploy_requests:     "catalog_name": "test_catalog_wgs7zzs2lzg33e2y3ykdpi6opy",
        LOG.deploy_requests:     "name": "myvolume",
        LOG.deploy_requests:     "schema_name": "myschema",
        LOG.deploy_requests:     "volume_type": "MANAGED"
        LOG.deploy_requests:   }
        LOG.deploy_requests: }
    acceptance_test.go:1123: 
        LOG.destroy_requests: {
        LOG.destroy_requests:   "method": "POST",
        LOG.destroy_requests:   "path": "/api/2.1/unity-catalog/catalogs",
        LOG.destroy_requests:   "body": {
        LOG.destroy_requests:     "name": "test_catalog_renamed_wgs7zzs2lzg33e2y3ykdpi6opy"
        LOG.destroy_requests:   }
        LOG.destroy_requests: }
        LOG.destroy_requests: {
        LOG.destroy_requests:   "method": "DELETE",
        LOG.destroy_requests:   "path": "/api/2.1/unity-catalog/catalogs/test_catalog_renamed_wgs7zzs2lzg33e2y3ykdpi6opy",
        LOG.destroy_requests:   "q": {
        LOG.destroy_requests:     "force": "true"
        LOG.destroy_requests:   }
        LOG.destroy_requests: }
    acceptance_test.go:1123: 
        LOG.rename_requests: {
        LOG.rename_requests:   "method": "PATCH",
        LOG.rename_requests:   "path": "/api/2.1/unity-catalog/volumes/test_catalog_wgs7zzs2lzg33e2y3ykdpi6opy.myschema.myvolume",
        LOG.rename_requests:   "body": {
        LOG.rename_requests:     "new_name": "myvolume2"
        LOG.rename_requests:   }
        LOG.rename_requests: }
        LOG.rename_requests: {
        LOG.rename_requests:   "method": "PATCH",
        LOG.rename_requests:   "path": "/api/2.1/unity-catalog/schemas/test_catalog_wgs7zzs2lzg33e2y3ykdpi6opy.myschema",
        LOG.rename_requests:   "body": {
        LOG.rename_requests:     "new_name": "myschema2"
        LOG.rename_requests:   }
        LOG.rename_requests: }
... (7 more lines truncated, raise DATABRICKS_CLI_TEST_MAX_LOG to see more)

latest (v1.25.0):

acceptance_test.go:1345: Diff:
        --- bundle/resources/catalogs/rename_all_out_of_band/output.txt
        +++ /tmp/TestAcceptbundleresourcescatalogsrename_all_out_of_bandDMS=881263001/002/output.txt
        @@ -51,56 +51,35 @@
             }
           },
           "resources.schemas.schema1": {
        -    "id": "test_catalog_renamed_[UNIQUE_NAME].myschema2",
             "depends_on": [
               {
                 "node": "resources.catalogs.catalog1",
                 "label": "${resources.catalogs.catalog1.name}"
               }
             ],
        -    "action": "update_id",
        -    "state_only": true,
        +    "action": "create",
             "new_state": {
               "value": {
                 "catalog_name": "test_catalog_renamed_[UNIQUE_NAME]",
                 "name": "myschema2"
               }
             },
        -    "remote_state": {
        -      "catalog_name": "test_catalog_renamed_[UNIQUE_NAME]",
        -      "catalog_type": "MANAGED_CATALOG",
        -      "created_at": [UNIX_TIME_MILLIS][0],
        -      "created_by": "[USERNAME]",
        -      "full_name": "test_catalog_renamed_[UNIQUE_NAME].myschema2",
        -      "name": "myschema2",
        -      "owner": "[USERNAME]",
        -      "schema_id": "[SCHEMA_ID]"
        -    },
             "changes": {
               "catalog_name": {
        -        "action": "skip",
        -        "reason": "remote_already_set",
        +        "action": "recreate",
        +        "reason": "id_field",
                 "old": "test_catalog_[UNIQUE_NAME]",
        -        "new": "test_catalog_renamed_[UNIQUE_NAME]",
        -        "remote": "test_catalog_renamed_[UNIQUE_NAME]"
        +        "new": "test_catalog_renamed_[UNIQUE_NAME]"
               },
               "name": {
        -        "action": "skip",
        -        "reason": "remote_already_set",
        +        "action": "recreate",
        +        "reason": "id_field",
                 "old": "myschema",
        -        "new": "myschema2",
        -        "remote": "myschema2"
        -      },
        -      "schema_id": {
        -        "action": "skip",
        -        "reason": "internal_id",
        -        "old": "[SCHEMA_ID]",
        -        "remote": "[SCHEMA_ID]"
        +        "new": "myschema2"
               }
             }
           },
           "resources.volumes.volume1": {
        -    "id": "test_catalog_renamed_[UNIQUE_NAME].myschema2.myvolume2",
             "depends_on": [
               {
                 "node": "resources.catalogs.catalog1",
        @@ -111,8 +68,7 @@
                 "label": "${resources.schemas.schema1.name}"
               }
             ],
        -    "action": "update_id",
        -    "state_only": true,
        +    "action": "create",
             "new_state": {
               "value": {
                 "catalog_name": "test_catalog_renamed_[UNIQUE_NAME]",
        @@ -121,44 +77,24 @@
                 "volume_type": "MANAGED"
               }
             },
        -    "remote_state": {
        -      "catalog_name": "test_catalog_renamed_[UNIQUE_NAME]",
        -      "created_at": [UNIX_TIME_MILLIS][1],
        -      "created_by": "[USERNAME]",
        -      "full_name": "test_catalog_renamed_[UNIQUE_NAME].myschema2.myvolume2",
        -      "name": "myvolume2",
        -      "owner": "[USERNAME]",
        -      "schema_name": "myschema2",
        -      "volume_id": "[VOLUME_ID]",
        -      "volume_type": "MANAGED"
        -    },
             "changes": {
               "catalog_name": {
        -        "action": "skip",
        -        "reason": "remote_already_set",
        +        "action": "recreate",
        +        "reason": "id_field",
                 "old": "test_catalog_[UNIQUE_NAME]",
        -        "new": "test_catalog_renamed_[UNIQUE_NAME]",
        -        "remote": "test_catalog_renamed_[UNIQUE_NAME]"
        +        "new": "test_catalog_renamed_[UNIQUE_NAME]"
               },
               "name": {
        -        "action": "skip",
        -        "reason": "remote_already_set",
        +        "action": "update_id",
        +        "reason": "id_changes",
                 "old": "myvolume",
        -        "new": "myvolume2",
        -        "remote": "myvolume2"
        +        "new": "myvolume2"
               },
               "schema_name": {
        -        "action": "skip",
        -        "reason": "remote_already_set",
        +        "action": "recreate",
        +        "reason": "id_field",
                 "old": "myschema",
        -        "new": "myschema2",
        -        "remote": "myschema2"
        -      },
        -      "volume_id": {
        -        "action": "skip",
        -        "reason": "internal_id",
        -        "old": "[VOLUME_ID]",
        -        "remote": "[VOLUME_ID]"
        +        "new": "myschema2"
               }
             }
           }
        @@ -174,9 +101,9 @@
         API error_code: CATALOG_ALREADY_EXISTS
         API message: Catalog 'test_catalog_renamed_[UNIQUE_NAME]' already exists
         
        -Error: cannot update_id resources.schemas.schema1: dependency failed: resources.catalogs.catalog1
        +Error: cannot create resources.schemas.schema1: dependency failed: resources.catalogs.catalog1
         
        -Error: cannot update_id resources.volumes.volume1: dependency failed: resources.catalogs.catalog1
        +Error: cannot create resources.volumes.volume1: dependency failed: resources.catalogs.catalog1
         
         Files: 3 uploaded, 0 deleted
         
        
    acceptance_test.go:1123: 
        LOG.deploy_requests: {
        LOG.deploy_requests:   "method": "POST",
        LOG.deploy_requests:   "path": "/api/2.1/unity-catalog/catalogs",
        LOG.deploy_requests:   "body": {
        LOG.deploy_requests:     "name": "test_catalog_d56kmzpacbavhaaaynv6tjpebq"
        LOG.deploy_requests:   }
        LOG.deploy_requests: }
        LOG.deploy_requests: {
        LOG.deploy_requests:   "method": "POST",
        LOG.deploy_requests:   "path": "/api/2.1/unity-catalog/schemas",
        LOG.deploy_requests:   "body": {
        LOG.deploy_requests:     "catalog_name": "test_catalog_d56kmzpacbavhaaaynv6tjpebq",
        LOG.deploy_requests:     "name": "myschema"
        LOG.deploy_requests:   }
        LOG.deploy_requests: }
        LOG.deploy_requests: {
        LOG.deploy_requests:   "method": "POST",
        LOG.deploy_requests:   "path": "/api/2.1/unity-catalog/volumes",
        LOG.deploy_requests:   "body": {
        LOG.deploy_requests:     "catalog_name": "test_catalog_d56kmzpacbavhaaaynv6tjpebq",
        LOG.deploy_requests:     "name": "myvolume",
        LOG.deploy_requests:     "schema_name": "myschema",
        LOG.deploy_requests:     "volume_type": "MANAGED"
        LOG.deploy_requests:   }
        LOG.deploy_requests: }
    acceptance_test.go:1123: 
        LOG.destroy_requests: {
        LOG.destroy_requests:   "method": "POST",
        LOG.destroy_requests:   "path": "/api/2.1/unity-catalog/catalogs",
        LOG.destroy_requests:   "body": {
        LOG.destroy_requests:     "name": "test_catalog_renamed_d56kmzpacbavhaaaynv6tjpebq"
        LOG.destroy_requests:   }
        LOG.destroy_requests: }
        LOG.destroy_requests: {
        LOG.destroy_requests:   "method": "DELETE",
        LOG.destroy_requests:   "path": "/api/2.1/unity-catalog/catalogs/test_catalog_renamed_d56kmzpacbavhaaaynv6tjpebq",
        LOG.destroy_requests:   "q": {
        LOG.destroy_requests:     "force": "true"
        LOG.destroy_requests:   }
        LOG.destroy_requests: }
    acceptance_test.go:1123: 
        LOG.rename_requests: {
        LOG.rename_requests:   "method": "PATCH",
        LOG.rename_requests:   "path": "/api/2.1/unity-catalog/volumes/test_catalog_d56kmzpacbavhaaaynv6tjpebq.myschema.myvolume",
        LOG.rename_requests:   "body": {
        LOG.rename_requests:     "new_name": "myvolume2"
        LOG.rename_requests:   }
        LOG.rename_requests: }
        LOG.rename_requests: {
        LOG.rename_requests:   "method": "PATCH",
        LOG.rename_requests:   "path": "/api/2.1/unity-catalog/schemas/test_catalog_d56kmzpacbavhaaaynv6tjpebq.myschema",
        LOG.rename_requests:   "body": {
        LOG.rename_requests:     "new_name": "myschema2"
        LOG.rename_requests:   }
        LOG.rename_requests: }
... (7 more lines truncated, raise DATABRICKS_CLI_TEST_MAX_LOG to see more)

29 more failure details omitted, see the full report in the run.

@denik
denik force-pushed the denik/schemas-remove branch from c643054 to 3aabe1b Compare November 4, 2026 13:15
@denik
denik changed the base branch from main to denik/grants-rekey November 4, 2026 13:16
@denik
denik added this pull request to stack #7346 November 4, 2026 13:16
@eng-dev-ecosystem-bot

eng-dev-ecosystem-bot commented Nov 4, 2026 •

Copy link
Copy Markdown
Collaborator

✅ Integration test report

Commit: 37e8eb3

Run: 42694169134

Env ✅​pass 🙈​skip Time
✅​ aws linux-2core-8gb 343 31 7:54
✅​ aws-windows-latest-4core-16gb 345 29 9:05
✅​ azure linux-2core-8gb 342 31 7:25
✅​ azure-windows-latest-4core-16gb 344 29 9:58
✅​ gcp linux-2core-8gb 343 31 8:49
✅​ gcp-windows-latest-4core-16gb 345 29 10:36
Top 4 slowest tests (at least 2 minutes):
duration env testname
3:07 gcp-windows-latest-4core-16gb TestAccept
3:04 azure-windows-latest-4core-16gb TestAccept
3:03 aws-windows-latest-4core-16gb TestAccept
2:20 gcp-windows-latest-4core-16gb TestAccept/bundle/resources/schemas/rename_then_change/DMS=true

@denik
denik force-pushed the denik/schemas-remove branch 4 times, most recently from 5f6e047 to 0d42d75 Compare November 4, 2026 15:00
Base automatically changed from denik/grants-rekey to main November 4, 2026 15:33
@denik
denik force-pushed the denik/schemas-remove branch 2 times, most recently from 3678e96 to 891fceb Compare November 4, 2026 16:43
@denik
denik removed this pull request from stack #7346 November 4, 2026 16:44
@denik
denik changed the base branch from main to denik/permissions-rekey November 4, 2026 16:45
@denik
denik added this pull request to stack #7362 November 4, 2026 16:45
@denik
denik force-pushed the denik/schemas-remove branch from 891fceb to fe7fb69 Compare November 4, 2026 16:50
@denik
denik marked this pull request as ready for review November 5, 2026 12:59
@denik
denik requested review from a team as code owners November 5, 2026 12:59
@denik
denik requested a review from shreyas-goenka November 5, 2026 12:59
@denik
denik force-pushed the denik/schemas-remove branch from a4a9475 to 6845544 Compare November 5, 2026 13:09
Base automatically changed from denik/permissions-rekey to main November 5, 2026 13:57
@denik
denik force-pushed the denik/schemas-remove branch from 4f7fd4e to 27ceb82 Compare November 5, 2026 13:57
@denik denik changed the title Rename schemas in place in the direct engine Support schema rename and improve catalog rename Nov 5, 2026
Comment thread bundle/direct/dresources/schema.go Outdated
return fullName, nil, nil
}

response, err := r.client.Schemas.Update(ctx, makeUpdateSchema(fullName, newName, config))

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.

IIRC including other fields during a rename caused issues.

Also; what happens if we rename to something that UC considers equivalent?

E.g. case change (via EqualFold)?

denik and others added 26 commits November 9, 2026 16:11
schema-rename now renames in place, so it no longer covers the schema recreate.

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

UC moves schemas and volumes with their renamed catalog or schema, so the
re-key needs no update. Read the child instead to record its full name as UC
spells it.

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

Co-authored-by: Isaac <no-reply@databricks.com>
Azure and GCP return their own volume storage_location and predictive
optimization metastore, and UC may touch a schema's updated_at after create.

Co-authored-by: Isaac <no-reply@databricks.com>
Co-authored-by: Isaac <no-reply@databricks.com>
Like the other DoUpdateWithID implementations, take the new ID from config, so a
child moved by its parent's rename needs no request at all.

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

A deploy can stop after renaming a schema but before re-keying its volume.
The next plan then saw no rename in progress, read the volume at its old path,
got 404, and planned a create, which fails on UC with RESOURCE_ALREADY_EXISTS.

An update_id now records the old values of the fields it changes (renamed_from)
in the same state write as the new ID. A child whose parent is not being renamed
in the plan follows that recorded rename instead, and is not planned as a create
just because its read at the old ID found nothing.

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

When the read at the recorded ID finds nothing, the plan reads at the ID the
config gives the resource and takes what it finds only if its stable ID
(schema_id, volume_id, now saved in the state entry and the DMS envelope)
matches. This covers a deploy that stopped after renaming the parent and a
rename done out of band, and never adopts a different object of the same name.
It replaces renamed_from, which missed repeated renames and could not tell a
rename from a recreate.

The test server now deletes children with a forced catalog/schema delete and
rejects a catalog create under a taken name, like UC. The migrate fixtures
dropped the out-of-band catalog create that the scripts already run.

Co-authored-by: Isaac <no-reply@databricks.com>
Co-authored-by: Isaac <no-reply@databricks.com>
Co-authored-by: Isaac <no-reply@databricks.com>
Co-authored-by: Isaac <no-reply@databricks.com>
…of stable_id

The internal ID now lives in the volume and schema state (VolumeState,
SchemaState), set from the API responses and copied by RemapState; the
framework reads it back through a new optional InternalID method. This
replaces the stable_id field on the state entry and in the DMS envelope.

A new drop_changes lifecycle rule leaves the always-different volume_id and
schema_id (config never sets them) out of the plan.

Co-authored-by: Isaac <no-reply@databricks.com>
With volume_id and schema_id in the state, the field-overlap match picks
VolumeInfo and SchemaInfo, as registered models already map to their Info
type; volume_id is marked output-only from the spec.

Co-authored-by: Isaac <no-reply@databricks.com>
Use ignore_local_changes (config never sets them) and ignore_remote_changes
(generated from the spec for volume_id, hand-written for schema_id, which the
spec does not mark output-only) instead of a new drop_changes rule. The skipped
change keeps the recorded and remote IDs visible in the plan.

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

The captured requests already create the destination catalog out of band, so
the scripts no longer create it again. This restores terraform-requests.json
as captured instead of editing it.

Co-authored-by: Isaac <no-reply@databricks.com>
The parent-rename rule now runs where provided ID fields are classified, so
the change is planned as update_id the first time instead of being planned as a
recreate and rewritten by a separate pass. The plan output is unchanged.

Co-authored-by: Isaac <no-reply@databricks.com>
Co-authored-by: Isaac <no-reply@databricks.com>
…nal IDs there

An update_id whose changes only follow a parent's rename (or a move the plan
found) is marked state_only. For a resource with IDFromState, apply records
it under the new ID without calling DoUpdateWithID; it is left out of the
textual plan and the applied lines, and counted as unchanged.

The internal ID is declared in config as internal_id_field. The framework
records it from the remote state on every save, skips its changes in the plan
and reads it in findMoved, replacing the InternalID method, the YAML ignore
rules and the VolumeId/SchemaId assignments in the adapters.

Co-authored-by: Isaac <no-reply@databricks.com>
A schema or catalog renamed with its comment changed sends both in one PATCH
and both land. A case-only rename of a schema or volume is accepted by UC,
which keeps the lowercase name, so the deploy succeeds and the next plan is a
no-op. The test server now lowercases a renamed volume, like UC.

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

Co-authored-by: Isaac <no-reply@databricks.com>
Co-authored-by: Isaac <no-reply@databricks.com>
@denik
denik force-pushed the denik/schemas-remove branch from fc6bb67 to c23c64f Compare November 9, 2026 15:11
denik and others added 2 commits November 9, 2026 16:42
…leReason

Co-authored-by: Isaac <no-reply@databricks.com>
…ting on main)

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

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

DABs DABs related issues

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants