Fix the N+1 query detector for an ORM migration

Review the AI's codeEasy12 min

Your task

An AI agent moved your data layer from hand-written SQL to an ORM. The endpoints return the same JSON, but database load has crept up. You suspect N+1 queries: one query per row where the old code ran a single join. To find them, you reduce each logged statement to its shape and count repeats.

An assistant wrote detect_n_plus_one(query_log, threshold). It is in the editor. It has a bug. Find it and fix it.

Input and output:

  • query_log: the SQL statements one request ran, in order.
  • threshold: how many times a shape must appear to be reported.
  • Return the reported shapes as a list of strings.

Rules the tests check:

  • A statement's shape is the statement with each maximal run of the digits 0 to 9 replaced by a single ?. Every other character stays as it is.
  • Count how many statements in the log have each shape. The empty string is a shape too.
  • A threshold below 1 counts as 1.
  • Return every shape whose count is at least threshold, each once, sorted in ascending order by plain string comparison.

Examples

detect_n_plus_one(query_log: list[str], threshold: int) -> list[str]
Example 1
Inputdetect_n_plus_one(["SELECT * FROM orders WHERE id = 1", "SELECT * FROM items WHERE order_id = 1", "SELECT * FROM items WHERE order_id = 2", "SELECT * FROM items WHERE order_id = 3"], 3)
Output["SELECT * FROM items WHERE order_id = ?"]
Example 2
Inputdetect_n_plus_one(["SELECT * FROM orders o JOIN items i ON i.order_id = o.id"], 2)
Output[]
Example 3
Inputdetect_n_plus_one([], 2)
Output[]