From: Tom Lane Date: Fri, 28 May 2010 20:02:32 +0000 (+0000) Subject: Abort a FETCH_COUNT-controlled query if we observe any I/O error on the X-Git-Tag: REL9_0_BETA2~40 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=47d6d4485bca56900dee8ae6f7ad82fa98efcc21;p=postgresql 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 --- diff --git a/src/bin/psql/common.c b/src/bin/psql/common.c index 9661f0cd80..cdb071f85e 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; }