Fix the batch planner for a large table backfill

Review the AI's codeEasy10 minStripe and Shopify style

Your task

An agent wrote a Postgres migration that backfills a new normalized_email column with one UPDATE over a 200-million-row table. That would hold locks for hours. The safe shape walks the primary key in bounded batches, commits after each one, and can resume after a crash. Your team now generates the batch plan first and inspects it before anything runs.

An assistant wrote plan_backfill_batches(last_done_id, max_id, batch_size, max_batches). It is in the editor. It has a bug. Find it and fix it.

Input and output:

  • last_done_id: the highest id already committed, the resume checkpoint. It is 0 or below when nothing has been done.
  • max_id: the highest id in the table.
  • batch_size: how many ids one batch covers. It comes from config.
  • max_batches: how many batches this run may plan.
  • Return the batches as [start, end] pairs, both ends included, in ascending order.

Rules the tests check:

  • If batch_size or max_batches is 0 or less, return []. A batch with no ids never advances.
  • The first batch starts one past last_done_id, or at 1 when last_done_id is below 0.
  • Each batch covers batch_size ids. The next batch starts right after the previous one ends. The last batch stops at max_id.
  • Stop when the next start would be past max_id, or when max_batches batches are planned.

Examples

plan_backfill_batches(last_done_id: int, max_id: int, batch_size: int, max_batches: int) -> list[list[int]]
Example 1
Inputplan_backfill_batches(0, 10, 4, 10)
Output[[1, 4], [5, 8], [9, 10]]
Example 2
Inputplan_backfill_batches(8, 10, 4, 10)
Output[[9, 10]]
Example 3
Inputplan_backfill_batches(0, 200000000, 5000000, 3)
Output[[1, 5000000], [5000001, 10000000], [10000001, 15000000]]