diff --git a/client/trino-jdbc/src/test/java/io/trino/jdbc/TestTrinoDatabaseMetaData.java b/client/trino-jdbc/src/test/java/io/trino/jdbc/TestTrinoDatabaseMetaData.java index 7ce476f211a2..02aace812e5d 100644 --- a/client/trino-jdbc/src/test/java/io/trino/jdbc/TestTrinoDatabaseMetaData.java +++ b/client/trino-jdbc/src/test/java/io/trino/jdbc/TestTrinoDatabaseMetaData.java @@ -1116,8 +1116,7 @@ public void testGetTablesMetadataCalls() databaseMetaData -> databaseMetaData.getTables(null, null, null, null), list("TABLE_CAT", "TABLE_SCHEM", "TABLE_NAME", "TABLE_TYPE")), ImmutableMultiset.builder() - .add("ConnectorMetadata.listViews") - .add("ConnectorMetadata.listTables") + .add("ConnectorMetadata.getRelationTypes") .build()); // Equality predicate on catalog name @@ -1127,8 +1126,7 @@ public void testGetTablesMetadataCalls() databaseMetaData -> databaseMetaData.getTables(COUNTING_CATALOG, null, null, null), list("TABLE_CAT", "TABLE_SCHEM", "TABLE_NAME", "TABLE_TYPE")), ImmutableMultiset.builder() - .add("ConnectorMetadata.listViews") - .add("ConnectorMetadata.listTables") + .add("ConnectorMetadata.getRelationTypes") .build()); // Equality predicate on schema name @@ -1142,8 +1140,7 @@ public void testGetTablesMetadataCalls() .map(schemaTableName -> list(COUNTING_CATALOG, schemaTableName.getSchemaName(), schemaTableName.getTableName(), "TABLE")) .collect(toImmutableList()), ImmutableMultiset.builder() - .add("ConnectorMetadata.listViews(schema=test_schema1)") - .add("ConnectorMetadata.listTables(schema=test_schema1)") + .add("ConnectorMetadata.getRelationTypes(schema=test_schema1)") .build()); // LIKE predicate on schema name @@ -1157,8 +1154,7 @@ public void testGetTablesMetadataCalls() .map(schemaTableName -> list(COUNTING_CATALOG, schemaTableName.getSchemaName(), schemaTableName.getTableName(), "TABLE")) .collect(toImmutableList()), ImmutableMultiset.builder() - .add("ConnectorMetadata.listViews") - .add("ConnectorMetadata.listTables") + .add("ConnectorMetadata.getRelationTypes") .build()); // Equality predicate on table name @@ -1171,8 +1167,7 @@ public void testGetTablesMetadataCalls() list(COUNTING_CATALOG, "test_schema1", "test_table1", "TABLE"), list(COUNTING_CATALOG, "test_schema2", "test_table1", "TABLE")), ImmutableMultiset.builder() - .add("ConnectorMetadata.listViews") - .add("ConnectorMetadata.listTables") + .add("ConnectorMetadata.getRelationTypes") .build()); // LIKE predicate on table name @@ -1185,8 +1180,7 @@ public void testGetTablesMetadataCalls() list(COUNTING_CATALOG, "test_schema1", "test_table1", "TABLE"), list(COUNTING_CATALOG, "test_schema2", "test_table1", "TABLE")), ImmutableMultiset.builder() - .add("ConnectorMetadata.listViews") - .add("ConnectorMetadata.listTables") + .add("ConnectorMetadata.getRelationTypes") .build()); // Equality predicate on schema name and table name @@ -1197,8 +1191,8 @@ public void testGetTablesMetadataCalls() list("TABLE_CAT", "TABLE_SCHEM", "TABLE_NAME", "TABLE_TYPE")), list(list(COUNTING_CATALOG, "test_schema1", "test_table1", "TABLE")), ImmutableMultiset.builder() - .addCopies("ConnectorMetadata.getSystemTable(schema=test_schema1, table=test_table1)", 5) - .addCopies("ConnectorMetadata.getView(schema=test_schema1, table=test_table1)", 2) + .addCopies("ConnectorMetadata.getSystemTable(schema=test_schema1, table=test_table1)", 4) + .add("ConnectorMetadata.getView(schema=test_schema1, table=test_table1)") .add("ConnectorMetadata.getMaterializedView(schema=test_schema1, table=test_table1)") .add("ConnectorMetadata.redirectTable(schema=test_schema1, table=test_table1)") .add("ConnectorMetadata.getTableHandle(schema=test_schema1, table=test_table1)") @@ -1212,8 +1206,7 @@ public void testGetTablesMetadataCalls() list("TABLE_CAT", "TABLE_SCHEM", "TABLE_NAME", "TABLE_TYPE")), list(list(COUNTING_CATALOG, "test_schema1", "test_table1", "TABLE")), ImmutableMultiset.builder() - .add("ConnectorMetadata.listViews") - .add("ConnectorMetadata.listTables") + .add("ConnectorMetadata.getRelationTypes") .build()); // catalog does not exist @@ -1337,7 +1330,7 @@ public void testGetColumnsMetadataCalls() list(list(COUNTING_CATALOG, "test_schema1", "test_table1", "column_17", "varchar")), ImmutableMultiset.builder() .add("ConnectorMetadata.listSchemaNames") - .add("ConnectorMetadata.listTables(schema=test_schema1)") + .add("ConnectorMetadata.listRelations(schema=test_schema1)") .addCopies("ConnectorMetadata.getSystemTable(schema=test_schema1, table=test_table1)", 4) .add("ConnectorMetadata.getMaterializedView(schema=test_schema1, table=test_table1)") .add("ConnectorMetadata.getView(schema=test_schema1, table=test_table1)") @@ -1357,7 +1350,7 @@ public void testGetColumnsMetadataCalls() .collect(toImmutableList()), ImmutableMultiset.builder() .add("ConnectorMetadata.listSchemaNames") - .add("ConnectorMetadata.listTables(schema=test_schema1)") + .add("ConnectorMetadata.listRelations(schema=test_schema1)") .addCopies("ConnectorMetadata.getSystemTable(schema=test_schema1, table=test_table1)", 4) .add("ConnectorMetadata.getMaterializedView(schema=test_schema1, table=test_table1)") .add("ConnectorMetadata.getView(schema=test_schema1, table=test_table1)") @@ -1395,10 +1388,10 @@ public void testGetColumnsMetadataCalls() .collect(toImmutableList()), ImmutableMultiset.builder() .addCopies("ConnectorMetadata.listSchemaNames", 5) - .add("ConnectorMetadata.listTables(schema=test_schema1)") - .add("ConnectorMetadata.listTables(schema=test_schema2)") - .add("ConnectorMetadata.listTables(schema=test_schema3_empty)") - .add("ConnectorMetadata.listTables(schema=test_schema4_empty)") + .add("ConnectorMetadata.listRelations(schema=test_schema1)") + .add("ConnectorMetadata.listRelations(schema=test_schema2)") + .add("ConnectorMetadata.listRelations(schema=test_schema3_empty)") + .add("ConnectorMetadata.listRelations(schema=test_schema4_empty)") .addCopies("ConnectorMetadata.getSystemTable(schema=test_schema1, table=test_table1)", 20) .addCopies("ConnectorMetadata.getMaterializedView(schema=test_schema1, table=test_table1)", 5) .addCopies("ConnectorMetadata.getView(schema=test_schema1, table=test_table1)", 5) @@ -1530,8 +1523,7 @@ private void testAssumeLiteralMetadataCalls(String escapeLiteralParameter) .map(schemaTableName -> list(COUNTING_CATALOG, schemaTableName.getSchemaName(), schemaTableName.getTableName(), "TABLE")) .collect(toImmutableList()), ImmutableMultiset.builder() - .add("ConnectorMetadata.listViews(schema=test_schema1)") - .add("ConnectorMetadata.listTables(schema=test_schema1)") + .add("ConnectorMetadata.getRelationTypes(schema=test_schema1)") .build()); // getTables's schema and table name patterns treated as literals @@ -1542,8 +1534,8 @@ private void testAssumeLiteralMetadataCalls(String escapeLiteralParameter) list("TABLE_CAT", "TABLE_SCHEM", "TABLE_NAME", "TABLE_TYPE")), list(list(COUNTING_CATALOG, "test_schema1", "test_table1", "TABLE")), ImmutableMultiset.builder() - .addCopies("ConnectorMetadata.getSystemTable(schema=test_schema1, table=test_table1)", 5) - .addCopies("ConnectorMetadata.getView(schema=test_schema1, table=test_table1)", 2) + .addCopies("ConnectorMetadata.getSystemTable(schema=test_schema1, table=test_table1)", 4) + .add("ConnectorMetadata.getView(schema=test_schema1, table=test_table1)") .add("ConnectorMetadata.getMaterializedView(schema=test_schema1, table=test_table1)") .add("ConnectorMetadata.redirectTable(schema=test_schema1, table=test_table1)") .add("ConnectorMetadata.getTableHandle(schema=test_schema1, table=test_table1)") @@ -1557,8 +1549,7 @@ private void testAssumeLiteralMetadataCalls(String escapeLiteralParameter) list("TABLE_CAT", "TABLE_SCHEM", "TABLE_NAME", "TABLE_TYPE")), list(), ImmutableMultiset.builder() - .add("ConnectorMetadata.listViews(schema=test_schema_)") - .add("ConnectorMetadata.listTables(schema=test_schema_)") + .add("ConnectorMetadata.getRelationTypes(schema=test_schema_)") .build()); // getColumns's schema and table name patterns treated as literals diff --git a/core/trino-main/src/main/java/io/trino/connector/informationschema/InformationSchemaMetadata.java b/core/trino-main/src/main/java/io/trino/connector/informationschema/InformationSchemaMetadata.java index 14c8bea286c7..e42bf358eb06 100644 --- a/core/trino-main/src/main/java/io/trino/connector/informationschema/InformationSchemaMetadata.java +++ b/core/trino-main/src/main/java/io/trino/connector/informationschema/InformationSchemaMetadata.java @@ -299,7 +299,7 @@ private Set calculatePrefixesWithTableName( } Set tablePrefixes = prefixes.stream() - .flatMap(prefix -> metadata.listTables(session, prefix).stream()) + .flatMap(prefix -> metadata.listRelations(session, prefix).stream()) .filter(objectName -> predicate.get().test(asFixedValues(objectName))) .map(QualifiedObjectName::asQualifiedTablePrefix) .distinct() diff --git a/core/trino-main/src/main/java/io/trino/connector/informationschema/InformationSchemaPageSource.java b/core/trino-main/src/main/java/io/trino/connector/informationschema/InformationSchemaPageSource.java index 521369d5c7cc..f5ae8574272b 100644 --- a/core/trino-main/src/main/java/io/trino/connector/informationschema/InformationSchemaPageSource.java +++ b/core/trino-main/src/main/java/io/trino/connector/informationschema/InformationSchemaPageSource.java @@ -26,6 +26,7 @@ import io.trino.spi.connector.ColumnHandle; import io.trino.spi.connector.ColumnMetadata; import io.trino.spi.connector.ConnectorPageSource; +import io.trino.spi.connector.RelationType; import io.trino.spi.connector.SchemaTableName; import io.trino.spi.security.AccessDeniedException; import io.trino.spi.security.GrantInfo; @@ -37,6 +38,7 @@ import java.util.Iterator; import java.util.List; import java.util.Map; +import java.util.Map.Entry; import java.util.Optional; import java.util.OptionalLong; import java.util.Queue; @@ -52,12 +54,12 @@ import static io.trino.SystemSessionProperties.isOmitDateTimeTypePrecision; import static io.trino.connector.informationschema.InformationSchemaMetadata.defaultPrefixes; import static io.trino.connector.informationschema.InformationSchemaMetadata.isTablesEnumeratingTable; +import static io.trino.metadata.MetadataListing.getRelationTypes; import static io.trino.metadata.MetadataListing.getViews; +import static io.trino.metadata.MetadataListing.listRelations; import static io.trino.metadata.MetadataListing.listSchemas; import static io.trino.metadata.MetadataListing.listTableColumns; import static io.trino.metadata.MetadataListing.listTablePrivileges; -import static io.trino.metadata.MetadataListing.listTables; -import static io.trino.metadata.MetadataListing.listViews; import static io.trino.spi.security.PrincipalType.USER; import static io.trino.spi.type.TypeUtils.writeNativeValue; import static io.trino.type.TypeUtils.getDisplayLabel; @@ -245,7 +247,7 @@ private void buildPages() private void addColumnsRecords(QualifiedTablePrefix prefix) { - for (Map.Entry> entry : listTableColumns(session, metadata, accessControl, prefix).entrySet()) { + for (Entry> entry : listTableColumns(session, metadata, accessControl, prefix).entrySet()) { SchemaTableName tableName = entry.getKey(); long ordinalPosition = 1; @@ -275,16 +277,24 @@ private void addColumnsRecords(QualifiedTablePrefix prefix) private void addTablesRecords(QualifiedTablePrefix prefix) { - Set tables = listTables(session, metadata, accessControl, prefix); boolean needsTableType = requiredColumns.contains("table_type"); - Set views = Set.of(); + Set relations; + Set views; if (needsTableType) { - // TODO introduce a dedicated method for getting relations with their type from the connector, instead of calling (potentially much more expensive) getViews - views = listViews(session, metadata, accessControl, prefix); + Map relationTypes = getRelationTypes(session, metadata, accessControl, prefix); + relations = relationTypes.keySet(); + views = relationTypes.entrySet().stream() + .filter(entry -> entry.getValue() == RelationType.VIEW) + .map(Entry::getKey) + .collect(toImmutableSet()); + } + else { + relations = listRelations(session, metadata, accessControl, prefix); + views = Set.of(); } // TODO (https://github.com/trinodb/trino/issues/8207) define a type for materialized views - for (SchemaTableName name : tables) { + for (SchemaTableName name : relations) { String type = null; if (needsTableType) { // if table and view names overlap, the view wins @@ -304,7 +314,7 @@ private void addTablesRecords(QualifiedTablePrefix prefix) private void addViewsRecords(QualifiedTablePrefix prefix) { - for (Map.Entry entry : getViews(session, metadata, accessControl, prefix).entrySet()) { + for (Entry entry : getViews(session, metadata, accessControl, prefix).entrySet()) { addRecord( prefix.getCatalogName(), entry.getKey().getSchemaName(), diff --git a/core/trino-main/src/main/java/io/trino/connector/system/jdbc/ColumnJdbcTable.java b/core/trino-main/src/main/java/io/trino/connector/system/jdbc/ColumnJdbcTable.java index 6913e9152ca4..257775c4d151 100644 --- a/core/trino-main/src/main/java/io/trino/connector/system/jdbc/ColumnJdbcTable.java +++ b/core/trino-main/src/main/java/io/trino/connector/system/jdbc/ColumnJdbcTable.java @@ -69,9 +69,9 @@ import static io.trino.connector.system.jdbc.FilterUtil.tablePrefix; import static io.trino.connector.system.jdbc.FilterUtil.tryGetSingleVarcharValue; import static io.trino.metadata.MetadataListing.listCatalogNames; +import static io.trino.metadata.MetadataListing.listRelations; import static io.trino.metadata.MetadataListing.listSchemas; import static io.trino.metadata.MetadataListing.listTableColumns; -import static io.trino.metadata.MetadataListing.listTables; import static io.trino.metadata.MetadataUtil.TableMetadataBuilder.tableMetadataBuilder; import static io.trino.spi.type.BigintType.BIGINT; import static io.trino.spi.type.BooleanType.BOOLEAN; @@ -211,7 +211,7 @@ TABLE_SCHEMA_COLUMN, toNullableValue(schemaName)))) QualifiedTablePrefix tablePrefix = tableFilter.isPresent() ? new QualifiedTablePrefix(schema.getCatalogName(), schema.getSchemaName(), tableFilter.get()) : new QualifiedTablePrefix(schema.getCatalogName(), schema.getSchemaName()); - return listTables(session, metadata, accessControl, tablePrefix).stream() + return listRelations(session, metadata, accessControl, tablePrefix).stream() .filter(schemaTableName -> predicate.test(ImmutableMap.of( TABLE_CATALOG_COLUMN, toNullableValue(schema.getCatalogName()), TABLE_SCHEMA_COLUMN, toNullableValue(schemaTableName.getSchemaName()), @@ -278,7 +278,7 @@ public RecordCursor cursor(ConnectorTransactionHandle transactionHandle, Connect QualifiedTablePrefix tablePrefix = tableFilter.isPresent() ? new QualifiedTablePrefix(catalog, schema, tableFilter.get()) : new QualifiedTablePrefix(catalog, schema); - Set tables = listTables(session, metadata, accessControl, tablePrefix); + Set tables = listRelations(session, metadata, accessControl, tablePrefix); for (SchemaTableName schemaTableName : tables) { String tableName = schemaTableName.getTableName(); if (!tableDomain.includesNullableValue(utf8Slice(tableName))) { diff --git a/core/trino-main/src/main/java/io/trino/connector/system/jdbc/TableJdbcTable.java b/core/trino-main/src/main/java/io/trino/connector/system/jdbc/TableJdbcTable.java index 320172490d1f..45413ef690b5 100644 --- a/core/trino-main/src/main/java/io/trino/connector/system/jdbc/TableJdbcTable.java +++ b/core/trino-main/src/main/java/io/trino/connector/system/jdbc/TableJdbcTable.java @@ -26,19 +26,18 @@ import io.trino.spi.connector.InMemoryRecordSet; import io.trino.spi.connector.InMemoryRecordSet.Builder; import io.trino.spi.connector.RecordCursor; +import io.trino.spi.connector.RelationType; import io.trino.spi.connector.SchemaTableName; import io.trino.spi.predicate.Domain; import io.trino.spi.predicate.TupleDomain; import java.util.Optional; -import java.util.Set; import static io.trino.connector.system.jdbc.FilterUtil.isImpossibleObjectName; import static io.trino.connector.system.jdbc.FilterUtil.tablePrefix; import static io.trino.connector.system.jdbc.FilterUtil.tryGetSingleVarcharValue; +import static io.trino.metadata.MetadataListing.getRelationTypes; import static io.trino.metadata.MetadataListing.listCatalogNames; -import static io.trino.metadata.MetadataListing.listTables; -import static io.trino.metadata.MetadataListing.listViews; import static io.trino.metadata.MetadataUtil.TableMetadataBuilder.tableMetadataBuilder; import static io.trino.spi.type.VarcharType.VARCHAR; import static java.util.Objects.requireNonNull; @@ -104,13 +103,12 @@ public RecordCursor cursor(ConnectorTransactionHandle transactionHandle, Connect for (String catalog : listCatalogNames(session, metadata, accessControl, catalogDomain)) { QualifiedTablePrefix prefix = tablePrefix(catalog, schemaFilter, tableFilter); - Set views = listViews(session, metadata, accessControl, prefix); - for (SchemaTableName name : listTables(session, metadata, accessControl, prefix)) { - boolean isView = views.contains(name); + getRelationTypes(session, metadata, accessControl, prefix).forEach((name, type) -> { + boolean isView = type == RelationType.VIEW; if ((includeTables && !isView) || (includeViews && isView)) { table.addRow(tableRow(catalog, name, isView ? "VIEW" : "TABLE")); } - } + }); } return table.build().cursor(); } diff --git a/core/trino-main/src/main/java/io/trino/execution/DropSchemaTask.java b/core/trino-main/src/main/java/io/trino/execution/DropSchemaTask.java index 0bec8f78f543..018b66d1a082 100644 --- a/core/trino-main/src/main/java/io/trino/execution/DropSchemaTask.java +++ b/core/trino-main/src/main/java/io/trino/execution/DropSchemaTask.java @@ -86,6 +86,6 @@ private static boolean isSchemaEmpty(Session session, CatalogSchemaName schema, QualifiedTablePrefix tablePrefix = new QualifiedTablePrefix(schema.getCatalogName(), schema.getSchemaName()); // This is a best effort check that doesn't provide any guarantees against concurrent DDL operations - return metadata.listTables(session, tablePrefix).isEmpty(); + return metadata.listRelations(session, tablePrefix).isEmpty(); } } diff --git a/core/trino-main/src/main/java/io/trino/metadata/Metadata.java b/core/trino-main/src/main/java/io/trino/metadata/Metadata.java index e55b75efa63a..e64b48b8524e 100644 --- a/core/trino-main/src/main/java/io/trino/metadata/Metadata.java +++ b/core/trino-main/src/main/java/io/trino/metadata/Metadata.java @@ -37,6 +37,7 @@ import io.trino.spi.connector.MaterializedViewFreshness; import io.trino.spi.connector.ProjectionApplicationResult; import io.trino.spi.connector.RelationCommentMetadata; +import io.trino.spi.connector.RelationType; import io.trino.spi.connector.RowChangeParadigm; import io.trino.spi.connector.SampleApplicationResult; import io.trino.spi.connector.SampleType; @@ -162,7 +163,13 @@ Optional getTableHandleForExecute( * Get the relation names that match the specified table prefix (never null). * This includes all relations (e.g. tables, views, materialized views). */ - List listTables(Session session, QualifiedTablePrefix prefix); + List listRelations(Session session, QualifiedTablePrefix prefix); + + /** + * Get the relation names that match the specified table prefix (never null). + * This includes all relations (e.g. tables, views, materialized views). + */ + Map getRelationTypes(Session session, QualifiedTablePrefix prefix); /** * Gets all of the columns on the specified table, or an empty map if the columns cannot be enumerated. diff --git a/core/trino-main/src/main/java/io/trino/metadata/MetadataListing.java b/core/trino-main/src/main/java/io/trino/metadata/MetadataListing.java index f72cb857704c..3c08d405bae2 100644 --- a/core/trino-main/src/main/java/io/trino/metadata/MetadataListing.java +++ b/core/trino-main/src/main/java/io/trino/metadata/MetadataListing.java @@ -22,6 +22,7 @@ import io.trino.spi.TrinoException; import io.trino.spi.connector.CatalogHandle; import io.trino.spi.connector.ColumnMetadata; +import io.trino.spi.connector.RelationType; import io.trino.spi.connector.SchemaTableName; import io.trino.spi.connector.TableColumnsMetadata; import io.trino.spi.predicate.Domain; @@ -46,6 +47,7 @@ import static io.trino.connector.system.jdbc.FilterUtil.tryGetSingleVarcharValue; import static io.trino.spi.StandardErrorCode.GENERIC_INTERNAL_ERROR; import static io.trino.spi.StandardErrorCode.TABLE_REDIRECTION_ERROR; +import static java.util.function.Function.identity; public final class MetadataListing { @@ -111,19 +113,19 @@ private static SortedSet doListSchemas(Session session, Metadata metadat return ImmutableSortedSet.copyOf(accessControl.filterSchemas(session.toSecurityContext(), catalogName, schemaNames)); } - public static Set listTables(Session session, Metadata metadata, AccessControl accessControl, QualifiedTablePrefix prefix) + public static Set listRelations(Session session, Metadata metadata, AccessControl accessControl, QualifiedTablePrefix prefix) { try { - return doListTables(session, metadata, accessControl, prefix); + return doListRelations(session, metadata, accessControl, prefix); } catch (RuntimeException exception) { throw handleListingException(exception, "tables", prefix.getCatalogName()); } } - private static Set doListTables(Session session, Metadata metadata, AccessControl accessControl, QualifiedTablePrefix prefix) + private static Set doListRelations(Session session, Metadata metadata, AccessControl accessControl, QualifiedTablePrefix prefix) { - Set tableNames = metadata.listTables(session, prefix).stream() + Set tableNames = metadata.listRelations(session, prefix).stream() .map(QualifiedObjectName::asSchemaTableName) .collect(toImmutableSet()); @@ -133,22 +135,29 @@ private static Set doListTables(Session session, Metadata metad return accessControl.filterTables(session.toSecurityContext(), prefix.getCatalogName(), tableNames); } - public static Set listViews(Session session, Metadata metadata, AccessControl accessControl, QualifiedTablePrefix prefix) + public static Map getRelationTypes(Session session, Metadata metadata, AccessControl accessControl, QualifiedTablePrefix prefix) { try { - return doListViews(session, metadata, accessControl, prefix); + return doGetRelationTypes(session, metadata, accessControl, prefix); } catch (RuntimeException exception) { - throw handleListingException(exception, "views", prefix.getCatalogName()); + throw handleListingException(exception, "tables", prefix.getCatalogName()); } } - private static Set doListViews(Session session, Metadata metadata, AccessControl accessControl, QualifiedTablePrefix prefix) + private static Map doGetRelationTypes(Session session, Metadata metadata, AccessControl accessControl, QualifiedTablePrefix prefix) { - Set tableNames = metadata.listViews(session, prefix).stream() - .map(QualifiedObjectName::asSchemaTableName) - .collect(toImmutableSet()); - return accessControl.filterTables(session.toSecurityContext(), prefix.getCatalogName(), tableNames); + Map relationTypes = metadata.getRelationTypes(session, prefix); + + // Table listing operation only involves getting table names, but not any metadata. So redirected tables are not + // handled any differently. The target table or catalog are not involved. Thus the following filter is only called + // for the source catalog on source table names. + Set accessibleNames = accessControl.filterTables(session.toSecurityContext(), prefix.getCatalogName(), relationTypes.keySet()); + if (accessibleNames.equals(relationTypes.keySet())) { + return relationTypes; + } + return accessibleNames.stream() + .collect(toImmutableMap(identity(), relationTypes::get)); } public static Map getViews(Session session, Metadata metadata, AccessControl accessControl, QualifiedTablePrefix prefix) diff --git a/core/trino-main/src/main/java/io/trino/metadata/MetadataManager.java b/core/trino-main/src/main/java/io/trino/metadata/MetadataManager.java index 80ca50b6a120..79d09000491b 100644 --- a/core/trino-main/src/main/java/io/trino/metadata/MetadataManager.java +++ b/core/trino-main/src/main/java/io/trino/metadata/MetadataManager.java @@ -69,6 +69,7 @@ import io.trino.spi.connector.ProjectionApplicationResult; import io.trino.spi.connector.RelationColumnsMetadata; import io.trino.spi.connector.RelationCommentMetadata; +import io.trino.spi.connector.RelationType; import io.trino.spi.connector.RowChangeParadigm; import io.trino.spi.connector.SampleApplicationResult; import io.trino.spi.connector.SampleType; @@ -502,7 +503,7 @@ public ColumnMetadata getColumnMetadata(Session session, TableHandle tableHandle } @Override - public List listTables(Session session, QualifiedTablePrefix prefix) + public List listRelations(Session session, QualifiedTablePrefix prefix) { requireNonNull(prefix, "prefix is null"); if (cannotExist(prefix)) { @@ -511,14 +512,15 @@ public List listTables(Session session, QualifiedTablePrefi Optional objectName = prefix.asQualifiedObjectName(); if (objectName.isPresent()) { - Optional exists = isExistingRelationForListing(session, objectName.get()); - if (exists.isPresent()) { - return exists.get() ? ImmutableList.of(objectName.get()) : ImmutableList.of(); + Optional relationType = getRelationTypeIfExists(session, objectName.get()); + if (relationType.isPresent()) { + return ImmutableList.of(objectName.get()); } + // TODO we can probably return empty lit here } Optional catalog = getOptionalCatalogMetadata(session, prefix.getCatalogName()); - Set tables = new LinkedHashSet<>(); + Set relations = new LinkedHashSet<>(); if (catalog.isPresent()) { CatalogMetadata catalogMetadata = catalog.get(); @@ -528,34 +530,72 @@ public List listTables(Session session, QualifiedTablePrefi if (isExternalInformationSchema(catalogHandle, prefix.getSchemaName())) { continue; } - metadata.listTables(connectorSession, prefix.getSchemaName()).stream() + metadata.listRelations(connectorSession, prefix.getSchemaName()).stream() .map(convertFromSchemaTableName(prefix.getCatalogName())) .filter(table -> !isExternalInformationSchema(catalogHandle, table.getSchemaName())) - .forEach(tables::add); + .forEach(relations::add); } } - return ImmutableList.copyOf(tables); + return ImmutableList.copyOf(relations); } - private Optional isExistingRelationForListing(Session session, QualifiedObjectName name) + @Override + public Map getRelationTypes(Session session, QualifiedTablePrefix prefix) + { + requireNonNull(prefix, "prefix is null"); + if (cannotExist(prefix)) { + return ImmutableMap.of(); + } + + Optional objectName = prefix.asQualifiedObjectName(); + if (objectName.isPresent()) { + Optional relationType = getRelationTypeIfExists(session, objectName.get()); + if (relationType.isPresent()) { + return ImmutableMap.of(objectName.get().asSchemaTableName(), relationType.get()); + } + return ImmutableMap.of(); + } + + Optional catalog = getOptionalCatalogMetadata(session, prefix.getCatalogName()); + Map relationTypes = new LinkedHashMap<>(); + if (catalog.isPresent()) { + CatalogMetadata catalogMetadata = catalog.get(); + + for (CatalogHandle catalogHandle : catalogMetadata.listCatalogHandles()) { + ConnectorMetadata metadata = catalogMetadata.getMetadataFor(session, catalogHandle); + ConnectorSession connectorSession = session.toConnectorSession(catalogHandle); + if (isExternalInformationSchema(catalogHandle, prefix.getSchemaName())) { + continue; + } + metadata.getRelationTypes(connectorSession, prefix.getSchemaName()).entrySet().stream() + .filter(entry -> !isExternalInformationSchema(catalogHandle, entry.getKey().getSchemaName())) + .forEach(entry -> relationTypes.put(entry.getKey(), entry.getValue())); + } + } + return ImmutableMap.copyOf(relationTypes); + } + + private Optional getRelationTypeIfExists(Session session, QualifiedObjectName name) { if (isMaterializedView(session, name)) { - return Optional.of(true); + return Optional.of(RelationType.MATERIALIZED_VIEW); } if (isView(session, name)) { - return Optional.of(true); + return Optional.of(RelationType.VIEW); } // TODO: consider a better way to resolve relation names: https://github.com/trinodb/trino/issues/9400 try { - return Optional.of(getRedirectionAwareTableHandle(session, name).tableHandle().isPresent()); + if (getRedirectionAwareTableHandle(session, name).tableHandle().isPresent()) { + return Optional.of(RelationType.TABLE); + } + return Optional.empty(); } catch (TrinoException e) { // ignore redirection errors for consistency with listing if (e.getErrorCode().equals(TABLE_REDIRECTION_ERROR.toErrorCode())) { - return Optional.of(true); + return Optional.of(RelationType.TABLE); } - // we don't know if it exists or not return Optional.empty(); } } diff --git a/core/trino-main/src/main/java/io/trino/testing/LocalQueryRunner.java b/core/trino-main/src/main/java/io/trino/testing/LocalQueryRunner.java index b7cdd40c0839..8c3d332e58ff 100644 --- a/core/trino-main/src/main/java/io/trino/testing/LocalQueryRunner.java +++ b/core/trino-main/src/main/java/io/trino/testing/LocalQueryRunner.java @@ -810,14 +810,14 @@ public TableHandle getTableHandle(String catalogName, String schemaName, String } @Override - public List listTables(Session session, String catalog, String schema) + public List listRelations(Session session, String catalog, String schema) { lock.readLock().lock(); try { return transaction(transactionManager, plannerContext.getMetadata(), accessControl) .readOnly() .execute(session, transactionSession -> { - return getMetadata().listTables(transactionSession, new QualifiedTablePrefix(catalog, schema)); + return getMetadata().listRelations(transactionSession, new QualifiedTablePrefix(catalog, schema)); }); } finally { diff --git a/core/trino-main/src/main/java/io/trino/testing/QueryRunner.java b/core/trino-main/src/main/java/io/trino/testing/QueryRunner.java index 4d5b6edf9a52..f19576ddb478 100644 --- a/core/trino-main/src/main/java/io/trino/testing/QueryRunner.java +++ b/core/trino-main/src/main/java/io/trino/testing/QueryRunner.java @@ -93,7 +93,7 @@ default Plan createPlan(Session session, @Language("SQL") String sql) throw new UnsupportedOperationException(); } - List listTables(Session session, String catalog, String schema); + List listRelations(Session session, String catalog, String schema); boolean tableExists(Session session, String table); diff --git a/core/trino-main/src/main/java/io/trino/testing/TestingMetadata.java b/core/trino-main/src/main/java/io/trino/testing/TestingMetadata.java index 27f174bc7da5..0a197f8aeef0 100644 --- a/core/trino-main/src/main/java/io/trino/testing/TestingMetadata.java +++ b/core/trino-main/src/main/java/io/trino/testing/TestingMetadata.java @@ -127,7 +127,7 @@ public Map> listTableColumns(ConnectorSess requireNonNull(prefix, "prefix is null"); ImmutableMap.Builder> tableColumns = ImmutableMap.builder(); - for (SchemaTableName tableName : listTables(session, prefix.getSchema())) { + for (SchemaTableName tableName : listRelations(session, prefix.getSchema())) { ImmutableList.Builder columns = ImmutableList.builder(); for (ColumnMetadata column : tables.get(tableName).getColumns()) { columns.add(new ColumnMetadata(column.getName(), column.getType())); diff --git a/core/trino-main/src/main/java/io/trino/tracing/TracingConnectorMetadata.java b/core/trino-main/src/main/java/io/trino/tracing/TracingConnectorMetadata.java index df84f0eec8bd..7a182a813445 100644 --- a/core/trino-main/src/main/java/io/trino/tracing/TracingConnectorMetadata.java +++ b/core/trino-main/src/main/java/io/trino/tracing/TracingConnectorMetadata.java @@ -51,6 +51,7 @@ import io.trino.spi.connector.ProjectionApplicationResult; import io.trino.spi.connector.RelationColumnsMetadata; import io.trino.spi.connector.RelationCommentMetadata; +import io.trino.spi.connector.RelationType; import io.trino.spi.connector.RetryMode; import io.trino.spi.connector.RowChangeParadigm; import io.trino.spi.connector.SampleApplicationResult; @@ -258,6 +259,15 @@ public Optional getInfo(ConnectorTableHandle table) } } + @Override + public List listRelations(ConnectorSession session, Optional schemaName) + { + Span span = startSpan("listRelations", schemaName); + try (var ignored = scopedSpan(span)) { + return delegate.listRelations(session, schemaName); + } + } + @Override public List listTables(ConnectorSession session, Optional schemaName) { @@ -267,6 +277,15 @@ public List listTables(ConnectorSession session, Optional getRelationTypes(ConnectorSession session, Optional schemaName) + { + Span span = startSpan("getRelationTypes", schemaName); + try (var ignored = scopedSpan(span)) { + return delegate.getRelationTypes(session, schemaName); + } + } + @Override public Map getColumnHandles(ConnectorSession session, ConnectorTableHandle tableHandle) { diff --git a/core/trino-main/src/main/java/io/trino/tracing/TracingMetadata.java b/core/trino-main/src/main/java/io/trino/tracing/TracingMetadata.java index e629d9524267..56815cb7097c 100644 --- a/core/trino-main/src/main/java/io/trino/tracing/TracingMetadata.java +++ b/core/trino-main/src/main/java/io/trino/tracing/TracingMetadata.java @@ -65,6 +65,7 @@ import io.trino.spi.connector.MaterializedViewFreshness; import io.trino.spi.connector.ProjectionApplicationResult; import io.trino.spi.connector.RelationCommentMetadata; +import io.trino.spi.connector.RelationType; import io.trino.spi.connector.RowChangeParadigm; import io.trino.spi.connector.SampleApplicationResult; import io.trino.spi.connector.SampleType; @@ -309,11 +310,20 @@ public TableStatistics getTableStatistics(Session session, TableHandle tableHand } @Override - public List listTables(Session session, QualifiedTablePrefix prefix) + public List listRelations(Session session, QualifiedTablePrefix prefix) { - Span span = startSpan("listTables", prefix); + Span span = startSpan("listRelations", prefix); try (var ignored = scopedSpan(span)) { - return delegate.listTables(session, prefix); + return delegate.listRelations(session, prefix); + } + } + + @Override + public Map getRelationTypes(Session session, QualifiedTablePrefix prefix) + { + Span span = startSpan("getRelationTypes", prefix); + try (var ignored = scopedSpan(span)) { + return delegate.getRelationTypes(session, prefix); } } diff --git a/core/trino-main/src/test/java/io/trino/execution/BaseDataDefinitionTaskTest.java b/core/trino-main/src/test/java/io/trino/execution/BaseDataDefinitionTaskTest.java index 8357a4d93a30..ad63dd31b798 100644 --- a/core/trino-main/src/test/java/io/trino/execution/BaseDataDefinitionTaskTest.java +++ b/core/trino-main/src/test/java/io/trino/execution/BaseDataDefinitionTaskTest.java @@ -310,7 +310,7 @@ public void dropSchema(Session session, CatalogSchemaName schema, boolean cascad } @Override - public List listTables(Session session, QualifiedTablePrefix prefix) + public List listRelations(Session session, QualifiedTablePrefix prefix) { List tables = ImmutableList.builder() .addAll(this.tables.keySet().stream().map(table -> new QualifiedObjectName(catalogName, table.getSchemaName(), table.getTableName())).collect(toImmutableList())) diff --git a/core/trino-main/src/test/java/io/trino/metadata/AbstractMockMetadata.java b/core/trino-main/src/test/java/io/trino/metadata/AbstractMockMetadata.java index 5d9d9f27d32e..0f66b3cb4643 100644 --- a/core/trino-main/src/test/java/io/trino/metadata/AbstractMockMetadata.java +++ b/core/trino-main/src/test/java/io/trino/metadata/AbstractMockMetadata.java @@ -43,6 +43,7 @@ import io.trino.spi.connector.MaterializedViewFreshness; import io.trino.spi.connector.ProjectionApplicationResult; import io.trino.spi.connector.RelationCommentMetadata; +import io.trino.spi.connector.RelationType; import io.trino.spi.connector.RowChangeParadigm; import io.trino.spi.connector.SampleApplicationResult; import io.trino.spi.connector.SampleType; @@ -227,7 +228,13 @@ public TableStatistics getTableStatistics(Session session, TableHandle tableHand } @Override - public List listTables(Session session, QualifiedTablePrefix prefix) + public List listRelations(Session session, QualifiedTablePrefix prefix) + { + throw new UnsupportedOperationException(); + } + + @Override + public Map getRelationTypes(Session session, QualifiedTablePrefix prefix) { throw new UnsupportedOperationException(); } diff --git a/core/trino-spi/src/main/java/io/trino/spi/connector/ConnectorMetadata.java b/core/trino-spi/src/main/java/io/trino/spi/connector/ConnectorMetadata.java index 09842afe22c6..6925c3098ffd 100644 --- a/core/trino-spi/src/main/java/io/trino/spi/connector/ConnectorMetadata.java +++ b/core/trino-spi/src/main/java/io/trino/spi/connector/ConnectorMetadata.java @@ -278,6 +278,37 @@ default Optional getInfo(ConnectorTableHandle table) * @see #listViews(ConnectorSession, Optional) * @see #listMaterializedViews(ConnectorSession, Optional) */ + default List listRelations(ConnectorSession session, Optional schemaName) + { + return listTables(session, schemaName); + } + + /** + * List table, view and materialized view names, possibly filtered by schema. + */ + default Map getRelationTypes(ConnectorSession session, Optional schemaName) + { + Set materializedViews = Set.copyOf(listMaterializedViews(session, schemaName)); + Set views = Set.copyOf(listViews(session, schemaName)); + + return listRelations(session, schemaName).stream() + .collect(toMap( + identity(), + relatioNname -> { + if (materializedViews.contains(relatioNname)) { + return RelationType.MATERIALIZED_VIEW; + } + if (views.contains(relatioNname)) { + return RelationType.VIEW; + } + return RelationType.TABLE; + })); + } + + /** + * @deprecated Use {@link #listRelations(ConnectorSession, Optional)} instead. + */ + @Deprecated(forRemoval = true) default List listTables(ConnectorSession session, Optional schemaName) { return emptyList(); @@ -330,7 +361,7 @@ default Iterator streamTableColumns(ConnectorSession sessi /** * Gets columns for all relations (tables, views, materialized views), possibly filtered by schemaName. - * (e.g. for all relations that would be returned by {@link #listTables(ConnectorSession, Optional)}). + * (e.g. for all relations that would be returned by {@link #listRelations(ConnectorSession, Optional)}). * Redirected table names are included, but the comment for them is not. */ @Experimental(eta = "2024-01-01") @@ -369,7 +400,7 @@ default Iterator streamRelationColumns( /** * Gets comments for all relations (tables, views, materialized views), possibly filtered by schemaName. - * (e.g. for all relations that would be returned by {@link #listTables(ConnectorSession, Optional)}). + * (e.g. for all relations that would be returned by {@link #listRelations(ConnectorSession, Optional)}). * Redirected table names are included, but the comment for them is not. */ @Experimental(eta = "2024-01-01") @@ -389,7 +420,7 @@ default Iterator streamRelationComments(ConnectorSessio Set mvAndViewNames = Stream.concat(mvNames.stream(), views.stream().map(RelationCommentMetadata::name)) .collect(toUnmodifiableSet()); - List tables = listTables(session, schemaName).stream() + List tables = listRelations(session, schemaName).stream() .filter(tableName -> !mvAndViewNames.contains(tableName)) .collect(collectingAndThen(toUnmodifiableSet(), relationFilter)).stream() .map(tableName -> { @@ -422,7 +453,7 @@ default Iterator streamRelationComments(ConnectorSessio // getTableHandle or getTableMetadata failed call may fail if table disappeared during listing or is unsupported. Helper.juliLogger.log(Level.WARNING, e, () -> "Failed to get metadata for table: " + tableName); } - // Since the getTableHandle did not return null (i.e. succeeded or failed), we assume the table would be returned by listTables + // Since the getTableHandle did not return null (i.e. succeeded or failed), we assume the table would be returned by listRelations return RelationCommentMetadata.forRelation(tableName, Optional.empty()); } }) @@ -760,7 +791,7 @@ default ConnectorOutputTableHandle beginCreateTable(ConnectorSession session, Co /** * Begin the atomic creation of a table with data. - * + *

*

* If connector does not support execution with retries, the method should throw: *

diff --git a/core/trino-spi/src/main/java/io/trino/spi/connector/RelationType.java b/core/trino-spi/src/main/java/io/trino/spi/connector/RelationType.java
new file mode 100644
index 000000000000..d038a1de8bc3
--- /dev/null
+++ b/core/trino-spi/src/main/java/io/trino/spi/connector/RelationType.java
@@ -0,0 +1,21 @@
+/*
+ * Licensed 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 io.trino.spi.connector;
+
+public enum RelationType
+{
+    TABLE,
+    VIEW,
+    MATERIALIZED_VIEW,
+}
diff --git a/lib/trino-plugin-toolkit/src/main/java/io/trino/plugin/base/classloader/ClassLoaderSafeConnectorMetadata.java b/lib/trino-plugin-toolkit/src/main/java/io/trino/plugin/base/classloader/ClassLoaderSafeConnectorMetadata.java
index adc7a7be7b7e..d97b94e7f11d 100644
--- a/lib/trino-plugin-toolkit/src/main/java/io/trino/plugin/base/classloader/ClassLoaderSafeConnectorMetadata.java
+++ b/lib/trino-plugin-toolkit/src/main/java/io/trino/plugin/base/classloader/ClassLoaderSafeConnectorMetadata.java
@@ -51,6 +51,7 @@
 import io.trino.spi.connector.ProjectionApplicationResult;
 import io.trino.spi.connector.RelationColumnsMetadata;
 import io.trino.spi.connector.RelationCommentMetadata;
+import io.trino.spi.connector.RelationType;
 import io.trino.spi.connector.RetryMode;
 import io.trino.spi.connector.RowChangeParadigm;
 import io.trino.spi.connector.SampleApplicationResult;
@@ -286,6 +287,14 @@ public Optional getInfo(ConnectorTableHandle table)
         }
     }
 
+    @Override
+    public List listRelations(ConnectorSession session, Optional schemaName)
+    {
+        try (ThreadContextClassLoader ignored = new ThreadContextClassLoader(classLoader)) {
+            return delegate.listRelations(session, schemaName);
+        }
+    }
+
     @Override
     public List listTables(ConnectorSession session, Optional schemaName)
     {
@@ -294,6 +303,14 @@ public List listTables(ConnectorSession session, Optional getRelationTypes(ConnectorSession session, Optional schemaName)
+    {
+        try (ThreadContextClassLoader ignored = new ThreadContextClassLoader(classLoader)) {
+            return delegate.getRelationTypes(session, schemaName);
+        }
+    }
+
     @Override
     public Map getColumnHandles(ConnectorSession session, ConnectorTableHandle tableHandle)
     {
diff --git a/plugin/trino-blackhole/src/test/java/io/trino/plugin/blackhole/TestBlackHoleSmoke.java b/plugin/trino-blackhole/src/test/java/io/trino/plugin/blackhole/TestBlackHoleSmoke.java
index 1c5aa32cbebc..0771a0c851d0 100644
--- a/plugin/trino-blackhole/src/test/java/io/trino/plugin/blackhole/TestBlackHoleSmoke.java
+++ b/plugin/trino-blackhole/src/test/java/io/trino/plugin/blackhole/TestBlackHoleSmoke.java
@@ -377,7 +377,7 @@ private void assertThatNoBlackHoleTableIsCreated()
 
     private List listBlackHoleTables()
     {
-        return queryRunner.listTables(queryRunner.getDefaultSession(), "blackhole", "default");
+        return queryRunner.listRelations(queryRunner.getDefaultSession(), "blackhole", "default");
     }
 
     private void assertThatQueryReturnsValue(String sql, Object expected)
diff --git a/plugin/trino-delta-lake/src/main/java/io/trino/plugin/deltalake/metastore/HiveMetastoreBackedDeltaLakeMetastore.java b/plugin/trino-delta-lake/src/main/java/io/trino/plugin/deltalake/metastore/HiveMetastoreBackedDeltaLakeMetastore.java
index df3a1c1a8f15..1a5f25e671df 100644
--- a/plugin/trino-delta-lake/src/main/java/io/trino/plugin/deltalake/metastore/HiveMetastoreBackedDeltaLakeMetastore.java
+++ b/plugin/trino-delta-lake/src/main/java/io/trino/plugin/deltalake/metastore/HiveMetastoreBackedDeltaLakeMetastore.java
@@ -63,7 +63,7 @@ public List getAllTables(String databaseName)
         // it would be nice to filter out non-Delta tables; however, we can not call
         // metastore.getTablesWithParameter(schema, TABLE_PROVIDER_PROP, TABLE_PROVIDER_VALUE), because that property
         // contains a dot and must be compared case-insensitive
-        return delegate.getAllTables(databaseName);
+        return delegate.getRelations(databaseName);
     }
 
     @Override
diff --git a/plugin/trino-delta-lake/src/test/java/io/trino/plugin/deltalake/metastore/TestDeltaLakeMetastoreAccessOperations.java b/plugin/trino-delta-lake/src/test/java/io/trino/plugin/deltalake/metastore/TestDeltaLakeMetastoreAccessOperations.java
index dda0004e5236..06e876ff9e6c 100644
--- a/plugin/trino-delta-lake/src/test/java/io/trino/plugin/deltalake/metastore/TestDeltaLakeMetastoreAccessOperations.java
+++ b/plugin/trino-delta-lake/src/test/java/io/trino/plugin/deltalake/metastore/TestDeltaLakeMetastoreAccessOperations.java
@@ -38,8 +38,8 @@
 import static io.trino.plugin.hive.metastore.CountingAccessHiveMetastore.Method.CREATE_TABLE;
 import static io.trino.plugin.hive.metastore.CountingAccessHiveMetastore.Method.DROP_TABLE;
 import static io.trino.plugin.hive.metastore.CountingAccessHiveMetastore.Method.GET_ALL_DATABASES;
-import static io.trino.plugin.hive.metastore.CountingAccessHiveMetastore.Method.GET_ALL_TABLES_FROM_DATABASE;
 import static io.trino.plugin.hive.metastore.CountingAccessHiveMetastore.Method.GET_DATABASE;
+import static io.trino.plugin.hive.metastore.CountingAccessHiveMetastore.Method.GET_RELATIONS_FROM_DATABASE;
 import static io.trino.plugin.hive.metastore.CountingAccessHiveMetastore.Method.GET_TABLE;
 import static io.trino.plugin.hive.metastore.file.TestingFileHiveMetastore.createTestingFileHiveMetastore;
 import static io.trino.testing.TestingSession.testSessionBuilder;
@@ -262,7 +262,7 @@ public void testShowTables()
         assertMetastoreInvocations("SHOW TABLES",
                 ImmutableMultiset.builder()
                         .add(GET_ALL_DATABASES)
-                        .add(GET_ALL_TABLES_FROM_DATABASE)
+                        .add(GET_RELATIONS_FROM_DATABASE)
                         .build());
     }
 
diff --git a/plugin/trino-example-http/pom.xml b/plugin/trino-example-http/pom.xml
index 3224a64921e9..8d612c270c96 100644
--- a/plugin/trino-example-http/pom.xml
+++ b/plugin/trino-example-http/pom.xml
@@ -17,6 +17,12 @@
     
 
     
+
+        
+            com.google.errorprone
+            error_prone_annotations
+            true
+        
         
             com.google.guava
             guava
diff --git a/plugin/trino-example-http/src/main/java/io/trino/plugin/example/ExampleMetadata.java b/plugin/trino-example-http/src/main/java/io/trino/plugin/example/ExampleMetadata.java
index 2842528bbb2a..7fb136103327 100644
--- a/plugin/trino-example-http/src/main/java/io/trino/plugin/example/ExampleMetadata.java
+++ b/plugin/trino-example-http/src/main/java/io/trino/plugin/example/ExampleMetadata.java
@@ -16,6 +16,7 @@
 import com.google.common.collect.ImmutableList;
 import com.google.common.collect.ImmutableMap;
 import com.google.common.collect.ImmutableSet;
+import com.google.errorprone.annotations.DoNotCall;
 import com.google.inject.Inject;
 import io.trino.spi.connector.ColumnHandle;
 import io.trino.spi.connector.ColumnMetadata;
@@ -78,7 +79,14 @@ public ConnectorTableMetadata getTableMetadata(ConnectorSession session, Connect
     }
 
     @Override
-    public List listTables(ConnectorSession session, Optional optionalSchemaName)
+    @DoNotCall
+    public final List listTables(ConnectorSession session, Optional schemaName)
+    {
+        throw new UnsupportedOperationException("listRelations should be called instead");
+    }
+
+    @Override
+    public List listRelations(ConnectorSession session, Optional optionalSchemaName)
     {
         Set schemaNames = optionalSchemaName.map(ImmutableSet::of)
                 .orElseGet(() -> ImmutableSet.copyOf(exampleClient.getSchemaNames()));
@@ -116,7 +124,7 @@ public Map> listTableColumns(ConnectorSess
     {
         requireNonNull(prefix, "prefix is null");
         ImmutableMap.Builder> columns = ImmutableMap.builder();
-        for (SchemaTableName tableName : listTables(session, prefix)) {
+        for (SchemaTableName tableName : listRelations(session, prefix)) {
             ConnectorTableMetadata tableMetadata = getTableMetadata(tableName);
             // table can disappear during listing operation
             if (tableMetadata != null) {
@@ -140,10 +148,10 @@ private ConnectorTableMetadata getTableMetadata(SchemaTableName tableName)
         return new ConnectorTableMetadata(tableName, table.getColumnsMetadata());
     }
 
-    private List listTables(ConnectorSession session, SchemaTablePrefix prefix)
+    private List listRelations(ConnectorSession session, SchemaTablePrefix prefix)
     {
         if (prefix.getTable().isEmpty()) {
-            return listTables(session, prefix.getSchema());
+            return listRelations(session, prefix.getSchema());
         }
         return ImmutableList.of(prefix.toSchemaTableName());
     }
diff --git a/plugin/trino-example-http/src/test/java/io/trino/plugin/example/TestExampleMetadata.java b/plugin/trino-example-http/src/test/java/io/trino/plugin/example/TestExampleMetadata.java
index 704aba27723a..18238a456195 100644
--- a/plugin/trino-example-http/src/test/java/io/trino/plugin/example/TestExampleMetadata.java
+++ b/plugin/trino-example-http/src/test/java/io/trino/plugin/example/TestExampleMetadata.java
@@ -104,23 +104,23 @@ public void getTableMetadata()
     }
 
     @Test
-    public void testListTables()
+    public void testListRelations()
     {
         // all schemas
-        assertThat(ImmutableSet.copyOf(metadata.listTables(SESSION, Optional.empty()))).isEqualTo(ImmutableSet.of(
+        assertThat(ImmutableSet.copyOf(metadata.listRelations(SESSION, Optional.empty()))).isEqualTo(ImmutableSet.of(
                 new SchemaTableName("example", "numbers"),
                 new SchemaTableName("tpch", "orders"),
                 new SchemaTableName("tpch", "lineitem")));
 
         // specific schema
-        assertThat(ImmutableSet.copyOf(metadata.listTables(SESSION, Optional.of("example")))).isEqualTo(ImmutableSet.of(
+        assertThat(ImmutableSet.copyOf(metadata.listRelations(SESSION, Optional.of("example")))).isEqualTo(ImmutableSet.of(
                 new SchemaTableName("example", "numbers")));
-        assertThat(ImmutableSet.copyOf(metadata.listTables(SESSION, Optional.of("tpch")))).isEqualTo(ImmutableSet.of(
+        assertThat(ImmutableSet.copyOf(metadata.listRelations(SESSION, Optional.of("tpch")))).isEqualTo(ImmutableSet.of(
                 new SchemaTableName("tpch", "orders"),
                 new SchemaTableName("tpch", "lineitem")));
 
         // unknown schema
-        assertThat(ImmutableSet.copyOf(metadata.listTables(SESSION, Optional.of("unknown")))).isEqualTo(ImmutableSet.of());
+        assertThat(ImmutableSet.copyOf(metadata.listRelations(SESSION, Optional.of("unknown")))).isEqualTo(ImmutableSet.of());
     }
 
     @Test
diff --git a/plugin/trino-hive-hadoop2/src/test/java/io/trino/plugin/hive/AbstractTestHiveFileSystemAbfs.java b/plugin/trino-hive-hadoop2/src/test/java/io/trino/plugin/hive/AbstractTestHiveFileSystemAbfs.java
index 8daba40b523b..4dc1a81e993d 100644
--- a/plugin/trino-hive-hadoop2/src/test/java/io/trino/plugin/hive/AbstractTestHiveFileSystemAbfs.java
+++ b/plugin/trino-hive-hadoop2/src/test/java/io/trino/plugin/hive/AbstractTestHiveFileSystemAbfs.java
@@ -91,7 +91,7 @@ private void ensureTableExists(SchemaTableName table, String tableDirectoryName,
                             .put(BUCKETED_BY_PROPERTY, ImmutableList.of())
                             .put(SORTED_BY_PROPERTY, ImmutableList.of())
                             .buildOrThrow());
-            if (!transaction.getMetadata().listTables(newSession(), Optional.of(table.getSchemaName())).contains(table)) {
+            if (!transaction.getMetadata().listRelations(newSession(), Optional.of(table.getSchemaName())).contains(table)) {
                 transaction.getMetadata().createTable(newSession(), tableMetadata, false);
             }
             transaction.commit();
diff --git a/plugin/trino-hive/src/main/java/io/trino/plugin/hive/HiveMetadata.java b/plugin/trino-hive/src/main/java/io/trino/plugin/hive/HiveMetadata.java
index 71bc4e010046..68070b6b38ef 100644
--- a/plugin/trino-hive/src/main/java/io/trino/plugin/hive/HiveMetadata.java
+++ b/plugin/trino-hive/src/main/java/io/trino/plugin/hive/HiveMetadata.java
@@ -24,6 +24,7 @@
 import com.google.common.collect.Iterables;
 import com.google.common.collect.Maps;
 import com.google.common.collect.Sets;
+import com.google.errorprone.annotations.DoNotCall;
 import io.airlift.json.JsonCodec;
 import io.airlift.log.Logger;
 import io.airlift.slice.Slice;
@@ -88,6 +89,7 @@
 import io.trino.spi.connector.MaterializedViewFreshness;
 import io.trino.spi.connector.MetadataProvider;
 import io.trino.spi.connector.ProjectionApplicationResult;
+import io.trino.spi.connector.RelationType;
 import io.trino.spi.connector.RetryMode;
 import io.trino.spi.connector.RowChangeParadigm;
 import io.trino.spi.connector.SchemaNotFoundException;
@@ -137,6 +139,7 @@
 import java.util.Iterator;
 import java.util.List;
 import java.util.Map;
+import java.util.Map.Entry;
 import java.util.NoSuchElementException;
 import java.util.Optional;
 import java.util.OptionalInt;
@@ -320,6 +323,7 @@
 import static java.lang.Boolean.parseBoolean;
 import static java.lang.String.format;
 import static java.util.Locale.ENGLISH;
+import static java.util.Map.entry;
 import static java.util.Objects.requireNonNull;
 import static java.util.function.Function.identity;
 import static java.util.stream.Collectors.joining;
@@ -789,13 +793,20 @@ public Optional getInfo(ConnectorTableHandle tableHandle)
     }
 
     @Override
-    public List listTables(ConnectorSession session, Optional optionalSchemaName)
+    @DoNotCall
+    public final List listTables(ConnectorSession session, Optional schemaName)
+    {
+        throw new UnsupportedOperationException("This method is not supported because listRelations is implemented instead");
+    }
+
+    @Override
+    public List listRelations(ConnectorSession session, Optional optionalSchemaName)
     {
         if (optionalSchemaName.isEmpty()) {
-            Optional> allTables = metastore.getAllTables();
-            if (allTables.isPresent()) {
+            Optional> relations = metastore.getRelations();
+            if (relations.isPresent()) {
                 return ImmutableSet.builder()
-                        .addAll(allTables.get().stream()
+                        .addAll(relations.get().stream()
                                 .filter(table -> !isHiveSystemSchema(table.getSchemaName()))
                                 .collect(toImmutableList()))
                         .addAll(listMaterializedViews(session, optionalSchemaName))
@@ -803,15 +814,43 @@ public List listTables(ConnectorSession session, Optional tableNames = ImmutableSet.builder();
+        ImmutableSet.Builder relations = ImmutableSet.builder();
         for (String schemaName : listSchemas(session, optionalSchemaName)) {
-            for (String tableName : metastore.getAllTables(schemaName)) {
-                tableNames.add(new SchemaTableName(schemaName, tableName));
+            for (String tableName : metastore.getRelations(schemaName)) {
+                relations.add(new SchemaTableName(schemaName, tableName));
+            }
+        }
+
+        relations.addAll(listMaterializedViews(session, optionalSchemaName));
+        return relations.build().asList();
+    }
+
+    @Override
+    public Map getRelationTypes(ConnectorSession session, Optional optionalSchemaName)
+    {
+        ImmutableMap.Builder result = ImmutableMap.builder();
+
+        boolean fetched = false;
+        if (optionalSchemaName.isEmpty()) {
+            Optional> relationTypes = metastore.getRelationTypes();
+            if (relationTypes.isPresent()) {
+                relationTypes.get().entrySet().stream()
+                        .filter(entry -> !isHiveSystemSchema(entry.getKey().getSchemaName()))
+                        .forEach(result::put);
+                fetched = true;
+            }
+        }
+        if (!fetched) {
+            for (String schemaName : listSchemas(session, optionalSchemaName)) {
+                for (Entry entry : metastore.getRelationTypes(schemaName).entrySet()) {
+                    result.put(new SchemaTableName(schemaName, entry.getKey()), entry.getValue());
+                }
             }
         }
 
-        tableNames.addAll(listMaterializedViews(session, optionalSchemaName));
-        return tableNames.build().asList();
+        listMaterializedViews(session, optionalSchemaName)
+                .forEach(name -> result.put(name, RelationType.MATERIALIZED_VIEW));
+        return result.buildKeepingLast();
     }
 
     private List listSchemas(ConnectorSession session, Optional schemaName)
@@ -892,7 +931,7 @@ public TableStatistics getTableStatistics(ConnectorSession session, ConnectorTab
                 .collect(toImmutableMap(HiveColumnHandle::getName, Function.identity()));
 
         Map columnTypes = columns.entrySet().stream()
-                .collect(toImmutableMap(Map.Entry::getKey, entry -> getColumnMetadata(session, tableHandle, entry.getValue()).getType()));
+                .collect(toImmutableMap(Entry::getKey, entry -> getColumnMetadata(session, tableHandle, entry.getValue()).getType()));
         HivePartitionResult partitionResult = partitionManager.getPartitions(metastore, tableHandle, new Constraint(hiveTableHandle.getEnforcedConstraint()));
         // If partitions are not loaded, then don't generate table statistics.
         // Note that the computation is not persisted in the table handle, so can be redone many times
@@ -910,7 +949,7 @@ private List listTables(ConnectorSession session, SchemaTablePr
             return ImmutableList.of();
         }
         if (prefix.getTable().isEmpty()) {
-            return listTables(session, prefix.getSchema());
+            return listRelations(session, prefix.getSchema());
         }
         SchemaTableName tableName = prefix.toSchemaTableName();
 
@@ -967,7 +1006,7 @@ public void dropSchema(ConnectorSession session, String schemaName, boolean casc
         if (cascade) {
             // List all objects first because such operations after adding/dropping/altering tables/views in a transaction is disallowed
             List views = listViews(session, Optional.of(schemaName));
-            List tables = listTables(session, Optional.of(schemaName)).stream()
+            List tables = listRelations(session, Optional.of(schemaName)).stream()
                     .filter(table -> !views.contains(table))
                     .collect(toImmutableList());
 
@@ -3075,7 +3114,7 @@ public Optional> applyProjecti
         ImmutableMap.Builder newVariablesBuilder = ImmutableMap.builder();
         ImmutableSet.Builder projectedColumnsBuilder = ImmutableSet.builder();
 
-        for (Map.Entry entry : columnProjections.entrySet()) {
+        for (Entry entry : columnProjections.entrySet()) {
             ConnectorExpression expression = entry.getKey();
             ProjectedColumnRepresentation projectedColumn = entry.getValue();
 
diff --git a/plugin/trino-hive/src/main/java/io/trino/plugin/hive/HiveMetastoreClosure.java b/plugin/trino-hive/src/main/java/io/trino/plugin/hive/HiveMetastoreClosure.java
index 190e81bd28fe..4578546b446b 100644
--- a/plugin/trino-hive/src/main/java/io/trino/plugin/hive/HiveMetastoreClosure.java
+++ b/plugin/trino-hive/src/main/java/io/trino/plugin/hive/HiveMetastoreClosure.java
@@ -30,6 +30,7 @@
 import io.trino.plugin.hive.metastore.Table;
 import io.trino.plugin.hive.projection.PartitionProjection;
 import io.trino.spi.TrinoException;
+import io.trino.spi.connector.RelationType;
 import io.trino.spi.connector.SchemaTableName;
 import io.trino.spi.connector.TableNotFoundException;
 import io.trino.spi.function.LanguageFunction;
@@ -154,14 +155,24 @@ public void updatePartitionStatistics(String databaseName, String tableName, Map
         delegate.updatePartitionStatistics(table, updates);
     }
 
-    public List getAllTables(String databaseName)
+    public List getRelations(String databaseName)
     {
-        return delegate.getAllTables(databaseName);
+        return delegate.getRelations(databaseName);
     }
 
-    public Optional> getAllTables()
+    public Optional> getRelations()
     {
-        return delegate.getAllTables();
+        return delegate.getRelations();
+    }
+
+    public Map getRelationTypes(String databaseName)
+    {
+        return delegate.getRelationTypes(databaseName);
+    }
+
+    public Optional> getRelationTypes()
+    {
+        return delegate.getRelationTypes();
     }
 
     public List getAllViews(String databaseName)
diff --git a/plugin/trino-hive/src/main/java/io/trino/plugin/hive/metastore/CoralSemiTransactionalHiveMSCAdapter.java b/plugin/trino-hive/src/main/java/io/trino/plugin/hive/metastore/CoralSemiTransactionalHiveMSCAdapter.java
index c432e3663f56..fdc421ea4bea 100644
--- a/plugin/trino-hive/src/main/java/io/trino/plugin/hive/metastore/CoralSemiTransactionalHiveMSCAdapter.java
+++ b/plugin/trino-hive/src/main/java/io/trino/plugin/hive/metastore/CoralSemiTransactionalHiveMSCAdapter.java
@@ -67,7 +67,7 @@ public com.linkedin.coral.hive.metastore.api.Database getDatabase(String dbName)
     @Override
     public List getAllTables(String dbName)
     {
-        return delegate.getAllTables(dbName);
+        return delegate.getRelations(dbName);
     }
 
     @Override
diff --git a/plugin/trino-hive/src/main/java/io/trino/plugin/hive/metastore/ForwardingHiveMetastore.java b/plugin/trino-hive/src/main/java/io/trino/plugin/hive/metastore/ForwardingHiveMetastore.java
index f8b3fcd5926c..48bbb159b7ca 100644
--- a/plugin/trino-hive/src/main/java/io/trino/plugin/hive/metastore/ForwardingHiveMetastore.java
+++ b/plugin/trino-hive/src/main/java/io/trino/plugin/hive/metastore/ForwardingHiveMetastore.java
@@ -21,6 +21,7 @@
 import io.trino.plugin.hive.acid.AcidOperation;
 import io.trino.plugin.hive.acid.AcidTransaction;
 import io.trino.plugin.hive.metastore.HivePrivilegeInfo.HivePrivilege;
+import io.trino.spi.connector.RelationType;
 import io.trino.spi.connector.SchemaTableName;
 import io.trino.spi.function.LanguageFunction;
 import io.trino.spi.predicate.TupleDomain;
@@ -111,15 +112,27 @@ public void updatePartitionStatistics(
     }
 
     @Override
-    public List getAllTables(String databaseName)
+    public List getRelations(String databaseName)
     {
-        return delegate.getAllTables(databaseName);
+        return delegate.getRelations(databaseName);
     }
 
     @Override
-    public Optional> getAllTables()
+    public Optional> getRelations()
     {
-        return delegate.getAllTables();
+        return delegate.getRelations();
+    }
+
+    @Override
+    public Map getRelationTypes(String databaseName)
+    {
+        return delegate.getRelationTypes(databaseName);
+    }
+
+    @Override
+    public Optional> getRelationTypes()
+    {
+        return delegate.getRelationTypes();
     }
 
     @Override
diff --git a/plugin/trino-hive/src/main/java/io/trino/plugin/hive/metastore/HiveMetastore.java b/plugin/trino-hive/src/main/java/io/trino/plugin/hive/metastore/HiveMetastore.java
index 30b91704acea..80942393a3db 100644
--- a/plugin/trino-hive/src/main/java/io/trino/plugin/hive/metastore/HiveMetastore.java
+++ b/plugin/trino-hive/src/main/java/io/trino/plugin/hive/metastore/HiveMetastore.java
@@ -23,6 +23,7 @@
 import io.trino.plugin.hive.acid.AcidTransaction;
 import io.trino.plugin.hive.metastore.HivePrivilegeInfo.HivePrivilege;
 import io.trino.spi.TrinoException;
+import io.trino.spi.connector.RelationType;
 import io.trino.spi.connector.SchemaTableName;
 import io.trino.spi.function.LanguageFunction;
 import io.trino.spi.predicate.TupleDomain;
@@ -62,12 +63,19 @@ default void updatePartitionStatistics(Table table, String partitionName, Functi
 
     void updatePartitionStatistics(Table table, Map> updates);
 
-    List getAllTables(String databaseName);
+    List getRelations(String databaseName);
 
     /**
      * @return List of tables, views and materialized views names from all schemas or Optional.empty if operation is not supported
      */
-    Optional> getAllTables();
+    Optional> getRelations();
+
+    Map getRelationTypes(String databaseName);
+
+    /**
+     * @return empty if operation is not supported
+     */
+    Optional> getRelationTypes();
 
     List getTablesWithParameter(String databaseName, String parameterKey, String parameterValue);
 
diff --git a/plugin/trino-hive/src/main/java/io/trino/plugin/hive/metastore/SemiTransactionalHiveMetastore.java b/plugin/trino-hive/src/main/java/io/trino/plugin/hive/metastore/SemiTransactionalHiveMetastore.java
index 8a377fa75504..176c3d6b15a3 100644
--- a/plugin/trino-hive/src/main/java/io/trino/plugin/hive/metastore/SemiTransactionalHiveMetastore.java
+++ b/plugin/trino-hive/src/main/java/io/trino/plugin/hive/metastore/SemiTransactionalHiveMetastore.java
@@ -52,6 +52,7 @@
 import io.trino.plugin.hive.util.ValidTxnWriteIdList;
 import io.trino.spi.TrinoException;
 import io.trino.spi.connector.ConnectorSession;
+import io.trino.spi.connector.RelationType;
 import io.trino.spi.connector.SchemaNotFoundException;
 import io.trino.spi.connector.SchemaTableName;
 import io.trino.spi.connector.TableNotFoundException;
@@ -234,22 +235,40 @@ public synchronized Optional getDatabase(String databaseName)
         return delegate.getDatabase(databaseName);
     }
 
-    public synchronized List getAllTables(String databaseName)
+    public synchronized List getRelations(String databaseName)
     {
         checkReadable();
         if (!tableActions.isEmpty()) {
-            throw new UnsupportedOperationException("Listing all tables after adding/dropping/altering tables/views in a transaction is not supported");
+            throw new UnsupportedOperationException("Listing all relations after adding/dropping/altering tables/views in a transaction is not supported");
         }
-        return delegate.getAllTables(databaseName);
+        return delegate.getRelations(databaseName);
     }
 
-    public synchronized Optional> getAllTables()
+    public synchronized Optional> getRelations()
     {
         checkReadable();
         if (!tableActions.isEmpty()) {
-            throw new UnsupportedOperationException("Listing all tables after adding/dropping/altering tables/views in a transaction is not supported");
+            throw new UnsupportedOperationException("Listing all relations after adding/dropping/altering tables/views in a transaction is not supported");
+        }
+        return delegate.getRelations();
+    }
+
+    public synchronized Map getRelationTypes(String databaseName)
+    {
+        checkReadable();
+        if (!tableActions.isEmpty()) {
+            throw new UnsupportedOperationException("Listing all relations after adding/dropping/altering tables/views in a transaction is not supported");
+        }
+        return delegate.getRelationTypes(databaseName);
+    }
+
+    public synchronized Optional> getRelationTypes()
+    {
+        checkReadable();
+        if (!tableActions.isEmpty()) {
+            throw new UnsupportedOperationException("Listing all relations after adding/dropping/altering tables/views in a transaction is not supported");
         }
-        return delegate.getAllTables();
+        return delegate.getRelationTypes();
     }
 
     public synchronized Optional getTable(String databaseName, String tableName)
diff --git a/plugin/trino-hive/src/main/java/io/trino/plugin/hive/metastore/cache/CachingHiveMetastore.java b/plugin/trino-hive/src/main/java/io/trino/plugin/hive/metastore/cache/CachingHiveMetastore.java
index b7e817737454..d438deb11a6c 100644
--- a/plugin/trino-hive/src/main/java/io/trino/plugin/hive/metastore/cache/CachingHiveMetastore.java
+++ b/plugin/trino-hive/src/main/java/io/trino/plugin/hive/metastore/cache/CachingHiveMetastore.java
@@ -17,6 +17,7 @@
 import com.google.common.cache.CacheLoader;
 import com.google.common.cache.CacheLoader.InvalidCacheLoadException;
 import com.google.common.cache.LoadingCache;
+import com.google.common.collect.ImmutableList;
 import com.google.common.collect.ImmutableMap;
 import com.google.common.collect.Iterables;
 import com.google.common.collect.Sets.SetView;
@@ -49,6 +50,7 @@
 import io.trino.plugin.hive.metastore.PrincipalPrivileges;
 import io.trino.plugin.hive.metastore.Table;
 import io.trino.spi.TrinoException;
+import io.trino.spi.connector.RelationType;
 import io.trino.spi.connector.SchemaTableName;
 import io.trino.spi.function.LanguageFunction;
 import io.trino.spi.predicate.TupleDomain;
@@ -114,8 +116,10 @@ public enum StatsRecording
     private final LoadingCache> databaseCache;
     private final LoadingCache> databaseNamesCache;
     private final LoadingCache> tableCache;
-    private final LoadingCache> tableNamesCache;
-    private final LoadingCache>> allTableNamesCache;
+    private final LoadingCache> relationNamesCache;
+    private final LoadingCache> relationTypesCache;
+    private final LoadingCache>> allRelationNamesCache;
+    private final LoadingCache>> allRelationTypesCache;
     private final LoadingCache> tablesWithParameterCache;
     private final Cache> tableStatisticsCache;
     private final Cache> partitionStatisticsCache;
@@ -200,8 +204,10 @@ private CachingHiveMetastore(
 
         databaseNamesCache = cacheFactory.buildCache(ignored -> loadAllDatabases());
         databaseCache = cacheFactory.buildCache(this::loadDatabase);
-        tableNamesCache = cacheFactory.buildCache(this::loadAllTables);
-        allTableNamesCache = cacheFactory.buildCache(ignore -> loadAllTables());
+        relationNamesCache = cacheFactory.buildCache(this::loadRelations);
+        relationTypesCache = cacheFactory.buildCache(this::loadRelationTypes);
+        allRelationNamesCache = cacheFactory.buildCache(ignore -> loadRelations());
+        allRelationTypesCache = cacheFactory.buildCache(ignore -> loadRelationTypes());
         tablesWithParameterCache = cacheFactory.buildCache(this::loadTablesMatchingParameter);
         tableStatisticsCache = statsCacheFactory.buildCache(this::refreshTableStatistics);
         tableCache = cacheFactory.buildCache(this::loadTable);
@@ -221,8 +227,10 @@ private CachingHiveMetastore(
     public void flushCache()
     {
         databaseNamesCache.invalidateAll();
-        tableNamesCache.invalidateAll();
-        allTableNamesCache.invalidateAll();
+        relationNamesCache.invalidateAll();
+        relationTypesCache.invalidateAll();
+        allRelationNamesCache.invalidateAll();
+        allRelationTypesCache.invalidateAll();
         viewNamesCache.invalidateAll();
         allViewNamesCache.invalidateAll();
         databaseCache.invalidateAll();
@@ -570,25 +578,55 @@ public void updatePartitionStatistics(Table table, Map getAllTables(String databaseName)
+    public List getRelations(String databaseName)
     {
-        return get(tableNamesCache, databaseName);
+        Map relationTypes = relationTypesCache.getIfPresent(databaseName);
+        if (relationTypes != null) {
+            return ImmutableList.copyOf(relationTypes.keySet());
+        }
+        return get(relationNamesCache, databaseName);
+    }
+
+    private List loadRelations(String databaseName)
+    {
+        return delegate.getRelations(databaseName);
+    }
+
+    @Override
+    public Map getRelationTypes(String databaseName)
+    {
+        return get(relationTypesCache, databaseName);
+    }
+
+    private Map loadRelationTypes(String databaseName)
+    {
+        return delegate.getRelationTypes(databaseName);
+    }
+
+    @Override
+    public Optional> getRelations()
+    {
+        Optional> relationTypes = allRelationTypesCache.getIfPresent(SingletonCacheKey.INSTANCE);
+        if (relationTypes != null && relationTypes.isPresent()) {
+            return Optional.of(ImmutableList.copyOf(relationTypes.get().keySet()));
+        }
+        return getOptional(allRelationNamesCache, SingletonCacheKey.INSTANCE);
     }
 
-    private List loadAllTables(String databaseName)
+    private Optional> loadRelations()
     {
-        return delegate.getAllTables(databaseName);
+        return delegate.getRelations();
     }
 
     @Override
-    public Optional> getAllTables()
+    public Optional> getRelationTypes()
     {
-        return getOptional(allTableNamesCache, SingletonCacheKey.INSTANCE);
+        return getOptional(allRelationTypesCache, SingletonCacheKey.INSTANCE);
     }
 
-    private Optional> loadAllTables()
+    private Optional> loadRelationTypes()
     {
-        return delegate.getAllTables();
+        return delegate.getRelationTypes();
     }
 
     @Override
@@ -792,8 +830,10 @@ public void invalidateTable(String databaseName, String tableName)
     {
         HiveTableName hiveTableName = new HiveTableName(databaseName, tableName);
         tableCache.invalidate(hiveTableName);
-        tableNamesCache.invalidate(databaseName);
-        allTableNamesCache.invalidateAll();
+        relationNamesCache.invalidate(databaseName);
+        relationTypesCache.invalidate(databaseName);
+        allRelationNamesCache.invalidateAll();
+        allRelationTypesCache.invalidateAll();
         viewNamesCache.invalidate(databaseName);
         allViewNamesCache.invalidateAll();
         invalidateAllIf(tablePrivilegesCache, userTableKey -> userTableKey.matches(databaseName, tableName));
@@ -1278,16 +1318,30 @@ public CacheStatsMBean getTableStats()
 
     @Managed
     @Nested
-    public CacheStatsMBean getTableNamesStats()
+    public CacheStatsMBean getRelationNamesStats()
     {
-        return new CacheStatsMBean(tableNamesCache);
+        return new CacheStatsMBean(relationNamesCache);
     }
 
     @Managed
     @Nested
-    public CacheStatsMBean getAllTableNamesStats()
+    public CacheStatsMBean getRelationTypesStats()
     {
-        return new CacheStatsMBean(allTableNamesCache);
+        return new CacheStatsMBean(relationTypesCache);
+    }
+
+    @Managed
+    @Nested
+    public CacheStatsMBean getAllRelationNamesStats()
+    {
+        return new CacheStatsMBean(allRelationNamesCache);
+    }
+
+    @Managed
+    @Nested
+    public CacheStatsMBean getAllRelationTypesStats()
+    {
+        return new CacheStatsMBean(allRelationTypesCache);
     }
 
     @Managed
@@ -1385,14 +1439,24 @@ LoadingCache> getTableCache()
         return tableCache;
     }
 
-    LoadingCache> getTableNamesCache()
+    LoadingCache> getRelationNamesCache()
+    {
+        return relationNamesCache;
+    }
+
+    LoadingCache> getRelationTypesCache()
+    {
+        return relationTypesCache;
+    }
+
+    LoadingCache>> getAllRelationNamesCache()
     {
-        return tableNamesCache;
+        return allRelationNamesCache;
     }
 
-    LoadingCache>> getAllTableNamesCache()
+    LoadingCache>> getAllRelationTypesCache()
     {
-        return allTableNamesCache;
+        return allRelationTypesCache;
     }
 
     LoadingCache> getTablesWithParameterCache()
@@ -1450,7 +1514,8 @@ LoadingCache> getConfigValuesCache()
         return configValuesCache;
     }
 
-    private record CacheFactory(OptionalLong expiresAfterWriteMillis, OptionalLong refreshMillis, Optional refreshExecutor, long maximumSize, StatsRecording statsRecording)
+    private record CacheFactory(OptionalLong expiresAfterWriteMillis, OptionalLong refreshMillis, Optional refreshExecutor, long maximumSize,
+                                StatsRecording statsRecording)
     {
         private static final CacheFactory NEVER_CACHE = new CacheFactory(OptionalLong.empty(), OptionalLong.empty(), Optional.empty(), 0, StatsRecording.DISABLED);
 
diff --git a/plugin/trino-hive/src/main/java/io/trino/plugin/hive/metastore/cache/SharedHiveMetastoreCache.java b/plugin/trino-hive/src/main/java/io/trino/plugin/hive/metastore/cache/SharedHiveMetastoreCache.java
index aeeefbbf6033..837fd91e4cce 100644
--- a/plugin/trino-hive/src/main/java/io/trino/plugin/hive/metastore/cache/SharedHiveMetastoreCache.java
+++ b/plugin/trino-hive/src/main/java/io/trino/plugin/hive/metastore/cache/SharedHiveMetastoreCache.java
@@ -249,16 +249,30 @@ public AggregateCacheStatsMBean getTableStats()
 
         @Managed
         @Nested
-        public AggregateCacheStatsMBean getTableNamesStats()
+        public AggregateCacheStatsMBean getRelationNamesStats()
         {
-            return new AggregateCacheStatsMBean(CachingHiveMetastore::getTableNamesCache);
+            return new AggregateCacheStatsMBean(CachingHiveMetastore::getRelationNamesCache);
         }
 
         @Managed
         @Nested
-        public AggregateCacheStatsMBean getAllTableNamesStats()
+        public AggregateCacheStatsMBean getRelationTypesStats()
         {
-            return new AggregateCacheStatsMBean(CachingHiveMetastore::getAllTableNamesCache);
+            return new AggregateCacheStatsMBean(CachingHiveMetastore::getRelationTypesCache);
+        }
+
+        @Managed
+        @Nested
+        public AggregateCacheStatsMBean getAllRelationNamesStats()
+        {
+            return new AggregateCacheStatsMBean(CachingHiveMetastore::getAllRelationNamesCache);
+        }
+
+        @Managed
+        @Nested
+        public AggregateCacheStatsMBean getAllRelationTypesStats()
+        {
+            return new AggregateCacheStatsMBean(CachingHiveMetastore::getAllRelationTypesCache);
         }
 
         @Managed
diff --git a/plugin/trino-hive/src/main/java/io/trino/plugin/hive/metastore/file/FileHiveMetastore.java b/plugin/trino-hive/src/main/java/io/trino/plugin/hive/metastore/file/FileHiveMetastore.java
index d529b1e22d5b..6c6f7505f798 100644
--- a/plugin/trino-hive/src/main/java/io/trino/plugin/hive/metastore/file/FileHiveMetastore.java
+++ b/plugin/trino-hive/src/main/java/io/trino/plugin/hive/metastore/file/FileHiveMetastore.java
@@ -56,6 +56,7 @@
 import io.trino.plugin.hive.metastore.thrift.ThriftMetastoreUtil;
 import io.trino.spi.TrinoException;
 import io.trino.spi.connector.ColumnNotFoundException;
+import io.trino.spi.connector.RelationType;
 import io.trino.spi.connector.SchemaNotFoundException;
 import io.trino.spi.connector.SchemaTableName;
 import io.trino.spi.connector.TableNotFoundException;
@@ -214,7 +215,7 @@ public synchronized void dropDatabase(String databaseName, boolean deleteData)
         databaseName = databaseName.toLowerCase(ENGLISH);
 
         getRequiredDatabase(databaseName);
-        if (!getAllTables(databaseName).isEmpty()) {
+        if (!getRelations(databaseName).isEmpty()) {
             throw new TrinoException(HIVE_METASTORE_ERROR, "Database " + databaseName + " is not empty");
         }
 
@@ -508,7 +509,7 @@ public synchronized void updatePartitionStatistics(Table table, Map getAllTables(String databaseName)
+    public synchronized List getRelations(String databaseName)
     {
         return listAllTables(databaseName).stream()
                 .filter(hideDeltaLakeTables
@@ -518,7 +519,22 @@ public synchronized List getAllTables(String databaseName)
     }
 
     @Override
-    public Optional> getAllTables()
+    public Optional> getRelations()
+    {
+        return Optional.empty();
+    }
+
+    @Override
+    public synchronized Map getRelationTypes(String databaseName)
+    {
+        ImmutableMap.Builder relationTypes = ImmutableMap.builder();
+        getRelations(databaseName).forEach(name -> relationTypes.put(name, RelationType.TABLE));
+        getAllViews(databaseName).forEach(name -> relationTypes.put(name, RelationType.VIEW));
+        return relationTypes.buildKeepingLast();
+    }
+
+    @Override
+    public Optional> getRelationTypes()
     {
         return Optional.empty();
     }
@@ -590,7 +606,7 @@ private List doListAllTables(String databaseName)
     @Override
     public synchronized List getAllViews(String databaseName)
     {
-        return getAllTables(databaseName).stream()
+        return getRelations(databaseName).stream()
                 .map(tableName -> getTable(databaseName, tableName))
                 .filter(Optional::isPresent)
                 .map(Optional::get)
diff --git a/plugin/trino-hive/src/main/java/io/trino/plugin/hive/metastore/glue/GlueHiveMetastore.java b/plugin/trino-hive/src/main/java/io/trino/plugin/hive/metastore/glue/GlueHiveMetastore.java
index fc6c078e9a65..e9d6beed969a 100644
--- a/plugin/trino-hive/src/main/java/io/trino/plugin/hive/metastore/glue/GlueHiveMetastore.java
+++ b/plugin/trino-hive/src/main/java/io/trino/plugin/hive/metastore/glue/GlueHiveMetastore.java
@@ -102,6 +102,7 @@
 import io.trino.plugin.hive.util.HiveUtil;
 import io.trino.spi.TrinoException;
 import io.trino.spi.connector.ColumnNotFoundException;
+import io.trino.spi.connector.RelationType;
 import io.trino.spi.connector.SchemaNotFoundException;
 import io.trino.spi.connector.SchemaTableName;
 import io.trino.spi.connector.TableNotFoundException;
@@ -423,13 +424,44 @@ private void updatePartitionStatisticsBatch(Table table, Map getAllTables(String databaseName)
+    public List getRelations(String databaseName)
     {
         return getTableNames(databaseName, tableFilter);
     }
 
     @Override
-    public Optional> getAllTables()
+    public Optional> getRelations()
+    {
+        return Optional.empty();
+    }
+
+    @Override
+    public Map getRelationTypes(String databaseName)
+    {
+        try {
+            return getGlueTables(databaseName)
+                    .filter(tableFilter.or(SOME_KIND_OF_VIEW_FILTER))
+                    .collect(toImmutableMap(
+                            com.amazonaws.services.glue.model.Table::getName,
+                            table -> {
+                                // GlueHiveMetastore currently does not distinguish views and materialized views, see getAllViews().
+                                if (SOME_KIND_OF_VIEW_FILTER.test(table)) {
+                                    return RelationType.VIEW;
+                                }
+                                return RelationType.TABLE;
+                            }));
+        }
+        catch (EntityNotFoundException | AccessDeniedException e) {
+            // database does not exist or permission denied
+            return ImmutableMap.of();
+        }
+        catch (AmazonServiceException e) {
+            throw new TrinoException(HIVE_METASTORE_ERROR, e);
+        }
+    }
+
+    @Override
+    public Optional> getRelationTypes()
     {
         return Optional.empty();
     }
diff --git a/plugin/trino-hive/src/main/java/io/trino/plugin/hive/metastore/thrift/BridgingHiveMetastore.java b/plugin/trino-hive/src/main/java/io/trino/plugin/hive/metastore/thrift/BridgingHiveMetastore.java
index d5926bb35155..f775ee5643a8 100644
--- a/plugin/trino-hive/src/main/java/io/trino/plugin/hive/metastore/thrift/BridgingHiveMetastore.java
+++ b/plugin/trino-hive/src/main/java/io/trino/plugin/hive/metastore/thrift/BridgingHiveMetastore.java
@@ -34,6 +34,7 @@
 import io.trino.plugin.hive.metastore.Table;
 import io.trino.plugin.hive.util.HiveUtil;
 import io.trino.spi.TrinoException;
+import io.trino.spi.connector.RelationType;
 import io.trino.spi.connector.SchemaNotFoundException;
 import io.trino.spi.connector.SchemaTableName;
 import io.trino.spi.connector.TableNotFoundException;
@@ -141,11 +142,20 @@ public void updatePartitionStatistics(Table table, Map getAllTables(String databaseName)
+    public List getRelations(String databaseName)
     {
         return delegate.getAllTables(databaseName);
     }
 
+    @Override
+    public Map getRelationTypes(String databaseName)
+    {
+        ImmutableMap.Builder relationTypes = ImmutableMap.builder();
+        getRelations(databaseName).forEach(name -> relationTypes.put(name, RelationType.TABLE));
+        getAllViews(databaseName).forEach(name -> relationTypes.put(name, RelationType.VIEW));
+        return relationTypes.buildKeepingLast();
+    }
+
     @Override
     public List getTablesWithParameter(String databaseName, String parameterKey, String parameterValue)
     {
@@ -159,11 +169,22 @@ public List getAllViews(String databaseName)
     }
 
     @Override
-    public Optional> getAllTables()
+    public Optional> getRelations()
     {
         return delegate.getAllTables();
     }
 
+    @Override
+    public Optional> getRelationTypes()
+    {
+        return getRelations().flatMap(relations -> getAllViews().map(views -> {
+            ImmutableMap.Builder relationTypes = ImmutableMap.builder();
+            relations.forEach(name -> relationTypes.put(name, RelationType.TABLE));
+            views.forEach(name -> relationTypes.put(name, RelationType.VIEW));
+            return relationTypes.buildKeepingLast();
+        }));
+    }
+
     @Override
     public Optional> getAllViews()
     {
diff --git a/plugin/trino-hive/src/main/java/io/trino/plugin/hive/metastore/tracing/TracingHiveMetastore.java b/plugin/trino-hive/src/main/java/io/trino/plugin/hive/metastore/tracing/TracingHiveMetastore.java
index dea02fb2ffd1..24b23154c9f6 100644
--- a/plugin/trino-hive/src/main/java/io/trino/plugin/hive/metastore/tracing/TracingHiveMetastore.java
+++ b/plugin/trino-hive/src/main/java/io/trino/plugin/hive/metastore/tracing/TracingHiveMetastore.java
@@ -31,6 +31,7 @@
 import io.trino.plugin.hive.metastore.PartitionWithStatistics;
 import io.trino.plugin.hive.metastore.PrincipalPrivileges;
 import io.trino.plugin.hive.metastore.Table;
+import io.trino.spi.connector.RelationType;
 import io.trino.spi.connector.SchemaTableName;
 import io.trino.spi.function.LanguageFunction;
 import io.trino.spi.predicate.TupleDomain;
@@ -169,27 +170,52 @@ public void updatePartitionStatistics(Table table, Map getAllTables(String databaseName)
+    public List getRelations(String databaseName)
     {
-        Span span = tracer.spanBuilder("HiveMetastore.getAllTables")
+        Span span = tracer.spanBuilder("HiveMetastore.getRelations")
                 .setAttribute(SCHEMA, databaseName)
                 .startSpan();
         return withTracing(span, () -> {
-            List tables = delegate.getAllTables(databaseName);
-            span.setAttribute(TABLE_RESPONSE_COUNT, tables.size());
-            return tables;
+            List relations = delegate.getRelations(databaseName);
+            span.setAttribute(TABLE_RESPONSE_COUNT, relations.size());
+            return relations;
         });
     }
 
     @Override
-    public Optional> getAllTables()
+    public Optional> getRelations()
     {
-        Span span = tracer.spanBuilder("HiveMetastore.getAllTables")
+        Span span = tracer.spanBuilder("HiveMetastore.getRelations")
                 .startSpan();
         return withTracing(span, () -> {
-            Optional> tables = delegate.getAllTables();
-            tables.ifPresent(list -> span.setAttribute(TABLE_RESPONSE_COUNT, list.size()));
-            return tables;
+            Optional> relations = delegate.getRelations();
+            relations.ifPresent(list -> span.setAttribute(TABLE_RESPONSE_COUNT, list.size()));
+            return relations;
+        });
+    }
+
+    @Override
+    public Map getRelationTypes(String databaseName)
+    {
+        Span span = tracer.spanBuilder("HiveMetastore.getRelationTypes")
+                .setAttribute(SCHEMA, databaseName)
+                .startSpan();
+        return withTracing(span, () -> {
+            Map relationTypes = delegate.getRelationTypes(databaseName);
+            span.setAttribute(TABLE_RESPONSE_COUNT, relationTypes.size());
+            return relationTypes;
+        });
+    }
+
+    @Override
+    public Optional> getRelationTypes()
+    {
+        Span span = tracer.spanBuilder("HiveMetastore.getRelations")
+                .startSpan();
+        return withTracing(span, () -> {
+            Optional> relationTypes = delegate.getRelationTypes();
+            relationTypes.ifPresent(map -> span.setAttribute(TABLE_RESPONSE_COUNT, map.size()));
+            return relationTypes;
         });
     }
 
diff --git a/plugin/trino-hive/src/test/java/io/trino/plugin/hive/AbstractTestHive.java b/plugin/trino-hive/src/test/java/io/trino/plugin/hive/AbstractTestHive.java
index 19c219dd9161..6ceda2fe9443 100644
--- a/plugin/trino-hive/src/test/java/io/trino/plugin/hive/AbstractTestHive.java
+++ b/plugin/trino-hive/src/test/java/io/trino/plugin/hive/AbstractTestHive.java
@@ -1062,7 +1062,7 @@ public void testGetTableNames()
     {
         try (Transaction transaction = newTransaction()) {
             ConnectorMetadata metadata = transaction.getMetadata();
-            List tables = metadata.listTables(newSession(), Optional.of(database));
+            List tables = metadata.listRelations(newSession(), Optional.of(database));
             assertThat(tables).contains(tablePartitionFormat);
             assertThat(tables).contains(tableUnpartitioned);
         }
@@ -1073,7 +1073,7 @@ public void testGetAllTableNames()
     {
         try (Transaction transaction = newTransaction()) {
             ConnectorMetadata metadata = transaction.getMetadata();
-            List tables = metadata.listTables(newSession(), Optional.empty());
+            List tables = metadata.listRelations(newSession(), Optional.empty());
             assertThat(tables).contains(tablePartitionFormat);
             assertThat(tables).contains(tableUnpartitioned);
         }
@@ -1108,7 +1108,7 @@ public void testListUnknownSchema()
             ConnectorMetadata metadata = transaction.getMetadata();
             ConnectorSession session = newSession();
             assertThat(metadata.getTableHandle(session, new SchemaTableName(INVALID_DATABASE, INVALID_TABLE))).isNull();
-            assertThat(metadata.listTables(session, Optional.of(INVALID_DATABASE))).isEqualTo(ImmutableList.of());
+            assertThat(metadata.listRelations(session, Optional.of(INVALID_DATABASE))).isEqualTo(ImmutableList.of());
             assertThat(listTableColumns(metadata, session, new SchemaTablePrefix(INVALID_DATABASE, INVALID_TABLE))).isEqualTo(ImmutableMap.of());
             assertThat(metadata.listViews(session, Optional.of(INVALID_DATABASE))).isEqualTo(ImmutableList.of());
             assertThat(metadata.getViews(session, Optional.of(INVALID_DATABASE))).isEqualTo(ImmutableMap.of());
@@ -3204,11 +3204,11 @@ public void testHideDeltaLakeTables()
                 //  as information_schema or MetadataManager may apply additional logic
 
                 // list all tables
-                assertThat(metadata.listTables(session, Optional.empty()))
+                assertThat(metadata.listRelations(session, Optional.empty()))
                         .doesNotContain(tableName);
 
                 // list all tables in a schema
-                assertThat(metadata.listTables(session, Optional.of(tableName.getSchemaName())))
+                assertThat(metadata.listRelations(session, Optional.of(tableName.getSchemaName())))
                         .doesNotContain(tableName);
 
                 // list all columns in a schema
diff --git a/plugin/trino-hive/src/test/java/io/trino/plugin/hive/AbstractTestHiveLocal.java b/plugin/trino-hive/src/test/java/io/trino/plugin/hive/AbstractTestHiveLocal.java
index ea4989f2e928..f72ed84acb2d 100644
--- a/plugin/trino-hive/src/test/java/io/trino/plugin/hive/AbstractTestHiveLocal.java
+++ b/plugin/trino-hive/src/test/java/io/trino/plugin/hive/AbstractTestHiveLocal.java
@@ -177,7 +177,7 @@ public void cleanup()
             throws IOException
     {
         try {
-            for (String tableName : metastoreClient.getAllTables(database)) {
+            for (String tableName : metastoreClient.getRelations(database)) {
                 metastoreClient.dropTable(database, tableName, true);
             }
             metastoreClient.dropDatabase(testDbName, true);
diff --git a/plugin/trino-hive/src/test/java/io/trino/plugin/hive/metastore/CountingAccessHiveMetastore.java b/plugin/trino-hive/src/test/java/io/trino/plugin/hive/metastore/CountingAccessHiveMetastore.java
index 1630456391e6..4efd70321cef 100644
--- a/plugin/trino-hive/src/test/java/io/trino/plugin/hive/metastore/CountingAccessHiveMetastore.java
+++ b/plugin/trino-hive/src/test/java/io/trino/plugin/hive/metastore/CountingAccessHiveMetastore.java
@@ -22,6 +22,7 @@
 import io.trino.plugin.hive.PartitionStatistics;
 import io.trino.plugin.hive.acid.AcidTransaction;
 import io.trino.plugin.hive.metastore.HivePrivilegeInfo.HivePrivilege;
+import io.trino.spi.connector.RelationType;
 import io.trino.spi.connector.SchemaTableName;
 import io.trino.spi.function.LanguageFunction;
 import io.trino.spi.predicate.TupleDomain;
@@ -35,8 +36,9 @@
 import java.util.Set;
 import java.util.function.Function;
 
-import static io.trino.plugin.hive.metastore.CountingAccessHiveMetastore.Method.GET_ALL_TABLES;
 import static io.trino.plugin.hive.metastore.CountingAccessHiveMetastore.Method.GET_ALL_VIEWS;
+import static io.trino.plugin.hive.metastore.CountingAccessHiveMetastore.Method.GET_RELATIONS;
+import static io.trino.plugin.hive.metastore.CountingAccessHiveMetastore.Method.GET_RELATION_TYPES;
 
 @ThreadSafe
 public class CountingAccessHiveMetastore
@@ -50,8 +52,10 @@ public enum Method
         GET_ALL_DATABASES,
         GET_DATABASE,
         GET_TABLE,
-        GET_ALL_TABLES,
-        GET_ALL_TABLES_FROM_DATABASE,
+        GET_RELATIONS,
+        GET_RELATIONS_FROM_DATABASE,
+        GET_RELATION_TYPES,
+        GET_RELATION_TYPES_FROM_DATABASE,
         GET_TABLES_WITH_PARAMETER,
         GET_TABLE_STATISTICS,
         GET_ALL_VIEWS,
@@ -355,20 +359,37 @@ public void updatePartitionStatistics(Table table, Map getAllTables(String databaseName)
+    public List getRelations(String databaseName)
     {
-        methodInvocations.add(Method.GET_ALL_TABLES_FROM_DATABASE);
-        return delegate.getAllTables(databaseName);
+        methodInvocations.add(Method.GET_RELATIONS_FROM_DATABASE);
+        return delegate.getRelations(databaseName);
     }
 
     @Override
-    public Optional> getAllTables()
+    public Optional> getRelations()
     {
-        Optional> allTables = delegate.getAllTables();
-        if (allTables.isPresent()) {
-            methodInvocations.add(GET_ALL_TABLES);
+        Optional> relations = delegate.getRelations();
+        if (relations.isPresent()) {
+            methodInvocations.add(GET_RELATIONS);
         }
-        return allTables;
+        return relations;
+    }
+
+    @Override
+    public Map getRelationTypes(String databaseName)
+    {
+        methodInvocations.add(Method.GET_RELATION_TYPES_FROM_DATABASE);
+        return delegate.getRelationTypes(databaseName);
+    }
+
+    @Override
+    public Optional> getRelationTypes()
+    {
+        Optional> relationTypes = delegate.getRelationTypes();
+        if (relationTypes.isPresent()) {
+            methodInvocations.add(GET_RELATION_TYPES);
+        }
+        return relationTypes;
     }
 
     @Override
diff --git a/plugin/trino-hive/src/test/java/io/trino/plugin/hive/metastore/UnimplementedHiveMetastore.java b/plugin/trino-hive/src/test/java/io/trino/plugin/hive/metastore/UnimplementedHiveMetastore.java
index cb7023359ce7..7f1d4c949206 100644
--- a/plugin/trino-hive/src/test/java/io/trino/plugin/hive/metastore/UnimplementedHiveMetastore.java
+++ b/plugin/trino-hive/src/test/java/io/trino/plugin/hive/metastore/UnimplementedHiveMetastore.java
@@ -18,6 +18,7 @@
 import io.trino.plugin.hive.PartitionStatistics;
 import io.trino.plugin.hive.acid.AcidTransaction;
 import io.trino.plugin.hive.metastore.HivePrivilegeInfo.HivePrivilege;
+import io.trino.spi.connector.RelationType;
 import io.trino.spi.connector.SchemaTableName;
 import io.trino.spi.function.LanguageFunction;
 import io.trino.spi.predicate.TupleDomain;
@@ -86,13 +87,25 @@ public void updatePartitionStatistics(Table table, Map getAllTables(String databaseName)
+    public List getRelations(String databaseName)
     {
         throw new UnsupportedOperationException();
     }
 
     @Override
-    public Optional> getAllTables()
+    public Optional> getRelations()
+    {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public Map getRelationTypes(String databaseName)
+    {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public Optional> getRelationTypes()
     {
         throw new UnsupportedOperationException();
     }
diff --git a/plugin/trino-hive/src/test/java/io/trino/plugin/hive/metastore/cache/TestCachingHiveMetastore.java b/plugin/trino-hive/src/test/java/io/trino/plugin/hive/metastore/cache/TestCachingHiveMetastore.java
index dc176ec0a00a..d0f68bd4b718 100644
--- a/plugin/trino-hive/src/test/java/io/trino/plugin/hive/metastore/cache/TestCachingHiveMetastore.java
+++ b/plugin/trino-hive/src/test/java/io/trino/plugin/hive/metastore/cache/TestCachingHiveMetastore.java
@@ -181,7 +181,7 @@ public void testCachingWithOnlyPartitionsCacheEnabled()
                 .usesCache();
 
         assertThatCachingWithDisabledPartitionCache()
-                .whenExecuting(testedMetastore -> testedMetastore.getAllTables(TEST_DATABASE))
+                .whenExecuting(testedMetastore -> testedMetastore.getRelations(TEST_DATABASE))
                 .usesCache();
 
         assertThatCachingWithDisabledPartitionCache()
@@ -227,49 +227,49 @@ public void testGetAllDatabases()
     }
 
     @Test
-    public void testGetAllTable()
+    public void testGetRelations()
     {
         assertThat(mockClient.getAccessCount()).isEqualTo(0);
-        assertThat(metastore.getAllTables(TEST_DATABASE)).isEqualTo(ImmutableList.of(TEST_TABLE));
+        assertThat(metastore.getRelations(TEST_DATABASE)).isEqualTo(ImmutableList.of(TEST_TABLE));
         assertThat(mockClient.getAccessCount()).isEqualTo(1);
-        assertThat(metastore.getAllTables(TEST_DATABASE)).isEqualTo(ImmutableList.of(TEST_TABLE));
+        assertThat(metastore.getRelations(TEST_DATABASE)).isEqualTo(ImmutableList.of(TEST_TABLE));
         assertThat(mockClient.getAccessCount()).isEqualTo(1);
-        assertThat(metastore.getTableNamesStats().getRequestCount()).isEqualTo(2);
-        assertThat(metastore.getTableNamesStats().getHitRate()).isEqualTo(0.5);
+        assertThat(metastore.getRelationNamesStats().getRequestCount()).isEqualTo(2);
+        assertThat(metastore.getRelationNamesStats().getHitRate()).isEqualTo(0.5);
 
         metastore.flushCache();
 
-        assertThat(metastore.getAllTables(TEST_DATABASE)).isEqualTo(ImmutableList.of(TEST_TABLE));
+        assertThat(metastore.getRelations(TEST_DATABASE)).isEqualTo(ImmutableList.of(TEST_TABLE));
         assertThat(mockClient.getAccessCount()).isEqualTo(2);
-        assertThat(metastore.getTableNamesStats().getRequestCount()).isEqualTo(3);
-        assertThat(metastore.getTableNamesStats().getHitRate()).isEqualTo(1.0 / 3);
+        assertThat(metastore.getRelationNamesStats().getRequestCount()).isEqualTo(3);
+        assertThat(metastore.getRelationNamesStats().getHitRate()).isEqualTo(1.0 / 3);
     }
 
     @Test
-    public void testBatchGetAllTable()
+    public void testBatchGetRelations()
     {
         assertThat(mockClient.getAccessCount()).isEqualTo(0);
-        assertThat(metastore.getAllTables()).isEqualTo(Optional.of(ImmutableList.of(TEST_SCHEMA_TABLE)));
+        assertThat(metastore.getRelations()).isEqualTo(Optional.of(ImmutableList.of(TEST_SCHEMA_TABLE)));
         assertThat(mockClient.getAccessCount()).isEqualTo(1);
-        assertThat(metastore.getAllTables()).isEqualTo(Optional.of(ImmutableList.of(TEST_SCHEMA_TABLE)));
+        assertThat(metastore.getRelations()).isEqualTo(Optional.of(ImmutableList.of(TEST_SCHEMA_TABLE)));
         assertThat(mockClient.getAccessCount()).isEqualTo(1);
-        assertThat(metastore.getAllTables(TEST_DATABASE)).isEqualTo(ImmutableList.of(TEST_TABLE));
+        assertThat(metastore.getRelations(TEST_DATABASE)).isEqualTo(ImmutableList.of(TEST_TABLE));
         assertThat(mockClient.getAccessCount()).isEqualTo(2);
-        assertThat(metastore.getAllTableNamesStats().getRequestCount()).isEqualTo(2);
-        assertThat(metastore.getAllTableNamesStats().getHitRate()).isEqualTo(.5);
+        assertThat(metastore.getAllRelationNamesStats().getRequestCount()).isEqualTo(2);
+        assertThat(metastore.getAllRelationNamesStats().getHitRate()).isEqualTo(.5);
 
         metastore.flushCache();
 
-        assertThat(metastore.getAllTables()).isEqualTo(Optional.of(ImmutableList.of(TEST_SCHEMA_TABLE)));
+        assertThat(metastore.getRelations()).isEqualTo(Optional.of(ImmutableList.of(TEST_SCHEMA_TABLE)));
         assertThat(mockClient.getAccessCount()).isEqualTo(3);
-        assertThat(metastore.getAllTableNamesStats().getRequestCount()).isEqualTo(3);
-        assertThat(metastore.getAllTableNamesStats().getHitRate()).isEqualTo(1. / 3);
+        assertThat(metastore.getAllRelationNamesStats().getRequestCount()).isEqualTo(3);
+        assertThat(metastore.getAllRelationNamesStats().getHitRate()).isEqualTo(1. / 3);
     }
 
     @Test
-    public void testInvalidDbGetAllTAbles()
+    public void testInvalidDbGetRelations()
     {
-        assertThat(metastore.getAllTables(BAD_DATABASE).isEmpty()).isTrue();
+        assertThat(metastore.getRelations(BAD_DATABASE).isEmpty()).isTrue();
     }
 
     @Test
@@ -1150,21 +1150,21 @@ public void testAllDatabases()
     }
 
     @Test
-    public void testAllTables()
+    public void testRelations()
     {
         assertThat(mockClient.getAccessCount()).isEqualTo(0);
 
-        assertThat(metastore.getAllTables()).contains(ImmutableList.of(TEST_SCHEMA_TABLE));
+        assertThat(metastore.getRelations()).contains(ImmutableList.of(TEST_SCHEMA_TABLE));
         assertThat(mockClient.getAccessCount()).isEqualTo(1);
-        assertThat(metastore.getAllTables()).contains(ImmutableList.of(TEST_SCHEMA_TABLE));
+        assertThat(metastore.getRelations()).contains(ImmutableList.of(TEST_SCHEMA_TABLE));
         assertThat(mockClient.getAccessCount()).isEqualTo(1); // should read it from cache
 
         metastore.dropTable(TEST_DATABASE, TEST_TABLE, false);
         assertThat(mockClient.getAccessCount()).isEqualTo(2); // dropTable check if the table exists
 
-        assertThat(metastore.getAllTables()).contains(ImmutableList.of(TEST_SCHEMA_TABLE));
+        assertThat(metastore.getRelations()).contains(ImmutableList.of(TEST_SCHEMA_TABLE));
         assertThat(mockClient.getAccessCount()).isEqualTo(3);
-        assertThat(metastore.getAllTables()).contains(ImmutableList.of(TEST_SCHEMA_TABLE));
+        assertThat(metastore.getRelations()).contains(ImmutableList.of(TEST_SCHEMA_TABLE));
         assertThat(mockClient.getAccessCount()).isEqualTo(3); // should read it from cache
 
         metastore.createTable(
@@ -1177,9 +1177,9 @@ public void testAllTables()
                         .build(),
                 new PrincipalPrivileges(ImmutableMultimap.of(), ImmutableMultimap.of()));
 
-        assertThat(metastore.getAllTables()).contains(ImmutableList.of(TEST_SCHEMA_TABLE));
+        assertThat(metastore.getRelations()).contains(ImmutableList.of(TEST_SCHEMA_TABLE));
         assertThat(mockClient.getAccessCount()).isEqualTo(4);
-        assertThat(metastore.getAllTables()).contains(ImmutableList.of(TEST_SCHEMA_TABLE));
+        assertThat(metastore.getRelations()).contains(ImmutableList.of(TEST_SCHEMA_TABLE));
         assertThat(mockClient.getAccessCount()).isEqualTo(4); // should read it from cache
     }
 
diff --git a/plugin/trino-hive/src/test/java/io/trino/plugin/hive/metastore/thrift/TestHiveMetastoreMetadataQueriesAccessOperations.java b/plugin/trino-hive/src/test/java/io/trino/plugin/hive/metastore/thrift/TestHiveMetastoreMetadataQueriesAccessOperations.java
index 9fa42c8e0c25..b30f498e7cce 100644
--- a/plugin/trino-hive/src/test/java/io/trino/plugin/hive/metastore/thrift/TestHiveMetastoreMetadataQueriesAccessOperations.java
+++ b/plugin/trino-hive/src/test/java/io/trino/plugin/hive/metastore/thrift/TestHiveMetastoreMetadataQueriesAccessOperations.java
@@ -42,10 +42,10 @@
 import static io.trino.plugin.hive.HiveStorageFormat.ORC;
 import static io.trino.plugin.hive.TableType.MANAGED_TABLE;
 import static io.trino.plugin.hive.metastore.CountingAccessHiveMetastore.Method.GET_ALL_DATABASES;
-import static io.trino.plugin.hive.metastore.CountingAccessHiveMetastore.Method.GET_ALL_TABLES;
-import static io.trino.plugin.hive.metastore.CountingAccessHiveMetastore.Method.GET_ALL_TABLES_FROM_DATABASE;
 import static io.trino.plugin.hive.metastore.CountingAccessHiveMetastore.Method.GET_ALL_VIEWS;
 import static io.trino.plugin.hive.metastore.CountingAccessHiveMetastore.Method.GET_ALL_VIEWS_FROM_DATABASE;
+import static io.trino.plugin.hive.metastore.CountingAccessHiveMetastore.Method.GET_RELATIONS;
+import static io.trino.plugin.hive.metastore.CountingAccessHiveMetastore.Method.GET_RELATIONS_FROM_DATABASE;
 import static io.trino.plugin.hive.metastore.CountingAccessHiveMetastore.Method.GET_TABLE;
 import static io.trino.plugin.hive.metastore.StorageFormat.fromHiveStorageFormat;
 import static io.trino.testing.TestingSession.testSessionBuilder;
@@ -123,7 +123,7 @@ public void testSelectTablesWithoutPredicate()
 
         mockMetastore.setAllTablesViewsImplemented(true);
         Multiset tables = ImmutableMultiset.builder()
-                .add(GET_ALL_TABLES)
+                .add(GET_RELATIONS)
                 .add(GET_ALL_VIEWS)
                 .build();
         assertMetastoreInvocations("SELECT * FROM information_schema.tables", tables);
@@ -132,7 +132,7 @@ public void testSelectTablesWithoutPredicate()
         mockMetastore.setAllTablesViewsImplemented(false);
         tables = ImmutableMultiset.builder()
                 .add(GET_ALL_DATABASES)
-                .addCopies(GET_ALL_TABLES_FROM_DATABASE, TEST_SCHEMAS_COUNT)
+                .addCopies(GET_RELATIONS_FROM_DATABASE, TEST_SCHEMAS_COUNT)
                 .addCopies(GET_ALL_VIEWS_FROM_DATABASE, TEST_SCHEMAS_COUNT)
                 .build();
         assertMetastoreInvocations("SELECT * FROM information_schema.tables", tables);
@@ -156,13 +156,13 @@ public void testSelectTablesWithFilterBySchema()
         assertMetastoreInvocations(
                 "SELECT * FROM information_schema.tables WHERE table_schema = 'test_schema_0'",
                 ImmutableMultiset.builder()
-                        .add(GET_ALL_TABLES_FROM_DATABASE)
+                        .add(GET_RELATIONS_FROM_DATABASE)
                         .add(GET_ALL_VIEWS_FROM_DATABASE)
                         .build());
         assertMetastoreInvocations(
                 "SELECT * FROM system.jdbc.tables WHERE table_schem = 'test_schema_0'",
                 ImmutableMultiset.builder()
-                        .add(GET_ALL_TABLES_FROM_DATABASE)
+                        .add(GET_RELATIONS_FROM_DATABASE)
                         .add(GET_ALL_VIEWS_FROM_DATABASE)
                         .build());
     }
@@ -177,20 +177,20 @@ public void testSelectTablesWithLikeOverSchema()
                 "SELECT * FROM information_schema.tables WHERE table_schema LIKE 'test%'",
                 ImmutableMultiset.builder()
                         .add(GET_ALL_DATABASES)
-                        .add(GET_ALL_TABLES)
+                        .add(GET_RELATIONS)
                         .add(GET_ALL_VIEWS)
                         .build());
         assertMetastoreInvocations(
                 "SELECT * FROM system.jdbc.tables WHERE table_schem LIKE 'test%'",
                 ImmutableMultiset.builder()
-                        .add(GET_ALL_TABLES)
+                        .add(GET_RELATIONS)
                         .add(GET_ALL_VIEWS)
                         .build());
 
         mockMetastore.setAllTablesViewsImplemented(false);
         Multiset tables = ImmutableMultiset.builder()
                 .add(GET_ALL_DATABASES)
-                .addCopies(GET_ALL_TABLES_FROM_DATABASE, TEST_SCHEMAS_COUNT)
+                .addCopies(GET_RELATIONS_FROM_DATABASE, TEST_SCHEMAS_COUNT)
                 .addCopies(GET_ALL_VIEWS_FROM_DATABASE, TEST_SCHEMAS_COUNT)
                 .build();
         assertMetastoreInvocations("SELECT * FROM information_schema.tables WHERE table_schema LIKE 'test%'", tables);
@@ -207,12 +207,12 @@ public void testSelectTablesWithFilterByTableName()
                 "SELECT * FROM information_schema.tables WHERE table_name = 'test_table_0'",
                 ImmutableMultiset.builder()
                         .add(GET_ALL_DATABASES)
-                        .add(GET_ALL_TABLES)
+                        .add(GET_RELATIONS)
                         .add(GET_ALL_VIEWS)
                         .build());
 
         Multiset tables = ImmutableMultiset.builder()
-                .add(GET_ALL_TABLES)
+                .add(GET_RELATIONS)
                 .add(GET_ALL_VIEWS)
                 .build();
         assertMetastoreInvocations("SELECT * FROM system.jdbc.tables WHERE table_name = 'test_table_0'", tables);
@@ -222,7 +222,7 @@ public void testSelectTablesWithFilterByTableName()
         mockMetastore.setAllTablesViewsImplemented(false);
         tables = ImmutableMultiset.builder()
                 .add(GET_ALL_DATABASES)
-                .addCopies(GET_ALL_TABLES_FROM_DATABASE, TEST_SCHEMAS_COUNT)
+                .addCopies(GET_RELATIONS_FROM_DATABASE, TEST_SCHEMAS_COUNT)
                 .addCopies(GET_ALL_VIEWS_FROM_DATABASE, TEST_SCHEMAS_COUNT)
                 .build();
         assertMetastoreInvocations("SELECT * FROM information_schema.tables WHERE table_name = 'test_table_0'", tables);
@@ -241,20 +241,20 @@ public void testSelectTablesWithLikeOverTableName()
                 "SELECT * FROM information_schema.tables WHERE table_name LIKE 'test%'",
                 ImmutableMultiset.builder()
                         .add(GET_ALL_DATABASES)
-                        .add(GET_ALL_TABLES)
+                        .add(GET_RELATIONS)
                         .add(GET_ALL_VIEWS)
                         .build());
         assertMetastoreInvocations(
                 "SELECT * FROM system.jdbc.tables WHERE table_name LIKE 'test%'",
                 ImmutableMultiset.builder()
-                        .add(GET_ALL_TABLES)
+                        .add(GET_RELATIONS)
                         .add(GET_ALL_VIEWS)
                         .build());
 
         mockMetastore.setAllTablesViewsImplemented(false);
         Multiset tables = ImmutableMultiset.builder()
                 .add(GET_ALL_DATABASES)
-                .addCopies(GET_ALL_TABLES_FROM_DATABASE, TEST_SCHEMAS_COUNT)
+                .addCopies(GET_RELATIONS_FROM_DATABASE, TEST_SCHEMAS_COUNT)
                 .addCopies(GET_ALL_VIEWS_FROM_DATABASE, TEST_SCHEMAS_COUNT)
                 .build();
         assertMetastoreInvocations("SELECT * FROM information_schema.tables WHERE table_name LIKE 'test%'", tables);
@@ -271,7 +271,7 @@ public void testSelectViewsWithoutPredicate()
         assertMetastoreInvocations(
                 "SELECT * FROM system.jdbc.tables WHERE table_type = 'VIEW'",
                 ImmutableMultiset.builder()
-                        .add(GET_ALL_TABLES)
+                        .add(GET_RELATIONS)
                         .add(GET_ALL_VIEWS)
                         .build());
 
@@ -286,7 +286,7 @@ public void testSelectViewsWithoutPredicate()
                 "SELECT * FROM system.jdbc.tables WHERE table_type = 'VIEW'",
                 ImmutableMultiset.builder()
                         .add(GET_ALL_DATABASES)
-                        .addCopies(GET_ALL_TABLES_FROM_DATABASE, TEST_SCHEMAS_COUNT)
+                        .addCopies(GET_RELATIONS_FROM_DATABASE, TEST_SCHEMAS_COUNT)
                         .addCopies(GET_ALL_VIEWS_FROM_DATABASE, TEST_SCHEMAS_COUNT)
                         .build());
     }
@@ -308,7 +308,7 @@ public void testSelectViewsWithFilterBySchema()
         assertMetastoreInvocations("SELECT * FROM information_schema.views WHERE table_schema = 'test_schema_0'", ImmutableMultiset.of(GET_ALL_VIEWS_FROM_DATABASE));
         assertMetastoreInvocations("SELECT * FROM system.jdbc.tables WHERE table_type = 'VIEW' AND table_schem = 'test_schema_0'",
                 ImmutableMultiset.builder()
-                        .add(GET_ALL_TABLES_FROM_DATABASE)
+                        .add(GET_RELATIONS_FROM_DATABASE)
                         .add(GET_ALL_VIEWS_FROM_DATABASE)
                         .build());
     }
@@ -328,7 +328,7 @@ public void testSelectViewsWithLikeOverSchema()
         assertMetastoreInvocations(
                 "SELECT * FROM system.jdbc.tables WHERE table_type = 'VIEW' AND table_schem LIKE 'test%'",
                 ImmutableMultiset.builder()
-                        .add(GET_ALL_TABLES)
+                        .add(GET_RELATIONS)
                         .add(GET_ALL_VIEWS)
                         .build());
 
@@ -343,7 +343,7 @@ public void testSelectViewsWithLikeOverSchema()
                 "SELECT * FROM system.jdbc.tables WHERE table_type = 'VIEW' AND table_schem LIKE 'test%'",
                 ImmutableMultiset.builder()
                         .add(GET_ALL_DATABASES)
-                        .addCopies(GET_ALL_TABLES_FROM_DATABASE, TEST_SCHEMAS_COUNT)
+                        .addCopies(GET_RELATIONS_FROM_DATABASE, TEST_SCHEMAS_COUNT)
                         .addCopies(GET_ALL_VIEWS_FROM_DATABASE, TEST_SCHEMAS_COUNT)
                         .build());
     }
@@ -363,7 +363,7 @@ public void testSelectViewsWithFilterByTableName()
         assertMetastoreInvocations(
                 "SELECT * FROM system.jdbc.tables WHERE table_type = 'VIEW' AND table_name = 'test_table_0'",
                 ImmutableMultiset.builder()
-                        .add(GET_ALL_TABLES)
+                        .add(GET_RELATIONS)
                         .add(GET_ALL_VIEWS)
                         .build());
 
@@ -378,7 +378,7 @@ public void testSelectViewsWithFilterByTableName()
                 "SELECT * FROM system.jdbc.tables WHERE table_type = 'VIEW' AND table_name = 'test_table_0'",
                 ImmutableMultiset.builder()
                         .add(GET_ALL_DATABASES)
-                        .addCopies(GET_ALL_TABLES_FROM_DATABASE, TEST_SCHEMAS_COUNT)
+                        .addCopies(GET_RELATIONS_FROM_DATABASE, TEST_SCHEMAS_COUNT)
                         .addCopies(GET_ALL_VIEWS_FROM_DATABASE, TEST_SCHEMAS_COUNT)
                         .build());
     }
@@ -398,7 +398,7 @@ public void testSelectViewsWithLikeOverTableName()
         assertMetastoreInvocations(
                 "SELECT * FROM system.jdbc.tables WHERE table_type = 'VIEW' AND table_name LIKE 'test%'",
                 ImmutableMultiset.builder()
-                        .add(GET_ALL_TABLES)
+                        .add(GET_RELATIONS)
                         .add(GET_ALL_VIEWS)
                         .build());
 
@@ -413,7 +413,7 @@ public void testSelectViewsWithLikeOverTableName()
                 "SELECT * FROM system.jdbc.tables WHERE table_type = 'VIEW' AND table_name LIKE 'test%'",
                 ImmutableMultiset.builder()
                         .add(GET_ALL_DATABASES)
-                        .addCopies(GET_ALL_TABLES_FROM_DATABASE, TEST_SCHEMAS_COUNT)
+                        .addCopies(GET_RELATIONS_FROM_DATABASE, TEST_SCHEMAS_COUNT)
                         .addCopies(GET_ALL_VIEWS_FROM_DATABASE, TEST_SCHEMAS_COUNT)
                         .build());
     }
@@ -425,7 +425,7 @@ public void testSelectColumnsWithoutPredicate()
 
         mockMetastore.setAllTablesViewsImplemented(true);
         ImmutableMultiset tables = ImmutableMultiset.builder()
-                .add(GET_ALL_TABLES)
+                .add(GET_RELATIONS)
                 .add(GET_ALL_VIEWS)
                 .addCopies(GET_TABLE, TEST_ALL_TABLES_COUNT)
                 .build();
@@ -435,7 +435,7 @@ public void testSelectColumnsWithoutPredicate()
         mockMetastore.setAllTablesViewsImplemented(false);
         tables = ImmutableMultiset.builder()
                 .add(GET_ALL_DATABASES)
-                .addCopies(GET_ALL_TABLES_FROM_DATABASE, TEST_SCHEMAS_COUNT)
+                .addCopies(GET_RELATIONS_FROM_DATABASE, TEST_SCHEMAS_COUNT)
                 .addCopies(GET_ALL_VIEWS_FROM_DATABASE, TEST_SCHEMAS_COUNT)
                 .addCopies(GET_TABLE, TEST_ALL_TABLES_COUNT)
                 .build();
@@ -459,26 +459,26 @@ public void testSelectColumnsFilterBySchema()
 
         assertMetastoreInvocations("SELECT * FROM information_schema.columns WHERE table_schema = 'test_schema_0'",
                 ImmutableMultiset.builder()
-                        .add(GET_ALL_TABLES_FROM_DATABASE)
+                        .add(GET_RELATIONS_FROM_DATABASE)
                         .add(GET_ALL_VIEWS_FROM_DATABASE)
                         .addCopies(GET_TABLE, TEST_TABLES_IN_SCHEMA_COUNT)
                         .build());
         assertMetastoreInvocations("SELECT * FROM system.jdbc.columns WHERE table_schem = 'test_schema_0'",
                 ImmutableMultiset.builder()
-                        .add(GET_ALL_TABLES_FROM_DATABASE)
+                        .add(GET_RELATIONS_FROM_DATABASE)
                         .add(GET_ALL_VIEWS_FROM_DATABASE)
                         .addCopies(GET_TABLE, TEST_TABLES_IN_SCHEMA_COUNT)
                         .build());
         assertMetastoreInvocations("SELECT * FROM system.jdbc.columns WHERE table_schem LIKE 'test\\_schema\\_0' ESCAPE '\\'",
                 ImmutableMultiset.builder()
-                        .add(GET_ALL_TABLES_FROM_DATABASE)
+                        .add(GET_RELATIONS_FROM_DATABASE)
                         .add(GET_ALL_VIEWS_FROM_DATABASE)
                         .addCopies(GET_TABLE, TEST_TABLES_IN_SCHEMA_COUNT)
                         .build());
         assertMetastoreInvocations("SELECT * FROM system.jdbc.columns WHERE table_schem LIKE 'test_schema_0' ESCAPE '\\'",
                 ImmutableMultiset.builder()
                         .add(GET_ALL_DATABASES)
-                        .add(GET_ALL_TABLES_FROM_DATABASE)
+                        .add(GET_RELATIONS_FROM_DATABASE)
                         .add(GET_ALL_VIEWS_FROM_DATABASE)
                         .addCopies(GET_TABLE, TEST_TABLES_IN_SCHEMA_COUNT)
                         .build());
@@ -494,7 +494,7 @@ public void testSelectColumnsWithLikeOverSchema()
                 "SELECT * FROM information_schema.columns WHERE table_schema LIKE 'test%'",
                 ImmutableMultiset.builder()
                         .add(GET_ALL_DATABASES)
-                        .add(GET_ALL_TABLES)
+                        .add(GET_RELATIONS)
                         .add(GET_ALL_VIEWS)
                         .addCopies(GET_TABLE, TEST_ALL_TABLES_COUNT)
                         .build());
@@ -502,7 +502,7 @@ public void testSelectColumnsWithLikeOverSchema()
                 "SELECT * FROM system.jdbc.columns WHERE table_schem LIKE 'test%'",
                 ImmutableMultiset.builder()
                         .add(GET_ALL_DATABASES)
-                        .addCopies(GET_ALL_TABLES_FROM_DATABASE, TEST_SCHEMAS_COUNT)
+                        .addCopies(GET_RELATIONS_FROM_DATABASE, TEST_SCHEMAS_COUNT)
                         .addCopies(GET_TABLE, TEST_ALL_TABLES_COUNT)
                         .build());
 
@@ -511,7 +511,7 @@ public void testSelectColumnsWithLikeOverSchema()
                 "SELECT * FROM information_schema.columns WHERE table_schema LIKE 'test%'",
                 ImmutableMultiset.builder()
                         .add(GET_ALL_DATABASES)
-                        .addCopies(GET_ALL_TABLES_FROM_DATABASE, TEST_SCHEMAS_COUNT)
+                        .addCopies(GET_RELATIONS_FROM_DATABASE, TEST_SCHEMAS_COUNT)
                         .addCopies(GET_ALL_VIEWS_FROM_DATABASE, TEST_SCHEMAS_COUNT)
                         .addCopies(GET_TABLE, TEST_ALL_TABLES_COUNT)
                         .build());
@@ -519,7 +519,7 @@ public void testSelectColumnsWithLikeOverSchema()
                 "SELECT * FROM system.jdbc.columns WHERE table_schem LIKE 'test%'",
                 ImmutableMultiset.builder()
                         .add(GET_ALL_DATABASES)
-                        .addCopies(GET_ALL_TABLES_FROM_DATABASE, TEST_SCHEMAS_COUNT)
+                        .addCopies(GET_RELATIONS_FROM_DATABASE, TEST_SCHEMAS_COUNT)
                         .addCopies(GET_TABLE, TEST_ALL_TABLES_COUNT)
                         .build());
     }
@@ -534,7 +534,7 @@ public void testSelectColumnsFilterByTableName()
                 "SELECT * FROM information_schema.columns WHERE table_name = 'test_table_0'",
                 ImmutableMultiset.builder()
                         .add(GET_ALL_DATABASES)
-                        .add(GET_ALL_TABLES)
+                        .add(GET_RELATIONS)
                         .add(GET_ALL_VIEWS)
                         // TODO When there are many schemas, there are no "prefixes" and we end up calling ConnectorMetadata without any filter whatsoever.
                         //  If such queries are common enough, we could iterate over schemas and for each schema try getting a table by given name.
@@ -556,7 +556,7 @@ public void testSelectColumnsFilterByTableName()
                 "SELECT * FROM system.jdbc.columns WHERE table_name LIKE 'test_table_0' ESCAPE '\\'",
                 ImmutableMultiset.builder()
                         .add(GET_ALL_DATABASES)
-                        .addCopies(GET_ALL_TABLES_FROM_DATABASE, TEST_SCHEMAS_COUNT)
+                        .addCopies(GET_RELATIONS_FROM_DATABASE, TEST_SCHEMAS_COUNT)
                         .addCopies(GET_TABLE, TEST_SCHEMAS_COUNT)
                         .build());
 
@@ -565,7 +565,7 @@ public void testSelectColumnsFilterByTableName()
                 "SELECT * FROM information_schema.columns WHERE table_name = 'test_table_0'",
                 ImmutableMultiset.builder()
                         .add(GET_ALL_DATABASES)
-                        .addCopies(GET_ALL_TABLES_FROM_DATABASE, TEST_SCHEMAS_COUNT)
+                        .addCopies(GET_RELATIONS_FROM_DATABASE, TEST_SCHEMAS_COUNT)
                         .addCopies(GET_ALL_VIEWS_FROM_DATABASE, TEST_SCHEMAS_COUNT)
                         // TODO When there are many schemas, there are no "prefixes" and we end up calling ConnectorMetadata without any filter whatsoever.
                         //  If such queries are common enough, we could iterate over schemas and for each schema try getting a table by given name.
@@ -587,7 +587,7 @@ public void testSelectColumnsFilterByTableName()
                 "SELECT * FROM system.jdbc.columns WHERE table_name LIKE 'test_table_0' ESCAPE '\\'",
                 ImmutableMultiset.builder()
                         .add(GET_ALL_DATABASES)
-                        .addCopies(GET_ALL_TABLES_FROM_DATABASE, TEST_SCHEMAS_COUNT)
+                        .addCopies(GET_RELATIONS_FROM_DATABASE, TEST_SCHEMAS_COUNT)
                         .addCopies(GET_TABLE, TEST_SCHEMAS_COUNT)
                         .build());
     }
@@ -601,14 +601,14 @@ public void testSelectColumnsWithLikeOverTableName()
         assertMetastoreInvocations("SELECT * FROM information_schema.columns WHERE table_name LIKE 'test%'",
                 ImmutableMultiset.builder()
                         .add(GET_ALL_DATABASES)
-                        .add(GET_ALL_TABLES)
+                        .add(GET_RELATIONS)
                         .add(GET_ALL_VIEWS)
                         .addCopies(GET_TABLE, TEST_ALL_TABLES_COUNT)
                         .build());
         assertMetastoreInvocations("SELECT * FROM system.jdbc.columns WHERE table_name LIKE 'test%'",
                 ImmutableMultiset.builder()
                         .add(GET_ALL_DATABASES)
-                        .addCopies(GET_ALL_TABLES_FROM_DATABASE, TEST_SCHEMAS_COUNT)
+                        .addCopies(GET_RELATIONS_FROM_DATABASE, TEST_SCHEMAS_COUNT)
                         .addCopies(GET_TABLE, TEST_ALL_TABLES_COUNT)
                         .build());
 
@@ -617,7 +617,7 @@ public void testSelectColumnsWithLikeOverTableName()
                 "SELECT * FROM information_schema.columns WHERE table_name LIKE 'test%'",
                 ImmutableMultiset.builder()
                         .add(GET_ALL_DATABASES)
-                        .addCopies(GET_ALL_TABLES_FROM_DATABASE, TEST_SCHEMAS_COUNT)
+                        .addCopies(GET_RELATIONS_FROM_DATABASE, TEST_SCHEMAS_COUNT)
                         .addCopies(GET_ALL_VIEWS_FROM_DATABASE, TEST_SCHEMAS_COUNT)
                         .addCopies(GET_TABLE, TEST_ALL_TABLES_COUNT)
                         .build());
@@ -625,7 +625,7 @@ public void testSelectColumnsWithLikeOverTableName()
                 "SELECT * FROM system.jdbc.columns WHERE table_name LIKE 'test%'",
                 ImmutableMultiset.builder()
                         .add(GET_ALL_DATABASES)
-                        .addCopies(GET_ALL_TABLES_FROM_DATABASE, TEST_SCHEMAS_COUNT)
+                        .addCopies(GET_RELATIONS_FROM_DATABASE, TEST_SCHEMAS_COUNT)
                         .addCopies(GET_TABLE, TEST_ALL_TABLES_COUNT)
                         .build());
     }
@@ -639,14 +639,14 @@ public void testSelectColumnsFilterByColumn()
         assertMetastoreInvocations(
                 "SELECT * FROM information_schema.columns WHERE column_name = 'name'",
                 ImmutableMultiset.builder()
-                        .add(GET_ALL_TABLES)
+                        .add(GET_RELATIONS)
                         .add(GET_ALL_VIEWS)
                         .addCopies(GET_TABLE, TEST_ALL_TABLES_COUNT)
                         .build());
         assertMetastoreInvocations(
                 "SELECT * FROM system.jdbc.columns WHERE column_name = 'name'",
                 ImmutableMultiset.builder()
-                        .add(GET_ALL_TABLES)
+                        .add(GET_RELATIONS)
                         .add(GET_ALL_VIEWS)
                         .addCopies(GET_TABLE, TEST_ALL_TABLES_COUNT)
                         .build());
@@ -656,7 +656,7 @@ public void testSelectColumnsFilterByColumn()
                 "SELECT * FROM information_schema.columns WHERE column_name = 'name'",
                 ImmutableMultiset.builder()
                         .add(GET_ALL_DATABASES)
-                        .addCopies(GET_ALL_TABLES_FROM_DATABASE, TEST_SCHEMAS_COUNT)
+                        .addCopies(GET_RELATIONS_FROM_DATABASE, TEST_SCHEMAS_COUNT)
                         .addCopies(GET_ALL_VIEWS_FROM_DATABASE, TEST_SCHEMAS_COUNT)
                         .addCopies(GET_TABLE, TEST_ALL_TABLES_COUNT)
                         .build());
@@ -664,7 +664,7 @@ public void testSelectColumnsFilterByColumn()
                 "SELECT * FROM system.jdbc.columns WHERE column_name = 'name'",
                 ImmutableMultiset.builder()
                         .add(GET_ALL_DATABASES)
-                        .addCopies(GET_ALL_TABLES_FROM_DATABASE, TEST_SCHEMAS_COUNT)
+                        .addCopies(GET_RELATIONS_FROM_DATABASE, TEST_SCHEMAS_COUNT)
                         .addCopies(GET_ALL_VIEWS_FROM_DATABASE, TEST_SCHEMAS_COUNT)
                         .addCopies(GET_TABLE, TEST_ALL_TABLES_COUNT)
                         .build());
@@ -680,14 +680,14 @@ public void testSelectColumnsWithLikeOverColumn()
                 "SELECT * FROM information_schema.columns WHERE column_name LIKE 'n%'",
                 ImmutableMultiset.builder()
                         .add(GET_ALL_DATABASES)
-                        .add(GET_ALL_TABLES)
+                        .add(GET_RELATIONS)
                         .add(GET_ALL_VIEWS)
                         .addCopies(GET_TABLE, TEST_ALL_TABLES_COUNT)
                         .build());
         assertMetastoreInvocations(
                 "SELECT * FROM system.jdbc.columns WHERE column_name LIKE 'n%'",
                 ImmutableMultiset.builder()
-                        .add(GET_ALL_TABLES)
+                        .add(GET_RELATIONS)
                         .add(GET_ALL_VIEWS)
                         .addCopies(GET_TABLE, TEST_ALL_TABLES_COUNT)
                         .build());
@@ -697,7 +697,7 @@ public void testSelectColumnsWithLikeOverColumn()
                 "SELECT * FROM information_schema.columns WHERE column_name LIKE 'n%'",
                 ImmutableMultiset.builder()
                         .add(GET_ALL_DATABASES)
-                        .addCopies(GET_ALL_TABLES_FROM_DATABASE, TEST_SCHEMAS_COUNT)
+                        .addCopies(GET_RELATIONS_FROM_DATABASE, TEST_SCHEMAS_COUNT)
                         .addCopies(GET_ALL_VIEWS_FROM_DATABASE, TEST_SCHEMAS_COUNT)
                         .addCopies(GET_TABLE, TEST_ALL_TABLES_COUNT)
                         .build());
@@ -705,7 +705,7 @@ public void testSelectColumnsWithLikeOverColumn()
                 "SELECT * FROM system.jdbc.columns WHERE column_name LIKE 'n%'",
                 ImmutableMultiset.builder()
                         .add(GET_ALL_DATABASES)
-                        .addCopies(GET_ALL_TABLES_FROM_DATABASE, TEST_SCHEMAS_COUNT)
+                        .addCopies(GET_RELATIONS_FROM_DATABASE, TEST_SCHEMAS_COUNT)
                         .addCopies(GET_ALL_VIEWS_FROM_DATABASE, TEST_SCHEMAS_COUNT)
                         .addCopies(GET_TABLE, TEST_ALL_TABLES_COUNT)
                         .build());
@@ -722,7 +722,7 @@ public void testSelectColumnsFilterByTableAndSchema()
         assertMetastoreInvocations("SELECT * FROM system.jdbc.columns WHERE table_schem LIKE 'test_schema_0' ESCAPE '\\' AND table_name LIKE 'test_table_0' ESCAPE '\\'",
                 ImmutableMultiset.builder()
                         .add(GET_ALL_DATABASES)
-                        .add(GET_ALL_TABLES_FROM_DATABASE)
+                        .add(GET_RELATIONS_FROM_DATABASE)
                         .add(GET_TABLE)
                         .build());
     }
@@ -755,13 +755,13 @@ public List getAllDatabases()
         }
 
         @Override
-        public List getAllTables(String databaseName)
+        public List getRelations(String databaseName)
         {
             return TABLES_PER_SCHEMA;
         }
 
         @Override
-        public Optional> getAllTables()
+        public Optional> getRelations()
         {
             if (allTablesViewsImplemented) {
                 return Optional.of(ALL_TABLES);
diff --git a/plugin/trino-hudi/src/main/java/io/trino/plugin/hudi/HudiMetadata.java b/plugin/trino-hudi/src/main/java/io/trino/plugin/hudi/HudiMetadata.java
index fbbc5e09cb4e..f62b22ab1991 100644
--- a/plugin/trino-hudi/src/main/java/io/trino/plugin/hudi/HudiMetadata.java
+++ b/plugin/trino-hudi/src/main/java/io/trino/plugin/hudi/HudiMetadata.java
@@ -205,7 +205,7 @@ public List listTables(ConnectorSession session, Optional tableNames = ImmutableList.builder();
         for (String schemaName : listSchemas(session, optionalSchemaName)) {
-            for (String tableName : metastore.getAllTables(schemaName)) {
+            for (String tableName : metastore.getRelations(schemaName)) {
                 tableNames.add(new SchemaTableName(schemaName, tableName));
             }
         }
diff --git a/plugin/trino-iceberg/src/main/java/io/trino/plugin/iceberg/catalog/hms/TrinoHiveCatalog.java b/plugin/trino-iceberg/src/main/java/io/trino/plugin/iceberg/catalog/hms/TrinoHiveCatalog.java
index a0a02eb6b1ee..efa11ebd5a1b 100644
--- a/plugin/trino-iceberg/src/main/java/io/trino/plugin/iceberg/catalog/hms/TrinoHiveCatalog.java
+++ b/plugin/trino-iceberg/src/main/java/io/trino/plugin/iceberg/catalog/hms/TrinoHiveCatalog.java
@@ -380,7 +380,7 @@ public List listTables(ConnectorSession session, Optional tablesListBuilder = ImmutableSet.builder();
         for (String schemaName : listNamespaces(session, namespace)) {
-            metastore.getAllTables(schemaName).forEach(tableName -> tablesListBuilder.add(new SchemaTableName(schemaName, tableName)));
+            metastore.getRelations(schemaName).forEach(tableName -> tablesListBuilder.add(new SchemaTableName(schemaName, tableName)));
         }
         return tablesListBuilder.build().asList();
     }
diff --git a/plugin/trino-iceberg/src/test/java/io/trino/plugin/iceberg/TestIcebergMetadataListing.java b/plugin/trino-iceberg/src/test/java/io/trino/plugin/iceberg/TestIcebergMetadataListing.java
index d05e92225477..493a1c97a5a2 100644
--- a/plugin/trino-iceberg/src/test/java/io/trino/plugin/iceberg/TestIcebergMetadataListing.java
+++ b/plugin/trino-iceberg/src/test/java/io/trino/plugin/iceberg/TestIcebergMetadataListing.java
@@ -102,7 +102,7 @@ public void tearDown()
     @Test
     public void testTableListing()
     {
-        assertThat(metastore.getAllTables("test_schema"))
+        assertThat(metastore.getRelations("test_schema"))
                 .containsExactlyInAnyOrder(
                         "iceberg_table1",
                         "iceberg_table2",
diff --git a/plugin/trino-iceberg/src/test/java/io/trino/plugin/iceberg/TestIcebergMetastoreAccessOperations.java b/plugin/trino-iceberg/src/test/java/io/trino/plugin/iceberg/TestIcebergMetastoreAccessOperations.java
index 005a0cfeccce..24223e88b544 100644
--- a/plugin/trino-iceberg/src/test/java/io/trino/plugin/iceberg/TestIcebergMetastoreAccessOperations.java
+++ b/plugin/trino-iceberg/src/test/java/io/trino/plugin/iceberg/TestIcebergMetastoreAccessOperations.java
@@ -34,8 +34,8 @@
 import static com.google.inject.util.Modules.EMPTY_MODULE;
 import static io.trino.plugin.hive.metastore.CountingAccessHiveMetastore.Method.CREATE_TABLE;
 import static io.trino.plugin.hive.metastore.CountingAccessHiveMetastore.Method.DROP_TABLE;
-import static io.trino.plugin.hive.metastore.CountingAccessHiveMetastore.Method.GET_ALL_TABLES_FROM_DATABASE;
 import static io.trino.plugin.hive.metastore.CountingAccessHiveMetastore.Method.GET_DATABASE;
+import static io.trino.plugin.hive.metastore.CountingAccessHiveMetastore.Method.GET_RELATIONS_FROM_DATABASE;
 import static io.trino.plugin.hive.metastore.CountingAccessHiveMetastore.Method.GET_TABLE;
 import static io.trino.plugin.hive.metastore.CountingAccessHiveMetastore.Method.GET_TABLES_WITH_PARAMETER;
 import static io.trino.plugin.hive.metastore.CountingAccessHiveMetastore.Method.REPLACE_TABLE;
@@ -393,7 +393,7 @@ public void testInformationSchemaColumns(int tables)
         // Bulk retrieval
         assertMetastoreInvocations(session, "SELECT * FROM information_schema.columns WHERE table_schema = CURRENT_SCHEMA AND table_name LIKE 'test_select_i_s_columns%'",
                 ImmutableMultiset.builder()
-                        .add(GET_ALL_TABLES_FROM_DATABASE)
+                        .add(GET_RELATIONS_FROM_DATABASE)
                         .addCopies(GET_TABLE, tables * 2)
                         .addCopies(GET_TABLES_WITH_PARAMETER, 2)
                         .build());
@@ -439,7 +439,7 @@ public void testSystemMetadataTableComments(int tables)
         // Bulk retrieval
         assertMetastoreInvocations(session, "SELECT * FROM system.metadata.table_comments WHERE schema_name = CURRENT_SCHEMA AND table_name LIKE 'test_select_s_m_t_comments%'",
                 ImmutableMultiset.builder()
-                        .add(GET_ALL_TABLES_FROM_DATABASE)
+                        .add(GET_RELATIONS_FROM_DATABASE)
                         .addCopies(GET_TABLE, tables * 2)
                         .addCopies(GET_TABLES_WITH_PARAMETER, 2)
                         .build());
@@ -447,7 +447,7 @@ public void testSystemMetadataTableComments(int tables)
         // Bulk retrieval for two schemas
         assertMetastoreInvocations(session, "SELECT * FROM system.metadata.table_comments WHERE schema_name IN (CURRENT_SCHEMA, 'non_existent') AND table_name LIKE 'test_select_s_m_t_comments%'",
                 ImmutableMultiset.builder()
-                        .addCopies(GET_ALL_TABLES_FROM_DATABASE, 2)
+                        .addCopies(GET_RELATIONS_FROM_DATABASE, 2)
                         .addCopies(GET_TABLES_WITH_PARAMETER, 4)
                         .addCopies(GET_TABLE, tables * 2)
                         .build());
@@ -533,7 +533,7 @@ public void testShowTables()
         assertMetastoreInvocations("SHOW TABLES",
                 ImmutableMultiset.builder()
                         .add(GET_DATABASE)
-                        .add(GET_ALL_TABLES_FROM_DATABASE)
+                        .add(GET_RELATIONS_FROM_DATABASE)
                         .build());
     }
 
diff --git a/plugin/trino-kafka/src/test/java/io/trino/plugin/kafka/TestMinimalFunctionality.java b/plugin/trino-kafka/src/test/java/io/trino/plugin/kafka/TestMinimalFunctionality.java
index c11b45322c96..8ddfabf31357 100644
--- a/plugin/trino-kafka/src/test/java/io/trino/plugin/kafka/TestMinimalFunctionality.java
+++ b/plugin/trino-kafka/src/test/java/io/trino/plugin/kafka/TestMinimalFunctionality.java
@@ -54,7 +54,7 @@ protected QueryRunner createQueryRunner()
     @Test
     public void testTopicExists()
     {
-        assertThat(getQueryRunner().listTables(getSession(), "kafka", "default")).contains(QualifiedObjectName.valueOf("kafka.default." + topicName));
+        assertThat(getQueryRunner().listRelations(getSession(), "kafka", "default")).contains(QualifiedObjectName.valueOf("kafka.default." + topicName));
     }
 
     @Test
diff --git a/plugin/trino-redshift/src/test/java/io/trino/plugin/redshift/RedshiftQueryRunner.java b/plugin/trino-redshift/src/test/java/io/trino/plugin/redshift/RedshiftQueryRunner.java
index fb9477742ce7..528f251c73c4 100644
--- a/plugin/trino-redshift/src/test/java/io/trino/plugin/redshift/RedshiftQueryRunner.java
+++ b/plugin/trino-redshift/src/test/java/io/trino/plugin/redshift/RedshiftQueryRunner.java
@@ -204,7 +204,7 @@ public static  T executeWithRedshift(HandleCallback> tables)
     {
-        Set existingTables = queryRunner.listTables(session, session.getCatalog().orElseThrow(), session.getSchema().orElseThrow())
+        Set existingTables = queryRunner.listRelations(session, session.getCatalog().orElseThrow(), session.getSchema().orElseThrow())
                 .stream()
                 .map(QualifiedObjectName::getObjectName)
                 .collect(toUnmodifiableSet());
diff --git a/plugin/trino-thrift/src/test/java/io/trino/plugin/thrift/integration/ThriftQueryRunner.java b/plugin/trino-thrift/src/test/java/io/trino/plugin/thrift/integration/ThriftQueryRunner.java
index c1890f3cfb78..928bf7ab67d6 100644
--- a/plugin/trino-thrift/src/test/java/io/trino/plugin/thrift/integration/ThriftQueryRunner.java
+++ b/plugin/trino-thrift/src/test/java/io/trino/plugin/thrift/integration/ThriftQueryRunner.java
@@ -308,9 +308,9 @@ public MaterializedResult execute(Session session, String sql)
         }
 
         @Override
-        public List listTables(Session session, String catalog, String schema)
+        public List listRelations(Session session, String catalog, String schema)
         {
-            return source.listTables(session, catalog, schema);
+            return source.listRelations(session, catalog, schema);
         }
 
         @Override
diff --git a/testing/trino-testing/src/main/java/io/trino/testing/AbstractTestingTrinoClient.java b/testing/trino-testing/src/main/java/io/trino/testing/AbstractTestingTrinoClient.java
index 806ba333ecb0..b887ec86bf28 100644
--- a/testing/trino-testing/src/main/java/io/trino/testing/AbstractTestingTrinoClient.java
+++ b/testing/trino-testing/src/main/java/io/trino/testing/AbstractTestingTrinoClient.java
@@ -196,7 +196,7 @@ private static ClientSelectedRole toClientSelectedRole(io.trino.spi.security.Sel
     public List listTables(Session session, String catalog, String schema)
     {
         return inTransaction(session, transactionSession ->
-                trinoServer.getMetadata().listTables(transactionSession, new QualifiedTablePrefix(catalog, schema)));
+                trinoServer.getMetadata().listRelations(transactionSession, new QualifiedTablePrefix(catalog, schema)));
     }
 
     public boolean tableExists(Session session, String table)
diff --git a/testing/trino-testing/src/main/java/io/trino/testing/DistributedQueryRunner.java b/testing/trino-testing/src/main/java/io/trino/testing/DistributedQueryRunner.java
index e77f27a55e36..f10d08047a46 100644
--- a/testing/trino-testing/src/main/java/io/trino/testing/DistributedQueryRunner.java
+++ b/testing/trino-testing/src/main/java/io/trino/testing/DistributedQueryRunner.java
@@ -454,7 +454,7 @@ public void createCatalog(String catalogName, String connectorName, Map listTables(Session session, String catalog, String schema)
+    public List listRelations(Session session, String catalog, String schema)
     {
         lock.readLock().lock();
         try {
diff --git a/testing/trino-testing/src/main/java/io/trino/testing/StandaloneQueryRunner.java b/testing/trino-testing/src/main/java/io/trino/testing/StandaloneQueryRunner.java
index 5a9824e46624..d0421d7a9638 100644
--- a/testing/trino-testing/src/main/java/io/trino/testing/StandaloneQueryRunner.java
+++ b/testing/trino-testing/src/main/java/io/trino/testing/StandaloneQueryRunner.java
@@ -225,7 +225,7 @@ public void createCatalog(String catalogName, String connectorName, Map listTables(Session session, String catalog, String schema)
+    public List listRelations(Session session, String catalog, String schema)
     {
         lock.readLock().lock();
         try {
diff --git a/testing/trino-tests/src/test/java/io/trino/connector/informationschema/TestInformationSchemaConnector.java b/testing/trino-tests/src/test/java/io/trino/connector/informationschema/TestInformationSchemaConnector.java
index 167dbe40d7b5..cf15343f8abb 100644
--- a/testing/trino-tests/src/test/java/io/trino/connector/informationschema/TestInformationSchemaConnector.java
+++ b/testing/trino-tests/src/test/java/io/trino/connector/informationschema/TestInformationSchemaConnector.java
@@ -175,32 +175,27 @@ public void testMetadataCalls()
                 "SELECT count(table_name), count(table_type) from test_catalog.information_schema.tables",
                 "VALUES (3008, 3008)",
                 ImmutableMultiset.builder()
-                        .add("ConnectorMetadata.listTables")
-                        .add("ConnectorMetadata.listViews")
+                        .add("ConnectorMetadata.getRelationTypes")
                         .build());
         assertMetadataCalls(
                 "SELECT count(table_name), count(table_type) from test_catalog.information_schema.tables WHERE table_schema = 'test_schema1'",
                 "VALUES (1000, 1000)",
                 ImmutableMultiset.builder()
-                        .add("ConnectorMetadata.listTables(schema=test_schema1)")
-                        .add("ConnectorMetadata.listViews(schema=test_schema1)")
+                        .add("ConnectorMetadata.getRelationTypes(schema=test_schema1)")
                         .build());
         assertMetadataCalls(
                 "SELECT count(table_name), count(table_type) from test_catalog.information_schema.tables WHERE table_schema LIKE 'test_sch_ma1'",
                 "VALUES (1000, 1000)",
                 ImmutableMultiset.builder()
                         .add("ConnectorMetadata.listSchemaNames")
-                        .add("ConnectorMetadata.listTables(schema=test_schema1)")
-                        .add("ConnectorMetadata.listViews(schema=test_schema1)")
+                        .add("ConnectorMetadata.getRelationTypes(schema=test_schema1)")
                         .build());
         assertMetadataCalls(
                 "SELECT count(table_name), count(table_type) from test_catalog.information_schema.tables WHERE table_schema LIKE 'test_sch_ma1' AND table_schema IN ('test_schema1', 'test_schema2')",
                 "VALUES (1000, 1000)",
                 ImmutableMultiset.builder()
-                        .add("ConnectorMetadata.listTables(schema=test_schema1)")
-                        .add("ConnectorMetadata.listViews(schema=test_schema1)")
-                        .add("ConnectorMetadata.listTables(schema=test_schema2)")
-                        .add("ConnectorMetadata.listViews(schema=test_schema2)")
+                        .add("ConnectorMetadata.getRelationTypes(schema=test_schema1)")
+                        .add("ConnectorMetadata.getRelationTypes(schema=test_schema2)")
                         .build());
         assertMetadataCalls(
                 "SELECT count(table_name), count(table_type) from test_catalog.information_schema.tables WHERE table_schema IN " +
@@ -212,26 +207,25 @@ public void testMetadataCalls()
                                 .collect(joining(",", "(", ")")),
                 "VALUES (3000, 3000)",
                 ImmutableMultiset.builder()
-                        .add("ConnectorMetadata.listTables")
-                        .add("ConnectorMetadata.listViews")
+                        .add("ConnectorMetadata.getRelationTypes")
                         .build());
         assertMetadataCalls(
                 "SELECT count(table_name), count(table_type) from test_catalog.information_schema.tables WHERE table_name = 'test_table1'",
                 "VALUES (2, 2)",
                 ImmutableMultiset.builder()
                         .add("ConnectorMetadata.listSchemaNames")
-                        .addCopies("ConnectorMetadata.getSystemTable(schema=test_schema1, table=test_table1)", 5)
-                        .addCopies("ConnectorMetadata.getSystemTable(schema=test_schema2, table=test_table1)", 5)
-                        .addCopies("ConnectorMetadata.getSystemTable(schema=test_schema3_empty, table=test_table1)", 5)
-                        .addCopies("ConnectorMetadata.getSystemTable(schema=test_schema4_empty, table=test_table1)", 5)
+                        .addCopies("ConnectorMetadata.getSystemTable(schema=test_schema1, table=test_table1)", 4)
+                        .addCopies("ConnectorMetadata.getSystemTable(schema=test_schema2, table=test_table1)", 4)
+                        .addCopies("ConnectorMetadata.getSystemTable(schema=test_schema3_empty, table=test_table1)", 4)
+                        .addCopies("ConnectorMetadata.getSystemTable(schema=test_schema4_empty, table=test_table1)", 4)
                         .add("ConnectorMetadata.getMaterializedView(schema=test_schema1, table=test_table1)")
                         .add("ConnectorMetadata.getMaterializedView(schema=test_schema2, table=test_table1)")
                         .add("ConnectorMetadata.getMaterializedView(schema=test_schema3_empty, table=test_table1)")
                         .add("ConnectorMetadata.getMaterializedView(schema=test_schema4_empty, table=test_table1)")
-                        .addCopies("ConnectorMetadata.getView(schema=test_schema1, table=test_table1)", 2)
-                        .addCopies("ConnectorMetadata.getView(schema=test_schema2, table=test_table1)", 2)
-                        .addCopies("ConnectorMetadata.getView(schema=test_schema3_empty, table=test_table1)", 2)
-                        .addCopies("ConnectorMetadata.getView(schema=test_schema4_empty, table=test_table1)", 2)
+                        .add("ConnectorMetadata.getView(schema=test_schema1, table=test_table1)")
+                        .add("ConnectorMetadata.getView(schema=test_schema2, table=test_table1)")
+                        .add("ConnectorMetadata.getView(schema=test_schema3_empty, table=test_table1)")
+                        .add("ConnectorMetadata.getView(schema=test_schema4_empty, table=test_table1)")
                         .add("ConnectorMetadata.redirectTable(schema=test_schema1, table=test_table1)")
                         .add("ConnectorMetadata.redirectTable(schema=test_schema2, table=test_table1)")
                         .add("ConnectorMetadata.redirectTable(schema=test_schema3_empty, table=test_table1)")
@@ -246,28 +240,24 @@ public void testMetadataCalls()
                 "VALUES (2, 2)",
                 ImmutableMultiset.builder()
                         .add("ConnectorMetadata.listSchemaNames")
-                        .add("ConnectorMetadata.listTables(schema=test_schema1)")
-                        .add("ConnectorMetadata.listTables(schema=test_schema2)")
-                        .add("ConnectorMetadata.listTables(schema=test_schema3_empty)")
-                        .add("ConnectorMetadata.listTables(schema=test_schema4_empty)")
-                        .add("ConnectorMetadata.listViews(schema=test_schema1)")
-                        .add("ConnectorMetadata.listViews(schema=test_schema2)")
-                        .add("ConnectorMetadata.listViews(schema=test_schema3_empty)")
-                        .add("ConnectorMetadata.listViews(schema=test_schema4_empty)")
+                        .add("ConnectorMetadata.getRelationTypes(schema=test_schema1)")
+                        .add("ConnectorMetadata.getRelationTypes(schema=test_schema2)")
+                        .add("ConnectorMetadata.getRelationTypes(schema=test_schema3_empty)")
+                        .add("ConnectorMetadata.getRelationTypes(schema=test_schema4_empty)")
                         .build());
         assertMetadataCalls(
                 "SELECT count(table_name), count(table_type) from test_catalog.information_schema.tables WHERE table_name LIKE 'test_t_ble1' AND table_name IN ('test_table1', 'test_table2')",
                 "VALUES (2, 2)",
                 ImmutableMultiset.builder()
                         .add("ConnectorMetadata.listSchemaNames")
-                        .addCopies("ConnectorMetadata.getSystemTable(schema=test_schema1, table=test_table1)", 5)
-                        .addCopies("ConnectorMetadata.getSystemTable(schema=test_schema1, table=test_table2)", 5)
-                        .addCopies("ConnectorMetadata.getSystemTable(schema=test_schema2, table=test_table1)", 5)
-                        .addCopies("ConnectorMetadata.getSystemTable(schema=test_schema2, table=test_table2)", 5)
-                        .addCopies("ConnectorMetadata.getSystemTable(schema=test_schema3_empty, table=test_table1)", 5)
-                        .addCopies("ConnectorMetadata.getSystemTable(schema=test_schema3_empty, table=test_table2)", 5)
-                        .addCopies("ConnectorMetadata.getSystemTable(schema=test_schema4_empty, table=test_table1)", 5)
-                        .addCopies("ConnectorMetadata.getSystemTable(schema=test_schema4_empty, table=test_table2)", 5)
+                        .addCopies("ConnectorMetadata.getSystemTable(schema=test_schema1, table=test_table1)", 4)
+                        .addCopies("ConnectorMetadata.getSystemTable(schema=test_schema1, table=test_table2)", 4)
+                        .addCopies("ConnectorMetadata.getSystemTable(schema=test_schema2, table=test_table1)", 4)
+                        .addCopies("ConnectorMetadata.getSystemTable(schema=test_schema2, table=test_table2)", 4)
+                        .addCopies("ConnectorMetadata.getSystemTable(schema=test_schema3_empty, table=test_table1)", 4)
+                        .addCopies("ConnectorMetadata.getSystemTable(schema=test_schema3_empty, table=test_table2)", 4)
+                        .addCopies("ConnectorMetadata.getSystemTable(schema=test_schema4_empty, table=test_table1)", 4)
+                        .addCopies("ConnectorMetadata.getSystemTable(schema=test_schema4_empty, table=test_table2)", 4)
                         .add("ConnectorMetadata.getMaterializedView(schema=test_schema1, table=test_table1)")
                         .add("ConnectorMetadata.getMaterializedView(schema=test_schema1, table=test_table2)")
                         .add("ConnectorMetadata.getMaterializedView(schema=test_schema2, table=test_table2)")
@@ -276,14 +266,14 @@ public void testMetadataCalls()
                         .add("ConnectorMetadata.getMaterializedView(schema=test_schema3_empty, table=test_table1)")
                         .add("ConnectorMetadata.getMaterializedView(schema=test_schema4_empty, table=test_table2)")
                         .add("ConnectorMetadata.getMaterializedView(schema=test_schema4_empty, table=test_table1)")
-                        .addCopies("ConnectorMetadata.getView(schema=test_schema1, table=test_table1)", 2)
-                        .addCopies("ConnectorMetadata.getView(schema=test_schema1, table=test_table2)", 2)
-                        .addCopies("ConnectorMetadata.getView(schema=test_schema2, table=test_table1)", 2)
-                        .addCopies("ConnectorMetadata.getView(schema=test_schema2, table=test_table2)", 2)
-                        .addCopies("ConnectorMetadata.getView(schema=test_schema3_empty, table=test_table1)", 2)
-                        .addCopies("ConnectorMetadata.getView(schema=test_schema3_empty, table=test_table2)", 2)
-                        .addCopies("ConnectorMetadata.getView(schema=test_schema4_empty, table=test_table1)", 2)
-                        .addCopies("ConnectorMetadata.getView(schema=test_schema4_empty, table=test_table2)", 2)
+                        .add("ConnectorMetadata.getView(schema=test_schema1, table=test_table1)")
+                        .add("ConnectorMetadata.getView(schema=test_schema1, table=test_table2)")
+                        .add("ConnectorMetadata.getView(schema=test_schema2, table=test_table1)")
+                        .add("ConnectorMetadata.getView(schema=test_schema2, table=test_table2)")
+                        .add("ConnectorMetadata.getView(schema=test_schema3_empty, table=test_table1)")
+                        .add("ConnectorMetadata.getView(schema=test_schema3_empty, table=test_table2)")
+                        .add("ConnectorMetadata.getView(schema=test_schema4_empty, table=test_table1)")
+                        .add("ConnectorMetadata.getView(schema=test_schema4_empty, table=test_table2)")
                         .add("ConnectorMetadata.redirectTable(schema=test_schema1, table=test_table1)")
                         .add("ConnectorMetadata.redirectTable(schema=test_schema1, table=test_table2)")
                         .add("ConnectorMetadata.redirectTable(schema=test_schema2, table=test_table1)")
@@ -376,7 +366,7 @@ public void testMetadataCalls()
                 "VALUES 1000",
                 ImmutableMultiset.builder()
                         .add("ConnectorMetadata.listSchemaNames")
-                        .add("ConnectorMetadata.listTables(schema=test_schema1)")
+                        .add("ConnectorMetadata.listRelations(schema=test_schema1)")
                         // view-related methods such as listViews not being called
                         .build());
     }
diff --git a/testing/trino-tests/src/test/java/io/trino/tests/TestMetadataManager.java b/testing/trino-tests/src/test/java/io/trino/tests/TestMetadataManager.java
index c40dec07c4c8..f1a7216f95ae 100644
--- a/testing/trino-tests/src/test/java/io/trino/tests/TestMetadataManager.java
+++ b/testing/trino-tests/src/test/java/io/trino/tests/TestMetadataManager.java
@@ -125,14 +125,14 @@ public void testMetadataIsClearedAfterQueryFailed()
     }
 
     @Test
-    public void testMetadataListTablesReturnsQualifiedView()
+    public void testMetadataListRelationsReturnsQualifiedView()
     {
         TransactionBuilder.transaction(queryRunner.getTransactionManager(), metadataManager, queryRunner.getAccessControl())
                 .execute(
                         TEST_SESSION,
                         transactionSession -> {
                             QualifiedTablePrefix viewName = new QualifiedTablePrefix("upper_case_schema_catalog", "upper_case_schema", "test_view");
-                            assertThat(metadataManager.listTables(transactionSession, viewName)).containsExactly(viewName.asQualifiedObjectName().get());
+                            assertThat(metadataManager.listRelations(transactionSession, viewName)).containsExactly(viewName.asQualifiedObjectName().get());
                         });
     }