mirror of
https://git.postgresql.org/git/postgresql.git
synced 2024-12-27 08:39:28 +08:00
Fix numericlocale psql option when used with a null string and latex and troff
formats; a null string must not be formatted as a numeric. The more exotic formats latex and troff also incorrectly formatted all strings as numerics when numericlocale was on. Backpatch to 8.1 where numericlocale option was added. This fixes bug #5355 reported by Andy Lester.
This commit is contained in:
parent
d6a6f8c6be
commit
93df658a01
@ -8,7 +8,7 @@
|
|||||||
*
|
*
|
||||||
* Copyright (c) 2000-2010, PostgreSQL Global Development Group
|
* Copyright (c) 2000-2010, PostgreSQL Global Development Group
|
||||||
*
|
*
|
||||||
* $PostgreSQL: pgsql/src/bin/psql/describe.c,v 1.238 2010/02/26 02:01:18 momjian Exp $
|
* $PostgreSQL: pgsql/src/bin/psql/describe.c,v 1.239 2010/03/01 20:55:45 heikki Exp $
|
||||||
*/
|
*/
|
||||||
#include "postgres_fe.h"
|
#include "postgres_fe.h"
|
||||||
|
|
||||||
@ -1349,10 +1349,10 @@ describeOneTableDetails(const char *schemaname,
|
|||||||
for (i = 0; i < numrows; i++)
|
for (i = 0; i < numrows; i++)
|
||||||
{
|
{
|
||||||
/* Column */
|
/* Column */
|
||||||
printTableAddCell(&cont, PQgetvalue(res, i, 0), false);
|
printTableAddCell(&cont, PQgetvalue(res, i, 0), false, false);
|
||||||
|
|
||||||
/* Type */
|
/* Type */
|
||||||
printTableAddCell(&cont, PQgetvalue(res, i, 1), false);
|
printTableAddCell(&cont, PQgetvalue(res, i, 1), false, false);
|
||||||
|
|
||||||
/* Modifiers: not null and default */
|
/* Modifiers: not null and default */
|
||||||
if (show_modifiers)
|
if (show_modifiers)
|
||||||
@ -1373,16 +1373,16 @@ describeOneTableDetails(const char *schemaname,
|
|||||||
}
|
}
|
||||||
|
|
||||||
modifiers[i] = pg_strdup(tmpbuf.data);
|
modifiers[i] = pg_strdup(tmpbuf.data);
|
||||||
printTableAddCell(&cont, modifiers[i], false);
|
printTableAddCell(&cont, modifiers[i], false, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Value: for sequences only */
|
/* Value: for sequences only */
|
||||||
if (tableinfo.relkind == 'S')
|
if (tableinfo.relkind == 'S')
|
||||||
printTableAddCell(&cont, seq_values[i], false);
|
printTableAddCell(&cont, seq_values[i], false, false);
|
||||||
|
|
||||||
/* Expression for index column */
|
/* Expression for index column */
|
||||||
if (tableinfo.relkind == 'i')
|
if (tableinfo.relkind == 'i')
|
||||||
printTableAddCell(&cont, PQgetvalue(res, i, 5), false);
|
printTableAddCell(&cont, PQgetvalue(res, i, 5), false, false);
|
||||||
|
|
||||||
/* Storage and Description */
|
/* Storage and Description */
|
||||||
if (verbose)
|
if (verbose)
|
||||||
@ -1396,8 +1396,9 @@ describeOneTableDetails(const char *schemaname,
|
|||||||
(storage[0] == 'x' ? "extended" :
|
(storage[0] == 'x' ? "extended" :
|
||||||
(storage[0] == 'e' ? "external" :
|
(storage[0] == 'e' ? "external" :
|
||||||
"???")))),
|
"???")))),
|
||||||
false);
|
false, false);
|
||||||
printTableAddCell(&cont, PQgetvalue(res, i, firstvcol + 1), false);
|
printTableAddCell(&cont, PQgetvalue(res, i, firstvcol + 1),
|
||||||
|
false, false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2243,7 +2244,7 @@ describeRoles(const char *pattern, bool verbose)
|
|||||||
|
|
||||||
for (i = 0; i < nrows; i++)
|
for (i = 0; i < nrows; i++)
|
||||||
{
|
{
|
||||||
printTableAddCell(&cont, PQgetvalue(res, i, 0), false);
|
printTableAddCell(&cont, PQgetvalue(res, i, 0), false, false);
|
||||||
|
|
||||||
resetPQExpBuffer(&buf);
|
resetPQExpBuffer(&buf);
|
||||||
if (strcmp(PQgetvalue(res, i, 1), "t") == 0)
|
if (strcmp(PQgetvalue(res, i, 1), "t") == 0)
|
||||||
@ -2278,12 +2279,12 @@ describeRoles(const char *pattern, bool verbose)
|
|||||||
|
|
||||||
attr[i] = pg_strdup(buf.data);
|
attr[i] = pg_strdup(buf.data);
|
||||||
|
|
||||||
printTableAddCell(&cont, attr[i], false);
|
printTableAddCell(&cont, attr[i], false, false);
|
||||||
|
|
||||||
printTableAddCell(&cont, PQgetvalue(res, i, 7), false);
|
printTableAddCell(&cont, PQgetvalue(res, i, 7), false, false);
|
||||||
|
|
||||||
if (verbose && pset.sversion >= 80200)
|
if (verbose && pset.sversion >= 80200)
|
||||||
printTableAddCell(&cont, PQgetvalue(res, i, 8), false);
|
printTableAddCell(&cont, PQgetvalue(res, i, 8), false, false);
|
||||||
}
|
}
|
||||||
termPQExpBuffer(&buf);
|
termPQExpBuffer(&buf);
|
||||||
|
|
||||||
|
@ -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/print.c,v 1.122 2010/02/26 02:01:19 momjian Exp $
|
* $PostgreSQL: pgsql/src/bin/psql/print.c,v 1.123 2010/03/01 20:55:45 heikki Exp $
|
||||||
*/
|
*/
|
||||||
#include "postgres_fe.h"
|
#include "postgres_fe.h"
|
||||||
|
|
||||||
@ -263,7 +263,6 @@ print_unaligned_text(const printTableContent *cont, FILE *fout)
|
|||||||
const char *opt_fieldsep = cont->opt->fieldSep;
|
const char *opt_fieldsep = cont->opt->fieldSep;
|
||||||
const char *opt_recordsep = cont->opt->recordSep;
|
const char *opt_recordsep = cont->opt->recordSep;
|
||||||
bool opt_tuples_only = cont->opt->tuples_only;
|
bool opt_tuples_only = cont->opt->tuples_only;
|
||||||
bool opt_numeric_locale = cont->opt->numericLocale;
|
|
||||||
unsigned int i;
|
unsigned int i;
|
||||||
const char *const * ptr;
|
const char *const * ptr;
|
||||||
bool need_recordsep = false;
|
bool need_recordsep = false;
|
||||||
@ -308,15 +307,7 @@ print_unaligned_text(const printTableContent *cont, FILE *fout)
|
|||||||
if (cancel_pressed)
|
if (cancel_pressed)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (cont->aligns[i % cont->ncolumns] == 'r' && opt_numeric_locale)
|
fputs(*ptr, fout);
|
||||||
{
|
|
||||||
char *my_cell = format_numeric_locale(*ptr);
|
|
||||||
|
|
||||||
fputs(my_cell, fout);
|
|
||||||
free(my_cell);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
fputs(*ptr, fout);
|
|
||||||
|
|
||||||
if ((i + 1) % cont->ncolumns)
|
if ((i + 1) % cont->ncolumns)
|
||||||
fputs(opt_fieldsep, fout);
|
fputs(opt_fieldsep, fout);
|
||||||
@ -355,7 +346,6 @@ print_unaligned_vertical(const printTableContent *cont, FILE *fout)
|
|||||||
const char *opt_fieldsep = cont->opt->fieldSep;
|
const char *opt_fieldsep = cont->opt->fieldSep;
|
||||||
const char *opt_recordsep = cont->opt->recordSep;
|
const char *opt_recordsep = cont->opt->recordSep;
|
||||||
bool opt_tuples_only = cont->opt->tuples_only;
|
bool opt_tuples_only = cont->opt->tuples_only;
|
||||||
bool opt_numeric_locale = cont->opt->numericLocale;
|
|
||||||
unsigned int i;
|
unsigned int i;
|
||||||
const char *const * ptr;
|
const char *const * ptr;
|
||||||
bool need_recordsep = false;
|
bool need_recordsep = false;
|
||||||
@ -396,15 +386,7 @@ print_unaligned_vertical(const printTableContent *cont, FILE *fout)
|
|||||||
|
|
||||||
fputs(cont->headers[i % cont->ncolumns], fout);
|
fputs(cont->headers[i % cont->ncolumns], fout);
|
||||||
fputs(opt_fieldsep, fout);
|
fputs(opt_fieldsep, fout);
|
||||||
if (cont->aligns[i % cont->ncolumns] == 'r' && opt_numeric_locale)
|
fputs(*ptr, fout);
|
||||||
{
|
|
||||||
char *my_cell = format_numeric_locale(*ptr);
|
|
||||||
|
|
||||||
fputs(my_cell, fout);
|
|
||||||
free(my_cell);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
fputs(*ptr, fout);
|
|
||||||
|
|
||||||
if ((i + 1) % cont->ncolumns)
|
if ((i + 1) % cont->ncolumns)
|
||||||
fputs(opt_recordsep, fout);
|
fputs(opt_recordsep, fout);
|
||||||
@ -484,7 +466,6 @@ static void
|
|||||||
print_aligned_text(const printTableContent *cont, FILE *fout)
|
print_aligned_text(const printTableContent *cont, FILE *fout)
|
||||||
{
|
{
|
||||||
bool opt_tuples_only = cont->opt->tuples_only;
|
bool opt_tuples_only = cont->opt->tuples_only;
|
||||||
bool opt_numeric_locale = cont->opt->numericLocale;
|
|
||||||
int encoding = cont->opt->encoding;
|
int encoding = cont->opt->encoding;
|
||||||
unsigned short opt_border = cont->opt->border;
|
unsigned short opt_border = cont->opt->border;
|
||||||
const printTextFormat *format = get_line_style(cont->opt);
|
const printTextFormat *format = get_line_style(cont->opt);
|
||||||
@ -590,11 +571,6 @@ print_aligned_text(const printTableContent *cont, FILE *fout)
|
|||||||
|
|
||||||
pg_wcssize((unsigned char *) *ptr, strlen(*ptr), encoding,
|
pg_wcssize((unsigned char *) *ptr, strlen(*ptr), encoding,
|
||||||
&width, &nl_lines, &bytes_required);
|
&width, &nl_lines, &bytes_required);
|
||||||
if (opt_numeric_locale && cont->aligns[i % col_count] == 'r')
|
|
||||||
{
|
|
||||||
width += additional_numeric_locale_len(*ptr);
|
|
||||||
bytes_required += additional_numeric_locale_len(*ptr);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (width > max_width[i % col_count])
|
if (width > max_width[i % col_count])
|
||||||
max_width[i % col_count] = width;
|
max_width[i % col_count] = width;
|
||||||
@ -743,8 +719,6 @@ print_aligned_text(const printTableContent *cont, FILE *fout)
|
|||||||
|
|
||||||
pg_wcssize((unsigned char *) *ptr, strlen(*ptr), encoding,
|
pg_wcssize((unsigned char *) *ptr, strlen(*ptr), encoding,
|
||||||
&width, &nl_lines, &bytes_required);
|
&width, &nl_lines, &bytes_required);
|
||||||
if (opt_numeric_locale && cont->align[i] == 'r')
|
|
||||||
width += additional_numeric_locale_len(*ptr);
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* A row can have both wrapping and newlines that cause it to
|
* A row can have both wrapping and newlines that cause it to
|
||||||
@ -869,24 +843,13 @@ print_aligned_text(const printTableContent *cont, FILE *fout)
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Format each cell. Format again, if it's a numeric formatting
|
* Format each cell.
|
||||||
* locale (e.g. 123,456 vs. 123456)
|
|
||||||
*/
|
*/
|
||||||
for (j = 0; j < col_count; j++)
|
for (j = 0; j < col_count; j++)
|
||||||
{
|
{
|
||||||
pg_wcsformat((unsigned char *) ptr[j], strlen(ptr[j]), encoding,
|
pg_wcsformat((unsigned char *) ptr[j], strlen(ptr[j]), encoding,
|
||||||
col_lineptrs[j], max_nl_lines[j]);
|
col_lineptrs[j], max_nl_lines[j]);
|
||||||
curr_nl_line[j] = 0;
|
curr_nl_line[j] = 0;
|
||||||
|
|
||||||
if (opt_numeric_locale && cont->aligns[j] == 'r')
|
|
||||||
{
|
|
||||||
char *my_cell;
|
|
||||||
|
|
||||||
my_cell = format_numeric_locale((char *) col_lineptrs[j]->ptr);
|
|
||||||
/* Buffer IS large enough... now */
|
|
||||||
strcpy((char *) col_lineptrs[j]->ptr, my_cell);
|
|
||||||
free(my_cell);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
memset(bytes_output, 0, col_count * sizeof(int));
|
memset(bytes_output, 0, col_count * sizeof(int));
|
||||||
@ -1131,7 +1094,6 @@ static void
|
|||||||
print_aligned_vertical(const printTableContent *cont, FILE *fout)
|
print_aligned_vertical(const printTableContent *cont, FILE *fout)
|
||||||
{
|
{
|
||||||
bool opt_tuples_only = cont->opt->tuples_only;
|
bool opt_tuples_only = cont->opt->tuples_only;
|
||||||
bool opt_numeric_locale = cont->opt->numericLocale;
|
|
||||||
unsigned short opt_border = cont->opt->border;
|
unsigned short opt_border = cont->opt->border;
|
||||||
const printTextFormat *format = get_line_style(cont->opt);
|
const printTextFormat *format = get_line_style(cont->opt);
|
||||||
const printTextLineFormat *dformat = &format->lrule[PRINT_RULE_DATA];
|
const printTextLineFormat *dformat = &format->lrule[PRINT_RULE_DATA];
|
||||||
@ -1181,19 +1143,12 @@ print_aligned_vertical(const printTableContent *cont, FILE *fout)
|
|||||||
/* find longest data cell */
|
/* find longest data cell */
|
||||||
for (i = 0, ptr = cont->cells; *ptr; ptr++, i++)
|
for (i = 0, ptr = cont->cells; *ptr; ptr++, i++)
|
||||||
{
|
{
|
||||||
int numeric_locale_len;
|
|
||||||
int width,
|
int width,
|
||||||
height,
|
height,
|
||||||
fs;
|
fs;
|
||||||
|
|
||||||
if (cont->aligns[i % cont->ncolumns] == 'r' && opt_numeric_locale)
|
|
||||||
numeric_locale_len = additional_numeric_locale_len(*ptr);
|
|
||||||
else
|
|
||||||
numeric_locale_len = 0;
|
|
||||||
|
|
||||||
pg_wcssize((unsigned char *) *ptr, strlen(*ptr), encoding,
|
pg_wcssize((unsigned char *) *ptr, strlen(*ptr), encoding,
|
||||||
&width, &height, &fs);
|
&width, &height, &fs);
|
||||||
width += numeric_locale_len;
|
|
||||||
if (width > dwidth)
|
if (width > dwidth)
|
||||||
dwidth = width;
|
dwidth = width;
|
||||||
if (height > dheight)
|
if (height > dheight)
|
||||||
@ -1279,27 +1234,12 @@ print_aligned_vertical(const printTableContent *cont, FILE *fout)
|
|||||||
|
|
||||||
if (!dcomplete)
|
if (!dcomplete)
|
||||||
{
|
{
|
||||||
if (cont->aligns[i % cont->ncolumns] == 'r' && opt_numeric_locale)
|
if (opt_border < 2)
|
||||||
{
|
fprintf(fout, "%s\n", dlineptr[line_count].ptr);
|
||||||
char *my_cell = format_numeric_locale((char *) dlineptr[line_count].ptr);
|
|
||||||
|
|
||||||
if (opt_border < 2)
|
|
||||||
fprintf(fout, "%s\n", my_cell);
|
|
||||||
else
|
|
||||||
fprintf(fout, "%-s%*s %s\n", my_cell,
|
|
||||||
(int) (dwidth - strlen(my_cell)), "",
|
|
||||||
dformat->rightvrule);
|
|
||||||
free(my_cell);
|
|
||||||
}
|
|
||||||
else
|
else
|
||||||
{
|
fprintf(fout, "%-s%*s %s\n", dlineptr[line_count].ptr,
|
||||||
if (opt_border < 2)
|
dwidth - dlineptr[line_count].width, "",
|
||||||
fprintf(fout, "%s\n", dlineptr[line_count].ptr);
|
dformat->rightvrule);
|
||||||
else
|
|
||||||
fprintf(fout, "%-s%*s %s\n", dlineptr[line_count].ptr,
|
|
||||||
dwidth - dlineptr[line_count].width, "",
|
|
||||||
dformat->rightvrule);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!dlineptr[line_count + 1].ptr)
|
if (!dlineptr[line_count + 1].ptr)
|
||||||
dcomplete = 1;
|
dcomplete = 1;
|
||||||
@ -1392,7 +1332,6 @@ static void
|
|||||||
print_html_text(const printTableContent *cont, FILE *fout)
|
print_html_text(const printTableContent *cont, FILE *fout)
|
||||||
{
|
{
|
||||||
bool opt_tuples_only = cont->opt->tuples_only;
|
bool opt_tuples_only = cont->opt->tuples_only;
|
||||||
bool opt_numeric_locale = cont->opt->numericLocale;
|
|
||||||
unsigned short opt_border = cont->opt->border;
|
unsigned short opt_border = cont->opt->border;
|
||||||
const char *opt_table_attr = cont->opt->tableAttr;
|
const char *opt_table_attr = cont->opt->tableAttr;
|
||||||
unsigned int i;
|
unsigned int i;
|
||||||
@ -1444,13 +1383,6 @@ print_html_text(const printTableContent *cont, FILE *fout)
|
|||||||
/* is string only whitespace? */
|
/* is string only whitespace? */
|
||||||
if ((*ptr)[strspn(*ptr, " \t")] == '\0')
|
if ((*ptr)[strspn(*ptr, " \t")] == '\0')
|
||||||
fputs(" ", fout);
|
fputs(" ", fout);
|
||||||
else if (cont->aligns[i % cont->ncolumns] == 'r' && opt_numeric_locale)
|
|
||||||
{
|
|
||||||
char *my_cell = format_numeric_locale(*ptr);
|
|
||||||
|
|
||||||
html_escaped_print(my_cell, fout);
|
|
||||||
free(my_cell);
|
|
||||||
}
|
|
||||||
else
|
else
|
||||||
html_escaped_print(*ptr, fout);
|
html_escaped_print(*ptr, fout);
|
||||||
|
|
||||||
@ -1487,7 +1419,6 @@ static void
|
|||||||
print_html_vertical(const printTableContent *cont, FILE *fout)
|
print_html_vertical(const printTableContent *cont, FILE *fout)
|
||||||
{
|
{
|
||||||
bool opt_tuples_only = cont->opt->tuples_only;
|
bool opt_tuples_only = cont->opt->tuples_only;
|
||||||
bool opt_numeric_locale = cont->opt->numericLocale;
|
|
||||||
unsigned short opt_border = cont->opt->border;
|
unsigned short opt_border = cont->opt->border;
|
||||||
const char *opt_table_attr = cont->opt->tableAttr;
|
const char *opt_table_attr = cont->opt->tableAttr;
|
||||||
unsigned long record = cont->opt->prior_records + 1;
|
unsigned long record = cont->opt->prior_records + 1;
|
||||||
@ -1536,13 +1467,6 @@ print_html_vertical(const printTableContent *cont, FILE *fout)
|
|||||||
/* is string only whitespace? */
|
/* is string only whitespace? */
|
||||||
if ((*ptr)[strspn(*ptr, " \t")] == '\0')
|
if ((*ptr)[strspn(*ptr, " \t")] == '\0')
|
||||||
fputs(" ", fout);
|
fputs(" ", fout);
|
||||||
else if (cont->aligns[i % cont->ncolumns] == 'r' && opt_numeric_locale)
|
|
||||||
{
|
|
||||||
char *my_cell = format_numeric_locale(*ptr);
|
|
||||||
|
|
||||||
html_escaped_print(my_cell, fout);
|
|
||||||
free(my_cell);
|
|
||||||
}
|
|
||||||
else
|
else
|
||||||
html_escaped_print(*ptr, fout);
|
html_escaped_print(*ptr, fout);
|
||||||
|
|
||||||
@ -1619,7 +1543,6 @@ static void
|
|||||||
print_latex_text(const printTableContent *cont, FILE *fout)
|
print_latex_text(const printTableContent *cont, FILE *fout)
|
||||||
{
|
{
|
||||||
bool opt_tuples_only = cont->opt->tuples_only;
|
bool opt_tuples_only = cont->opt->tuples_only;
|
||||||
bool opt_numeric_locale = cont->opt->numericLocale;
|
|
||||||
unsigned short opt_border = cont->opt->border;
|
unsigned short opt_border = cont->opt->border;
|
||||||
unsigned int i;
|
unsigned int i;
|
||||||
const char *const * ptr;
|
const char *const * ptr;
|
||||||
@ -1678,15 +1601,7 @@ print_latex_text(const printTableContent *cont, FILE *fout)
|
|||||||
/* print cells */
|
/* print cells */
|
||||||
for (i = 0, ptr = cont->cells; *ptr; i++, ptr++)
|
for (i = 0, ptr = cont->cells; *ptr; i++, ptr++)
|
||||||
{
|
{
|
||||||
if (opt_numeric_locale)
|
latex_escaped_print(*ptr, fout);
|
||||||
{
|
|
||||||
char *my_cell = format_numeric_locale(*ptr);
|
|
||||||
|
|
||||||
latex_escaped_print(my_cell, fout);
|
|
||||||
free(my_cell);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
latex_escaped_print(*ptr, fout);
|
|
||||||
|
|
||||||
if ((i + 1) % cont->ncolumns == 0)
|
if ((i + 1) % cont->ncolumns == 0)
|
||||||
{
|
{
|
||||||
@ -1726,7 +1641,6 @@ static void
|
|||||||
print_latex_vertical(const printTableContent *cont, FILE *fout)
|
print_latex_vertical(const printTableContent *cont, FILE *fout)
|
||||||
{
|
{
|
||||||
bool opt_tuples_only = cont->opt->tuples_only;
|
bool opt_tuples_only = cont->opt->tuples_only;
|
||||||
bool opt_numeric_locale = cont->opt->numericLocale;
|
|
||||||
unsigned short opt_border = cont->opt->border;
|
unsigned short opt_border = cont->opt->border;
|
||||||
unsigned long record = cont->opt->prior_records + 1;
|
unsigned long record = cont->opt->prior_records + 1;
|
||||||
unsigned int i;
|
unsigned int i;
|
||||||
@ -1801,15 +1715,7 @@ print_latex_vertical(const printTableContent *cont, FILE *fout)
|
|||||||
|
|
||||||
for (f = cont->footers; f; f = f->next)
|
for (f = cont->footers; f; f = f->next)
|
||||||
{
|
{
|
||||||
if (opt_numeric_locale)
|
latex_escaped_print(f->data, fout);
|
||||||
{
|
|
||||||
char *my_cell = format_numeric_locale(f->data);
|
|
||||||
|
|
||||||
latex_escaped_print(my_cell, fout);
|
|
||||||
free(my_cell);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
latex_escaped_print(f->data, fout);
|
|
||||||
fputs(" \\\\\n", fout);
|
fputs(" \\\\\n", fout);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1845,7 +1751,6 @@ static void
|
|||||||
print_troff_ms_text(const printTableContent *cont, FILE *fout)
|
print_troff_ms_text(const printTableContent *cont, FILE *fout)
|
||||||
{
|
{
|
||||||
bool opt_tuples_only = cont->opt->tuples_only;
|
bool opt_tuples_only = cont->opt->tuples_only;
|
||||||
bool opt_numeric_locale = cont->opt->numericLocale;
|
|
||||||
unsigned short opt_border = cont->opt->border;
|
unsigned short opt_border = cont->opt->border;
|
||||||
unsigned int i;
|
unsigned int i;
|
||||||
const char *const * ptr;
|
const char *const * ptr;
|
||||||
@ -1899,15 +1804,7 @@ print_troff_ms_text(const printTableContent *cont, FILE *fout)
|
|||||||
/* print cells */
|
/* print cells */
|
||||||
for (i = 0, ptr = cont->cells; *ptr; i++, ptr++)
|
for (i = 0, ptr = cont->cells; *ptr; i++, ptr++)
|
||||||
{
|
{
|
||||||
if (opt_numeric_locale)
|
troff_ms_escaped_print(*ptr, fout);
|
||||||
{
|
|
||||||
char *my_cell = format_numeric_locale(*ptr);
|
|
||||||
|
|
||||||
troff_ms_escaped_print(my_cell, fout);
|
|
||||||
free(my_cell);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
troff_ms_escaped_print(*ptr, fout);
|
|
||||||
|
|
||||||
if ((i + 1) % cont->ncolumns == 0)
|
if ((i + 1) % cont->ncolumns == 0)
|
||||||
{
|
{
|
||||||
@ -1944,7 +1841,6 @@ static void
|
|||||||
print_troff_ms_vertical(const printTableContent *cont, FILE *fout)
|
print_troff_ms_vertical(const printTableContent *cont, FILE *fout)
|
||||||
{
|
{
|
||||||
bool opt_tuples_only = cont->opt->tuples_only;
|
bool opt_tuples_only = cont->opt->tuples_only;
|
||||||
bool opt_numeric_locale = cont->opt->numericLocale;
|
|
||||||
unsigned short opt_border = cont->opt->border;
|
unsigned short opt_border = cont->opt->border;
|
||||||
unsigned long record = cont->opt->prior_records + 1;
|
unsigned long record = cont->opt->prior_records + 1;
|
||||||
unsigned int i;
|
unsigned int i;
|
||||||
@ -2022,15 +1918,7 @@ print_troff_ms_vertical(const printTableContent *cont, FILE *fout)
|
|||||||
|
|
||||||
troff_ms_escaped_print(cont->headers[i % cont->ncolumns], fout);
|
troff_ms_escaped_print(cont->headers[i % cont->ncolumns], fout);
|
||||||
fputc('\t', fout);
|
fputc('\t', fout);
|
||||||
if (opt_numeric_locale)
|
troff_ms_escaped_print(*ptr, fout);
|
||||||
{
|
|
||||||
char *my_cell = format_numeric_locale(*ptr);
|
|
||||||
|
|
||||||
troff_ms_escaped_print(my_cell, fout);
|
|
||||||
free(my_cell);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
troff_ms_escaped_print(*ptr, fout);
|
|
||||||
|
|
||||||
fputc('\n', fout);
|
fputc('\n', fout);
|
||||||
}
|
}
|
||||||
@ -2155,6 +2043,7 @@ printTableInit(printTableContent *const content, const printTableOpt *opt,
|
|||||||
content->cells = pg_local_calloc(ncolumns * nrows + 1,
|
content->cells = pg_local_calloc(ncolumns * nrows + 1,
|
||||||
sizeof(*content->cells));
|
sizeof(*content->cells));
|
||||||
|
|
||||||
|
content->cellmustfree = NULL;
|
||||||
content->footers = NULL;
|
content->footers = NULL;
|
||||||
|
|
||||||
content->aligns = pg_local_calloc(ncolumns + 1,
|
content->aligns = pg_local_calloc(ncolumns + 1,
|
||||||
@ -2164,6 +2053,7 @@ printTableInit(printTableContent *const content, const printTableOpt *opt,
|
|||||||
content->cell = content->cells;
|
content->cell = content->cells;
|
||||||
content->footer = content->footers;
|
content->footer = content->footers;
|
||||||
content->align = content->aligns;
|
content->align = content->aligns;
|
||||||
|
content->cellsadded = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -2214,16 +2104,18 @@ printTableAddHeader(printTableContent *const content, const char *header,
|
|||||||
*
|
*
|
||||||
* If translate is true, the function will pass the cell through gettext.
|
* If translate is true, the function will pass the cell through gettext.
|
||||||
* Otherwise, the cell will not be translated.
|
* Otherwise, the cell will not be translated.
|
||||||
|
*
|
||||||
|
* If mustfree is true, the cell string is freed by printTableCleanup().
|
||||||
*/
|
*/
|
||||||
void
|
void
|
||||||
printTableAddCell(printTableContent *const content, const char *cell,
|
printTableAddCell(printTableContent *const content, const char *cell,
|
||||||
const bool translate)
|
const bool translate, const bool mustfree)
|
||||||
{
|
{
|
||||||
#ifndef ENABLE_NLS
|
#ifndef ENABLE_NLS
|
||||||
(void) translate; /* unused parameter */
|
(void) translate; /* unused parameter */
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (content->cell >= content->cells + (content->ncolumns * content->nrows))
|
if (content->cellsadded >= content->ncolumns * content->nrows)
|
||||||
{
|
{
|
||||||
fprintf(stderr, _("Cannot add cell to table content: "
|
fprintf(stderr, _("Cannot add cell to table content: "
|
||||||
"total cell count of %d exceeded.\n"),
|
"total cell count of %d exceeded.\n"),
|
||||||
@ -2238,7 +2130,17 @@ printTableAddCell(printTableContent *const content, const char *cell,
|
|||||||
if (translate)
|
if (translate)
|
||||||
*content->header = _(*content->header);
|
*content->header = _(*content->header);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
if (mustfree)
|
||||||
|
{
|
||||||
|
if (content->cellmustfree == NULL)
|
||||||
|
content->cellmustfree = pg_local_calloc(
|
||||||
|
content->ncolumns * content->nrows + 1, sizeof(bool));
|
||||||
|
|
||||||
|
content->cellmustfree[content->cellsadded] = true;
|
||||||
|
}
|
||||||
content->cell++;
|
content->cell++;
|
||||||
|
content->cellsadded++;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -2299,6 +2201,17 @@ printTableSetFooter(printTableContent *const content, const char *footer)
|
|||||||
void
|
void
|
||||||
printTableCleanup(printTableContent *const content)
|
printTableCleanup(printTableContent *const content)
|
||||||
{
|
{
|
||||||
|
if (content->cellmustfree)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
for (i = 0; i < content->nrows * content->ncolumns; i++)
|
||||||
|
{
|
||||||
|
if (content->cellmustfree[i])
|
||||||
|
free((char *) content->cells[i]);
|
||||||
|
}
|
||||||
|
free(content->cellmustfree);
|
||||||
|
content->cellmustfree = NULL;
|
||||||
|
}
|
||||||
free(content->headers);
|
free(content->headers);
|
||||||
free(content->cells);
|
free(content->cells);
|
||||||
free(content->aligns);
|
free(content->aligns);
|
||||||
@ -2486,15 +2399,23 @@ printQuery(const PGresult *result, const printQueryOpt *opt, FILE *fout, FILE *f
|
|||||||
for (c = 0; c < cont.ncolumns; c++)
|
for (c = 0; c < cont.ncolumns; c++)
|
||||||
{
|
{
|
||||||
char *cell;
|
char *cell;
|
||||||
|
bool mustfree = false;
|
||||||
bool translate;
|
bool translate;
|
||||||
|
|
||||||
if (PQgetisnull(result, r, c))
|
if (PQgetisnull(result, r, c))
|
||||||
cell = opt->nullPrint ? opt->nullPrint : "";
|
cell = opt->nullPrint ? opt->nullPrint : "";
|
||||||
else
|
else
|
||||||
|
{
|
||||||
cell = PQgetvalue(result, r, c);
|
cell = PQgetvalue(result, r, c);
|
||||||
|
if (cont.aligns[c] == 'r' && opt->topt.numericLocale)
|
||||||
|
{
|
||||||
|
cell = format_numeric_locale(cell);
|
||||||
|
mustfree = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
translate = (opt->translate_columns && opt->translate_columns[c]);
|
translate = (opt->translate_columns && opt->translate_columns[c]);
|
||||||
printTableAddCell(&cont, cell, translate);
|
printTableAddCell(&cont, cell, translate, mustfree);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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/print.h,v 1.44 2010/02/26 02:01:19 momjian Exp $
|
* $PostgreSQL: pgsql/src/bin/psql/print.h,v 1.45 2010/03/01 20:55:45 heikki Exp $
|
||||||
*/
|
*/
|
||||||
#ifndef PRINT_H
|
#ifndef PRINT_H
|
||||||
#define PRINT_H
|
#define PRINT_H
|
||||||
@ -119,6 +119,8 @@ typedef struct printTableContent
|
|||||||
const char **cells; /* NULL-terminated array of cell content
|
const char **cells; /* NULL-terminated array of cell content
|
||||||
* strings */
|
* strings */
|
||||||
const char **cell; /* Pointer to the last added cell */
|
const char **cell; /* Pointer to the last added cell */
|
||||||
|
long cellsadded; /* Number of cells added this far */
|
||||||
|
bool *cellmustfree; /* true for cells that need to be free()d */
|
||||||
printTableFooter *footers; /* Pointer to the first footer */
|
printTableFooter *footers; /* Pointer to the first footer */
|
||||||
printTableFooter *footer; /* Pointer to the last added footer */
|
printTableFooter *footer; /* Pointer to the last added footer */
|
||||||
char *aligns; /* Array of alignment specifiers; 'l' or 'r',
|
char *aligns; /* Array of alignment specifiers; 'l' or 'r',
|
||||||
@ -156,7 +158,7 @@ extern void printTableInit(printTableContent *const content,
|
|||||||
extern void printTableAddHeader(printTableContent *const content,
|
extern void printTableAddHeader(printTableContent *const content,
|
||||||
const char *header, const bool translate, const char align);
|
const char *header, const bool translate, const char align);
|
||||||
extern void printTableAddCell(printTableContent *const content,
|
extern void printTableAddCell(printTableContent *const content,
|
||||||
const char *cell, const bool translate);
|
const char *cell, const bool translate, const bool mustfree);
|
||||||
extern void printTableAddFooter(printTableContent *const content,
|
extern void printTableAddFooter(printTableContent *const content,
|
||||||
const char *footer);
|
const char *footer);
|
||||||
extern void printTableSetFooter(printTableContent *const content,
|
extern void printTableSetFooter(printTableContent *const content,
|
||||||
|
Loading…
Reference in New Issue
Block a user