@@ -152,65 +152,55 @@ void consume_results(PGconn* conn) {
152152 PGresult* res = nullptr ;
153153 bool saw_error = false ;
154154 std::string errmsg;
155+
156+ // Keep looping until PQgetResult() returns NULL and
157+ // connection is not busy anymore.
155158 for (;;) {
156- // Drain all immediately available results
157159 while ((res = PQgetResult (conn)) != nullptr ) {
158160 ExecStatusType status = PQresultStatus (res);
159161 if (status == PGRES_FATAL_ERROR) {
160162 saw_error = true ;
161163 errmsg = PQresultErrorMessage (res);
162164 }
163- if (status == PGRES_PIPELINE_ABORTED) {
164- // If pipeline was aborted, we need to clear the error
165+ else if (status == PGRES_PIPELINE_ABORTED) {
165166 saw_error = true ;
166- errmsg = std::string (" Pipeline aborted : " ) + PQresultErrorMessage (res);
167+ errmsg = std::string (" Pipeline aborted: " ) + PQresultErrorMessage (res);
167168 }
168169 PQclear (res);
169170 }
170171
171172 if (!PQisBusy (conn)) {
172- while ((res = PQgetResult (conn)) != nullptr ) {
173+ // Ensure all results are drained
174+ while ((res = PQgetResult (conn)) != nullptr )
173175 PQclear (res);
174- }
175- break ; // ReadyForQuery reached
176+ break ;
176177 }
177178
178- // ---- handle flushing + reading ----
179- int f = PQflush (conn);
180- if (f == -1 ) {
179+ if (PQflush (conn) == -1 ) {
181180 throw std::runtime_error (std::string (" PQflush failed: " ) + PQerrorMessage (conn));
182181 }
183182
184- short events = POLLIN;
185- if (f == 1 ) {
186- // still data to send also watch POLLOUT
187- events |= POLLOUT;
188- }
189-
190183 struct pollfd pfd;
191184 pfd.fd = PQsocket (conn);
192- pfd.events = events ;
193- if (pfd.fd < 0 ) {
185+ pfd.events = POLLIN | POLLOUT ;
186+ if (pfd.fd < 0 )
194187 throw std::runtime_error (" Invalid PostgreSQL socket" );
195- }
196188
197- if (poll (&pfd, 1 , -1 ) < 0 ) {
189+ if (poll (&pfd, 1 , -1 ) < 0 )
198190 throw std::runtime_error (" poll() failed" );
199- }
200191
201- // If socket readable consume input
202- if (pfd.revents & POLLIN) {
203- if (PQconsumeInput (conn) == 0 ) {
204- throw std::runtime_error (
205- std::string (" PQconsumeInput failed: " ) + PQerrorMessage (conn));
206- }
192+ if ((pfd.revents & POLLIN) && PQconsumeInput (conn) == 0 ) {
193+ throw std::runtime_error (std::string (" PQconsumeInput failed: " ) + PQerrorMessage (conn));
207194 }
208- // If socket writable and f==1 PQflush() will be retried on next iteration
209195 }
210196
211197 if (saw_error) {
212198 throw std::runtime_error (" PostgreSQL error: " + errmsg);
213199 }
200+
201+ // call PQgetResult() one final time to clear any leftover
202+ while ((res = PQgetResult (conn)) != nullptr )
203+ PQclear (res);
214204}
215205
216206void test_query_processor (PGconn* admin_conn) {
0 commit comments