diff --git a/docs/src/main/sphinx/connector/mongodb.rst b/docs/src/main/sphinx/connector/mongodb.rst index 79ab1dfe7792..13b36119c4bd 100644 --- a/docs/src/main/sphinx/connector/mongodb.rst +++ b/docs/src/main/sphinx/connector/mongodb.rst @@ -389,5 +389,6 @@ statements, the connector supports the following features: ALTER TABLE ^^^^^^^^^^^ -The connector does not support ``ALTER TABLE RENAME`` operations. Other uses of -``ALTER TABLE`` are supported. +The connector supports ``ALTER TABLE RENAME TO``, ``ALTER TABLE ADD COLUMN`` +and ``ALTER TABLE DROP COLUMN`` operations. +Other uses of ``ALTER TABLE`` are not supported. diff --git a/plugin/trino-mongodb/src/main/java/io/trino/plugin/mongodb/MongoMetadata.java b/plugin/trino-mongodb/src/main/java/io/trino/plugin/mongodb/MongoMetadata.java index 8ec301e60134..dc59ee2ba4de 100644 --- a/plugin/trino-mongodb/src/main/java/io/trino/plugin/mongodb/MongoMetadata.java +++ b/plugin/trino-mongodb/src/main/java/io/trino/plugin/mongodb/MongoMetadata.java @@ -198,6 +198,13 @@ public void setColumnComment(ConnectorSession session, ConnectorTableHandle tabl mongoSession.setColumnComment(table.getSchemaTableName(), column.getName(), comment); } + @Override + public void renameTable(ConnectorSession session, ConnectorTableHandle tableHandle, SchemaTableName newTableName) + { + MongoTableHandle table = (MongoTableHandle) tableHandle; + mongoSession.renameTable(table.getSchemaTableName(), newTableName); + } + @Override public void addColumn(ConnectorSession session, ConnectorTableHandle tableHandle, ColumnMetadata column) { diff --git a/plugin/trino-mongodb/src/main/java/io/trino/plugin/mongodb/MongoSession.java b/plugin/trino-mongodb/src/main/java/io/trino/plugin/mongodb/MongoSession.java index 8346f74928a0..873ffbec2db6 100644 --- a/plugin/trino-mongodb/src/main/java/io/trino/plugin/mongodb/MongoSession.java +++ b/plugin/trino-mongodb/src/main/java/io/trino/plugin/mongodb/MongoSession.java @@ -23,6 +23,7 @@ import com.google.common.primitives.SignedBytes; import com.google.common.util.concurrent.UncheckedExecutionException; import com.mongodb.DBRef; +import com.mongodb.MongoNamespace; import com.mongodb.client.FindIterable; import com.mongodb.client.MongoClient; import com.mongodb.client.MongoCollection; @@ -253,6 +254,29 @@ public void setColumnComment(SchemaTableName schemaTableName, String columnName, tableCache.invalidate(schemaTableName); } + public void renameTable(SchemaTableName oldName, SchemaTableName newName) + { + String oldSchemaName = toRemoteSchemaName(oldName.getSchemaName()); + String oldTableName = toRemoteTableName(oldSchemaName, oldName.getTableName()); + String newSchemaName = toRemoteSchemaName(newName.getSchemaName()); + + // Schema collection should always have the source table definition + MongoCollection oldSchema = client.getDatabase(oldSchemaName).getCollection(schemaCollection); + Document tableDefinition = oldSchema.findOneAndDelete(new Document(TABLE_NAME_KEY, oldTableName)); + requireNonNull(tableDefinition, "Table definition not found in schema collection: " + oldTableName); + + MongoCollection newSchema = client.getDatabase(newSchemaName).getCollection(schemaCollection); + tableDefinition.append(TABLE_NAME_KEY, newName.getTableName()); + newSchema.insertOne(tableDefinition); + + // Need to check explicitly because the old collection may not exist when it doesn't have any data + if (collectionExists(client.getDatabase(oldSchemaName), oldTableName)) { + getCollection(oldName).renameCollection(new MongoNamespace(newSchemaName, newName.getTableName())); + } + + tableCache.invalidate(oldName); + } + public void addColumn(SchemaTableName schemaTableName, ColumnMetadata columnMetadata) { String schemaName = toRemoteSchemaName(schemaTableName.getSchemaName()); diff --git a/plugin/trino-mongodb/src/test/java/io/trino/plugin/mongodb/BaseMongoConnectorSmokeTest.java b/plugin/trino-mongodb/src/test/java/io/trino/plugin/mongodb/BaseMongoConnectorSmokeTest.java index 6aebcfc9bed4..29e9f760bac7 100644 --- a/plugin/trino-mongodb/src/test/java/io/trino/plugin/mongodb/BaseMongoConnectorSmokeTest.java +++ b/plugin/trino-mongodb/src/test/java/io/trino/plugin/mongodb/BaseMongoConnectorSmokeTest.java @@ -26,9 +26,6 @@ protected boolean hasBehavior(TestingConnectorBehavior connectorBehavior) case SUPPORTS_RENAME_SCHEMA: return false; - case SUPPORTS_RENAME_TABLE: - return false; - case SUPPORTS_NOT_NULL_CONSTRAINT: return false; 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 13f694ae9cfc..b20dea2ca164 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 @@ -63,7 +63,6 @@ protected boolean hasBehavior(TestingConnectorBehavior connectorBehavior) switch (connectorBehavior) { case SUPPORTS_RENAME_SCHEMA: case SUPPORTS_NOT_NULL_CONSTRAINT: - case SUPPORTS_RENAME_TABLE: case SUPPORTS_RENAME_COLUMN: return false; default: @@ -470,6 +469,21 @@ public void testCaseInsensitive() assertUpdate("DROP TABLE testcase.testinsensitive"); } + @Test + public void testCaseInsensitiveRenameTable() + { + MongoCollection collection = client.getDatabase("testCase_RenameTable").getCollection("testInsensitive_RenameTable"); + collection.insertOne(new Document(ImmutableMap.of("value", 1))); + assertQuery("SHOW TABLES IN testcase_renametable", "SELECT 'testinsensitive_renametable'"); + assertQuery("SELECT value FROM testcase_renametable.testinsensitive_renametable", "SELECT 1"); + + assertUpdate("ALTER TABLE testcase_renametable.testinsensitive_renametable RENAME TO testcase_renametable.testinsensitive_renamed_table"); + + assertQuery("SHOW TABLES IN testcase_renametable", "SELECT 'testinsensitive_renamed_table'"); + assertQuery("SELECT value FROM testcase_renametable.testinsensitive_renamed_table", "SELECT 1"); + assertUpdate("DROP TABLE testcase_renametable.testinsensitive_renamed_table"); + } + @Test public void testNonLowercaseViewName() {