Exercise 1: Index Result vs. Manual Scan Count, Real Agreement — Possible Solution ==================================================================== THE TEST ------------------------------ scan_count = sum(1 for row in db.tables['users'][1].scan() if row[2] == 30) index_result = db.select('users', where=('age', '=', 30)) RESULT ------------------------------ scan_count -> 1 len(index_result) -> 1 Both approaches agree exactly: one row in this chapter's own dataset has age == 30. WHY THE TWO COUNTS AGREE ------------------------------ The manual scan directly walks every real row via table.scan() (a plain generator over every page/slot, Chapter 4), checking row[2] (the 'age' column, since the schema is [id, name, age]) against 30 by hand -- this is ground truth, completely independent of the index. db.select('users', where=('age', '=', 30')) goes through choose_plan(), which -- since the operator is genuinely '=' and 'age' is indexed -- returns ('index', 'age', 30). db.select() then calls btree_search(root, 30), which correctly finds the one row whose age key is exactly 30 (verified back in Chapter 5 to agree with a linear scan on every real key), and fetches that row's own real stored bytes via table.fetch(location) -- the exact same page/slot HeapTable.insert() originally returned when that row was written. Since this chapter's own dataset was built with ages deliberately kept UNIQUE (a fact stated directly in the chapter's own comments), there's exactly one row with age=30 to find either way -- the index-based path and the scan-based path are simply two different, independently correct routes to the identical single answer. WHY THIS WORKS AS AN ANSWER ------------------------------ This is the direct, concrete confirmation that Chapter 9's own central promise -- "the index answers equality queries correctly" -- holds up against completely independent verification, the same discipline Chapter 5 already applied to raw btree_search() itself. Cross-checking a faster path (the index) against a slower, more obviously-correct path (a full scan) is a real, general technique for building confidence in an optimization: if the two ever disagreed, that would be a genuine red flag worth investigating immediately, exactly the kind of check that caught this chapter's own main bug (the range-query mismatch) in the first place.