diff --git a/presto-docs/src/main/sphinx/connector/mongodb.rst b/presto-docs/src/main/sphinx/connector/mongodb.rst index 2c18c698bb7a5..1dc506c8cb7c2 100644 --- a/presto-docs/src/main/sphinx/connector/mongodb.rst +++ b/presto-docs/src/main/sphinx/connector/mongodb.rst @@ -261,3 +261,11 @@ MongoDB collection has the special field ``_id``. The connector tries to follow .. note:: Unfortunately, there is no way to represent ``_id`` fields more fancy like ``55b151633864d6438c61a9ce``. + +SQL support +----------- + +ALTER TABLE +^^^^^^^^^^^ + +The connector supports ``ALTER TABLE RENAME TO`` operation. Other uses of ``ALTER TABLE`` are not supported. diff --git a/presto-mongodb/src/main/java/com/facebook/presto/mongodb/MongoMetadata.java b/presto-mongodb/src/main/java/com/facebook/presto/mongodb/MongoMetadata.java index 23ffd3004988d..242744dca2b24 100644 --- a/presto-mongodb/src/main/java/com/facebook/presto/mongodb/MongoMetadata.java +++ b/presto-mongodb/src/main/java/com/facebook/presto/mongodb/MongoMetadata.java @@ -212,7 +212,8 @@ public void dropTable(ConnectorSession session, ConnectorTableHandle tableHandle @Override public void renameTable(ConnectorSession session, ConnectorTableHandle tableHandle, SchemaTableName newTableName) { - throw new UnsupportedOperationException(); + MongoTableHandle table = (MongoTableHandle) tableHandle; + mongoSession.renameTable(table.getSchemaTableName(), newTableName); } @Override diff --git a/presto-mongodb/src/main/java/com/facebook/presto/mongodb/MongoSession.java b/presto-mongodb/src/main/java/com/facebook/presto/mongodb/MongoSession.java index 4f24876c1b7f1..36b67f8b8cb2e 100644 --- a/presto-mongodb/src/main/java/com/facebook/presto/mongodb/MongoSession.java +++ b/presto-mongodb/src/main/java/com/facebook/presto/mongodb/MongoSession.java @@ -37,6 +37,7 @@ import com.google.common.collect.ImmutableSet; import com.google.common.util.concurrent.UncheckedExecutionException; import com.mongodb.MongoClient; +import com.mongodb.MongoNamespace; import com.mongodb.client.FindIterable; import com.mongodb.client.MongoCollection; import com.mongodb.client.MongoCursor; @@ -239,6 +240,29 @@ public MongoCursor execute(MongoSplit split, List c return iterable.iterator(); } + public void renameTable(SchemaTableName oldName, SchemaTableName newName) + { + String oldSchemaName = oldName.getSchemaName(); + String oldTableName = oldName.getTableName(); + String newSchemaName = 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); + } + @VisibleForTesting static Document buildQuery(TupleDomain tupleDomain) { diff --git a/presto-mongodb/src/test/java/com/facebook/presto/mongodb/TestMongoIntegrationSmokeTest.java b/presto-mongodb/src/test/java/com/facebook/presto/mongodb/TestMongoIntegrationSmokeTest.java index 88fbd232a205c..38474722104b4 100644 --- a/presto-mongodb/src/test/java/com/facebook/presto/mongodb/TestMongoIntegrationSmokeTest.java +++ b/presto-mongodb/src/test/java/com/facebook/presto/mongodb/TestMongoIntegrationSmokeTest.java @@ -19,6 +19,7 @@ import com.facebook.presto.tests.AbstractTestIntegrationSmokeTest; import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableMap; +import com.mongodb.client.MongoCollection; import org.bson.Document; import org.testng.annotations.AfterClass; import org.testng.annotations.BeforeClass; @@ -253,4 +254,20 @@ private void assertOneNotNullResult(String query) assertEquals(results.getMaterializedRows().get(0).getFieldCount(), 1); assertNotNull(results.getMaterializedRows().get(0).getField(0)); } + + @Test + public void testRenameTable() + { + assertUpdate("CREATE TABLE test_rename.tmp_rename_table (value bigint)"); + MongoCollection collection = mongoQueryRunner.getMongoClient().getDatabase("test_rename").getCollection("tmp_rename_table"); + collection.insertOne(new Document(ImmutableMap.of("value", 1))); + assertQuery("SHOW TABLES IN test_rename", "SELECT 'tmp_rename_table'"); + assertQuery("SELECT value FROM test_rename.tmp_rename_table", "SELECT 1"); + + assertUpdate("ALTER TABLE test_rename.tmp_rename_table RENAME TO test_rename.tmp_rename_new_table"); + + assertQuery("SHOW TABLES IN test_rename", "SELECT 'tmp_rename_new_table'"); + assertQuery("SELECT value FROM test_rename.tmp_rename_new_table", "SELECT 1"); + assertUpdate("DROP TABLE test_rename.tmp_rename_new_table"); + } }