diff options
Diffstat (limited to 'src/bin/psql/print.c')
-rw-r--r-- | src/bin/psql/print.c | 148 |
1 files changed, 120 insertions, 28 deletions
diff --git a/src/bin/psql/print.c b/src/bin/psql/print.c index 1ad04783d0c..97f6f1e665c 100644 --- a/src/bin/psql/print.c +++ b/src/bin/psql/print.c @@ -3,11 +3,15 @@ * * Copyright (c) 2000-2006, PostgreSQL Global Development Group * - * $PostgreSQL: pgsql/src/bin/psql/print.c,v 1.86 2006/06/07 22:24:45 momjian Exp $ + * $PostgreSQL: pgsql/src/bin/psql/print.c,v 1.87 2006/06/14 16:49:02 tgl Exp $ + * + * Note: we include postgres.h not postgres_fe.h so that we can include + * catalog/pg_type.h, and thereby have access to INT4OID and similar macros. */ -#include "postgres_fe.h" +#include "postgres.h" #include "common.h" #include "print.h" +#include "catalog/pg_type.h" #include <math.h> #include <signal.h> @@ -28,6 +32,17 @@ #include "mbprint.h" +/* + * We define the cancel_pressed flag in this file, rather than common.c where + * it naturally belongs, because this file is also used by non-psql programs + * (see the bin/scripts/ directory). In those programs cancel_pressed will + * never become set and will have no effect. + * + * Note: print.c's general strategy for when to check cancel_pressed is to do + * so at completion of each row of output. + */ +volatile bool cancel_pressed = false; + static char *decimal_point; static char *grouping; static char *thousands_sep; @@ -171,6 +186,9 @@ print_unaligned_text(const char *title, const char *const * headers, const char *const * ptr; bool need_recordsep = false; + if (cancel_pressed) + return; + if (!opt_fieldsep) opt_fieldsep = ""; if (!opt_recordsep) @@ -202,6 +220,8 @@ print_unaligned_text(const char *title, const char *const * headers, { fputs(opt_recordsep, fout); need_recordsep = false; + if (cancel_pressed) + break; } if (opt_align[i % col_count] == 'r' && opt_numeric_locale) { @@ -222,7 +242,7 @@ print_unaligned_text(const char *title, const char *const * headers, /* print footers */ - if (!opt_tuples_only && footers) + if (!opt_tuples_only && footers && !cancel_pressed) for (ptr = footers; *ptr; ptr++) { if (need_recordsep) @@ -252,6 +272,9 @@ print_unaligned_vertical(const char *title, const char *const * headers, unsigned int i; const char *const * ptr; + if (cancel_pressed) + return; + if (!opt_fieldsep) opt_fieldsep = ""; if (!opt_recordsep) @@ -273,6 +296,8 @@ print_unaligned_vertical(const char *title, const char *const * headers, fputs(opt_recordsep, fout); if (i % col_count == 0) fputs(opt_recordsep, fout); /* another one */ + if (cancel_pressed) + break; } fputs(headers[i % col_count], fout); @@ -289,7 +314,7 @@ print_unaligned_vertical(const char *title, const char *const * headers, } /* print footers */ - if (!opt_tuples_only && footers && *footers) + if (!opt_tuples_only && footers && *footers && !cancel_pressed) { fputs(opt_recordsep, fout); for (ptr = footers; *ptr; ptr++) @@ -369,6 +394,9 @@ print_aligned_text(const char *title, const char *const * headers, int *complete; /* Array remembering which columns have completed output */ + if (cancel_pressed) + return; + /* count columns */ for (ptr = headers; *ptr; ptr++) col_count++; @@ -543,7 +571,6 @@ print_aligned_text(const char *title, const char *const * headers, fputc('\n', fout); } - _print_horizontal_line(col_count, widths, opt_border, fout); } @@ -553,7 +580,10 @@ print_aligned_text(const char *title, const char *const * headers, int j; int cols_todo = col_count; int line_count; /* Number of lines output so far in row */ - + + if (cancel_pressed) + break; + for (j = 0; j < col_count; j++) pg_wcsformat((unsigned char*)ptr[j], strlen(ptr[j]), encoding, col_lineptrs[j], heights[j]); @@ -630,11 +660,11 @@ print_aligned_text(const char *title, const char *const * headers, } } - if (opt_border == 2) + if (opt_border == 2 && !cancel_pressed) _print_horizontal_line(col_count, widths, opt_border, fout); /* print footers */ - if (footers && !opt_tuples_only) + if (footers && !opt_tuples_only && !cancel_pressed) for (ptr = footers; *ptr; ptr++) fprintf(fout, "%s\n", *ptr); @@ -681,6 +711,9 @@ print_aligned_vertical(const char *title, const char *const * headers, char *divider; unsigned int cell_count = 0; struct lineptr *hlineptr, *dlineptr; + + if (cancel_pressed) + return; if (cells[0] == NULL) { @@ -764,6 +797,8 @@ print_aligned_vertical(const char *title, const char *const * headers, if (i % col_count == 0) { + if (cancel_pressed) + break; if (!opt_tuples_only) { char *record_str = pg_local_malloc(32); @@ -860,12 +895,12 @@ print_aligned_vertical(const char *title, const char *const * headers, } } - if (opt_border == 2) + if (opt_border == 2 && !cancel_pressed) fprintf(fout, "%s\n", divider); /* print footers */ - if (!opt_tuples_only && footers && *footers) + if (!opt_tuples_only && footers && *footers && !cancel_pressed) { if (opt_border < 2) fputc('\n', fout); @@ -943,6 +978,9 @@ print_html_text(const char *title, const char *const * headers, unsigned int i; const char *const * ptr; + if (cancel_pressed) + return; + fprintf(fout, "<table border=\"%d\"", opt_border); if (opt_table_attr) fprintf(fout, " %s", opt_table_attr); @@ -976,7 +1014,11 @@ print_html_text(const char *title, const char *const * headers, for (i = 0, ptr = cells; *ptr; i++, ptr++) { if (i % col_count == 0) + { + if (cancel_pressed) + break; fputs(" <tr valign=\"top\">\n", fout); + } fprintf(fout, " <td align=\"%s\">", opt_align[(i) % col_count] == 'r' ? "right" : "left"); /* is string only whitespace? */ @@ -1002,7 +1044,7 @@ print_html_text(const char *title, const char *const * headers, /* print footers */ - if (!opt_tuples_only && footers && *footers) + if (!opt_tuples_only && footers && *footers && !cancel_pressed) { fputs("<p>", fout); for (ptr = footers; *ptr; ptr++) @@ -1029,6 +1071,9 @@ print_html_vertical(const char *title, const char *const * headers, unsigned int record = 1; const char *const * ptr; + if (cancel_pressed) + return; + fprintf(fout, "<table border=\"%d\"", opt_border); if (opt_table_attr) fprintf(fout, " %s", opt_table_attr); @@ -1051,6 +1096,8 @@ print_html_vertical(const char *title, const char *const * headers, { if (i % col_count == 0) { + if (cancel_pressed) + break; if (!opt_tuples_only) fprintf(fout, "\n <tr><td colspan=\"2\" align=\"center\">Record %d</td></tr>\n", record++); else @@ -1081,7 +1128,7 @@ print_html_vertical(const char *title, const char *const * headers, fputs("</table>\n", fout); /* print footers */ - if (!opt_tuples_only && footers && *footers) + if (!opt_tuples_only && footers && *footers && !cancel_pressed) { fputs("<p>", fout); for (ptr = footers; *ptr; ptr++) @@ -1151,6 +1198,8 @@ print_latex_text(const char *title, const char *const * headers, unsigned int i; const char *const * ptr; + if (cancel_pressed) + return; /* print title */ if (!opt_tuples_only && title) @@ -1216,7 +1265,11 @@ print_latex_text(const char *title, const char *const * headers, latex_escaped_print(*ptr, fout); if ((i + 1) % col_count == 0) + { fputs(" \\\\\n", fout); + if (cancel_pressed) + break; + } else fputs(" & ", fout); } @@ -1229,7 +1282,7 @@ print_latex_text(const char *title, const char *const * headers, /* print footers */ - if (footers && !opt_tuples_only) + if (footers && !opt_tuples_only && !cancel_pressed) for (ptr = footers; *ptr; ptr++) { latex_escaped_print(*ptr, fout); @@ -1255,6 +1308,9 @@ print_latex_vertical(const char *title, const char *const * headers, (void) opt_align; /* currently unused parameter */ + if (cancel_pressed) + return; + /* print title */ if (!opt_tuples_only && title) { @@ -1285,6 +1341,8 @@ print_latex_vertical(const char *title, const char *const * headers, /* new record */ if (i % col_count == 0) { + if (cancel_pressed) + break; if (!opt_tuples_only) { if (opt_border == 2) @@ -1313,7 +1371,7 @@ print_latex_vertical(const char *title, const char *const * headers, /* print footers */ - if (footers && !opt_tuples_only) + if (footers && !opt_tuples_only && !cancel_pressed) for (ptr = footers; *ptr; ptr++) { if (opt_numeric_locale) @@ -1367,6 +1425,8 @@ print_troff_ms_text(const char *title, const char *const * headers, unsigned int i; const char *const * ptr; + if (cancel_pressed) + return; /* print title */ if (!opt_tuples_only && title) @@ -1425,7 +1485,11 @@ print_troff_ms_text(const char *title, const char *const * headers, troff_ms_escaped_print(*ptr, fout); if ((i + 1) % col_count == 0) + { fputc('\n', fout); + if (cancel_pressed) + break; + } else fputc('\t', fout); } @@ -1435,7 +1499,7 @@ print_troff_ms_text(const char *title, const char *const * headers, /* print footers */ - if (footers && !opt_tuples_only) + if (footers && !opt_tuples_only && !cancel_pressed) for (ptr = footers; *ptr; ptr++) { troff_ms_escaped_print(*ptr, fout); @@ -1462,6 +1526,9 @@ print_troff_ms_vertical(const char *title, const char *const * headers, (void) opt_align; /* currently unused parameter */ + if (cancel_pressed) + return; + /* print title */ if (!opt_tuples_only && title) { @@ -1491,6 +1558,8 @@ print_troff_ms_vertical(const char *title, const char *const * headers, /* new record */ if (i % col_count == 0) { + if (cancel_pressed) + break; if (!opt_tuples_only) { if (current_format != 1) @@ -1542,7 +1611,7 @@ print_troff_ms_vertical(const char *title, const char *const * headers, /* print footers */ - if (footers && !opt_tuples_only) + if (footers && !opt_tuples_only && !cancel_pressed) for (ptr = footers; *ptr; ptr++) { troff_ms_escaped_print(*ptr, fout); @@ -1618,6 +1687,9 @@ printTable(const char *title, FILE *output; bool use_expanded; + if (cancel_pressed) + return; + if (opt->format == PRINT_NOTHING) return; @@ -1731,6 +1803,17 @@ printTable(const char *title, /* Only close if we used the pager */ if (fout == stdout && output != stdout) { + /* + * If printing was canceled midstream, warn about it. + * + * Some pagers like less use Ctrl-C as part of their command + * set. Even so, we abort our processing and warn the user + * what we did. If the pager quit as a result of the + * SIGINT, this message won't go anywhere ... + */ + if (cancel_pressed) + fprintf(output, _("Interrupted\n")); + pclose(output); #ifndef WIN32 pqsignal(SIGPIPE, SIG_DFL); @@ -1751,6 +1834,9 @@ printQuery(const PGresult *result, const printQueryOpt *opt, FILE *fout, FILE *f char *align; int i; + if (cancel_pressed) + return; + /* extract headers */ nfields = PQnfields(result); @@ -1798,18 +1884,24 @@ printQuery(const PGresult *result, const printQueryOpt *opt, FILE *fout, FILE *f { Oid ftype = PQftype(result, i); - if (ftype == 20 || /* int8 */ - ftype == 21 || /* int2 */ - ftype == 23 || /* int4 */ - (ftype >= 26 && ftype <= 30) || /* ?id */ - ftype == 700 || /* float4 */ - ftype == 701 || /* float8 */ - ftype == 790 || /* money */ - ftype == 1700 /* numeric */ - ) - align[i] = 'r'; - else - align[i] = 'l'; + switch (ftype) + { + case INT2OID: + case INT4OID: + case INT8OID: + case FLOAT4OID: + case FLOAT8OID: + case NUMERICOID: + case OIDOID: + case XIDOID: + case CIDOID: + case CASHOID: + align[i] = 'r'; + break; + default: + align[i] = 'l'; + break; + } } /* call table printer */ |