diff --git a/plugin/trino-bigquery/pom.xml b/plugin/trino-bigquery/pom.xml index 9383232f1e0a..2676d0d1e759 100644 --- a/plugin/trino-bigquery/pom.xml +++ b/plugin/trino-bigquery/pom.xml @@ -335,6 +335,12 @@ test + + org.jetbrains + annotations + test + + org.mockito mockito-core diff --git a/plugin/trino-bigquery/src/main/java/io/trino/plugin/bigquery/BigQueryMetadata.java b/plugin/trino-bigquery/src/main/java/io/trino/plugin/bigquery/BigQueryMetadata.java index 57d7a5502687..7789d42a601e 100644 --- a/plugin/trino-bigquery/src/main/java/io/trino/plugin/bigquery/BigQueryMetadata.java +++ b/plugin/trino-bigquery/src/main/java/io/trino/plugin/bigquery/BigQueryMetadata.java @@ -65,6 +65,7 @@ import java.util.function.Function; import java.util.stream.Stream; +import static com.google.cloud.bigquery.TableDefinition.Type.MATERIALIZED_VIEW; import static com.google.cloud.bigquery.TableDefinition.Type.TABLE; import static com.google.cloud.bigquery.TableDefinition.Type.VIEW; import static com.google.common.base.Preconditions.checkArgument; @@ -176,7 +177,7 @@ public List listTables(ConnectorSession session, Optional tableNames = ImmutableList.builder(); for (String remoteSchemaName : remoteSchemaNames) { try { - Iterable tables = client.listTables(DatasetId.of(projectId, remoteSchemaName), TABLE, VIEW); + Iterable
tables = client.listTables(DatasetId.of(projectId, remoteSchemaName), TABLE, VIEW, MATERIALIZED_VIEW); for (Table table : tables) { // filter ambiguous tables client.toRemoteTable(projectId, remoteSchemaName, table.getTableId().getTable().toLowerCase(ENGLISH), tables) diff --git a/plugin/trino-bigquery/src/main/java/io/trino/plugin/bigquery/BigQuerySplitManager.java b/plugin/trino-bigquery/src/main/java/io/trino/plugin/bigquery/BigQuerySplitManager.java index 5b8df2b584c9..56bdd8c45302 100644 --- a/plugin/trino-bigquery/src/main/java/io/trino/plugin/bigquery/BigQuerySplitManager.java +++ b/plugin/trino-bigquery/src/main/java/io/trino/plugin/bigquery/BigQuerySplitManager.java @@ -41,6 +41,7 @@ import java.util.List; import java.util.Optional; +import static com.google.cloud.bigquery.TableDefinition.Type.MATERIALIZED_VIEW; import static com.google.cloud.bigquery.TableDefinition.Type.TABLE; import static com.google.cloud.bigquery.TableDefinition.Type.VIEW; import static com.google.common.collect.ImmutableList.toImmutableList; @@ -115,6 +116,10 @@ private List readFromBigQuery(ConnectorSession session, TableDefi .map(column -> ((BigQueryColumnHandle) column).getName()) .collect(toImmutableList()); + if (type == MATERIALIZED_VIEW) { + // Storage API doesn't support reading materialized views + return ImmutableList.of(BigQuerySplit.forViewStream(columns, filter)); + } if (skipViewMaterialization && type == VIEW) { return ImmutableList.of(BigQuerySplit.forViewStream(columns, filter)); } diff --git a/plugin/trino-bigquery/src/main/java/io/trino/plugin/bigquery/ReadSessionCreator.java b/plugin/trino-bigquery/src/main/java/io/trino/plugin/bigquery/ReadSessionCreator.java index 468cc492b3ca..2c1926ae0f66 100644 --- a/plugin/trino-bigquery/src/main/java/io/trino/plugin/bigquery/ReadSessionCreator.java +++ b/plugin/trino-bigquery/src/main/java/io/trino/plugin/bigquery/ReadSessionCreator.java @@ -29,6 +29,8 @@ import java.util.List; import java.util.Optional; +import static com.google.cloud.bigquery.TableDefinition.Type.TABLE; +import static com.google.cloud.bigquery.TableDefinition.Type.VIEW; import static io.trino.spi.StandardErrorCode.NOT_SUPPORTED; import static java.lang.String.format; import static java.util.stream.Collectors.toList; @@ -96,10 +98,10 @@ private TableInfo getActualTable( { TableDefinition tableDefinition = remoteTable.getDefinition(); TableDefinition.Type tableType = tableDefinition.getType(); - if (TableDefinition.Type.TABLE == tableType) { + if (tableType == TABLE) { return remoteTable; } - if (TableDefinition.Type.VIEW == tableType) { + if (tableType == VIEW) { if (!viewEnabled) { throw new TrinoException(NOT_SUPPORTED, format( "Views are not enabled. You can enable views by setting '%s' to true. Notice additional cost may occur.", diff --git a/plugin/trino-bigquery/src/test/java/io/trino/plugin/bigquery/BigQueryQueryRunner.java b/plugin/trino-bigquery/src/test/java/io/trino/plugin/bigquery/BigQueryQueryRunner.java index 2ae01370a66d..8978837fc0bf 100644 --- a/plugin/trino-bigquery/src/test/java/io/trino/plugin/bigquery/BigQueryQueryRunner.java +++ b/plugin/trino-bigquery/src/test/java/io/trino/plugin/bigquery/BigQueryQueryRunner.java @@ -31,6 +31,7 @@ import io.trino.plugin.tpch.TpchPlugin; import io.trino.testing.DistributedQueryRunner; import io.trino.testing.sql.SqlExecutor; +import org.intellij.lang.annotations.Language; import java.io.ByteArrayInputStream; import java.io.IOException; @@ -107,12 +108,12 @@ public BigQuerySqlExecutor() } @Override - public void execute(String sql) + public void execute(@Language("SQL") String sql) { executeQuery(sql); } - public TableResult executeQuery(String sql) + public TableResult executeQuery(@Language("SQL") String sql) { try { return bigQuery.query(QueryJobConfiguration.of(sql)); diff --git a/plugin/trino-bigquery/src/test/java/io/trino/plugin/bigquery/TestBigQueryConnectorTest.java b/plugin/trino-bigquery/src/test/java/io/trino/plugin/bigquery/TestBigQueryConnectorTest.java index 60b4d42b918d..abeb3d53fc83 100644 --- a/plugin/trino-bigquery/src/test/java/io/trino/plugin/bigquery/TestBigQueryConnectorTest.java +++ b/plugin/trino-bigquery/src/test/java/io/trino/plugin/bigquery/TestBigQueryConnectorTest.java @@ -21,6 +21,7 @@ import io.trino.testing.TestingConnectorBehavior; import io.trino.testing.sql.TestTable; import io.trino.testing.sql.TestView; +import org.intellij.lang.annotations.Language; import org.testng.annotations.BeforeClass; import org.testng.annotations.DataProvider; import org.testng.annotations.Test; @@ -582,7 +583,26 @@ public void testSymbolAliasing() assertUpdate("DROP TABLE " + tableName); } - private void onBigQuery(String sql) + @Test + public void testBigQueryMaterializedView() + { + String materializedView = "test_materialized_view" + randomTableSuffix(); + try { + onBigQuery("CREATE MATERIALIZED VIEW test." + materializedView + " AS SELECT count(1) AS cnt FROM tpch.region"); + assertQuery("SELECT table_type FROM information_schema.tables WHERE table_schema = 'test' AND table_name = '" + materializedView + "'", "VALUES 'BASE TABLE'"); + + assertQuery("DESCRIBE test." + materializedView, "VALUES ('cnt', 'bigint', '', '')"); + assertQuery("SELECT * FROM test." + materializedView, "VALUES 5"); + + assertUpdate("DROP TABLE test." + materializedView); + assertQueryReturnsEmptyResult("SELECT * FROM information_schema.tables WHERE table_schema = 'test' AND table_name = '" + materializedView + "'"); + } + finally { + onBigQuery("DROP MATERIALIZED VIEW IF EXISTS test." + materializedView); + } + } + + private void onBigQuery(@Language("SQL") String sql) { bigQuerySqlExecutor.execute(sql); }