Skip to content

Commit

Permalink
Allow differentiating materialized views from tables efficiently
Browse files Browse the repository at this point in the history
Tools often need to list tables/relations and know whether they are
regular tables, views, or materialized views. For example, on a table
one can `SHOW CREATE TABLE` or `DROP TABLE`, but syntax for views and
materialized views is different. Before this change, to differentiate
different relations types, tools need to join
`information_schema.tables` with `system.metadata.materialized_views`.
This is effective, but not efficient:
`system.metadata.materialized_views` contains much more information. To
address the inefficiency, this commit introduces a new column to
`information_schema.tables`. To guarantee SQL spec future-compatibility,
the column is hidden and prefixed with `trino_`
  • Loading branch information
findepi committed Dec 1, 2023
1 parent 78ccc2d commit 1c5e5eb
Show file tree
Hide file tree
Showing 3 changed files with 25 additions and 15 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -277,34 +277,43 @@ private void addColumnsRecords(QualifiedTablePrefix prefix)

private void addTablesRecords(QualifiedTablePrefix prefix)
{
boolean needsTableType = requiredColumns.contains("table_type");
boolean needsTableType = requiredColumns.contains("table_type") || requiredColumns.contains("trino_relation_type");
Set<SchemaTableName> relations;
Set<SchemaTableName> views;
Map<SchemaTableName, RelationType> relationTypes;
if (needsTableType) {
Map<SchemaTableName, RelationType> relationTypes = getRelationTypes(session, metadata, accessControl, prefix);
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 = listTables(session, metadata, accessControl, prefix);
views = Set.of();
relationTypes = null;
}
// TODO (https://github.com/trinodb/trino/issues/8207) define a type for materialized views

for (SchemaTableName name : relations) {
String type = null;
String trinoRelationType = null;
if (needsTableType) {
// if table and view names overlap, the view wins
type = views.contains(name) ? "VIEW" : "BASE TABLE";
switch (relationTypes.get(name)) {
case TABLE -> {
type = "BASE TABLE";
trinoRelationType = type;
}
case VIEW -> {
type = "VIEW";
trinoRelationType = type;
}
case MATERIALIZED_VIEW -> {
type = "BASE TABLE";
trinoRelationType = "MATERIALIZED VIEW";
}
}
}
addRecord(
prefix.getCatalogName(),
name.getSchemaName(),
name.getTableName(),
type,
trinoRelationType,
null);
if (isLimitExhausted()) {
return;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ public enum InformationSchemaTable
.column("table_schema", createUnboundedVarcharType())
.column("table_name", createUnboundedVarcharType())
.column("table_type", createUnboundedVarcharType())
.hiddenColumn("trino_relation_type", createUnboundedVarcharType())
.hiddenColumn("table_comment", createUnboundedVarcharType()) // MySQL compatible
.build()),
VIEWS(table("views")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1052,15 +1052,15 @@ public void testMaterializedView()
.containsAll("VALUES '" + view.getObjectName() + "'");
// information_schema.tables without table_name filter so that ConnectorMetadata.listViews is exercised
assertThat(query(
"SELECT table_name, table_type FROM information_schema.tables " +
"SELECT table_name, table_type, trino_relation_type FROM information_schema.tables " +
"WHERE table_schema = '" + view.getSchemaName() + "'"))
.skippingTypesCheck()
.containsAll("VALUES ('" + view.getObjectName() + "', 'BASE TABLE')");
.containsAll("VALUES ('" + view.getObjectName() + "', 'BASE TABLE', 'MATERIALIZED VIEW')");
// information_schema.tables with table_name filter
assertQuery(
"SELECT table_name, table_type FROM information_schema.tables " +
"SELECT table_name, table_type, trino_relation_type FROM information_schema.tables " +
"WHERE table_schema = '" + view.getSchemaName() + "' and table_name = '" + view.getObjectName() + "'",
"VALUES ('" + view.getObjectName() + "', 'BASE TABLE')");
"VALUES ('" + view.getObjectName() + "', 'BASE TABLE', 'MATERIALIZED VIEW')");

// system.jdbc.tables without filter
assertThat(query("SELECT table_schem, table_name, table_type FROM system.jdbc.tables"))
Expand Down

0 comments on commit 1c5e5eb

Please sign in to comment.