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 181cee3a46 [#9414] fix(trino-connector) Add support for querying
iceberg metadata tables (#9415)
181cee3a46 is described below
commit 181cee3a46a4d8ea643b2d26e38bcd4c46d615dc
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);
+ }
+}