diff --git a/packages/models/src/sql/normalize.js b/packages/models/src/sql/normalize.js index 357096a5d3..e63f32a43a 100644 --- a/packages/models/src/sql/normalize.js +++ b/packages/models/src/sql/normalize.js @@ -92,6 +92,13 @@ function detectUnmatchedPairs(obfuscated, adapter) { * @returns {string} */ export default function normalize(sql, adapter) { + // The MongoDB agents record each operation as a statement whose argument + // values are already replaced with placeholders, for example + // db.users.updateOne({"_id": ?}, {"$set": {"name": ?}}). The generic + // obfuscation below would treat the quoted keys as string literals and a + // pair of $operators as a dollar-quoted string, so leave it as it is. + if (adapter === 'mongodb') return sql; + /** @type {RegExp[]} */ let regexp; switch (adapter) { case 'mysql': diff --git a/packages/models/tests/unit/sql.normalize.spec.js b/packages/models/tests/unit/sql.normalize.spec.js new file mode 100644 index 0000000000..17f4b4c6c9 --- /dev/null +++ b/packages/models/tests/unit/sql.normalize.spec.js @@ -0,0 +1,28 @@ +import normalize from '../../src/sql/normalize'; + +describe('normalize SQL', () => { + test('replaces literals for a known dialect', () => { + expect(normalize("SELECT * FROM users WHERE id = 1 AND name = 'bob'", 'postgres')).toEqual( + 'SELECT * FROM users WHERE id = ? AND name = ?' + ); + }); + + test('replaces literals with the fallback for an unknown dialect', () => { + expect(normalize('SELECT * FROM users WHERE id = 1', 'something')).toEqual( + 'SELECT * FROM users WHERE id = ?' + ); + }); + + test('leaves MongoDB statements alone, since the agent already normalized them', () => { + const statements = [ + 'db.users.find({"a": ?})', + 'db.users.updateOne({"_id": ?}, {"$set": {"name": ?}, "$inc": {"n": ?}}, {"upsert": ?})', + 'db.orders.aggregate([{"$match": {"status": ?}}, {"$group": {"_id": ?, "total": {"$sum": ?}}}])', + 'db.getCollection("with-dash").insertOne({"a": ?})', + 'db.users.distinct("email", {"deleted": ?})', + ]; + statements.forEach((statement) => { + expect(normalize(statement, 'mongodb')).toEqual(statement); + }); + }); +});