One Seat, Many Shows: Why the Query Needs Both

A real bug hiding in a query that looks correct: filtering ShowSeat by seat alone silently returns rows from every show that seat has ever been part of.

September 1, 20261 min read37 / 43

Finding the ShowSeat rows for a set of Seat objects looks like enough on its own. It isn't.

The Bug: The Same Seat Belongs to More Than One Show

A single physical seat isn't unique to the show being booked right now. That same seat has its own ShowSeat row for every other show it's ever been part of — this morning's screening, tonight's, tomorrow's, each one a separate row, each one pointing back to the same seat.

Filtering by seat alone doesn't narrow anything down to the one show actually being booked. It pulls back every ShowSeat row for that seat, across every show that seat has ever appeared in, when only one of those rows is actually relevant.

The Fix: Filter by Both, Not Either

The query needs both the seats and the show together, not one or the other. A show and a set of seats aren't two independent ways of reaching the same answer, the way looking up a person by their ID or their email might be. They narrow the result down along two different dimensions at once, and dropping either one lets rows leak in that were never supposed to match.

This is worth catching precisely because the query still runs, still returns rows, and still looks like it's doing its job. A query missing a condition rarely fails loudly. It just quietly returns more than it should have.