This is an automated email from the ASF dual-hosted git repository.

jshao pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/gravitino.git


The following commit(s) were added to refs/heads/main by this push:
     new 89e7997436 [#8632] feature(alterTable): add core workflow for 
renameTable with newSchema (#8635)
89e7997436 is described below

commit 89e799743688f8313103e5acc3560c23999e2d19
Author: mchades <[email protected]>
AuthorDate: Tue Sep 23 15:13:52 2025 +0800

    [#8632] feature(alterTable): add core workflow for renameTable with 
newSchema (#8635)
    
    ### What changes were proposed in this pull request?
    
    dd core workflow for renameTable with newSchema
    
    ### Why are the changes needed?
    
    Fix: #8632
    
    ### Does this PR introduce _any_ user-facing change?
    
    no, it is backward compatibility
    
    ### How was this patch tested?
    
    tests added
---
 .../java/org/apache/gravitino/rel/TableChange.java |  33 ++++-
 .../java/org/apache/gravitino/TestTableChange.java |   6 +
 .../catalog/hive/HiveCatalogOperations.java        |   2 +
 .../catalog/jdbc/JdbcCatalogOperations.java        |   2 +
 .../org/apache/gravitino/client/DTOConverters.java |   3 +-
 .../gravitino/dto/requests/TableUpdateRequest.java |  21 ++-
 .../dto/requests/TestTableUpdatesRequest.java      |  22 ++-
 .../gravitino/catalog/CapabilityHelpers.java       |   7 +-
 .../catalog/TableOperationDispatcher.java          |  66 ++++++---
 .../apache/gravitino/hook/TableHookDispatcher.java |   1 +
 .../relational/mapper/TableColumnMapper.java       |   4 +
 .../mapper/TableColumnSQLProviderFactory.java      |   5 +
 .../storage/relational/mapper/TableMetaMapper.java |   4 +-
 .../mapper/TableMetaSQLProviderFactory.java        |   6 +-
 .../provider/base/TableColumnBaseSQLProvider.java  |   8 ++
 .../provider/base/TableMetaBaseSQLProvider.java    |   6 +-
 .../relational/service/TableColumnMetaService.java |   7 +
 .../relational/service/TableMetaService.java       |  14 +-
 .../storage/relational/utils/POConverters.java     |   7 +-
 .../relational/service/TestTableMetaService.java   | 152 +++++++++++++++++++++
 .../storage/relational/utils/TestPOConverters.java |   3 +-
 docs/manage-relational-metadata-using-gravitino.md |  28 ++--
 docs/open-api/tables.yaml                          |   7 +-
 23 files changed, 360 insertions(+), 54 deletions(-)

diff --git a/api/src/main/java/org/apache/gravitino/rel/TableChange.java 
b/api/src/main/java/org/apache/gravitino/rel/TableChange.java
index ea5849eb6e..03c05622b7 100644
--- a/api/src/main/java/org/apache/gravitino/rel/TableChange.java
+++ b/api/src/main/java/org/apache/gravitino/rel/TableChange.java
@@ -23,6 +23,7 @@ package org.apache.gravitino.rel;
 import com.google.common.base.Preconditions;
 import java.util.Arrays;
 import java.util.Objects;
+import java.util.Optional;
 import org.apache.gravitino.annotation.Evolving;
 import org.apache.gravitino.rel.expressions.Expression;
 import org.apache.gravitino.rel.indexes.Index.IndexType;
@@ -44,6 +45,17 @@ public interface TableChange {
     return new RenameTable(newName);
   }
 
+  /**
+   * Create a TableChange for renaming a table, possibly moving it to a new 
schema.
+   *
+   * @param newName the new table name
+   * @param newSchemaName the new schema name, or null to leave the schema 
unchanged
+   * @return A TableChange for the rename.
+   */
+  static TableChange rename(String newName, String newSchemaName) {
+    return new RenameTable(newName, Optional.ofNullable(newSchemaName));
+  }
+
   /**
    * Create a TableChange for updating the comment.
    *
@@ -467,9 +479,15 @@ public interface TableChange {
   /** A TableChange to rename a table. */
   final class RenameTable implements TableChange {
     private final String newName;
+    private final Optional<String> newSchemaName;
 
     private RenameTable(String newName) {
+      this(newName, Optional.empty());
+    }
+
+    private RenameTable(String newName, Optional<String> newSchemaName) {
       this.newName = newName;
+      this.newSchemaName = newSchemaName;
     }
 
     /**
@@ -481,6 +499,15 @@ public interface TableChange {
       return newName;
     }
 
+    /**
+     * Retrieves the new schema name for the table, if provided.
+     *
+     * @return An Optional containing the new schema of the table, or empty if 
not provided.
+     */
+    public Optional<String> getNewSchemaName() {
+      return newSchemaName;
+    }
+
     /**
      * Compares this RenameTable instance with another object for equality. 
The comparison is based
      * on the new name of the table.
@@ -493,7 +520,7 @@ public interface TableChange {
       if (this == o) return true;
       if (o == null || getClass() != o.getClass()) return false;
       RenameTable that = (RenameTable) o;
-      return newName.equals(that.newName);
+      return newName.equals(that.newName) && 
newSchemaName.equals(that.newSchemaName);
     }
 
     /**
@@ -504,7 +531,7 @@ public interface TableChange {
      */
     @Override
     public int hashCode() {
-      return newName.hashCode();
+      return Objects.hash(newName, newSchemaName);
     }
 
     /**
@@ -515,7 +542,7 @@ public interface TableChange {
      */
     @Override
     public String toString() {
-      return "RENAMETABLE " + newName;
+      return "RENAMETABLE " + newSchemaName.map(s -> s + "." + 
newName).orElse(newName);
     }
   }
 
diff --git a/api/src/test/java/org/apache/gravitino/TestTableChange.java 
b/api/src/test/java/org/apache/gravitino/TestTableChange.java
index 8f32c238f7..47a0e23c35 100644
--- a/api/src/test/java/org/apache/gravitino/TestTableChange.java
+++ b/api/src/test/java/org/apache/gravitino/TestTableChange.java
@@ -307,6 +307,12 @@ public class TestTableChange {
     assertFalse(change1.equals(change2));
     assertFalse(change2.equals(change1));
     assertNotEquals(change1.hashCode(), change2.hashCode());
+
+    String schemaNameA = "Schema A";
+    RenameTable change3 = (RenameTable) TableChange.rename(nameA, schemaNameA);
+    RenameTable change4 = (RenameTable) TableChange.rename(nameB, schemaNameA);
+
+    assertNotEquals(change3, change4);
   }
 
   @Test
diff --git 
a/catalogs/catalog-hive/src/main/java/org/apache/gravitino/catalog/hive/HiveCatalogOperations.java
 
b/catalogs/catalog-hive/src/main/java/org/apache/gravitino/catalog/hive/HiveCatalogOperations.java
index 482dbc67da..8334ff0dad 100644
--- 
a/catalogs/catalog-hive/src/main/java/org/apache/gravitino/catalog/hive/HiveCatalogOperations.java
+++ 
b/catalogs/catalog-hive/src/main/java/org/apache/gravitino/catalog/hive/HiveCatalogOperations.java
@@ -968,6 +968,8 @@ public class HiveCatalogOperations implements 
CatalogOperations, SupportsSchemas
 
   private void doRenameTable(
       org.apache.hadoop.hive.metastore.api.Table hiveTable, 
TableChange.RenameTable change) {
+    Preconditions.checkArgument(
+        !change.getNewSchemaName().isPresent(), "Does not support rename 
schema yet");
     hiveTable.setTableName(change.getNewName());
   }
 
diff --git 
a/catalogs/catalog-jdbc-common/src/main/java/org/apache/gravitino/catalog/jdbc/JdbcCatalogOperations.java
 
b/catalogs/catalog-jdbc-common/src/main/java/org/apache/gravitino/catalog/jdbc/JdbcCatalogOperations.java
index 3b318150c7..7c505b08f5 100644
--- 
a/catalogs/catalog-jdbc-common/src/main/java/org/apache/gravitino/catalog/jdbc/JdbcCatalogOperations.java
+++ 
b/catalogs/catalog-jdbc-common/src/main/java/org/apache/gravitino/catalog/jdbc/JdbcCatalogOperations.java
@@ -505,6 +505,8 @@ public class JdbcCatalogOperations implements 
CatalogOperations, SupportsSchemas
    */
   private Table renameTable(NameIdentifier tableIdent, TableChange.RenameTable 
renameTable)
       throws NoSuchTableException, IllegalArgumentException {
+    Preconditions.checkArgument(
+        !renameTable.getNewSchemaName().isPresent(), "Does not support rename 
schema yet");
     String databaseName = 
NameIdentifier.of(tableIdent.namespace().levels()).name();
     tableOperation.rename(databaseName, tableIdent.name(), 
renameTable.getNewName());
     return loadTable(NameIdentifier.of(tableIdent.namespace(), 
renameTable.getNewName()));
diff --git 
a/clients/client-java/src/main/java/org/apache/gravitino/client/DTOConverters.java
 
b/clients/client-java/src/main/java/org/apache/gravitino/client/DTOConverters.java
index 4657644e1f..2cf7acda4e 100644
--- 
a/clients/client-java/src/main/java/org/apache/gravitino/client/DTOConverters.java
+++ 
b/clients/client-java/src/main/java/org/apache/gravitino/client/DTOConverters.java
@@ -197,8 +197,9 @@ class DTOConverters {
 
   static TableUpdateRequest toTableUpdateRequest(TableChange change) {
     if (change instanceof TableChange.RenameTable) {
+      TableChange.RenameTable renameTable = (TableChange.RenameTable) change;
       return new TableUpdateRequest.RenameTableRequest(
-          ((TableChange.RenameTable) change).getNewName());
+          renameTable.getNewName(), 
renameTable.getNewSchemaName().orElse(null));
 
     } else if (change instanceof TableChange.UpdateComment) {
       return new TableUpdateRequest.UpdateTableCommentRequest(
diff --git 
a/common/src/main/java/org/apache/gravitino/dto/requests/TableUpdateRequest.java
 
b/common/src/main/java/org/apache/gravitino/dto/requests/TableUpdateRequest.java
index db1702ce6d..c1f7acd4a4 100644
--- 
a/common/src/main/java/org/apache/gravitino/dto/requests/TableUpdateRequest.java
+++ 
b/common/src/main/java/org/apache/gravitino/dto/requests/TableUpdateRequest.java
@@ -99,19 +99,23 @@ public interface TableUpdateRequest extends RESTRequest {
   /** Represents a request to rename a table. */
   @EqualsAndHashCode
   @ToString
+  @Getter
   class RenameTableRequest implements TableUpdateRequest {
 
-    @Getter
     @JsonProperty("newName")
     private final String newName;
 
+    @JsonProperty("newSchemaName")
+    @Nullable
+    private final String newSchemaName;
+
     /**
      * Constructor for RenameTableRequest.
      *
      * @param newName the new name of the table
      */
     public RenameTableRequest(String newName) {
-      this.newName = newName;
+      this(newName, null);
     }
 
     /** Default constructor for Jackson deserialization. */
@@ -119,6 +123,17 @@ public interface TableUpdateRequest extends RESTRequest {
       this(null);
     }
 
+    /**
+     * Constructor for RenameTableRequest.
+     *
+     * @param newName the new name of the table
+     * @param newSchemaName the new schema name of the table, null if not 
changing schema
+     */
+    public RenameTableRequest(String newName, @Nullable String newSchemaName) {
+      this.newName = newName;
+      this.newSchemaName = newSchemaName;
+    }
+
     /**
      * Validates the request.
      *
@@ -137,7 +152,7 @@ public interface TableUpdateRequest extends RESTRequest {
      */
     @Override
     public TableChange tableChange() {
-      return TableChange.rename(newName);
+      return TableChange.rename(newName, newSchemaName);
     }
   }
 
diff --git 
a/common/src/test/java/org/apache/gravitino/dto/requests/TestTableUpdatesRequest.java
 
b/common/src/test/java/org/apache/gravitino/dto/requests/TestTableUpdatesRequest.java
index 1395af798b..9276383066 100644
--- 
a/common/src/test/java/org/apache/gravitino/dto/requests/TestTableUpdatesRequest.java
+++ 
b/common/src/test/java/org/apache/gravitino/dto/requests/TestTableUpdatesRequest.java
@@ -66,7 +66,8 @@ public class TestTableUpdatesRequest {
             + "  \"updates\": [\n"
             + "    {\n"
             + "      \"@type\": \"rename\",\n"
-            + "      \"newName\": \"newTable\"\n"
+            + "      \"newName\": \"newTable\",\n"
+            + "      \"newSchemaName\": null\n"
             + "    },\n"
             + "    {\n"
             + "      \"@type\": \"updateComment\",\n"
@@ -139,6 +140,25 @@ public class TestTableUpdatesRequest {
     Assertions.assertEquals(
         JsonUtils.objectMapper().readTree(expected), 
JsonUtils.objectMapper().readTree(jsonString));
 
+    // validate backward compatibility for renameTable without newSchemaName
+    String renameTableJsonString =
+        "{\n"
+            + "  \"updates\": [\n"
+            + "    {\n"
+            + "      \"@type\": \"rename\",\n"
+            + "      \"newName\": \"newTable\"\n"
+            + "    }\n"
+            + "  ]\n"
+            + "}";
+    TableUpdatesRequest renameTableRequest =
+        JsonUtils.objectMapper().readValue(renameTableJsonString, 
TableUpdatesRequest.class);
+    Assertions.assertEquals(1, renameTableRequest.getUpdates().size());
+    TableUpdateRequest renameTable = renameTableRequest.getUpdates().get(0);
+    Assertions.assertInstanceOf(TableUpdateRequest.RenameTableRequest.class, 
renameTable);
+    Assertions.assertEquals(
+        "newTable", ((TableUpdateRequest.RenameTableRequest) 
renameTable).getNewName());
+    Assertions.assertNull(((TableUpdateRequest.RenameTableRequest) 
renameTable).getNewSchemaName());
+
     // test validate blank property value
     TableUpdateRequest.SetTablePropertyRequest setTablePropertyRequest =
         new TableUpdateRequest.SetTablePropertyRequest("key", " ");
diff --git 
a/core/src/main/java/org/apache/gravitino/catalog/CapabilityHelpers.java 
b/core/src/main/java/org/apache/gravitino/catalog/CapabilityHelpers.java
index 172d4b89d8..fe4659c28e 100644
--- a/core/src/main/java/org/apache/gravitino/catalog/CapabilityHelpers.java
+++ b/core/src/main/java/org/apache/gravitino/catalog/CapabilityHelpers.java
@@ -325,8 +325,13 @@ public class CapabilityHelpers {
       TableChange.RenameTable renameTable, Capability capabilities) {
     String newName =
         applyCaseSensitiveOnName(Capability.Scope.TABLE, 
renameTable.getNewName(), capabilities);
+    String newSchemaName =
+        renameTable
+            .getNewSchemaName()
+            .map(s -> applyCaseSensitiveOnName(Capability.Scope.SCHEMA, s, 
capabilities))
+            .orElse(null);
     applyNameSpecification(Capability.Scope.TABLE, newName, capabilities);
-    return TableChange.rename(newName);
+    return TableChange.rename(newName, newSchemaName);
   }
 
   private static TableChange applyCapabilities(
diff --git 
a/core/src/main/java/org/apache/gravitino/catalog/TableOperationDispatcher.java 
b/core/src/main/java/org/apache/gravitino/catalog/TableOperationDispatcher.java
index f110dc02bb..a777f2a511 100644
--- 
a/core/src/main/java/org/apache/gravitino/catalog/TableOperationDispatcher.java
+++ 
b/core/src/main/java/org/apache/gravitino/catalog/TableOperationDispatcher.java
@@ -23,6 +23,7 @@ import static 
org.apache.gravitino.catalog.CapabilityHelpers.applyCapabilities;
 import static 
org.apache.gravitino.catalog.PropertiesMetadataHelpers.validatePropertyForCreate;
 import static 
org.apache.gravitino.rel.expressions.transforms.Transforms.EMPTY_TRANSFORM;
 import static 
org.apache.gravitino.utils.NameIdentifierUtil.getCatalogIdentifier;
+import static 
org.apache.gravitino.utils.NameIdentifierUtil.getSchemaIdentifier;
 
 import com.google.common.base.Objects;
 import com.google.common.collect.Lists;
@@ -62,7 +63,7 @@ import 
org.apache.gravitino.rel.expressions.transforms.Transform;
 import org.apache.gravitino.rel.indexes.Index;
 import org.apache.gravitino.rel.indexes.Indexes;
 import org.apache.gravitino.storage.IdGenerator;
-import org.apache.gravitino.utils.NameIdentifierUtil;
+import org.apache.gravitino.utils.NamespaceUtil;
 import org.apache.gravitino.utils.PrincipalUtils;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -199,16 +200,31 @@ public class TableOperationDispatcher extends 
OperationDispatcher implements Tab
       throws NoSuchTableException, IllegalArgumentException {
     validateAlterProperties(ident, 
HasPropertyMetadata::tablePropertiesMetadata, changes);
 
-    // Check if there exist TableChange.RenameTable in the changes, if so, we 
need to TreeLock of
-    // write on the new table name, or use the read lock on the table instead.
-    boolean containsRenameTable =
-        Arrays.stream(changes).anyMatch(c -> c instanceof 
TableChange.RenameTable);
-    NameIdentifier nameIdentifierForLock =
-        containsRenameTable ? NameIdentifier.of(ident.namespace().levels()) : 
ident;
+    // use the read lock on the table if there does not exist 
TableChange.RenameTable in the
+    // changes, or:
+    // 1. if the TableChange.RenameTable change the schema name, we need to 
acquire write lock on
+    // the catalog,
+    //    because the treeLock tool currently does not support acquiring write 
locks on two tables
+    // at the same time.
+    // 2. if the TableChange.RenameTable only change the table name, we need 
to acquire write lock
+    // to on the schema.
+    NameIdentifier nameIdentifierForLock = ident;
+    String schemaName = ident.namespace().level(2);
+    for (TableChange change : changes) {
+      if (change instanceof TableChange.RenameTable) {
+        TableChange.RenameTable rename = (TableChange.RenameTable) change;
+        if (rename.getNewSchemaName().isPresent()
+            && !rename.getNewSchemaName().get().equals(schemaName)) {
+          nameIdentifierForLock = getCatalogIdentifier(ident);
+          break;
+        }
+        nameIdentifierForLock = getSchemaIdentifier(ident);
+      }
+    }
 
     return TreeLockUtils.doWithTreeLock(
         nameIdentifierForLock,
-        LockType.WRITE,
+        nameIdentifierForLock.equals(ident) ? LockType.READ : LockType.WRITE,
         () -> {
           NameIdentifier catalogIdent = getCatalogIdentifier(ident);
           Table alteredTable =
@@ -251,20 +267,16 @@ public class TableOperationDispatcher extends 
OperationDispatcher implements Tab
                           TableEntity.class,
                           TABLE,
                           tableEntity -> {
-                            String newName =
-                                Arrays.stream(changes)
-                                    .filter(c -> c instanceof 
TableChange.RenameTable)
-                                    .map(c -> ((TableChange.RenameTable) 
c).getNewName())
-                                    .reduce((c1, c2) -> c2)
-                                    .orElse(tableEntity.name());
+                            Namespace newNamespace = getNewNamespace(ident, 
changes);
+
                             // Update the columns
                             Pair<Boolean, List<ColumnEntity>> 
columnsUpdateResult =
                                 updateColumnsIfNecessary(alteredTable, 
tableEntity);
 
                             return TableEntity.builder()
                                 .withId(tableEntity.id())
-                                .withName(newName)
-                                .withNamespace(ident.namespace())
+                                .withName(alteredTable.name())
+                                .withNamespace(newNamespace)
                                 .withColumns(columnsUpdateResult.getRight())
                                 .withAuditInfo(
                                     AuditInfo.builder()
@@ -298,7 +310,7 @@ public class TableOperationDispatcher extends 
OperationDispatcher implements Tab
    */
   @Override
   public boolean dropTable(NameIdentifier ident) {
-    NameIdentifier schemaIdentifier = 
NameIdentifierUtil.getSchemaIdentifier(ident);
+    NameIdentifier schemaIdentifier = getSchemaIdentifier(ident);
     return TreeLockUtils.doWithTreeLock(
         schemaIdentifier,
         LockType.WRITE,
@@ -351,7 +363,7 @@ public class TableOperationDispatcher extends 
OperationDispatcher implements Tab
    */
   @Override
   public boolean purgeTable(NameIdentifier ident) throws 
UnsupportedOperationException {
-    NameIdentifier schemaIdentifier = 
NameIdentifierUtil.getSchemaIdentifier(ident);
+    NameIdentifier schemaIdentifier = getSchemaIdentifier(ident);
     NameIdentifier catalogIdent = getCatalogIdentifier(ident);
     return TreeLockUtils.doWithTreeLock(
         schemaIdentifier,
@@ -390,6 +402,24 @@ public class TableOperationDispatcher extends 
OperationDispatcher implements Tab
         });
   }
 
+  private Namespace getNewNamespace(NameIdentifier tableIdent, TableChange... 
changes) {
+    String schemaName = tableIdent.namespace().level(2);
+    return Arrays.stream(changes)
+        .filter(
+            c ->
+                c instanceof TableChange.RenameTable
+                    && ((TableChange.RenameTable) 
c).getNewSchemaName().isPresent()
+                    && !((TableChange.RenameTable) 
c).getNewSchemaName().get().equals(schemaName))
+        .map(
+            c ->
+                NamespaceUtil.ofTable(
+                    tableIdent.namespace().level(0),
+                    tableIdent.namespace().level(1),
+                    ((TableChange.RenameTable) c).getNewSchemaName().get()))
+        .reduce((c1, c2) -> c2)
+        .orElse(tableIdent.namespace());
+  }
+
   private EntityCombinedTable importTable(NameIdentifier identifier) {
     EntityCombinedTable table = internalLoadTable(identifier);
 
diff --git 
a/core/src/main/java/org/apache/gravitino/hook/TableHookDispatcher.java 
b/core/src/main/java/org/apache/gravitino/hook/TableHookDispatcher.java
index 3bb6a8da26..5afa9ac533 100644
--- a/core/src/main/java/org/apache/gravitino/hook/TableHookDispatcher.java
+++ b/core/src/main/java/org/apache/gravitino/hook/TableHookDispatcher.java
@@ -110,6 +110,7 @@ public class TableHookDispatcher implements TableDispatcher 
{
     Table alteredTable = dispatcher.alterTable(ident, changes);
 
     if (lastRenameChange != null) {
+      // todo: support rename across different schemas
       AuthorizationUtils.authorizationPluginRenamePrivileges(
           ident, Entity.EntityType.TABLE, lastRenameChange.getNewName(), 
locations);
     }
diff --git 
a/core/src/main/java/org/apache/gravitino/storage/relational/mapper/TableColumnMapper.java
 
b/core/src/main/java/org/apache/gravitino/storage/relational/mapper/TableColumnMapper.java
index 64859c5921..5782d1c535 100644
--- 
a/core/src/main/java/org/apache/gravitino/storage/relational/mapper/TableColumnMapper.java
+++ 
b/core/src/main/java/org/apache/gravitino/storage/relational/mapper/TableColumnMapper.java
@@ -39,6 +39,10 @@ public interface TableColumnMapper {
   @InsertProvider(type = TableColumnSQLProviderFactory.class, method = 
"insertColumnPOs")
   void insertColumnPOs(@Param("columnPOs") List<ColumnPO> columnPOs);
 
+  @UpdateProvider(type = TableColumnSQLProviderFactory.class, method = 
"updateSchemaIdByTableId")
+  void updateSchemaIdByTableId(
+      @Param("tableId") Long tableId, @Param("newSchemaId") Long newSchemaId);
+
   @UpdateProvider(type = TableColumnSQLProviderFactory.class, method = 
"softDeleteColumnsByTableId")
   Integer softDeleteColumnsByTableId(@Param("tableId") Long tableId);
 
diff --git 
a/core/src/main/java/org/apache/gravitino/storage/relational/mapper/TableColumnSQLProviderFactory.java
 
b/core/src/main/java/org/apache/gravitino/storage/relational/mapper/TableColumnSQLProviderFactory.java
index a0e7655e2b..35b5e01cb8 100644
--- 
a/core/src/main/java/org/apache/gravitino/storage/relational/mapper/TableColumnSQLProviderFactory.java
+++ 
b/core/src/main/java/org/apache/gravitino/storage/relational/mapper/TableColumnSQLProviderFactory.java
@@ -61,6 +61,11 @@ public class TableColumnSQLProviderFactory {
     return getProvider().insertColumnPOs(columnPOs);
   }
 
+  public static String updateSchemaIdByTableId(
+      @Param("tableId") Long tableId, @Param("newSchemaId") Long newSchemaId) {
+    return getProvider().updateSchemaIdByTableId(tableId, newSchemaId);
+  }
+
   public static String softDeleteColumnsByTableId(@Param("tableId") Long 
tableId) {
     return getProvider().softDeleteColumnsByTableId(tableId);
   }
diff --git 
a/core/src/main/java/org/apache/gravitino/storage/relational/mapper/TableMetaMapper.java
 
b/core/src/main/java/org/apache/gravitino/storage/relational/mapper/TableMetaMapper.java
index 41621027bf..e919e539e9 100644
--- 
a/core/src/main/java/org/apache/gravitino/storage/relational/mapper/TableMetaMapper.java
+++ 
b/core/src/main/java/org/apache/gravitino/storage/relational/mapper/TableMetaMapper.java
@@ -69,7 +69,9 @@ public interface TableMetaMapper {
 
   @UpdateProvider(type = TableMetaSQLProviderFactory.class, method = 
"updateTableMeta")
   Integer updateTableMeta(
-      @Param("newTableMeta") TablePO newTablePO, @Param("oldTableMeta") 
TablePO oldTablePO);
+      @Param("newTableMeta") TablePO newTablePO,
+      @Param("oldTableMeta") TablePO oldTablePO,
+      @Param("newSchemaId") Long newSchemaId);
 
   @UpdateProvider(
       type = TableMetaSQLProviderFactory.class,
diff --git 
a/core/src/main/java/org/apache/gravitino/storage/relational/mapper/TableMetaSQLProviderFactory.java
 
b/core/src/main/java/org/apache/gravitino/storage/relational/mapper/TableMetaSQLProviderFactory.java
index 664b2423f8..ad16f69ceb 100644
--- 
a/core/src/main/java/org/apache/gravitino/storage/relational/mapper/TableMetaSQLProviderFactory.java
+++ 
b/core/src/main/java/org/apache/gravitino/storage/relational/mapper/TableMetaSQLProviderFactory.java
@@ -82,8 +82,10 @@ public class TableMetaSQLProviderFactory {
   }
 
   public static String updateTableMeta(
-      @Param("newTableMeta") TablePO newTablePO, @Param("oldTableMeta") 
TablePO oldTablePO) {
-    return getProvider().updateTableMeta(newTablePO, oldTablePO);
+      @Param("newTableMeta") TablePO newTablePO,
+      @Param("oldTableMeta") TablePO oldTablePO,
+      @Param("newSchemaId") Long newSchemaId) {
+    return getProvider().updateTableMeta(newTablePO, oldTablePO, newSchemaId);
   }
 
   public static String softDeleteTableMetasByTableId(@Param("tableId") Long 
tableId) {
diff --git 
a/core/src/main/java/org/apache/gravitino/storage/relational/mapper/provider/base/TableColumnBaseSQLProvider.java
 
b/core/src/main/java/org/apache/gravitino/storage/relational/mapper/provider/base/TableColumnBaseSQLProvider.java
index 0b59855023..df3d1a3eaf 100644
--- 
a/core/src/main/java/org/apache/gravitino/storage/relational/mapper/provider/base/TableColumnBaseSQLProvider.java
+++ 
b/core/src/main/java/org/apache/gravitino/storage/relational/mapper/provider/base/TableColumnBaseSQLProvider.java
@@ -66,6 +66,14 @@ public class TableColumnBaseSQLProvider {
         + "</script>";
   }
 
+  public String updateSchemaIdByTableId(
+      @Param("tableId") Long tableId, @Param("newSchemaId") Long newSchemaId) {
+    return "UPDATE "
+        + TableColumnMapper.COLUMN_TABLE_NAME
+        + " SET schema_id = #{newSchemaId}"
+        + " WHERE table_id = #{tableId} AND deleted_at = 0";
+  }
+
   public String softDeleteColumnsByTableId(@Param("tableId") Long tableId) {
     return "UPDATE "
         + TableColumnMapper.COLUMN_TABLE_NAME
diff --git 
a/core/src/main/java/org/apache/gravitino/storage/relational/mapper/provider/base/TableMetaBaseSQLProvider.java
 
b/core/src/main/java/org/apache/gravitino/storage/relational/mapper/provider/base/TableMetaBaseSQLProvider.java
index 41f26e2340..83a14d31c5 100644
--- 
a/core/src/main/java/org/apache/gravitino/storage/relational/mapper/provider/base/TableMetaBaseSQLProvider.java
+++ 
b/core/src/main/java/org/apache/gravitino/storage/relational/mapper/provider/base/TableMetaBaseSQLProvider.java
@@ -134,13 +134,15 @@ public class TableMetaBaseSQLProvider {
   }
 
   public String updateTableMeta(
-      @Param("newTableMeta") TablePO newTablePO, @Param("oldTableMeta") 
TablePO oldTablePO) {
+      @Param("newTableMeta") TablePO newTablePO,
+      @Param("oldTableMeta") TablePO oldTablePO,
+      @Param("newSchemaId") Long newSchemaId) {
     return "UPDATE "
         + TABLE_NAME
         + " SET table_name = #{newTableMeta.tableName},"
         + " metalake_id = #{newTableMeta.metalakeId},"
         + " catalog_id = #{newTableMeta.catalogId},"
-        + " schema_id = #{newTableMeta.schemaId},"
+        + " schema_id = #{newSchemaId},"
         + " audit_info = #{newTableMeta.auditInfo},"
         + " current_version = #{newTableMeta.currentVersion},"
         + " last_version = #{newTableMeta.lastVersion},"
diff --git 
a/core/src/main/java/org/apache/gravitino/storage/relational/service/TableColumnMetaService.java
 
b/core/src/main/java/org/apache/gravitino/storage/relational/service/TableColumnMetaService.java
index d3dabbe89a..1e4bcc7fc2 100644
--- 
a/core/src/main/java/org/apache/gravitino/storage/relational/service/TableColumnMetaService.java
+++ 
b/core/src/main/java/org/apache/gravitino/storage/relational/service/TableColumnMetaService.java
@@ -184,6 +184,13 @@ public class TableColumnMetaService {
 
     // If there is no change, directly return
     if (columnPOsToInsert.isEmpty()) {
+      // If namespace is changed, just update the schema_id of the columns.
+      if (!newTable.namespace().equals(oldTable.namespace())) {
+        SessionUtils.doWithoutCommit(
+            TableColumnMapper.class,
+            mapper ->
+                mapper.updateSchemaIdByTableId(newTablePO.getTableId(), 
newTablePO.getSchemaId()));
+      }
       return;
     }
 
diff --git 
a/core/src/main/java/org/apache/gravitino/storage/relational/service/TableMetaService.java
 
b/core/src/main/java/org/apache/gravitino/storage/relational/service/TableMetaService.java
index db3646c94a..326ba63b5f 100644
--- 
a/core/src/main/java/org/apache/gravitino/storage/relational/service/TableMetaService.java
+++ 
b/core/src/main/java/org/apache/gravitino/storage/relational/service/TableMetaService.java
@@ -176,10 +176,18 @@ public class TableMetaService {
         newTableEntity.id(),
         oldTableEntity.id());
 
+    boolean isSchemaChanged = 
!newTableEntity.namespace().equals(oldTableEntity.namespace());
+    Long newSchemaId =
+        isSchemaChanged
+            ? CommonMetaService.getInstance()
+                .getParentEntityIdByNamespace(newTableEntity.namespace())
+            : schemaId;
+
     boolean isColumnChanged =
         TableColumnMetaService.getInstance().isColumnUpdated(oldTableEntity, 
newTableEntity);
     TablePO newTablePO =
-        POConverters.updateTablePOWithVersion(oldTablePO, newTableEntity, 
isColumnChanged);
+        POConverters.updateTablePOWithVersionAndSchemaId(
+            oldTablePO, newTableEntity, isColumnChanged, newSchemaId);
 
     final AtomicInteger updateResult = new AtomicInteger(0);
     try {
@@ -188,9 +196,9 @@ public class TableMetaService {
               updateResult.set(
                   SessionUtils.getWithoutCommit(
                       TableMetaMapper.class,
-                      mapper -> mapper.updateTableMeta(newTablePO, 
oldTablePO))),
+                      mapper -> mapper.updateTableMeta(newTablePO, oldTablePO, 
newSchemaId))),
           () -> {
-            if (updateResult.get() > 0 && isColumnChanged) {
+            if (updateResult.get() > 0 && (isColumnChanged || 
isSchemaChanged)) {
               TableColumnMetaService.getInstance()
                   .updateColumnPOsFromTableDiff(oldTableEntity, 
newTableEntity, newTablePO);
             }
diff --git 
a/core/src/main/java/org/apache/gravitino/storage/relational/utils/POConverters.java
 
b/core/src/main/java/org/apache/gravitino/storage/relational/utils/POConverters.java
index 1376fc39a5..127cb022e8 100644
--- 
a/core/src/main/java/org/apache/gravitino/storage/relational/utils/POConverters.java
+++ 
b/core/src/main/java/org/apache/gravitino/storage/relational/utils/POConverters.java
@@ -409,10 +409,11 @@ public class POConverters {
    * @param oldTablePO the old TablePO object
    * @param newTable the new TableEntity object
    * @param needUpdateVersion whether need to update the version
+   * @param newSchemaId the new schema id
    * @return TablePO object with updated version
    */
-  public static TablePO updateTablePOWithVersion(
-      TablePO oldTablePO, TableEntity newTable, boolean needUpdateVersion) {
+  public static TablePO updateTablePOWithVersionAndSchemaId(
+      TablePO oldTablePO, TableEntity newTable, boolean needUpdateVersion, 
Long newSchemaId) {
     Long lastVersion;
     Long currentVersion;
     if (needUpdateVersion) {
@@ -429,7 +430,7 @@ public class POConverters {
           .withTableName(newTable.name())
           .withMetalakeId(oldTablePO.getMetalakeId())
           .withCatalogId(oldTablePO.getCatalogId())
-          .withSchemaId(oldTablePO.getSchemaId())
+          .withSchemaId(newSchemaId)
           
.withAuditInfo(JsonUtils.anyFieldMapper().writeValueAsString(newTable.auditInfo()))
           .withCurrentVersion(currentVersion)
           .withLastVersion(lastVersion)
diff --git 
a/core/src/test/java/org/apache/gravitino/storage/relational/service/TestTableMetaService.java
 
b/core/src/test/java/org/apache/gravitino/storage/relational/service/TestTableMetaService.java
new file mode 100644
index 0000000000..2f2e20f26f
--- /dev/null
+++ 
b/core/src/test/java/org/apache/gravitino/storage/relational/service/TestTableMetaService.java
@@ -0,0 +1,152 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.gravitino.storage.relational.service;
+
+import java.io.IOException;
+import java.time.Instant;
+import java.util.List;
+import java.util.Map;
+import java.util.function.Function;
+import java.util.stream.Collectors;
+import org.apache.gravitino.Namespace;
+import org.apache.gravitino.exceptions.NoSuchEntityException;
+import org.apache.gravitino.meta.AuditInfo;
+import org.apache.gravitino.meta.ColumnEntity;
+import org.apache.gravitino.meta.SchemaEntity;
+import org.apache.gravitino.meta.TableEntity;
+import org.apache.gravitino.rel.expressions.literals.Literals;
+import org.apache.gravitino.rel.types.Types;
+import org.apache.gravitino.storage.RandomIdGenerator;
+import org.apache.gravitino.storage.relational.TestJDBCBackend;
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.Test;
+
+public class TestTableMetaService extends TestJDBCBackend {
+  private final String metalakeName = "metalake_for_table_test";
+  private final AuditInfo auditInfo =
+      
AuditInfo.builder().withCreator("creator").withCreateTime(Instant.now()).build();
+
+  @Test
+  public void testUpdateTable() throws IOException {
+    String catalogName = "catalog1";
+    String schemaName = "schema1";
+    createParentEntities(metalakeName, catalogName, schemaName, auditInfo);
+
+    ColumnEntity column1 =
+        ColumnEntity.builder()
+            .withId(RandomIdGenerator.INSTANCE.nextId())
+            .withName("column1")
+            .withPosition(0)
+            .withComment("comment1")
+            .withDataType(Types.IntegerType.get())
+            .withNullable(true)
+            .withAutoIncrement(false)
+            .withDefaultValue(Literals.integerLiteral(1))
+            .withAuditInfo(auditInfo)
+            .build();
+    TableEntity createdTable =
+        TableEntity.builder()
+            .withId(RandomIdGenerator.INSTANCE.nextId())
+            .withName("table1")
+            .withNamespace(Namespace.of(metalakeName, catalogName, schemaName))
+            .withColumns(List.of(column1))
+            .withAuditInfo(auditInfo)
+            .build();
+    TableMetaService.getInstance().insertTable(createdTable, false);
+
+    // test update table without changing schema name
+    TableEntity updatedTable =
+        TableEntity.builder()
+            .withId(createdTable.id())
+            .withName("table2")
+            .withNamespace(createdTable.namespace())
+            .withColumns(createdTable.columns())
+            .withAuditInfo(auditInfo)
+            .build();
+    Function<TableEntity, TableEntity> updater = oldTable -> updatedTable;
+    TableMetaService.getInstance().updateTable(createdTable.nameIdentifier(), 
updater);
+
+    TableEntity retrievedTable =
+        
TableMetaService.getInstance().getTableByIdentifier(updatedTable.nameIdentifier());
+    Assertions.assertEquals(updatedTable.id(), retrievedTable.id());
+    Assertions.assertEquals(updatedTable.name(), retrievedTable.name());
+    Assertions.assertEquals(updatedTable.namespace(), 
retrievedTable.namespace());
+    Assertions.assertEquals(updatedTable.auditInfo(), 
retrievedTable.auditInfo());
+    compareTwoColumns(updatedTable.columns(), retrievedTable.columns());
+    compareTwoColumns(updatedTable.columns(), retrievedTable.columns());
+
+    // test update table with changing schema name to a non-existing schema
+    String newSchemaName = "schema2";
+    TableEntity updatedTable2 =
+        TableEntity.builder()
+            .withId(updatedTable.id())
+            .withName("table3")
+            .withNamespace(Namespace.of(metalakeName, catalogName, 
newSchemaName))
+            .withColumns(updatedTable.columns())
+            .withAuditInfo(auditInfo)
+            .build();
+    Function<TableEntity, TableEntity> updater2 = oldTable -> updatedTable2;
+    Exception e =
+        Assertions.assertThrows(
+            NoSuchEntityException.class,
+            () ->
+                TableMetaService.getInstance()
+                    .updateTable(updatedTable.nameIdentifier(), updater2));
+    Assertions.assertTrue(e.getMessage().contains(newSchemaName));
+
+    // test update table with changing schema name to an existing schema
+    SchemaEntity newSchema =
+        createSchemaEntity(
+            RandomIdGenerator.INSTANCE.nextId(),
+            Namespace.of(metalakeName, catalogName),
+            newSchemaName,
+            auditInfo);
+    backend.insert(newSchema, false);
+    TableMetaService.getInstance().updateTable(updatedTable.nameIdentifier(), 
updater2);
+
+    TableEntity retrievedTable2 =
+        
TableMetaService.getInstance().getTableByIdentifier(updatedTable2.nameIdentifier());
+    Assertions.assertEquals(updatedTable2.id(), retrievedTable2.id());
+    Assertions.assertEquals(updatedTable2.name(), retrievedTable2.name());
+    Assertions.assertEquals(updatedTable2.namespace(), 
retrievedTable2.namespace());
+    Assertions.assertEquals(updatedTable2.auditInfo(), 
retrievedTable2.auditInfo());
+    compareTwoColumns(updatedTable2.columns(), retrievedTable2.columns());
+  }
+
+  private void compareTwoColumns(
+      List<ColumnEntity> expectedColumns, List<ColumnEntity> actualColumns) {
+    Assertions.assertEquals(expectedColumns.size(), actualColumns.size());
+    Map<String, ColumnEntity> expectedColumnsMap =
+        expectedColumns.stream().collect(Collectors.toMap(ColumnEntity::name, 
Function.identity()));
+    actualColumns.forEach(
+        column -> {
+          ColumnEntity expectedColumn = expectedColumnsMap.get(column.name());
+          Assertions.assertNotNull(expectedColumn);
+          Assertions.assertEquals(expectedColumn.id(), column.id());
+          Assertions.assertEquals(expectedColumn.name(), column.name());
+          Assertions.assertEquals(expectedColumn.position(), 
column.position());
+          Assertions.assertEquals(expectedColumn.comment(), column.comment());
+          Assertions.assertEquals(expectedColumn.dataType(), 
column.dataType());
+          Assertions.assertEquals(expectedColumn.nullable(), 
column.nullable());
+          Assertions.assertEquals(expectedColumn.autoIncrement(), 
column.autoIncrement());
+          Assertions.assertEquals(expectedColumn.defaultValue(), 
column.defaultValue());
+          Assertions.assertEquals(expectedColumn.auditInfo(), 
column.auditInfo());
+        });
+  }
+}
diff --git 
a/core/src/test/java/org/apache/gravitino/storage/relational/utils/TestPOConverters.java
 
b/core/src/test/java/org/apache/gravitino/storage/relational/utils/TestPOConverters.java
index 9d72d31fa9..a2d8a259da 100644
--- 
a/core/src/test/java/org/apache/gravitino/storage/relational/utils/TestPOConverters.java
+++ 
b/core/src/test/java/org/apache/gravitino/storage/relational/utils/TestPOConverters.java
@@ -694,7 +694,8 @@ public class TestPOConverters {
     TablePO.Builder builder =
         
TablePO.builder().withMetalakeId(1L).withCatalogId(1L).withSchemaId(1L);
     TablePO initPO = POConverters.initializeTablePOWithVersion(tableEntity, 
builder);
-    TablePO updatePO = POConverters.updateTablePOWithVersion(initPO, 
updatedTable, false);
+    TablePO updatePO =
+        POConverters.updateTablePOWithVersionAndSchemaId(initPO, updatedTable, 
false, 1L);
     assertEquals(1, initPO.getCurrentVersion());
     assertEquals(1, initPO.getLastVersion());
     assertEquals(0, initPO.getDeletedAt());
diff --git a/docs/manage-relational-metadata-using-gravitino.md 
b/docs/manage-relational-metadata-using-gravitino.md
index 224d9a2500..a05d9393f1 100644
--- a/docs/manage-relational-metadata-using-gravitino.md
+++ b/docs/manage-relational-metadata-using-gravitino.md
@@ -1118,20 +1118,20 @@ Table t = 
tableCatalog.alterTable(NameIdentifier.of("schema", "table"),
 
 Currently, Gravitino supports the following changes to a table:
 
-| Supported modification               | JSON                                  
                                                                                
                                                                                
                                                       | Java                   
                     |
-|--------------------------------------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|---------------------------------------------|
-| Rename table                         | 
`{"@type":"rename","newName":"table_renamed"}`                                  
                                                                                
                                                                                
             | `TableChange.rename("table_renamed")`       |
-| Update comment                       | 
`{"@type":"updateComment","newComment":"new_comment"}`                          
                                                                                
                                                                                
             | `TableChange.updateComment("new_comment")`  |
-| Set a table property                 | 
`{"@type":"setProperty","property":"key1","value":"value1"}`                    
                                                                                
                                                                                
             | `TableChange.setProperty("key1", "value1")` |
-| Remove a table property              | 
`{"@type":"removeProperty","property":"key1"}`                                  
                                                                                
                                                                                
             | `TableChange.removeProperty("key1")`        |
-| Add a column                         | 
`{"@type":"addColumn","fieldName":["position"],"type":"varchar(20)","comment":"Position
 of user","position":"FIRST","nullable": true, "autoIncrement": false, 
"defaultValue" : {"type": "literal", "dataType": "varchar(20)", "value": 
"Default Position"}}` | `TableChange.addColumn(...)`                |
-| Delete a column                      | `{"@type":"deleteColumn","fieldName": 
["name"], "ifExists": true}`                                                    
                                                                                
                                                       | 
`TableChange.deleteColumn(...)`             |
-| Rename a column                      | 
`{"@type":"renameColumn","oldFieldName":["name_old"], 
"newFieldName":"name_new"}`                                                     
                                                                                
                                       | `TableChange.renameColumn(...)`        
     |
-| Update the column comment            | `{"@type":"updateColumnComment", 
"fieldName": ["name"], "newComment": "new comment"}`                            
                                                                                
                                                            | 
`TableChange.updateColumnCommment(...)`     |
-| Update the type of a column          | 
`{"@type":"updateColumnType","fieldName": ["name"], "newType":"varchar(100)"}`  
                                                                                
                                                                                
             | `TableChange.updateColumnType(...)`         |
-| Update the nullability of a column   | 
`{"@type":"updateColumnNullability","fieldName": ["name"],"nullable":true}`     
                                                                                
                                                                                
             | `TableChange.updateColumnNullability(...)`  |
-| Update the position of a column      | 
`{"@type":"updateColumnPosition","fieldName": ["name"], 
"newPosition":"default"}`                                                       
                                                                                
                                     | `TableChange.updateColumnPosition(...)`  
   |
-| Update the default value of a column | 
`{"@type":"updateColumnDefaultValue","fieldName": ["name"], 
"newDefaultValue":{"type":"literal","dataType":"varchar(100)","value":"new 
default value}}`                                                                
                                      | 
`TableChange.updateColumnDefaultValue(...)` |
+| Supported modification               | JSON                                  
                                                                                
                                                                                
                                                       | Java                   
                                                                      |
+|--------------------------------------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|----------------------------------------------------------------------------------------------|
+| Rename table                         | 
`{"@type":"rename","newName":"table_renamed"}` or 
`{"@type":"rename","newName":"table_renamed, "newSchemaName":"new_schema"}`     
                                                                                
                                           | 
`TableChange.rename("table_renamed")` or `TableChange.rename("table_renamed", 
"new_schema")` |
+| Update comment                       | 
`{"@type":"updateComment","newComment":"new_comment"}`                          
                                                                                
                                                                                
             | `TableChange.updateComment("new_comment")`                       
                            |
+| Set a table property                 | 
`{"@type":"setProperty","property":"key1","value":"value1"}`                    
                                                                                
                                                                                
             | `TableChange.setProperty("key1", "value1")`                      
                            |
+| Remove a table property              | 
`{"@type":"removeProperty","property":"key1"}`                                  
                                                                                
                                                                                
             | `TableChange.removeProperty("key1")`                             
                            |
+| Add a column                         | 
`{"@type":"addColumn","fieldName":["position"],"type":"varchar(20)","comment":"Position
 of user","position":"FIRST","nullable": true, "autoIncrement": false, 
"defaultValue" : {"type": "literal", "dataType": "varchar(20)", "value": 
"Default Position"}}` | `TableChange.addColumn(...)`                            
                                     |
+| Delete a column                      | `{"@type":"deleteColumn","fieldName": 
["name"], "ifExists": true}`                                                    
                                                                                
                                                       | 
`TableChange.deleteColumn(...)`                                                 
             |
+| Rename a column                      | 
`{"@type":"renameColumn","oldFieldName":["name_old"], 
"newFieldName":"name_new"}`                                                     
                                                                                
                                       | `TableChange.renameColumn(...)`        
                                                      |
+| Update the column comment            | `{"@type":"updateColumnComment", 
"fieldName": ["name"], "newComment": "new comment"}`                            
                                                                                
                                                            | 
`TableChange.updateColumnCommment(...)`                                         
             |
+| Update the type of a column          | 
`{"@type":"updateColumnType","fieldName": ["name"], "newType":"varchar(100)"}`  
                                                                                
                                                                                
             | `TableChange.updateColumnType(...)`                              
                            |
+| Update the nullability of a column   | 
`{"@type":"updateColumnNullability","fieldName": ["name"],"nullable":true}`     
                                                                                
                                                                                
             | `TableChange.updateColumnNullability(...)`                       
                            |
+| Update the position of a column      | 
`{"@type":"updateColumnPosition","fieldName": ["name"], 
"newPosition":"default"}`                                                       
                                                                                
                                     | `TableChange.updateColumnPosition(...)`  
                                                    |
+| Update the default value of a column | 
`{"@type":"updateColumnDefaultValue","fieldName": ["name"], 
"newDefaultValue":{"type":"literal","dataType":"varchar(100)","value":"new 
default value}}`                                                                
                                      | 
`TableChange.updateColumnDefaultValue(...)`                                     
             |
 
 ### Drop a table
 
diff --git a/docs/open-api/tables.yaml b/docs/open-api/tables.yaml
index 361602e1b5..1e199c5dd1 100644
--- a/docs/open-api/tables.yaml
+++ b/docs/open-api/tables.yaml
@@ -431,9 +431,14 @@ components:
         newName:
           type: string
           description: The new name of the table
+        newSchemaName:
+          type: string
+          description: The new schema name of the table, if not provided, the 
schema will not be changed
+          nullable: true
       example: {
         "@type": "rename",
-        "newName": "my_hive_table_new"
+        "newName": "my_hive_table_new",
+        "newSchemaName": "my_hive_schema_new"
       }
 
     UpdateTableCommentRequest:

Reply via email to