When a query with an index lookup as a LIMIT, it's possible for the result
iterator to be closed before all the index results have been streamed. When
that happens, we can end up with queueRows goroutine which is enqueuing rows
into a ring buffer that is going to be used by a different query later.
This PR adds two mechanisms, one to stop the wrong results from being seen and
to cancel the unnecessary work.
1. RingBuffer gets an epoch, which is incremented on each Reset(). If a given
Push does not match the current epoch, then nothing is added to the ring
buffer.
2. queueRows is run with a cancelable (sub-)Context, and that Context is
canceled when the corresponding iterator is Closed().