diff --git a/psycopg/green.c b/psycopg/green.c index 9e7e5d2f..c9df5190 100644 --- a/psycopg/green.c +++ b/psycopg/green.c @@ -29,6 +29,7 @@ #include "psycopg/psycopg.h" #include "psycopg/green.h" #include "psycopg/connection.h" +#include "psycopg/pqpath.h" HIDDEN PyObject *wait_callback = NULL; @@ -143,8 +144,7 @@ psyco_wait(connectionObject *conn) PGresult * psyco_exec_green(connectionObject *conn, const char *command) { - PGconn *pgconn = conn->pgconn; - PGresult *result = NULL, *res; + PGresult *result = NULL; PyObject *cb, *pyrv; if (!(cb = have_wait_callback())) { @@ -153,7 +153,7 @@ psyco_exec_green(connectionObject *conn, const char *command) /* Send the query asynchronously */ Dprintf("psyco_exec_green: sending query async"); - if (0 == PQsendQuery(pgconn, command)) { + if (0 == PQsendQuery(conn->pgconn, command)) { Dprintf("psyco_exec_green: PQsendQuery returned 0"); goto clear; } @@ -172,19 +172,8 @@ psyco_exec_green(connectionObject *conn, const char *command) } Py_DECREF(pyrv); - /* Now we can read the data without fear of blocking. - * Read until PQgetResult gives a NULL */ - while (NULL != (res = PQgetResult(pgconn))) { - if (result) { - /* TODO too bad: we are discarding results from all the queries - * except the last. We could have populated `nextset()` with it - * but it would be an incompatible change (apps currently issue - * groups of queries expecting to receive the last result: they - * would start receiving the first instead). */ - PQclear(result); - } - result = res; - } + /* Now we can read the data without fear of blocking. */ + result = pq_get_last_result(conn); clear: conn->async_status = ASYNC_DONE; diff --git a/psycopg/pqpath.c b/psycopg/pqpath.c index e4533d9c..0704701d 100644 --- a/psycopg/pqpath.c +++ b/psycopg/pqpath.c @@ -782,6 +782,33 @@ pq_execute(cursorObject *curs, const char *query, int async) return 1-async; } +/* Return the last result available on the connection. + * + * The function will block will block only if a command is active and the + * necessary response data has not yet been read by PQconsumeInput. + * + * The result should be disposed using PQclear() + */ +PGresult * +pq_get_last_result(connectionObject *conn) +{ + PGresult *result = NULL, *res; + + /* Read until PQgetResult gives a NULL */ + while (NULL != (res = PQgetResult(conn->pgconn))) { + if (result) { + /* TODO too bad: we are discarding results from all the queries + * except the last. We could have populated `nextset()` with it + * but it would be an incompatible change (apps currently issue + * groups of queries expecting to receive the last result: they + * would start receiving the first instead). */ + PQclear(result); + } + result = res; + } + + return result; +} /* pq_fetch - fetch data after a query diff --git a/psycopg/pqpath.h b/psycopg/pqpath.h index e7e957e9..cd57546d 100644 --- a/psycopg/pqpath.h +++ b/psycopg/pqpath.h @@ -35,6 +35,7 @@ #define CLEARPGRES(pgres) PQclear(pgres); pgres = NULL /* exported functions */ +HIDDEN PGresult *pq_get_last_result(connectionObject *conn); HIDDEN int pq_fetch(cursorObject *curs); HIDDEN int pq_execute(cursorObject *curs, const char *query, int async); HIDDEN int pq_begin_locked(connectionObject *conn, PGresult **pgres,