Commit 47d6d448 authored by Tom Lane's avatar Tom Lane

Abort a FETCH_COUNT-controlled query if we observe any I/O error on the

output stream.  This typically indicates that the user quit out of $PAGER,
or that we are writing to a file and ran out of disk space.  In either case
we shouldn't bother to continue fetching data.

Stephen Frost
parent ece869b1
...@@ -3,7 +3,7 @@ ...@@ -3,7 +3,7 @@
* *
* Copyright (c) 2000-2010, PostgreSQL Global Development Group * Copyright (c) 2000-2010, PostgreSQL Global Development Group
* *
* $PostgreSQL: pgsql/src/bin/psql/common.c,v 1.144 2010/02/16 22:34:50 tgl Exp $ * $PostgreSQL: pgsql/src/bin/psql/common.c,v 1.145 2010/05/28 20:02:32 tgl Exp $
*/ */
#include "postgres_fe.h" #include "postgres_fe.h"
#include "common.h" #include "common.h"
...@@ -982,6 +982,7 @@ ExecQueryUsingCursor(const char *query, double *elapsed_msec) ...@@ -982,6 +982,7 @@ ExecQueryUsingCursor(const char *query, double *elapsed_msec)
char fetch_cmd[64]; char fetch_cmd[64];
instr_time before, instr_time before,
after; after;
int flush_error;
*elapsed_msec = 0; *elapsed_msec = 0;
...@@ -1045,6 +1046,9 @@ ExecQueryUsingCursor(const char *query, double *elapsed_msec) ...@@ -1045,6 +1046,9 @@ ExecQueryUsingCursor(const char *query, double *elapsed_msec)
} }
} }
/* clear any pre-existing error indication on the output stream */
clearerr(pset.queryFout);
for (;;) for (;;)
{ {
if (pset.timing) if (pset.timing)
...@@ -1096,19 +1100,29 @@ ExecQueryUsingCursor(const char *query, double *elapsed_msec) ...@@ -1096,19 +1100,29 @@ ExecQueryUsingCursor(const char *query, double *elapsed_msec)
printQuery(results, &my_popt, pset.queryFout, pset.logfile); printQuery(results, &my_popt, pset.queryFout, pset.logfile);
/* PQclear(results);
* Make sure to flush the output stream, so intermediate results are
* visible to the client immediately.
*/
fflush(pset.queryFout);
/* after the first result set, disallow header decoration */ /* after the first result set, disallow header decoration */
my_popt.topt.start_table = false; my_popt.topt.start_table = false;
my_popt.topt.prior_records += ntuples; my_popt.topt.prior_records += ntuples;
PQclear(results); /*
* Make sure to flush the output stream, so intermediate results are
* visible to the client immediately. We check the results because
* if the pager dies/exits/etc, there's no sense throwing more data
* at it.
*/
flush_error = fflush(pset.queryFout);
if (ntuples < pset.fetch_count || cancel_pressed) /*
* Check if we are at the end, if a cancel was pressed, or if
* there were any errors either trying to flush out the results,
* or more generally on the output stream at all. If we hit any
* errors writing things to the stream, we presume $PAGER has
* disappeared and stop bothering to pull down more data.
*/
if (ntuples < pset.fetch_count || cancel_pressed || flush_error ||
ferror(pset.queryFout))
break; break;
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment