diff --git a/Plugins/MongoDBDriverPlugin/MongoDBPluginDriver.swift b/Plugins/MongoDBDriverPlugin/MongoDBPluginDriver.swift index 478462791..211e691a6 100644 --- a/Plugins/MongoDBDriverPlugin/MongoDBPluginDriver.swift +++ b/Plugins/MongoDBDriverPlugin/MongoDBPluginDriver.swift @@ -634,6 +634,13 @@ final class MongoDBPluginDriver: PluginDatabaseDriver, @unchecked Sendable { ) } + /// A collection drop is a shell statement, not a SQL one: `db.getCollection("").drop()`. + /// The app-level fallback would emit `DROP TABLE `, which the Mongo shell parser rejects. + /// Mongo has no schemas or cascade, so both are ignored. + func dropObjectStatement(name: String, objectType: String, schema: String?, cascade: Bool) -> String? { + "db.getCollection(\"\(escapeJsonString(name))\").drop()" + } + func dropDatabase(name: String) async throws { guard let conn = mongoConnection else { throw MongoDBPluginError.notConnected diff --git a/TableProTests/Core/MongoDB/MongoShellParserTests.swift b/TableProTests/Core/MongoDB/MongoShellParserTests.swift index 96f4e58c3..1448ec4fa 100644 --- a/TableProTests/Core/MongoDB/MongoShellParserTests.swift +++ b/TableProTests/Core/MongoDB/MongoShellParserTests.swift @@ -312,6 +312,29 @@ struct MongoShellParserTests { } } + @Test("getCollection with drop") + func testGetCollectionDrop() throws { + let op = try MongoShellParser.parse("db.getCollection(\"audit-logs.2026\").drop()") + if case .drop(let collection) = op { + #expect(collection == "audit-logs.2026") + } else { + Issue.record("Expected .drop operation") + } + } + + @Test("SQL DROP TABLE fallback is rejected for MongoDB collections") + func testDropTableFallbackIsRejected() { + // The sidebar's drop used to fall through to the SQL fallback and emit + // `DROP TABLE ""`, which the Mongo shell parser rejects. Dropping a + // collection must go through `db.getCollection("").drop()` instead. + do { + _ = try MongoShellParser.parse("DROP TABLE \"users\"") + Issue.record("Expected the SQL DROP TABLE fallback to be rejected") + } catch { + // Any parse failure is the point: a Mongo connection must never send SQL. + } + } + @Test("runCommand") func testRunCommand() throws { let op = try MongoShellParser.parse("db.runCommand({\"ping\": 1})")