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

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

commit a3cc5cebdc0c619f3a1bf9f176d8994c335d73d3
Author: Joseph Perez <[email protected]>
AuthorDate: Fri Dec 12 01:15:05 2025 -0800

    [#9414] fix(trino-connector) Add support for querying iceberg metadata 
tables (#9415)
    
    <!--
    1. Title: [#<issue>] <type>(<scope>): <subject>
       Examples:
         - "[#123] feat(operator): support xxx"
         - "[#233] fix: check null before access result in xxx"
         - "[MINOR] refactor: fix typo in variable name"
         - "[MINOR] docs: fix typo in README"
         - "[#255] test: fix flaky test NameOfTheTest"
       Reference: https://www.conventionalcommits.org/en/v1.0.0/
    2. If the PR is unfinished, please mark this PR as draft.
    -->
    
    ### What changes were proposed in this pull request?
    
    Added `getSystemTable()` override in `GravitinoMetadata` to delegate
    system table lookups to internal connector. This enables querying
    Iceberg metadata tables like `$snapshots` and `$manifests`, with trino
    connector.
    
    ### Why are the changes needed?
    
    For a bug fix - as of right now iceberg metadata tables are not
    queryable with the gravitino trino connector.
    
    Fix: #9414
    
    ### Does this PR introduce _any_ user-facing change?
    
    Yes, users will now be able to query iceberg metatables.
    
    ### How was this patch tested?
    
    Without fix, unit test fails:
    ```
    TestGravitinoMetadataGetSystemTable > 
testGetSystemTableDelegatesToInternalMetadata() FAILED
        org.opentest4j.AssertionFailedError: expected: <true> but was: <false>
            at 
app//org.junit.jupiter.api.AssertionFailureBuilder.build(AssertionFailureBuilder.java:151)
            at 
app//org.junit.jupiter.api.AssertionFailureBuilder.buildAndThrow(AssertionFailureBuilder.java:132)
            at 
app//org.junit.jupiter.api.AssertTrue.failNotTrue(AssertTrue.java:63)
            at 
app//org.junit.jupiter.api.AssertTrue.assertTrue(AssertTrue.java:36)
            at 
app//org.junit.jupiter.api.AssertTrue.assertTrue(AssertTrue.java:31)
            at 
app//org.junit.jupiter.api.Assertions.assertTrue(Assertions.java:179)
            at 
app//org.apache.gravitino.trino.connector.TestGravitinoMetadataGetSystemTable.testGetSystemTableDelegatesToInternalMetadata(TestGravitinoMetadataGetSystemTable.java:58)
    ```
    
    Also, made a targz of the change with ```./gradlew
    assembleTrinoConnector ``` and added trino deployment, then querying
    snapshots worked.
    
    ---------
    
    Co-authored-by: Yuhui <[email protected]>
---
 .../lakehouse-iceberg/00012_system_tables.sql      | 38 ++++++++++
 .../lakehouse-iceberg/00012_system_tables.txt      | 13 ++++
 .../trino/connector/GravitinoMetadata.java         |  6 ++
 .../TestGravitinoMetadataGetSystemTable.java       | 83 ++++++++++++++++++++++
 4 files changed, 140 insertions(+)

diff --git 
a/trino-connector/integration-test/src/test/resources/trino-ci-testset/testsets/lakehouse-iceberg/00012_system_tables.sql
 
b/trino-connector/integration-test/src/test/resources/trino-ci-testset/testsets/lakehouse-iceberg/00012_system_tables.sql
new file mode 100644
index 0000000000..9e4f286c15
--- /dev/null
+++ 
b/trino-connector/integration-test/src/test/resources/trino-ci-testset/testsets/lakehouse-iceberg/00012_system_tables.sql
@@ -0,0 +1,38 @@
+-- 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.
+
+-- Test Iceberg system tables are accessible through Gravitino connector
+
+CREATE SCHEMA IF NOT EXISTS gt_system_test;
+
+CREATE TABLE gt_system_test.test_table (
+    id int,
+    name varchar
+);
+
+INSERT INTO gt_system_test.test_table VALUES (1, 'test');
+
+-- Query $snapshots system table - should have at least 1 snapshot from INSERT
+SELECT count(*) >= 1 FROM "gt_system_test"."test_table$snapshots";
+
+-- Query $history system table - should have at least 1 history entry
+SELECT count(*) >= 1 FROM "gt_system_test"."test_table$history";
+
+-- Cleanup
+DROP TABLE gt_system_test.test_table;
+
+DROP SCHEMA gt_system_test;
diff --git 
a/trino-connector/integration-test/src/test/resources/trino-ci-testset/testsets/lakehouse-iceberg/00012_system_tables.txt
 
b/trino-connector/integration-test/src/test/resources/trino-ci-testset/testsets/lakehouse-iceberg/00012_system_tables.txt
new file mode 100644
index 0000000000..5c492839a2
--- /dev/null
+++ 
b/trino-connector/integration-test/src/test/resources/trino-ci-testset/testsets/lakehouse-iceberg/00012_system_tables.txt
@@ -0,0 +1,13 @@
+CREATE SCHEMA
+
+CREATE TABLE
+
+INSERT: 1 row
+
+"true"
+
+"true"
+
+DROP TABLE
+
+DROP SCHEMA
diff --git 
a/trino-connector/trino-connector/src/main/java/org/apache/gravitino/trino/connector/GravitinoMetadata.java
 
b/trino-connector/trino-connector/src/main/java/org/apache/gravitino/trino/connector/GravitinoMetadata.java
index 36ad9bcdf4..eadb9d5bde 100644
--- 
a/trino-connector/trino-connector/src/main/java/org/apache/gravitino/trino/connector/GravitinoMetadata.java
+++ 
b/trino-connector/trino-connector/src/main/java/org/apache/gravitino/trino/connector/GravitinoMetadata.java
@@ -52,6 +52,7 @@ import io.trino.spi.connector.RowChangeParadigm;
 import io.trino.spi.connector.SaveMode;
 import io.trino.spi.connector.SchemaTableName;
 import io.trino.spi.connector.SortItem;
+import io.trino.spi.connector.SystemTable;
 import io.trino.spi.connector.TopNApplicationResult;
 import io.trino.spi.expression.ConnectorExpression;
 import io.trino.spi.expression.Constant;
@@ -152,6 +153,11 @@ public class GravitinoMetadata implements 
ConnectorMetadata {
     return metadataAdapter.getTableMetadata(table);
   }
 
+  @Override
+  public Optional<SystemTable> getSystemTable(ConnectorSession session, 
SchemaTableName tableName) {
+    return internalMetadata.getSystemTable(session, tableName);
+  }
+
   @Override
   public SchemaTableName getTableName(ConnectorSession session, 
ConnectorTableHandle table) {
     return getTableName(table);
diff --git 
a/trino-connector/trino-connector/src/test/java/org/apache/gravitino/trino/connector/TestGravitinoMetadataGetSystemTable.java
 
b/trino-connector/trino-connector/src/test/java/org/apache/gravitino/trino/connector/TestGravitinoMetadataGetSystemTable.java
new file mode 100644
index 0000000000..cfd846b05b
--- /dev/null
+++ 
b/trino-connector/trino-connector/src/test/java/org/apache/gravitino/trino/connector/TestGravitinoMetadataGetSystemTable.java
@@ -0,0 +1,83 @@
+/*
+ * 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.trino.connector;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertFalse;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import io.trino.spi.connector.ConnectorMetadata;
+import io.trino.spi.connector.ConnectorSession;
+import io.trino.spi.connector.SchemaTableName;
+import io.trino.spi.connector.SystemTable;
+import java.util.Optional;
+import org.apache.gravitino.trino.connector.catalog.CatalogConnectorMetadata;
+import 
org.apache.gravitino.trino.connector.catalog.CatalogConnectorMetadataAdapter;
+import org.junit.jupiter.api.Test;
+
+public class TestGravitinoMetadataGetSystemTable {
+
+  @Test
+  public void testGetSystemTableDelegatesToInternalMetadata() {
+    CatalogConnectorMetadata catalogConnectorMetadata = 
mock(CatalogConnectorMetadata.class);
+    CatalogConnectorMetadataAdapter metadataAdapter = 
mock(CatalogConnectorMetadataAdapter.class);
+    ConnectorMetadata internalMetadata = mock(ConnectorMetadata.class);
+    ConnectorSession session = mock(ConnectorSession.class);
+
+    SystemTable mockSystemTable = mock(SystemTable.class);
+    SchemaTableName tableName = new SchemaTableName("test_schema", 
"test_table$snapshots");
+
+    when(internalMetadata.getSystemTable(any(ConnectorSession.class), 
any(SchemaTableName.class)))
+        .thenReturn(Optional.of(mockSystemTable));
+
+    GravitinoMetadata gravitinoMetadata =
+        new GravitinoMetadata(catalogConnectorMetadata, metadataAdapter, 
internalMetadata);
+
+    Optional<SystemTable> result = gravitinoMetadata.getSystemTable(session, 
tableName);
+
+    assertTrue(result.isPresent());
+    assertEquals(mockSystemTable, result.get());
+    verify(internalMetadata).getSystemTable(session, tableName);
+  }
+
+  @Test
+  public void testGetSystemTableReturnsEmptyWhenInternalReturnsEmpty() {
+    CatalogConnectorMetadata catalogConnectorMetadata = 
mock(CatalogConnectorMetadata.class);
+    CatalogConnectorMetadataAdapter metadataAdapter = 
mock(CatalogConnectorMetadataAdapter.class);
+    ConnectorMetadata internalMetadata = mock(ConnectorMetadata.class);
+    ConnectorSession session = mock(ConnectorSession.class);
+
+    SchemaTableName tableName = new SchemaTableName("test_schema", 
"test_table$invalid");
+
+    when(internalMetadata.getSystemTable(any(ConnectorSession.class), 
any(SchemaTableName.class)))
+        .thenReturn(Optional.empty());
+
+    GravitinoMetadata gravitinoMetadata =
+        new GravitinoMetadata(catalogConnectorMetadata, metadataAdapter, 
internalMetadata);
+
+    Optional<SystemTable> result = gravitinoMetadata.getSystemTable(session, 
tableName);
+
+    assertFalse(result.isPresent());
+    verify(internalMetadata).getSystemTable(session, tableName);
+  }
+}

Reply via email to