QueryExecState has some methods to allow clients to wait for rows to be ready to consume:
- Wait() blocks until the rows are ready, but may only be called once - yet its name suggests it can be called by any client that wants to wait for rows.
- WaitAsync() starts a thread to run Wait(). So it doesn't actually wait.
- BlockOnWait() does wait, and may be called several times.
Wait() also does actual work (again, counter to its name), so it must always be called for queries (not for DML). So we should, presumably, always kick it off from Exec() rather than rely on callers to do it.
I suggest changing the API to the following:
- WaitForFirstRows() - callable by multiple clients, returns as soon as the first rows are ready to consume.
- StartWaitThread() - private method, should only be called once, does everything Wait() does but is always async (the non-async case is only executed by Beeswax, and could be retired). It should be called from Exec().