diff --git a/plugin/trino-accumulo/src/test/java/io/trino/plugin/accumulo/TestAccumuloConnectorTest.java b/plugin/trino-accumulo/src/test/java/io/trino/plugin/accumulo/TestAccumuloConnectorTest.java index 8b7be9d8eb9c..049e8ad656b7 100644 --- a/plugin/trino-accumulo/src/test/java/io/trino/plugin/accumulo/TestAccumuloConnectorTest.java +++ b/plugin/trino-accumulo/src/test/java/io/trino/plugin/accumulo/TestAccumuloConnectorTest.java @@ -71,6 +71,9 @@ protected boolean hasBehavior(TestingConnectorBehavior connectorBehavior) case SUPPORTS_TOPN_PUSHDOWN: return false; + case SUPPORTS_CREATE_VIEW: + return true; + default: return super.hasBehavior(connectorBehavior); } diff --git a/plugin/trino-hive/src/test/java/io/trino/plugin/hive/TestHiveConnectorSmokeTest.java b/plugin/trino-hive/src/test/java/io/trino/plugin/hive/TestHiveConnectorSmokeTest.java new file mode 100644 index 000000000000..4762a869b326 --- /dev/null +++ b/plugin/trino-hive/src/test/java/io/trino/plugin/hive/TestHiveConnectorSmokeTest.java @@ -0,0 +1,78 @@ +/* + * 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.plugin.hive; + +import io.trino.testing.BaseConnectorSmokeTest; +import io.trino.testing.QueryRunner; +import io.trino.testing.TestingConnectorBehavior; +import org.testng.annotations.Test; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatThrownBy; + +// Redundant over TestHiveConnectorTest, but exists to exercise BaseConnectorSmokeTest +// Some features like views may be supported by Hive only. +public class TestHiveConnectorSmokeTest + extends BaseConnectorSmokeTest +{ + @Override + protected QueryRunner createQueryRunner() + throws Exception + { + return HiveQueryRunner.builder() + .setInitialTables(REQUIRED_TPCH_TABLES) + .build(); + } + + @Override + protected boolean hasBehavior(TestingConnectorBehavior connectorBehavior) + { + switch (connectorBehavior) { + case SUPPORTS_TOPN_PUSHDOWN: + return false; + + case SUPPORTS_CREATE_VIEW: + return true; + + case SUPPORTS_DELETE: + return true; + + default: + return super.hasBehavior(connectorBehavior); + } + } + + @Override + public void testDelete() + { + assertThatThrownBy(super::testDelete) + .hasMessage("Deletes must match whole partitions for non-transactional tables"); + } + + @Test + @Override + public void testShowCreateTable() + { + assertThat((String) computeScalar("SHOW CREATE TABLE region")) + .isEqualTo("" + + "CREATE TABLE hive.tpch.region (\n" + + " regionkey bigint,\n" + + " name varchar(25),\n" + + " comment varchar(152)\n" + + ")\n" + + "WITH (\n" + + " format = 'ORC'\n" + + ")"); + } +} diff --git a/plugin/trino-hive/src/test/java/io/trino/plugin/hive/TestHiveConnectorTest.java b/plugin/trino-hive/src/test/java/io/trino/plugin/hive/TestHiveConnectorTest.java index ffa7f736d727..d15feb2d1c5f 100644 --- a/plugin/trino-hive/src/test/java/io/trino/plugin/hive/TestHiveConnectorTest.java +++ b/plugin/trino-hive/src/test/java/io/trino/plugin/hive/TestHiveConnectorTest.java @@ -203,6 +203,13 @@ protected boolean hasBehavior(TestingConnectorBehavior connectorBehavior) switch (connectorBehavior) { case SUPPORTS_TOPN_PUSHDOWN: return false; + + case SUPPORTS_CREATE_VIEW: + return true; + + case SUPPORTS_DELETE: + return true; + default: return super.hasBehavior(connectorBehavior); } @@ -211,7 +218,8 @@ protected boolean hasBehavior(TestingConnectorBehavior connectorBehavior) @Override public void testDelete() { - throw new SkipException("Hive connector supports row-by-row delete only for ACID tables but these currently cannot be used with file metastore."); + assertThatThrownBy(super::testDelete) + .hasStackTraceContaining("Deletes must match whole partitions for non-transactional tables"); } @Test diff --git a/plugin/trino-iceberg/src/test/java/io/trino/plugin/iceberg/AbstractTestIcebergConnectorTest.java b/plugin/trino-iceberg/src/test/java/io/trino/plugin/iceberg/AbstractTestIcebergConnectorTest.java index 7990e2bb77eb..16e1007a9ae5 100644 --- a/plugin/trino-iceberg/src/test/java/io/trino/plugin/iceberg/AbstractTestIcebergConnectorTest.java +++ b/plugin/trino-iceberg/src/test/java/io/trino/plugin/iceberg/AbstractTestIcebergConnectorTest.java @@ -121,6 +121,10 @@ protected boolean hasBehavior(TestingConnectorBehavior connectorBehavior) case SUPPORTS_RENAME_TABLE: case SUPPORTS_TOPN_PUSHDOWN: return false; + + case SUPPORTS_CREATE_MATERIALIZED_VIEW: + return true; + case SUPPORTS_DELETE: return true; default: @@ -142,6 +146,7 @@ public void testDelete() public void testRenameTable() { // Iceberg table rename is not supported in FileHiveMetastore + // TODO add a test with a different metastore, or block rename in IcebergMetadata assertThatThrownBy(super::testRenameTable) .hasStackTraceContaining("Rename not supported for Iceberg tables"); } @@ -203,6 +208,46 @@ public void testShowCreateTable() ")"); } + @Override + protected void checkInformationSchemaTablesForPointedQueryForMaterializedView(String schemaName, String viewName) + { + // TODO The query should not fail, obviously. It should return the viewName, as information_schema.tables returns it when invoked without filters + assertThatThrownBy(() -> super.checkInformationSchemaTablesForPointedQueryForMaterializedView(schemaName, viewName)) + .hasMessageContaining("Not an Iceberg table"); + } + + @Override + protected void checkShowColumnsForMaterializedView(String viewName) + { + // TODO The query should not fail, obviously. It should return all the columns in the view + assertThatThrownBy(() -> super.checkShowColumnsForMaterializedView(viewName)) + .hasMessageContaining("Not an Iceberg table"); + } + + @Override + protected void checkInformationSchemaColumnsForMaterializedView(String schemaName, String viewName) + { + // TODO The query should not fail, obviously. It should return columns for all tables, views, and materialized views + assertThatThrownBy(() -> super.checkInformationSchemaColumnsForMaterializedView(schemaName, viewName)) + .hasMessageFindingMatch("(?s)Expecting.*to contain:.*, nationkey\\).*, name\\).*, regionkey\\).*, comment\\)"); + } + + @Override + protected void checkInformationSchemaColumnsForPointedQueryForMaterializedView(String schemaName, String viewName) + { + // TODO The query should not fail, obviously. It should return columns for the materialized view + assertThatThrownBy(() -> super.checkInformationSchemaColumnsForPointedQueryForMaterializedView(schemaName, viewName)) + .hasMessageContaining("Not an Iceberg table"); + } + + @Override + protected void checkInformationSchemaViewsForMaterializedView(String schemaName, String viewName) + { + // TODO should probably return materialized view, as it's also a view -- to be double checked + assertThatThrownBy(() -> super.checkInformationSchemaViewsForMaterializedView(schemaName, viewName)) + .hasMessageFindingMatch("(?s)Expecting.*to contain:.*\\Q[(" + viewName + ")]"); + } + @Test // This particular method may or may not be @Flaky. It is annotated since the problem is generic. @Flaky(issue = "https://github.com/trinodb/trino/issues/5201", match = "Failed to read footer of file: HdfsInputFile") diff --git a/plugin/trino-iceberg/src/test/java/io/trino/plugin/iceberg/TestIcebergConnectorSmokeTest.java b/plugin/trino-iceberg/src/test/java/io/trino/plugin/iceberg/TestIcebergConnectorSmokeTest.java new file mode 100644 index 000000000000..c5383bed3d08 --- /dev/null +++ b/plugin/trino-iceberg/src/test/java/io/trino/plugin/iceberg/TestIcebergConnectorSmokeTest.java @@ -0,0 +1,92 @@ +/* + * 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.plugin.iceberg; + +import com.google.common.collect.ImmutableMap; +import io.trino.testing.BaseConnectorSmokeTest; +import io.trino.testing.QueryRunner; +import io.trino.testing.TestingConnectorBehavior; +import org.apache.iceberg.FileFormat; +import org.testng.annotations.Test; + +import static io.trino.plugin.iceberg.IcebergQueryRunner.createIcebergQueryRunner; +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatThrownBy; + +// Redundant over TestIcebergOrcConnectorTest, but exists to exercise BaseConnectorSmokeTest +// Some features like materialized views may be supported by Iceberg only. +public class TestIcebergConnectorSmokeTest + extends BaseConnectorSmokeTest +{ + @Override + protected QueryRunner createQueryRunner() + throws Exception + { + return createIcebergQueryRunner(ImmutableMap.of(), FileFormat.ORC, REQUIRED_TPCH_TABLES); + } + + @Override + protected boolean hasBehavior(TestingConnectorBehavior connectorBehavior) + { + switch (connectorBehavior) { + case SUPPORTS_COMMENT_ON_COLUMN: + case SUPPORTS_RENAME_TABLE: + case SUPPORTS_TOPN_PUSHDOWN: + return false; + + case SUPPORTS_CREATE_MATERIALIZED_VIEW: + return true; + + case SUPPORTS_DELETE: + return true; + default: + return super.hasBehavior(connectorBehavior); + } + } + + @Test + @Override + public void testDelete() + { + // Deletes are covered AbstractTestIcebergConnectorTest + assertThatThrownBy(super::testDelete) + .hasStackTraceContaining("This connector only supports delete where one or more partitions are deleted entirely"); + } + + @Test + @Override + public void testRenameTable() + { + // Iceberg table rename is not supported in FileHiveMetastore + // TODO add a test with a different metastore, or block rename in IcebergMetadata + assertThatThrownBy(super::testRenameTable) + .hasStackTraceContaining("Rename not supported for Iceberg tables"); + } + + @Test + @Override + public void testShowCreateTable() + { + assertThat((String) computeScalar("SHOW CREATE TABLE region")) + .isEqualTo("" + + "CREATE TABLE iceberg.tpch.region (\n" + + " regionkey bigint,\n" + + " name varchar,\n" + + " comment varchar\n" + + ")\n" + + "WITH (\n" + + " format = 'ORC'\n" + + ")"); + } +} diff --git a/plugin/trino-postgresql/src/test/java/io/trino/plugin/postgresql/TestPostgreSqlConnectorTest.java b/plugin/trino-postgresql/src/test/java/io/trino/plugin/postgresql/TestPostgreSqlConnectorTest.java index 9a734ce38d69..b77076e19c2e 100644 --- a/plugin/trino-postgresql/src/test/java/io/trino/plugin/postgresql/TestPostgreSqlConnectorTest.java +++ b/plugin/trino-postgresql/src/test/java/io/trino/plugin/postgresql/TestPostgreSqlConnectorTest.java @@ -154,7 +154,7 @@ public void testViews() } @Test - public void testMaterializedView() + public void testPostgreSqlMaterializedView() throws Exception { execute("CREATE MATERIALIZED VIEW test_mv as SELECT * FROM orders"); diff --git a/testing/trino-testing/src/main/java/io/trino/testing/AbstractTestDistributedQueries.java b/testing/trino-testing/src/main/java/io/trino/testing/AbstractTestDistributedQueries.java index e460641878a5..c81a79173c24 100644 --- a/testing/trino-testing/src/main/java/io/trino/testing/AbstractTestDistributedQueries.java +++ b/testing/trino-testing/src/main/java/io/trino/testing/AbstractTestDistributedQueries.java @@ -731,7 +731,10 @@ public void testDropTableIfExists() @Test public void testView() { - skipTestUnless(supportsViews()); + if (!supportsViews()) { + assertQueryFails("CREATE VIEW nation_v AS SELECT * FROM nation", "This connector does not support creating views"); + return; + } @Language("SQL") String query = "SELECT orderkey, orderstatus, totalprice / 2 half FROM orders"; diff --git a/testing/trino-testing/src/main/java/io/trino/testing/AbstractTestIntegrationSmokeTest.java b/testing/trino-testing/src/main/java/io/trino/testing/AbstractTestIntegrationSmokeTest.java index 29abd4aeb0d7..0b1199d0b001 100644 --- a/testing/trino-testing/src/main/java/io/trino/testing/AbstractTestIntegrationSmokeTest.java +++ b/testing/trino-testing/src/main/java/io/trino/testing/AbstractTestIntegrationSmokeTest.java @@ -352,7 +352,7 @@ public void testTableSampleWithFiltering() @Test public void testShowCreateTable() { - assertThat((String) computeActual("SHOW CREATE TABLE orders").getOnlyValue()) + assertThat((String) computeScalar("SHOW CREATE TABLE orders")) // If the connector reports additional column properties, the expected value needs to be adjusted in the test subclass .matches("CREATE TABLE \\w+\\.\\w+\\.orders \\Q(\n" + " orderkey bigint,\n" + diff --git a/testing/trino-testing/src/main/java/io/trino/testing/BaseConnectorSmokeTest.java b/testing/trino-testing/src/main/java/io/trino/testing/BaseConnectorSmokeTest.java index aeb02622ae99..8690ac006d7e 100644 --- a/testing/trino-testing/src/main/java/io/trino/testing/BaseConnectorSmokeTest.java +++ b/testing/trino-testing/src/main/java/io/trino/testing/BaseConnectorSmokeTest.java @@ -21,9 +21,11 @@ import java.util.List; import java.util.regex.Pattern; +import static io.trino.testing.TestingConnectorBehavior.SUPPORTS_CREATE_MATERIALIZED_VIEW; import static io.trino.testing.TestingConnectorBehavior.SUPPORTS_CREATE_SCHEMA; import static io.trino.testing.TestingConnectorBehavior.SUPPORTS_CREATE_TABLE; import static io.trino.testing.TestingConnectorBehavior.SUPPORTS_CREATE_TABLE_WITH_DATA; +import static io.trino.testing.TestingConnectorBehavior.SUPPORTS_CREATE_VIEW; import static io.trino.testing.TestingConnectorBehavior.SUPPORTS_DELETE; import static io.trino.testing.TestingConnectorBehavior.SUPPORTS_INSERT; import static io.trino.testing.TestingConnectorBehavior.SUPPORTS_RENAME_TABLE; @@ -303,11 +305,11 @@ public void testSelectInformationSchemaColumns() .matches("VALUES 'regionkey', 'name', 'comment'"); } + // SHOW CREATE TABLE exercises table properties and comments, which may be skipped during regular SELECT execution @Test public void testShowCreateTable() { - // SHOW CREATE TABLE exercises table properties and comments, which may be skipped during regular SELECT execution - assertThat((String) computeActual("SHOW CREATE TABLE region").getOnlyValue()) + assertThat((String) computeScalar("SHOW CREATE TABLE region")) .matches(format( "CREATE TABLE %s.%s.region \\(\n" + " regionkey (bigint|decimal\\(19, 0\\)),\n" + @@ -317,4 +319,62 @@ public void testShowCreateTable() Pattern.quote(getSession().getCatalog().orElseThrow()), Pattern.quote(getSession().getSchema().orElseThrow()))); } + + @Test + public void testView() + { + if (!hasBehavior(SUPPORTS_CREATE_VIEW)) { + assertQueryFails("CREATE VIEW nation_v AS SELECT * FROM nation", "This connector does not support creating views"); + return; + } + + String catalogName = getSession().getCatalog().orElseThrow(); + String schemaName = getSession().getSchema().orElseThrow(); + String viewName = "test_view_" + randomTableSuffix(); + assertUpdate("CREATE VIEW " + viewName + " AS SELECT * FROM nation"); + + assertThat(query("SELECT * FROM " + viewName)) + .skippingTypesCheck() + .matches("SELECT * FROM nation"); + + assertThat(((String) computeScalar("SHOW CREATE VIEW " + viewName))) + .matches("(?s)" + + "CREATE VIEW \\Q" + catalogName + "." + schemaName + "." + viewName + "\\E" + + ".* AS\n" + + "SELECT \\*\n" + + "FROM\n" + + " nation"); + + assertUpdate("DROP VIEW " + viewName); + } + + @Test + public void testMaterializedView() + { + if (!hasBehavior(SUPPORTS_CREATE_MATERIALIZED_VIEW)) { + assertQueryFails("CREATE MATERIALIZED VIEW nation_mv AS SELECT * FROM nation", "This connector does not support creating materialized views"); + return; + } + + String catalogName = getSession().getCatalog().orElseThrow(); + String schemaName = getSession().getSchema().orElseThrow(); + String viewName = "test_materialized_view_" + randomTableSuffix(); + assertUpdate("CREATE MATERIALIZED VIEW " + viewName + " AS SELECT * FROM nation"); + + // reading + assertThat(query("SELECT * FROM " + viewName)) + .skippingTypesCheck() + .matches("SELECT * FROM nation"); + + // details + assertThat(((String) computeScalar("SHOW CREATE MATERIALIZED VIEW " + viewName))) + .matches("(?s)" + + "CREATE MATERIALIZED VIEW \\Q" + catalogName + "." + schemaName + "." + viewName + "\\E" + + ".* AS\n" + + "SELECT \\*\n" + + "FROM\n" + + " nation"); + + assertUpdate("DROP MATERIALIZED VIEW " + viewName); + } } diff --git a/testing/trino-testing/src/main/java/io/trino/testing/BaseConnectorTest.java b/testing/trino-testing/src/main/java/io/trino/testing/BaseConnectorTest.java index e914e33eaae3..a623ca79f397 100644 --- a/testing/trino-testing/src/main/java/io/trino/testing/BaseConnectorTest.java +++ b/testing/trino-testing/src/main/java/io/trino/testing/BaseConnectorTest.java @@ -29,6 +29,7 @@ import static io.trino.testing.TestingConnectorBehavior.SUPPORTS_ARRAY; import static io.trino.testing.TestingConnectorBehavior.SUPPORTS_COMMENT_ON_COLUMN; import static io.trino.testing.TestingConnectorBehavior.SUPPORTS_COMMENT_ON_TABLE; +import static io.trino.testing.TestingConnectorBehavior.SUPPORTS_CREATE_MATERIALIZED_VIEW; import static io.trino.testing.TestingConnectorBehavior.SUPPORTS_CREATE_SCHEMA; import static io.trino.testing.TestingConnectorBehavior.SUPPORTS_CREATE_TABLE; import static io.trino.testing.TestingConnectorBehavior.SUPPORTS_CREATE_VIEW; @@ -397,6 +398,111 @@ public void testDescribeTable() assertEquals(actualColumns, expectedColumns); } + @Override + public void testView() + { + // TODO merge AbstractTestDistributedQueries into BaseConnectorTest + super.testView(); + } + + @Test + public void testMaterializedView() + { + if (!hasBehavior(SUPPORTS_CREATE_MATERIALIZED_VIEW)) { + assertQueryFails("CREATE MATERIALIZED VIEW nation_mv AS SELECT * FROM nation", "This connector does not support creating materialized views"); + return; + } + + String catalogName = getSession().getCatalog().orElseThrow(); + String schemaName = getSession().getSchema().orElseThrow(); + String viewName = "test_materialized_view_" + randomTableSuffix(); + assertUpdate("CREATE MATERIALIZED VIEW " + viewName + " AS SELECT * FROM nation"); + + // reading + assertThat(query("SELECT * FROM " + viewName)) + .skippingTypesCheck() + .matches("SELECT * FROM nation"); + + // table listing + assertThat(query("SHOW TABLES")) + .skippingTypesCheck() + .containsAll("VALUES '" + viewName + "'"); + // information_schema.tables without table_name filter + assertThat(query("SELECT table_name, table_type FROM information_schema.tables WHERE table_schema = '" + schemaName + "'")) + .skippingTypesCheck() + .containsAll("VALUES ('" + viewName + "', 'BASE TABLE')"); // TODO table_type should probably be "* VIEW" + // information_schema.tables with table_name filter + checkInformationSchemaTablesForPointedQueryForMaterializedView(schemaName, viewName); + + // column listing + checkShowColumnsForMaterializedView(viewName); + + // information_schema.columns without table_name filter + checkInformationSchemaColumnsForMaterializedView(schemaName, viewName); + + // information_schema.columns with table_name filter + checkInformationSchemaColumnsForPointedQueryForMaterializedView(schemaName, viewName); + + // view-specific listings + checkInformationSchemaViewsForMaterializedView(schemaName, viewName); + + // details + assertThat(((String) computeScalar("SHOW CREATE MATERIALIZED VIEW " + viewName))) + .matches("(?s)" + + "CREATE MATERIALIZED VIEW \\Q" + catalogName + "." + schemaName + "." + viewName + "\\E" + + ".* AS\n" + + "SELECT \\*\n" + + "FROM\n" + + " nation"); + + assertUpdate("DROP MATERIALIZED VIEW " + viewName); + } + + // TODO inline when all implementations fixed + protected void checkInformationSchemaTablesForPointedQueryForMaterializedView(String schemaName, String viewName) + { + assertThat(query("SELECT table_name FROM information_schema.tables WHERE table_schema = '" + schemaName + "' and table_name = '" + viewName + "'")) + .skippingTypesCheck() + .isEqualTo("VALUES '" + viewName + "'"); + } + + // TODO inline when all implementations fixed + protected void checkShowColumnsForMaterializedView(String viewName) + { + assertThat(query("SHOW COLUMNS FROM " + viewName)) + .skippingTypesCheck() + .matches("VALUES 'nationkey', 'name', 'regionkey', 'comment'"); + + assertThat(query("DESCRIBE " + viewName)) + .projected(1) + .skippingTypesCheck() + .matches("VALUES 'nationkey', 'name', 'regionkey', 'comment'"); + } + + // TODO inline when all implementations fixed + protected void checkInformationSchemaColumnsForMaterializedView(String schemaName, String viewName) + { + assertThat(query("SELECT table_name, column_name FROM information_schema.columns WHERE table_schema = '" + schemaName + "'")) + .skippingTypesCheck() + .containsAll("SELECT * FROM (VALUES '" + viewName + "') CROSS JOIN UNNEST(ARRAY['nationkey', 'name', 'regionkey', 'comment'])"); + } + + // TODO inline when all implementations fixed + protected void checkInformationSchemaColumnsForPointedQueryForMaterializedView(String schemaName, String viewName) + { + assertThat(query("SELECT table_name, column_name FROM information_schema.columns WHERE table_schema = '" + schemaName + "' and table_name = '" + viewName + "'")) + .skippingTypesCheck() + .containsAll("SELECT * FROM (VALUES '" + viewName + "') CROSS JOIN UNNEST(ARRAY['nationkey', 'name', 'regionkey', 'comment'])"); + } + + // TODO inline when all implementations fixed + protected void checkInformationSchemaViewsForMaterializedView(String schemaName, String viewName) + { + assertThat(query("SELECT table_name FROM information_schema.views WHERE table_schema = '" + schemaName + "'")) + .skippingTypesCheck() + .containsAll("VALUES '" + viewName + "'"); + } + @Test public void testExplainAnalyze() { diff --git a/testing/trino-testing/src/main/java/io/trino/testing/TestingConnectorBehavior.java b/testing/trino-testing/src/main/java/io/trino/testing/TestingConnectorBehavior.java index 8683b4ae7df8..04f87cb30eb6 100644 --- a/testing/trino-testing/src/main/java/io/trino/testing/TestingConnectorBehavior.java +++ b/testing/trino-testing/src/main/java/io/trino/testing/TestingConnectorBehavior.java @@ -50,6 +50,8 @@ public enum TestingConnectorBehavior SUPPORTS_CREATE_VIEW(false), + SUPPORTS_CREATE_MATERIALIZED_VIEW(false), + SUPPORTS_INSERT, SUPPORTS_DELETE(false),