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

diqiu50 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 995f6a0640 [#10986][#10985] fix(iceberg): Fix the issue of creating 
remote IRC catalog tables using Trino (#10989)
995f6a0640 is described below

commit 995f6a06403b1d90e80941d1464e26a512a5ae73
Author: roryqi <[email protected]>
AuthorDate: Mon May 11 09:57:44 2026 +0800

    [#10986][#10985] fix(iceberg): Fix the issue of creating remote IRC catalog 
tables using Trino (#10989)
    
    ### What changes were proposed in this pull request?
    
    Fix the issue of creating remote IRC catalog tables using Trino
    
    ### Why are the changes needed?
    
    Fix:
    #10986
    #10985
    
    ### Does this PR introduce _any_ user-facing change?
    
    No.
    
    ### How was this patch tested?
    
    Added tests.
---
 .../iceberg/service/CatalogWrapperForREST.java     | 150 +++++++++++++-
 .../iceberg/service/TestCatalogWrapperForREST.java | 222 ++++++++++++++++++++-
 2 files changed, 365 insertions(+), 7 deletions(-)

diff --git 
a/iceberg/iceberg-rest-server/src/main/java/org/apache/gravitino/iceberg/service/CatalogWrapperForREST.java
 
b/iceberg/iceberg-rest-server/src/main/java/org/apache/gravitino/iceberg/service/CatalogWrapperForREST.java
index 18980ea857..bc0e456410 100644
--- 
a/iceberg/iceberg-rest-server/src/main/java/org/apache/gravitino/iceberg/service/CatalogWrapperForREST.java
+++ 
b/iceberg/iceberg-rest-server/src/main/java/org/apache/gravitino/iceberg/service/CatalogWrapperForREST.java
@@ -20,6 +20,7 @@
 package org.apache.gravitino.iceberg.service;
 
 import com.google.common.annotations.VisibleForTesting;
+import com.google.common.base.Preconditions;
 import com.google.common.collect.ImmutableMap;
 import com.google.common.collect.ImmutableSet;
 import com.google.common.collect.Maps;
@@ -55,17 +56,23 @@ import org.apache.gravitino.utils.MapUtils;
 import org.apache.gravitino.utils.PrincipalUtils;
 import org.apache.iceberg.BaseMetadataTable;
 import org.apache.iceberg.BaseTable;
+import org.apache.iceberg.BaseTransaction;
 import org.apache.iceberg.DeleteFile;
 import org.apache.iceberg.FileScanTask;
 import org.apache.iceberg.IncrementalAppendScan;
+import org.apache.iceberg.MetadataUpdate;
 import org.apache.iceberg.PartitionSpec;
 import org.apache.iceberg.Scan;
 import org.apache.iceberg.ScanTaskParser;
+import org.apache.iceberg.Schema;
 import org.apache.iceberg.SortOrder;
 import org.apache.iceberg.Table;
 import org.apache.iceberg.TableMetadata;
+import org.apache.iceberg.TableOperations;
 import org.apache.iceberg.TableProperties;
 import org.apache.iceberg.TableScan;
+import org.apache.iceberg.Transaction;
+import org.apache.iceberg.UpdateRequirement;
 import org.apache.iceberg.catalog.Catalog;
 import org.apache.iceberg.catalog.Namespace;
 import org.apache.iceberg.catalog.TableIdentifier;
@@ -99,6 +106,7 @@ public class CatalogWrapperForREST extends 
IcebergCatalogWrapper {
 
   private static final String DATA_ACCESS_VENDED_CREDENTIALS = 
"vended-credentials";
   private static final String DATA_ACCESS_REMOTE_SIGNING = "remote-signing";
+  private static final Schema EMPTY_SCHEMA = new Schema();
 
   private static final Set<String> catalogPropertiesToClientKeys =
       ImmutableSet.of(
@@ -176,7 +184,7 @@ public class CatalogWrapperForREST extends 
IcebergCatalogWrapper {
   public LoadTableResponse updateTable(
       TableIdentifier tableIdentifier, UpdateTableRequest updateTableRequest) {
     if (isRESTCatalog()) {
-      return CatalogHandlers.updateTable(getCatalog(), tableIdentifier, 
updateTableRequest);
+      return tableUpdateInternal(tableIdentifier, updateTableRequest);
     } else {
       return super.updateTable(tableIdentifier, updateTableRequest);
     }
@@ -735,6 +743,51 @@ public class CatalogWrapperForREST extends 
IcebergCatalogWrapper {
     return 
LoadTableResponse.builder().withTableMetadata(metadata).addAllConfig(config).build();
   }
 
+  private LoadTableResponse tableUpdateInternal(TableIdentifier ident, 
UpdateTableRequest request) {
+    if (isCreate(request)) {
+      // this is a hacky way to get TableOperations for an uncommitted table
+      Optional<Integer> formatVersion =
+          request.updates().stream()
+              .filter(update -> update instanceof 
MetadataUpdate.UpgradeFormatVersion)
+              .map(update -> ((MetadataUpdate.UpgradeFormatVersion) 
update).formatVersion())
+              .findFirst();
+
+      Schema schema =
+          request.updates().stream()
+              .filter(update -> update instanceof MetadataUpdate.AddSchema)
+              .map(update -> ((MetadataUpdate.AddSchema) update).schema())
+              .findFirst()
+              .orElse(EMPTY_SCHEMA);
+
+      Catalog.TableBuilder tableBuilder = getCatalog().buildTable(ident, 
schema);
+
+      TableMetadata.Builder changedMetadata =
+          
formatVersion.map(TableMetadata::buildFromEmpty).orElse(TableMetadata.buildFromEmpty());
+      request.updates().forEach(update -> update.applyTo(changedMetadata));
+
+      TableMetadata changedTableMeta = changedMetadata.build();
+      tableBuilder.withPartitionSpec(changedTableMeta.spec());
+      tableBuilder.withSortOrder(changedTableMeta.sortOrder());
+      tableBuilder.withLocation(changedTableMeta.location());
+      tableBuilder.withProperties(changedTableMeta.properties());
+
+      Transaction transaction = tableBuilder.createOrReplaceTransaction();
+      if (transaction instanceof BaseTransaction) {
+        BaseTransaction baseTransaction = (BaseTransaction) transaction;
+
+        return LoadTableResponse.builder()
+            .withTableMetadata(create(baseTransaction, request))
+            .build();
+      } else {
+        throw new IllegalStateException(
+            "Cannot wrap catalog that does not produce BaseTransaction");
+      }
+
+    } else {
+      return CatalogHandlers.updateTable(getCatalog(), ident, request);
+    }
+  }
+
   private LoadTableResponse loadTableInternal(TableIdentifier ident) {
     Table table = getCatalog().loadTable(ident);
 
@@ -756,6 +809,101 @@ public class CatalogWrapperForREST extends 
IcebergCatalogWrapper {
     throw new IllegalStateException("Cannot wrap catalog that does not produce 
BaseTable");
   }
 
+  private static boolean isCreate(UpdateTableRequest request) {
+    boolean isCreate =
+        request.requirements().stream()
+            
.anyMatch(UpdateRequirement.AssertTableDoesNotExist.class::isInstance);
+
+    if (isCreate) {
+      List<UpdateRequirement> invalidRequirements =
+          request.requirements().stream()
+              .filter(req -> !(req instanceof 
UpdateRequirement.AssertTableDoesNotExist))
+              .collect(Collectors.toList());
+      Preconditions.checkArgument(
+          invalidRequirements.isEmpty(), "Invalid create requirements: %s", 
invalidRequirements);
+    }
+
+    return isCreate;
+  }
+
+  private static TableMetadata create(BaseTransaction baseTransaction, 
UpdateTableRequest request) {
+    // the only valid requirement is that the table will be created
+    TableOperations ops = baseTransaction.underlyingOps();
+    request.requirements().forEach(requirement -> 
requirement.validate(ops.current()));
+
+    TableMetadata.Builder builder = 
TableMetadata.buildFrom(baseTransaction.currentMetadata());
+    request
+        .updates()
+        .forEach(
+            update -> {
+              if (shouldApplyMetadataUpdateAfterBuilder(update)) {
+                update.applyTo(builder);
+              }
+            });
+
+    // create transactions do not retry. if the table exists, retrying is not 
a solution
+    ops.commit(null, builder.build());
+
+    return ops.current();
+  }
+
+  /**
+   * Returns {@code false} for updates already reflected through {@link 
Catalog.TableBuilder} during
+   * staged create; those must not be applied again on {@link 
TableMetadata.Builder}.
+   */
+  @VisibleForTesting
+  static boolean shouldApplyMetadataUpdateAfterBuilder(MetadataUpdate update) {
+    if (update instanceof MetadataUpdate.UpgradeFormatVersion) {
+      return false;
+    }
+
+    if (update instanceof MetadataUpdate.AddSchema) {
+      return false;
+    }
+
+    if (update instanceof MetadataUpdate.SetCurrentSchema) {
+      return false;
+    }
+
+    if (update instanceof MetadataUpdate.RemoveSchemas) {
+      return false;
+    }
+
+    if (update instanceof MetadataUpdate.SetLocation) {
+      return false;
+    }
+
+    if (update instanceof MetadataUpdate.SetProperties) {
+      return false;
+    }
+
+    if (update instanceof MetadataUpdate.RemoveProperties) {
+      return false;
+    }
+
+    if (update instanceof MetadataUpdate.AddSortOrder) {
+      return false;
+    }
+
+    if (update instanceof MetadataUpdate.SetDefaultSortOrder) {
+      return false;
+    }
+
+    if (update instanceof MetadataUpdate.AddPartitionSpec) {
+      return false;
+    }
+
+    if (update instanceof MetadataUpdate.SetDefaultPartitionSpec) {
+      return false;
+    }
+
+    if (update instanceof MetadataUpdate.RemovePartitionSpecs) {
+      return false;
+    }
+
+    return true;
+  }
+
   private static Map<String, String> retrieveFileIOProperties(FileIO fileIO) {
     return fileIO instanceof InMemoryFileIO ? Maps.newHashMap() : 
fileIO.properties();
   }
diff --git 
a/iceberg/iceberg-rest-server/src/test/java/org/apache/gravitino/iceberg/service/TestCatalogWrapperForREST.java
 
b/iceberg/iceberg-rest-server/src/test/java/org/apache/gravitino/iceberg/service/TestCatalogWrapperForREST.java
index 1652548096..88acbec5f7 100644
--- 
a/iceberg/iceberg-rest-server/src/test/java/org/apache/gravitino/iceberg/service/TestCatalogWrapperForREST.java
+++ 
b/iceberg/iceberg-rest-server/src/test/java/org/apache/gravitino/iceberg/service/TestCatalogWrapperForREST.java
@@ -21,25 +21,41 @@ package org.apache.gravitino.iceberg.service;
 
 import static org.mockito.Mockito.any;
 import static org.mockito.Mockito.anyMap;
+import static org.mockito.Mockito.anyString;
+import static org.mockito.Mockito.doAnswer;
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.never;
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.when;
 
 import com.google.common.collect.ImmutableMap;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
 import java.util.Map;
+import java.util.Optional;
+import java.util.UUID;
 import java.util.concurrent.atomic.AtomicBoolean;
+import java.util.concurrent.atomic.AtomicReference;
 import org.apache.gravitino.catalog.lakehouse.iceberg.IcebergConstants;
 import org.apache.gravitino.iceberg.common.IcebergConfig;
+import org.apache.iceberg.BaseTransaction;
+import org.apache.iceberg.MetadataUpdate;
+import org.apache.iceberg.PartitionSpec;
 import org.apache.iceberg.Schema;
+import org.apache.iceberg.SortOrder;
 import org.apache.iceberg.Table;
+import org.apache.iceberg.TableMetadata;
+import org.apache.iceberg.TableOperations;
 import org.apache.iceberg.Transaction;
+import org.apache.iceberg.UpdateRequirement;
 import org.apache.iceberg.catalog.Catalog;
 import org.apache.iceberg.catalog.Namespace;
 import org.apache.iceberg.catalog.TableIdentifier;
 import org.apache.iceberg.io.FileIO;
 import org.apache.iceberg.rest.RESTCatalog;
 import org.apache.iceberg.rest.requests.CreateTableRequest;
+import org.apache.iceberg.rest.requests.UpdateTableRequest;
 import org.apache.iceberg.rest.responses.LoadTableResponse;
 import org.apache.iceberg.types.Types;
 import org.junit.jupiter.api.Assertions;
@@ -99,7 +115,7 @@ public class TestCatalogWrapperForREST {
   }
 
   @Test
-  void testCatalogConfigToClientsForRestBackendUsesMergedRemoteProperties() {
+  void testRestCatalogClientConfigMergesRemote() {
     IcebergConfig config =
         new IcebergConfig(
             ImmutableMap.of(
@@ -135,7 +151,7 @@ public class TestCatalogWrapperForREST {
   }
 
   @Test
-  void testCatalogConfigToClientsForNonRestBackend() {
+  void testNonRestCatalogClientConfig() {
     Catalog catalog = mock(Catalog.class);
     IcebergConfig config =
         new IcebergConfig(
@@ -155,7 +171,7 @@ public class TestCatalogWrapperForREST {
   }
 
   @Test
-  void testCatalogConfigToClientsRejectsInvalidDataAccessValue() {
+  void testCatalogClientConfigRejectsBadDataAccess() {
     Catalog catalog = mock(Catalog.class);
     IcebergConfig config =
         new IcebergConfig(
@@ -171,7 +187,7 @@ public class TestCatalogWrapperForREST {
   }
 
   @Test
-  void testConstructorDoesNotLoadCatalogEagerly() {
+  void testWrapperLazyLoadsCatalog() {
     IcebergConfig config =
         new IcebergConfig(
             ImmutableMap.of(
@@ -189,7 +205,7 @@ public class TestCatalogWrapperForREST {
   }
 
   @Test
-  void testStageTableCreateWithLocationIncludesFileIoProperties() throws 
Exception {
+  void testStageCreateWithLocationIncludesFileIo() throws Exception {
     RESTCatalog catalog = mock(RESTCatalog.class);
     Catalog.TableBuilder tableBuilder = mock(Catalog.TableBuilder.class);
     Transaction transaction = mock(Transaction.class);
@@ -240,7 +256,7 @@ public class TestCatalogWrapperForREST {
   }
 
   @Test
-  void testStageTableCreateWithNullLocationDoesNotCallWithLocation() {
+  void testStageCreateNullLocationSkipsWithLocation() {
     RESTCatalog catalog = mock(RESTCatalog.class);
     Catalog.TableBuilder tableBuilder = mock(Catalog.TableBuilder.class);
     Transaction transaction = mock(Transaction.class);
@@ -284,6 +300,200 @@ public class TestCatalogWrapperForREST {
     verify(tableBuilder, never()).withLocation(any());
   }
 
+  @Test
+  void testStagedCreateRejectsExtraRequirements() {
+    RESTCatalog catalog = mock(RESTCatalog.class);
+    IcebergConfig config =
+        new IcebergConfig(
+            ImmutableMap.of(
+                IcebergConstants.CATALOG_BACKEND,
+                "memory",
+                IcebergConstants.WAREHOUSE,
+                "/tmp/warehouse"));
+    CatalogWrapperForREST wrapper = new StaticCatalogWrapperForREST("test", 
config, catalog);
+
+    UpdateRequirement extraRequirement = mock(UpdateRequirement.class);
+    UpdateTableRequest request =
+        new UpdateTableRequest(
+            List.of(new UpdateRequirement.AssertTableDoesNotExist(), 
extraRequirement),
+            Collections.emptyList());
+
+    Assertions.assertThrowsExactly(
+        IllegalArgumentException.class,
+        () -> wrapper.updateTable(TableIdentifier.of("db", "tbl"), request));
+  }
+
+  @Test
+  void testPostBuilderMetadataSkipsHandledKinds() {
+    Schema schema = new Schema(Types.NestedField.required(1, "c", 
Types.LongType.get()));
+    Assertions.assertFalse(
+        CatalogWrapperForREST.shouldApplyMetadataUpdateAfterBuilder(
+            new MetadataUpdate.AddSchema(schema)));
+    Assertions.assertFalse(
+        CatalogWrapperForREST.shouldApplyMetadataUpdateAfterBuilder(
+            new MetadataUpdate.UpgradeFormatVersion(2)));
+    Assertions.assertFalse(
+        CatalogWrapperForREST.shouldApplyMetadataUpdateAfterBuilder(
+            new MetadataUpdate.SetCurrentSchema(-1)));
+    Assertions.assertFalse(
+        CatalogWrapperForREST.shouldApplyMetadataUpdateAfterBuilder(
+            new MetadataUpdate.SetLocation("file:///tmp/loc")));
+    Assertions.assertFalse(
+        CatalogWrapperForREST.shouldApplyMetadataUpdateAfterBuilder(
+            new MetadataUpdate.SetProperties(ImmutableMap.of("k", "v"))));
+    Assertions.assertFalse(
+        CatalogWrapperForREST.shouldApplyMetadataUpdateAfterBuilder(
+            new MetadataUpdate.RemoveProperties(Collections.singleton("k"))));
+    Assertions.assertFalse(
+        CatalogWrapperForREST.shouldApplyMetadataUpdateAfterBuilder(
+            new 
MetadataUpdate.AddPartitionSpec(PartitionSpec.unpartitioned())));
+    Assertions.assertFalse(
+        CatalogWrapperForREST.shouldApplyMetadataUpdateAfterBuilder(
+            new 
MetadataUpdate.SetDefaultPartitionSpec(PartitionSpec.unpartitioned().specId())));
+    Assertions.assertFalse(
+        CatalogWrapperForREST.shouldApplyMetadataUpdateAfterBuilder(
+            new MetadataUpdate.AddSortOrder(SortOrder.unsorted())));
+    Assertions.assertFalse(
+        CatalogWrapperForREST.shouldApplyMetadataUpdateAfterBuilder(
+            new 
MetadataUpdate.SetDefaultSortOrder(SortOrder.unsorted().orderId())));
+  }
+
+  @Test
+  void testPostBuilderMetadataAllowsAssignUuid() {
+    Assertions.assertTrue(
+        CatalogWrapperForREST.shouldApplyMetadataUpdateAfterBuilder(
+            new MetadataUpdate.AssignUUID(UUID.randomUUID().toString())));
+  }
+
+  @Test
+  void testStagedCreateBuilderUsesDerivedMetadataV3() {
+    RESTCatalog catalog = mock(RESTCatalog.class);
+    Catalog.TableBuilder tableBuilder = mock(Catalog.TableBuilder.class);
+    BaseTransaction baseTransaction = mock(BaseTransaction.class);
+    TableOperations ops = mock(TableOperations.class);
+    when(catalog.buildTable(any(TableIdentifier.class), any(Schema.class)))
+        .thenReturn(tableBuilder);
+    when(tableBuilder.withPartitionSpec(any())).thenReturn(tableBuilder);
+    when(tableBuilder.withSortOrder(any())).thenReturn(tableBuilder);
+    when(tableBuilder.withLocation(any())).thenReturn(tableBuilder);
+    when(tableBuilder.withProperties(any())).thenReturn(tableBuilder);
+    
when(tableBuilder.createOrReplaceTransaction()).thenReturn(baseTransaction);
+    when(baseTransaction.underlyingOps()).thenReturn(ops);
+    
when(baseTransaction.currentMetadata()).thenReturn(minimalTableMetadataForStagedCreateTest());
+
+    AtomicReference<TableMetadata> opsCurrent = new AtomicReference<>();
+    when(ops.current()).thenAnswer(invocation -> opsCurrent.get());
+    doAnswer(
+            invocation -> {
+              opsCurrent.set(invocation.getArgument(1));
+              return null;
+            })
+        .when(ops)
+        .commit(any(), any());
+
+    IcebergConfig config =
+        new IcebergConfig(
+            ImmutableMap.of(
+                IcebergConstants.CATALOG_BACKEND,
+                "memory",
+                IcebergConstants.WAREHOUSE,
+                "/tmp/warehouse"));
+    CatalogWrapperForREST wrapper = new StaticCatalogWrapperForREST("test", 
config, catalog);
+
+    Schema schema = new Schema(Types.NestedField.required(1, "id", 
Types.IntegerType.get()));
+    UpdateTableRequest request =
+        new UpdateTableRequest(
+            List.of(new UpdateRequirement.AssertTableDoesNotExist()),
+            stagedCreateMetadataUpdates(schema, Optional.of(3)));
+
+    Assertions.assertDoesNotThrow(
+        () -> wrapper.updateTable(TableIdentifier.of("db", "tbl"), request));
+
+    verify(tableBuilder).withPartitionSpec(any());
+    verify(tableBuilder).withSortOrder(any());
+    verify(tableBuilder).withProperties(any());
+    verify(tableBuilder, never()).withProperty(anyString(), anyString());
+    verify(tableBuilder).createOrReplaceTransaction();
+  }
+
+  @Test
+  void testStagedCreateOmitsFormatWithProperty() {
+    RESTCatalog catalog = mock(RESTCatalog.class);
+    Catalog.TableBuilder tableBuilder = mock(Catalog.TableBuilder.class);
+    BaseTransaction baseTransaction = mock(BaseTransaction.class);
+    TableOperations ops = mock(TableOperations.class);
+    when(catalog.buildTable(any(TableIdentifier.class), any(Schema.class)))
+        .thenReturn(tableBuilder);
+    when(tableBuilder.withPartitionSpec(any())).thenReturn(tableBuilder);
+    when(tableBuilder.withSortOrder(any())).thenReturn(tableBuilder);
+    when(tableBuilder.withLocation(any())).thenReturn(tableBuilder);
+    when(tableBuilder.withProperties(any())).thenReturn(tableBuilder);
+    
when(tableBuilder.createOrReplaceTransaction()).thenReturn(baseTransaction);
+    when(baseTransaction.underlyingOps()).thenReturn(ops);
+    
when(baseTransaction.currentMetadata()).thenReturn(minimalTableMetadataForStagedCreateTest());
+
+    AtomicReference<TableMetadata> opsCurrent = new AtomicReference<>();
+    when(ops.current()).thenAnswer(invocation -> opsCurrent.get());
+    doAnswer(
+            invocation -> {
+              opsCurrent.set(invocation.getArgument(1));
+              return null;
+            })
+        .when(ops)
+        .commit(any(), any());
+
+    IcebergConfig config =
+        new IcebergConfig(
+            ImmutableMap.of(
+                IcebergConstants.CATALOG_BACKEND,
+                "memory",
+                IcebergConstants.WAREHOUSE,
+                "/tmp/warehouse"));
+    CatalogWrapperForREST wrapper = new StaticCatalogWrapperForREST("test", 
config, catalog);
+
+    Schema schema = new Schema(Types.NestedField.required(1, "id", 
Types.IntegerType.get()));
+    UpdateTableRequest request =
+        new UpdateTableRequest(
+            List.of(new UpdateRequirement.AssertTableDoesNotExist()),
+            stagedCreateMetadataUpdates(schema, Optional.empty()));
+
+    Assertions.assertDoesNotThrow(
+        () -> wrapper.updateTable(TableIdentifier.of("db", "tbl"), request));
+
+    verify(tableBuilder, never()).withProperty(anyString(), anyString());
+  }
+
+  /**
+   * Minimal valid Iceberg staged-create update sequence so {@link 
TableMetadata.Builder#build()}
+   * succeeds in {@link CatalogWrapperForREST#tableUpdateInternal}.
+   */
+  private static List<MetadataUpdate> stagedCreateMetadataUpdates(
+      Schema schema, Optional<Integer> formatVersion) {
+    List<MetadataUpdate> updates = new ArrayList<>();
+    updates.add(new MetadataUpdate.AssignUUID(UUID.randomUUID().toString()));
+    formatVersion.ifPresent(v -> updates.add(new 
MetadataUpdate.UpgradeFormatVersion(v)));
+    updates.add(new MetadataUpdate.AddSchema(schema));
+    updates.add(new MetadataUpdate.SetCurrentSchema(-1));
+    PartitionSpec spec = PartitionSpec.unpartitioned();
+    updates.add(new MetadataUpdate.AddPartitionSpec(spec));
+    updates.add(new MetadataUpdate.SetDefaultPartitionSpec(spec.specId()));
+    SortOrder sortOrder = SortOrder.unsorted();
+    updates.add(new MetadataUpdate.AddSortOrder(sortOrder));
+    updates.add(new MetadataUpdate.SetDefaultSortOrder(sortOrder.orderId()));
+    updates.add(new MetadataUpdate.SetLocation("file:///tmp/t"));
+    return updates;
+  }
+
+  private static TableMetadata minimalTableMetadataForStagedCreateTest() {
+    Schema schema = new Schema(Types.NestedField.required(1, "id", 
Types.IntegerType.get()));
+    return TableMetadata.newTableMetadata(
+        schema,
+        PartitionSpec.unpartitioned(),
+        SortOrder.unsorted(),
+        "file:///tmp/t",
+        Collections.emptyMap());
+  }
+
   private static class LazyCheckCatalogWrapperForREST extends 
CatalogWrapperForREST {
 
     LazyCheckCatalogWrapperForREST(String catalogName, IcebergConfig config) {

Reply via email to