Skip to content

Add rename_column support to UpdateSchemaAction #2562

@nazq

Description

@nazq

Add rename_column support to UpdateSchemaAction

Label: enhancement

Is your feature request related to a problem or challenge?

UpdateSchemaAction currently supports add_column and delete_column (PR #2120), but not rename_column. Schema evolution APIs in sibling implementations (PyIceberg, Java) all expose rename as a first-class operation, and downstream Rust users who need parity with those implementations have to fall back to:

The add_column / delete_column infrastructure already does almost everything rename needs (the rebuild-the-schema-tree pattern, the AddSchema + SetCurrentSchema emission, the CurrentSchemaIdMatch requirement). The gap is just the builder method, the validation, and threading the renames through the rebuild step.

Describe the solution you'd like

A new builder method on UpdateSchemaAction matching the existing add/delete shape:

let tx = Transaction::new(&table);
let action = tx.update_schema()
    .rename_column("old_name", "new_name")
    .rename_column("person.name", "fullname");  // nested supported
let tx = action.apply(tx).unwrap();
let table = tx.commit(&catalog).await.unwrap();

Semantics modeled on pyiceberg.table.update.schema.UpdateSchema.rename_column:

  • Field ID is preserved. This is Iceberg's invariant — rename is a metadata-only operation on the name; the column ID stays stable so existing data files and snapshots remain valid.
  • path_from uses SCHEMA_NAME_DELIMITER (.) for nested fields. new_name is the unqualified leaf name; rename does not move a field between parent structs.
  • Identifier fields handled transparently. Iceberg keys identifier_field_ids by ID, not name, so the existing with_identifier_field_ids(base_schema.identifier_field_ids()) step in commit() already propagates them correctly across renames.
  • Composes with add/delete in the same action. A rename frees the old name for re-use by an addition; the renamed field can take a name previously held by a sibling being deleted.

Validation rules (all PreconditionFailed):

  • path_from must exist in the current schema.
  • A field cannot be both renamed and deleted in the same action — intent is ambiguous.
  • new_name cannot contain SCHEMA_NAME_DELIMITER — would otherwise silently look like a move-across-structs.
  • new_name cannot collide with a sibling that is not itself being deleted or renamed away.
  • If the same field is renamed multiple times, the last rename wins (matches PyIceberg).

Scope

This issue covers only rename_column. PyIceberg's UpdateSchema exposes other operations not covered here:

  • update_column (type promotion / nullability / doc edits)
  • make_column_optional / make_column_required
  • move_first / move_before / move_after
  • set_identifier_fields

Those are out of scope and would be follow-up issues if there's interest.

Willingness to contribute

I can contribute to this feature independently. I have a working branch with the implementation + 10 new unit tests (matching the style and depth of the existing test_*_add_column* / test_*_delete_column* tests in transaction::update_schema::tests), and a PR ready to open once this issue is filed for reference.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions