aboutsummaryrefslogtreecommitdiff
path: root/src/bin/psql/print.c
diff options
context:
space:
mode:
authorTom Lane <tgl@sss.pgh.pa.us>2007-12-12 21:41:47 +0000
committerTom Lane <tgl@sss.pgh.pa.us>2007-12-12 21:41:47 +0000
commitdf4271fedd3a3428ffafb9c2cff7de37e13976a0 (patch)
tree7bae4d81aa5a895c4a9402428f500992f700bc2a /src/bin/psql/print.c
parent286049dbe4e2763412ef71f62c61b2b297aed6cc (diff)
downloadpostgresql-df4271fedd3a3428ffafb9c2cff7de37e13976a0.tar.gz
postgresql-df4271fedd3a3428ffafb9c2cff7de37e13976a0.zip
Improve the method of localizing column names and other fixed strings in
psql's \d commands and other uses of printQuery(). Previously we would pass these strings through gettext() and then send them to the server as literals in the SQL query. But the code was not set up to handle doubling of quotes in the strings, causing failure if a translation attempted to use the wrong kind of quote marks, as indeed is now the case for (at least) the French translation of \dFp. Another hazard was that gettext() would translate to whatever encoding was implied by the client's LC_CTYPE setting, which might be different from the client_encoding setting, which would probably cause the server to reject the query as mis-encoded. The new arrangement is to send the untranslated ASCII strings to the server, and do the translations inside printQuery() after the query results come back. Per report from Guillaume Lelarge and subsequent discussion.
Diffstat (limited to 'src/bin/psql/print.c')
-rw-r--r--src/bin/psql/print.c45
1 files changed, 33 insertions, 12 deletions
diff --git a/src/bin/psql/print.c b/src/bin/psql/print.c
index d0e378b7bdc..c7df0072f84 100644
--- a/src/bin/psql/print.c
+++ b/src/bin/psql/print.c
@@ -3,7 +3,7 @@
*
* Copyright (c) 2000-2007, PostgreSQL Global Development Group
*
- * $PostgreSQL: pgsql/src/bin/psql/print.c,v 1.94 2007/11/22 17:51:39 momjian Exp $
+ * $PostgreSQL: pgsql/src/bin/psql/print.c,v 1.95 2007/12/12 21:41:47 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.
@@ -1926,38 +1926,59 @@ printTable(const char *title,
void
printQuery(const PGresult *result, const printQueryOpt *opt, FILE *fout, FILE *flog)
{
+ int ntuples;
int nfields;
int ncells;
const char **headers;
const char **cells;
char **footers;
char *align;
- int i;
+ int i,
+ r,
+ c;
if (cancel_pressed)
return;
/* extract headers */
+ ntuples = PQntuples(result);
nfields = PQnfields(result);
headers = pg_local_calloc(nfields + 1, sizeof(*headers));
for (i = 0; i < nfields; i++)
+ {
headers[i] = (char *) mbvalidate((unsigned char *) PQfname(result, i),
opt->topt.encoding);
+#ifdef ENABLE_NLS
+ if (opt->trans_headers)
+ headers[i] = _(headers[i]);
+#endif
+ }
/* set cells */
- ncells = PQntuples(result) * nfields;
+ ncells = ntuples * nfields;
cells = pg_local_calloc(ncells + 1, sizeof(*cells));
- for (i = 0; i < ncells; i++)
+ i = 0;
+ for (r = 0; r < ntuples; r++)
{
- if (PQgetisnull(result, i / nfields, i % nfields))
- cells[i] = opt->nullPrint ? opt->nullPrint : "";
- else
- cells[i] = (char *)
- mbvalidate((unsigned char *) PQgetvalue(result, i / nfields, i % nfields),
- opt->topt.encoding);
+ for (c = 0; c < nfields; c++)
+ {
+ if (PQgetisnull(result, r, c))
+ cells[i] = opt->nullPrint ? opt->nullPrint : "";
+ else
+ {
+ cells[i] = (char *)
+ mbvalidate((unsigned char *) PQgetvalue(result, r, c),
+ opt->topt.encoding);
+#ifdef ENABLE_NLS
+ if (opt->trans_columns && opt->trans_columns[c])
+ cells[i] = _(cells[i]);
+#endif
+ }
+ i++;
+ }
}
/* set footers */
@@ -1970,7 +1991,7 @@ printQuery(const PGresult *result, const printQueryOpt *opt, FILE *fout, FILE *f
footers = pg_local_calloc(2, sizeof(*footers));
footers[0] = pg_local_malloc(100);
- total_records = opt->topt.prior_records + PQntuples(result);
+ total_records = opt->topt.prior_records + ntuples;
if (total_records == 1)
snprintf(footers[0], 100, _("(1 row)"));
else
@@ -2013,7 +2034,7 @@ printQuery(const PGresult *result, const printQueryOpt *opt, FILE *fout, FILE *f
free(headers);
free(cells);
- if (footers)
+ if (footers && !opt->footers)
{
free(footers[0]);
free(footers);