aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTom Lane <tgl@sss.pgh.pa.us>2010-05-28 20:02:32 +0000
committerTom Lane <tgl@sss.pgh.pa.us>2010-05-28 20:02:32 +0000
commit47d6d4485bca56900dee8ae6f7ad82fa98efcc21 (patch)
tree74ee88f2c372342037d0a8482d512742e8661d35
parentece869b11eedd082ccd0bbd73ab9013c9ad9fa13 (diff)
downloadpostgresql-47d6d4485bca56900dee8ae6f7ad82fa98efcc21.tar.gz
postgresql-47d6d4485bca56900dee8ae6f7ad82fa98efcc21.zip
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
-rw-r--r--src/bin/psql/common.c30
1 files changed, 22 insertions, 8 deletions
diff --git a/src/bin/psql/common.c b/src/bin/psql/common.c
index 9661f0cd803..cdb071f85e2 100644
--- a/src/bin/psql/common.c
+++ b/src/bin/psql/common.c
@@ -3,7 +3,7 @@
*
* 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 "common.h"
@@ -982,6 +982,7 @@ ExecQueryUsingCursor(const char *query, double *elapsed_msec)
char fetch_cmd[64];
instr_time before,
after;
+ int flush_error;
*elapsed_msec = 0;
@@ -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 (;;)
{
if (pset.timing)
@@ -1096,19 +1100,29 @@ ExecQueryUsingCursor(const char *query, double *elapsed_msec)
printQuery(results, &my_popt, pset.queryFout, pset.logfile);
- /*
- * Make sure to flush the output stream, so intermediate results are
- * visible to the client immediately.
- */
- fflush(pset.queryFout);
+ PQclear(results);
/* after the first result set, disallow header decoration */
my_popt.topt.start_table = false;
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;
}