Skip to content

Support schema rename and improve catalog rename - #7343

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

denik wants to merge 54 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.

A resource recreated in the same deploy as its parent's rename is now deleted where the rename moved it. The parent's rename runs first and moves the resource, so the plan points the recreate's delete at the re-keyed ID (the entry's id) and orders it after the parent. The parent comes from the state's depends_on, because the config may now reference another one. Before, the delete went to the old path, got a 404, and the moved volume was left behind untracked.

The test server changes this relies on are in #7408 (merged). 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, as on main, marked Badness; Find a catalog renamed outside the bundle by its id #7418 fixes it).
  • New volumes/move_from_renamed_schema (Cloud = true) and volumes/recreate_in_renamed_schema (local only: an external volume needs an external location): a volume recreated while its schema is renamed, by moving it to another schema or changing its type. The old volume is deleted where the rename moved it.
  • 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 addParentMoves, 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: 8e778fadb | Workflow run

Regression test report

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

45 tests: regression=43 unreleased=0 coverage=2 failing=0
test branch main (37cd1d9) latest (v1.25.0)
TestAccept/bundle/resources/catalogs/rename/DMS=/READPLAN= ✅ ❌ ❌
TestAccept/bundle/resources/catalogs/rename/DMS=/READPLAN=1 ✅ ❌ ❌
TestAccept/bundle/resources/catalogs/rename/DMS=true/READPLAN= ✅ ❌ ❌
TestAccept/bundle/resources/catalogs/rename/DMS=true/READPLAN=1 ✅ ❌ ❌
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_out_of_band_old_state/DMS= ✅ ❌ ❌
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=/READPLAN= ✅ ❌ ❌
TestAccept/bundle/resources/schemas/rename_with_volume/DMS=/READPLAN=1 ✅ ❌ ❌
TestAccept/bundle/resources/schemas/rename_with_volume/DMS=true/READPLAN= ✅ ❌ ❌
TestAccept/bundle/resources/schemas/rename_with_volume/DMS=true/READPLAN=1 ✅ ❌ ❌
TestAccept/bundle/resources/schemas/rename_with_volume_ref/DMS= ✅ ❌ ❌
TestAccept/bundle/resources/schemas/rename_with_volume_ref/DMS=true ✅ ❌ ❌
TestAccept/bundle/resources/volumes/move_from_renamed_schema/DMS=/READPLAN= ✅ ❌ ❌
TestAccept/bundle/resources/volumes/move_from_renamed_schema/DMS=/READPLAN=1 ✅ ❌ ❌
TestAccept/bundle/resources/volumes/move_from_renamed_schema/DMS=true/READPLAN= ✅ ❌ ❌
TestAccept/bundle/resources/volumes/move_from_renamed_schema/DMS=true/READPLAN=1 ✅ ❌ ❌
TestAccept/bundle/resources/volumes/recreate_in_renamed_schema/DMS= ✅ ❌ ❌
TestAccept/bundle/resources/volumes/recreate_in_renamed_schema/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=/READPLAN= ✅ ❌ ❌
TestAccept/bundle/resources/volumes/rename_catalog_and_schema/DMS=/READPLAN=1 ✅ ❌ ❌
TestAccept/bundle/resources/volumes/rename_catalog_and_schema/DMS=true/READPLAN= ✅ ❌ ❌
TestAccept/bundle/resources/volumes/rename_catalog_and_schema/DMS=true/READPLAN=1 ✅ ❌ ❌
TestAccept/bundle/resources/catalogs/rename/DMS=/READPLAN=: branch ✅ | main (37cd1d9) ❌ | latest (v1.25.0) ❌

main (37cd1d9):

acceptance_test.go:1345: Diff:
        --- bundle/resources/catalogs/rename/output.txt
        +++ /tmp/TestAcceptbundleresourcescatalogsrenameDMS=READPLAN=57954909/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_732r5u2rh5cwjbu2tyosz4t3ei.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_732r5u2rh5cwjbu2tyosz4t3ei.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_732r5u2rh5cwjbu2tyosz4t3ei",
        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=READPLAN=1512894849/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_ma43atihmrei3btt3cltr5jo5q.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_ma43atihmrei3btt3cltr5jo5q.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_ma43atihmrei3btt3cltr5jo5q",
        LOG.destroy_requests:   "q": {
        LOG.destroy_requests:     "force": "true"
        LOG.destroy_requests:   }
        LOG.destroy_requests: }
TestAccept/bundle/resources/catalogs/rename/DMS=/READPLAN=1: branch ✅ | main (37cd1d9) ❌ | latest (v1.25.0) ❌

main (37cd1d9):

acceptance_test.go:1345: Diff:
        --- bundle/resources/catalogs/rename/output.txt
        +++ /tmp/TestAcceptbundleresourcescatalogsrenameDMS=READPLAN=11128208278/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_p6cfvzftpffmtgi4qgqstkyq4q.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_p6cfvzftpffmtgi4qgqstkyq4q.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_p6cfvzftpffmtgi4qgqstkyq4q",
        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=READPLAN=13230536581/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_6264y2dtindqxjysacrqktrswi.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_6264y2dtindqxjysacrqktrswi.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_6264y2dtindqxjysacrqktrswi",
        LOG.destroy_requests:   "q": {
        LOG.destroy_requests:     "force": "true"
        LOG.destroy_requests:   }
        LOG.destroy_requests: }
TestAccept/bundle/resources/catalogs/rename/DMS=true/READPLAN=: branch ✅ | main (37cd1d9) ❌ | latest (v1.25.0) ❌

main (37cd1d9):

acceptance_test.go:1345: Diff:
        --- bundle/resources/catalogs/rename/output.txt
        +++ /tmp/TestAcceptbundleresourcescatalogsrenameDMS=trueREADPLAN=2611766461/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_uo5wxrnxpfbmjggxdx5ftesgs4.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_uo5wxrnxpfbmjggxdx5ftesgs4.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_uo5wxrnxpfbmjggxdx5ftesgs4",
        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=trueREADPLAN=1109051531/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_gkufzek4nvh67caxztgxzo7eoq.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_gkufzek4nvh67caxztgxzo7eoq.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_gkufzek4nvh67caxztgxzo7eoq",
        LOG.destroy_requests:   "q": {
        LOG.destroy_requests:     "force": "true"
        LOG.destroy_requests:   }
        LOG.destroy_requests: }

40 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: 8e778fa

Run: 43020529211

Env ✅​pass 🙈​skip Time
✅​ aws linux-2core-8gb 355 39 9:44
✅​ aws-windows-latest-4core-16gb 357 37 11:49
✅​ azure linux-2core-8gb 354 39 9:58
✅​ azure-windows-latest-4core-16gb 356 37 12:01
✅​ gcp linux-2core-8gb 355 39 10:19
✅​ gcp-windows-latest-4core-16gb 357 37 11:47
Top 6 slowest tests (at least 2 minutes):
duration env testname
3:56 gcp-windows-latest-4core-16gb TestAccept
3:56 azure-windows-latest-4core-16gb TestAccept
3:52 aws linux-2core-8gb TestAccept
3:50 azure linux-2core-8gb TestAccept
3:48 aws-windows-latest-4core-16gb TestAccept
3:42 gcp linux-2core-8gb TestAccept

@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)?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

schemas/rename_with_comment covers rename + update and schemas/rename_case_only covers case change. Both work on cloud. In case of case_only change there is one avoidable PATCH but it's not harmful (and makes DABs more independent of backend folding rules).

denik and others added 13 commits November 10, 2026 17:09
…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>
…leReason

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

Co-authored-by: Isaac <no-reply@databricks.com>
Co-authored-by: Isaac <no-reply@databricks.com>
Co-authored-by: Isaac <no-reply@databricks.com>
…; record volume_id in empty-resource-id

The volume's created_at/updated_at made rename_interrupted flaky ([UNIX_TIME_MILLIS]
vs [UNIX_TIME_MILLIS][0] depending on timing).

Co-authored-by: Isaac <no-reply@databricks.com>
Co-authored-by: Jan N Rose <janniklas.rose@gmail.com>
The recreate deletes the volume at its recorded path after the schema's rename
moved it, so the moved volume is left behind.

Co-authored-by: Isaac <no-reply@databricks.com>
A parent renamed in the same plan moves the resource before its recreate runs.
The recreate now deletes it at the ID the rename gives it, after the rename.
The parent comes from the state's depends_on, since the config may no longer
reference it.

Co-authored-by: Isaac <no-reply@databricks.com>
The plan's state_only re-keys, found IDs and added depends_on must survive
serialization.

Co-authored-by: Isaac <no-reply@databricks.com>
@denik
denik force-pushed the denik/schemas-remove branch from 947cc9d to da3786a Compare November 10, 2026 16:20
denik and others added 14 commits November 10, 2026 17:27
Numbered UUIDs from main (#7021); restores the volume_id skip in change-name and
the recorded schema_id in user_agent/simple, which the rebase dropped.

Co-authored-by: Isaac <no-reply@databricks.com>
… case-insensitive volume lookups

On AWS the re-keyed ID keeps the config's casing (main.s.MyVolume) and UC still
reads the volume at it, so the next plan is a no-op. The test server now looks a
volume's full name up case-insensitively too, instead of planning a create.

Co-authored-by: Isaac <no-reply@databricks.com>
Without IDFromState the update_id would reach DoUpdateWithID with the stale ID.

Co-authored-by: Isaac <no-reply@databricks.com>
…ew B5)

Co-authored-by: Isaac <no-reply@databricks.com>
…ad (review B6)

Co-authored-by: Isaac <no-reply@databricks.com>
…view B7)

Co-authored-by: Isaac <no-reply@databricks.com>
…w B8)

Co-authored-by: Isaac <no-reply@databricks.com>
…om four goldens

Co-authored-by: Isaac <no-reply@databricks.com>
… rename (review A3, Badness); testserver: reject a taken schema name

Recorded on AWS: the schema's create fails with SCHEMA_ALREADY_EXISTS. The test
server now rejects it the same way instead of creating it again.

Co-authored-by: Isaac <no-reply@databricks.com>
The test server now rejects a taken schema name, as UC does.

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

A state recorded without schema_id/volume_id (by an older CLI, or by bind) never
got them, since a skip writes no state, so the plan could not follow an
out-of-band rename. An otherwise unchanged resource whose state lacks the ID is
now planned as a state-only update that records it from the remote state.

Co-authored-by: Isaac <no-reply@databricks.com>
…y (review A3)

The terraform state has no volume_id, and the migrated state would otherwise get
the IDs from a state-only update in the next plan. The migration's plan check
already read every resource, so record them from there.

Co-authored-by: Isaac <no-reply@databricks.com>
The provider records UC's schema_id on databricks_schema. databricks_volume has
no volume_id, so a volume migrated this way has none.

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

The fixture was captured with the init script, so replaying it after the init
created the source schema twice, which the test server now rejects as UC does.

Co-authored-by: Isaac <no-reply@databricks.com>
idelafuente-oc pushed a commit to idelafuente-oc/cli that referenced this pull request Nov 11, 2026
## Changes
Grants are keyed by their parent's full name (`volume/main.s.vol`). When
the parent got a new ID, the grants were applied under the new name, but
their state kept the old ID. This happens on a rename (catalogs,
volumes) or a recreate under a new name (schemas). The next `bundle
plan` then proposed the grants again. On UC the old name 404s, so the
plan shows `create ...grants` once; on the test server the plan shows
`update ...grants` forever.

`full_name` is now an `updatable_id_fields` entry for every grants type,
and `DoUpdateWithID` records the new ID. This follows
`secret_scopes.permissions.yml`, which solves the same problem for
secret scope ACLs. The rule lives in a single `configs/grants.yml`: a
config file named after a sub-resource now applies to that sub-resource
of every parent (`catalogs.grants`, `schemas.grants`, ...).

Needed before databricks#7343 (schema
rename), so that renamed schemas keep their grants in sync.

## Tests
New acceptance tests, `Cloud = true`, passing locally and on AWS:
- `grants/volume_change_name`: volume rename (`update_id`).
- `grants/schemas/change_name`: schema name change (a recreate today).

The first commit adds them with the pre-fix goldens; the second commit
shows the fix flipping them to a no-op plan.

This pull request and its description were written by Isaac.

---------

Co-authored-by: Isaac <no-reply@databricks.com>
idelafuente-oc pushed a commit to idelafuente-oc/cli that referenced this pull request Nov 11, 2026
…names (databricks#7408)

## Changes

Make the test server behave like Unity Catalog where the UC rename PRs
depend on it:

- A renamed catalog moves its schemas, volumes, registered models and
secrets. A renamed schema moves its volumes, registered models and
secrets.
- A forced catalog or schema delete also deletes what is in it.
- Creating a catalog under a taken name fails with
`CATALOG_ALREADY_EXISTS`.
- A renamed schema or volume gets a lowercased name. A renamed
registered model updates its `full_name` and keeps its versions, and
setting `name` and `new_name` in one update is rejected.

The `schema-catalog-change` and `registered-model-catalog-change`
migrate scripts created a catalog that their captured replay creates
again; the fake now rejects that, so the scripts no longer create it.

## Tests

New `acceptance/cmd/workspace/uc-renames` (Cloud = true) checks each
behavior with plain CLI calls. It passes locally and on AWS, GCP and
Azure.

Next: databricks#7343 (schema rename) stacks
on this PR, followed by databricks#7379 and
databricks#7381.

This pull request and its description were written by Isaac.

---------

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.

5 participants