From 3a4168d6260980e956b4c3bc75fc81e3f2052794 Mon Sep 17 00:00:00 2001 From: Yuya Ebihara Date: Thu, 19 May 2022 21:15:43 +0900 Subject: [PATCH] Add concurrent adding columns test to BaseConnectorTest --- .../plugin/jdbc/TestJdbcConnectorTest.java | 7 ++ .../BaseClickHouseConnectorTest.java | 7 ++ .../iceberg/BaseIcebergConnectorTest.java | 7 ++ .../kudu/AbstractKuduConnectorTest.java | 7 ++ .../mongodb/BaseMongoConnectorTest.java | 7 ++ .../oracle/BaseOracleConnectorTest.java | 7 ++ .../phoenix/TestPhoenixConnectorTest.java | 7 ++ .../phoenix5/TestPhoenixConnectorTest.java | 7 ++ .../legacy/BaseRaptorConnectorTest.java | 13 ++++ .../io/trino/testing/BaseConnectorTest.java | 65 +++++++++++++++++++ 10 files changed, 134 insertions(+) diff --git a/plugin/trino-base-jdbc/src/test/java/io/trino/plugin/jdbc/TestJdbcConnectorTest.java b/plugin/trino-base-jdbc/src/test/java/io/trino/plugin/jdbc/TestJdbcConnectorTest.java index 80a4ea3be695..d7282558a929 100644 --- a/plugin/trino-base-jdbc/src/test/java/io/trino/plugin/jdbc/TestJdbcConnectorTest.java +++ b/plugin/trino-base-jdbc/src/test/java/io/trino/plugin/jdbc/TestJdbcConnectorTest.java @@ -255,6 +255,13 @@ protected String errorMessageForInsertIntoNotNullColumn(String columnName) return format("NULL not allowed for column \"%s\"(?s).*", columnName.toUpperCase(ENGLISH)); } + @Override + public void testAddColumnConcurrently() + { + // TODO: Difficult to determine whether the exception is concurrent issue or not from the error message + throw new SkipException("TODO: Enable this test after finding the failure cause"); + } + @Override protected JdbcSqlExecutor onRemoteDatabase() { diff --git a/plugin/trino-clickhouse/src/test/java/io/trino/plugin/clickhouse/BaseClickHouseConnectorTest.java b/plugin/trino-clickhouse/src/test/java/io/trino/plugin/clickhouse/BaseClickHouseConnectorTest.java index 22090b79557a..73b3dd66aec9 100644 --- a/plugin/trino-clickhouse/src/test/java/io/trino/plugin/clickhouse/BaseClickHouseConnectorTest.java +++ b/plugin/trino-clickhouse/src/test/java/io/trino/plugin/clickhouse/BaseClickHouseConnectorTest.java @@ -119,6 +119,13 @@ public void testDropColumn() assertQueryFails("ALTER TABLE " + tableName + " DROP COLUMN a", "(?s).* Missing columns: 'a' while processing query: 'a', required columns: 'a' 'a'.*"); } + @Override + public void testAddColumnConcurrently() + { + // TODO: Default storage engine doesn't support adding new columns + throw new SkipException("TODO: test not implemented yet"); + } + @Override public void testAddColumn() { diff --git a/plugin/trino-iceberg/src/test/java/io/trino/plugin/iceberg/BaseIcebergConnectorTest.java b/plugin/trino-iceberg/src/test/java/io/trino/plugin/iceberg/BaseIcebergConnectorTest.java index fbe3fc389fe7..833098e73c31 100644 --- a/plugin/trino-iceberg/src/test/java/io/trino/plugin/iceberg/BaseIcebergConnectorTest.java +++ b/plugin/trino-iceberg/src/test/java/io/trino/plugin/iceberg/BaseIcebergConnectorTest.java @@ -170,6 +170,13 @@ protected void verifyConcurrentUpdateFailurePermissible(Exception e) assertThat(e).hasMessageContaining("Failed to commit Iceberg update to table"); } + @Override + protected void verifyConcurrentAddColumnFailurePermissible(Exception e) + { + assertThat(e) + .hasMessageContaining("Cannot update Iceberg table: supplied previous location does not match current location"); + } + @Test public void testDeleteOnV1Table() { diff --git a/plugin/trino-kudu/src/test/java/io/trino/plugin/kudu/AbstractKuduConnectorTest.java b/plugin/trino-kudu/src/test/java/io/trino/plugin/kudu/AbstractKuduConnectorTest.java index d769c3aa2585..3eba6155be7c 100644 --- a/plugin/trino-kudu/src/test/java/io/trino/plugin/kudu/AbstractKuduConnectorTest.java +++ b/plugin/trino-kudu/src/test/java/io/trino/plugin/kudu/AbstractKuduConnectorTest.java @@ -346,6 +346,13 @@ public void testInsertRowConcurrently() throw new SkipException("TODO"); } + @Override + public void testAddColumnConcurrently() + { + // TODO Support these test once kudu connector can create tables with default partitions + throw new SkipException("TODO"); + } + @Test @Override public void testDelete() diff --git a/plugin/trino-mongodb/src/test/java/io/trino/plugin/mongodb/BaseMongoConnectorTest.java b/plugin/trino-mongodb/src/test/java/io/trino/plugin/mongodb/BaseMongoConnectorTest.java index 02458d39809c..2a71ee5583d9 100644 --- a/plugin/trino-mongodb/src/test/java/io/trino/plugin/mongodb/BaseMongoConnectorTest.java +++ b/plugin/trino-mongodb/src/test/java/io/trino/plugin/mongodb/BaseMongoConnectorTest.java @@ -568,6 +568,13 @@ public void testLimitPushdown() assertThat(query("SELECT name FROM nation LIMIT 2147483648")).isNotFullyPushedDown(LimitNode.class); } + @Override + public void testAddColumnConcurrently() + { + // TODO: Enable after supporting multi-document transaction https://www.mongodb.com/docs/manual/core/transactions/ + throw new SkipException("TODO"); + } + private void assertOneNotNullResult(String query) { MaterializedResult results = getQueryRunner().execute(getSession(), query).toTestTypes(); diff --git a/plugin/trino-oracle/src/test/java/io/trino/plugin/oracle/BaseOracleConnectorTest.java b/plugin/trino-oracle/src/test/java/io/trino/plugin/oracle/BaseOracleConnectorTest.java index bd05d8562c92..41cc083d9faa 100644 --- a/plugin/trino-oracle/src/test/java/io/trino/plugin/oracle/BaseOracleConnectorTest.java +++ b/plugin/trino-oracle/src/test/java/io/trino/plugin/oracle/BaseOracleConnectorTest.java @@ -417,6 +417,13 @@ protected String errorMessageForInsertIntoNotNullColumn(String columnName) return format("ORA-01400: cannot insert NULL into \\(.*\"%s\"\\)\n", columnName.toUpperCase(ENGLISH)); } + @Override + protected void verifyConcurrentAddColumnFailurePermissible(Exception e) + { + assertThat(e) + .hasMessage("ORA-14411: The DDL cannot be run concurrently with other DDLs\n"); + } + private void predicatePushdownTest(String oracleType, String oracleLiteral, String operator, String filterLiteral) { String tableName = ("test_pdown_" + oracleType.replaceAll("[^a-zA-Z0-9]", "")) diff --git a/plugin/trino-phoenix/src/test/java/io/trino/plugin/phoenix/TestPhoenixConnectorTest.java b/plugin/trino-phoenix/src/test/java/io/trino/plugin/phoenix/TestPhoenixConnectorTest.java index a1080c6ea985..8c85600d63e7 100644 --- a/plugin/trino-phoenix/src/test/java/io/trino/plugin/phoenix/TestPhoenixConnectorTest.java +++ b/plugin/trino-phoenix/src/test/java/io/trino/plugin/phoenix/TestPhoenixConnectorTest.java @@ -434,6 +434,13 @@ protected TestTable createTableWithDoubleAndRealColumns(String name, List>> futures = IntStream.range(0, threads) + .mapToObj(threadNumber -> executor.submit(() -> { + barrier.await(30, SECONDS); + try { + String columnName = "col" + threadNumber; + getQueryRunner().execute("ALTER TABLE " + tableName + " ADD COLUMN " + columnName + " integer"); + return Optional.of(columnName); + } + catch (Exception e) { + RuntimeException trinoException = getTrinoExceptionCause(e); + try { + verifyConcurrentAddColumnFailurePermissible(trinoException); + } + catch (Throwable verifyFailure) { + if (verifyFailure != e) { + verifyFailure.addSuppressed(e); + } + throw verifyFailure; + } + return Optional.empty(); + } + })) + .collect(toImmutableList()); + + List addedColumns = futures.stream() + .map(future -> tryGetFutureValue(future, 30, SECONDS).orElseThrow(() -> new RuntimeException("Wait timed out"))) + .filter(Optional::isPresent) + .map(Optional::get) + .collect(toImmutableList()); + + assertThat(query("DESCRIBE " + tableName)) + .projected(0) + .skippingTypesCheck() + .matches(Stream.concat(Stream.of("col"), addedColumns.stream()) + .map(value -> format("'%s'", value)) + .collect(joining(",", "VALUES ", ""))); + } + finally { + executor.shutdownNow(); + executor.awaitTermination(30, SECONDS); + } + } + + protected void verifyConcurrentAddColumnFailurePermissible(Exception e) + { + // By default, do not expect ALTER TABLE ADD COLUMN to fail in case of concurrent inserts + throw new AssertionError("Unexpected concurrent add column failure", e); + } + @Test public void testUpdateWithPredicates() {