Search code examples
cpostgresqllibpq

How to execute an async Query with libpq


I want to execute a SQL query with libpq in a non-blocking fashion. Thus I want to be notified when my query has finished executing.

As I understand this is supported by libpq if I use the asynchronous api.

With the PQsendQuery function I can send the query to the backend and with the PQgetResult function I can retrieve the result.

I call the PQsendQuery function multiple times without waiting for the previous one to finish.

Now I have the following questions:

  • How can I associate the results that I am going to pull later with PQgetResult to the corresponding query?
  • Is there a method of using a callback instead of PQgetResult?
  • Is there a way to run this in an event loop (e.g. libevent)?

Solution

  • You misunderstand something here: PQsendQuery() sends an asynchronous query, meaning, that the command does not block until the results are available. However, you may not call PQsendQuery() again before all results were read!

    From the manpage:

    After successfully calling PQsendQuery, call PQgetResult one or more times to obtain the results. PQsendQuery may not be called again (on the same connection) until PQgetResult has returned a null pointer, indicating that the command is done.

    As the manpage indicates, you would have to open several connections to run several concurrent queries. The different results are then associated with the different database handles.

    The PostgreSQLc async io api does not provide callback mechanisms; however, this is not too hard to build yourself. libevent can be used, since you can retrieve the socket file descriptor with PQsocket(). However, quite some glue is needed to make it work.