1
0
mirror of https://github.com/postgres/postgres.git synced 2025-06-13 07:41:39 +03:00

psql: Support zero byte field and record separators

Add new psql settings and command-line options to support setting the
field and record separators for unaligned output to a zero byte, for
easier interfacing with other shell tools.

reviewed by Abhijit Menon-Sen
This commit is contained in:
Peter Eisentraut
2012-02-09 20:15:48 +02:00
parent dd7c84185c
commit 169c8a9112
6 changed files with 154 additions and 46 deletions

View File

@ -268,6 +268,16 @@ fputnbytes(FILE *f, const char *str, size_t n)
}
static void
print_separator(struct separator sep, FILE *fout)
{
if (sep.separator_zero)
fputc('\000', fout);
else if (sep.separator)
fputs(sep.separator, fout);
}
/*************************/
/* Unaligned text */
/*************************/
@ -276,8 +286,6 @@ fputnbytes(FILE *f, const char *str, size_t n)
static void
print_unaligned_text(const printTableContent *cont, FILE *fout)
{
const char *opt_fieldsep = cont->opt->fieldSep;
const char *opt_recordsep = cont->opt->recordSep;
bool opt_tuples_only = cont->opt->tuples_only;
unsigned int i;
const char *const * ptr;
@ -286,16 +294,14 @@ print_unaligned_text(const printTableContent *cont, FILE *fout)
if (cancel_pressed)
return;
if (!opt_fieldsep)
opt_fieldsep = "";
if (!opt_recordsep)
opt_recordsep = "";
if (cont->opt->start_table)
{
/* print title */
if (!opt_tuples_only && cont->title)
fprintf(fout, "%s%s", cont->title, opt_recordsep);
{
fputs(cont->title, fout);
print_separator(cont->opt->recordSep, fout);
}
/* print headers */
if (!opt_tuples_only)
@ -303,7 +309,7 @@ print_unaligned_text(const printTableContent *cont, FILE *fout)
for (ptr = cont->headers; *ptr; ptr++)
{
if (ptr != cont->headers)
fputs(opt_fieldsep, fout);
print_separator(cont->opt->fieldSep, fout);
fputs(*ptr, fout);
}
need_recordsep = true;
@ -318,7 +324,7 @@ print_unaligned_text(const printTableContent *cont, FILE *fout)
{
if (need_recordsep)
{
fputs(opt_recordsep, fout);
print_separator(cont->opt->recordSep, fout);
need_recordsep = false;
if (cancel_pressed)
break;
@ -326,7 +332,7 @@ print_unaligned_text(const printTableContent *cont, FILE *fout)
fputs(*ptr, fout);
if ((i + 1) % cont->ncolumns)
fputs(opt_fieldsep, fout);
print_separator(cont->opt->fieldSep, fout);
else
need_recordsep = true;
}
@ -342,16 +348,25 @@ print_unaligned_text(const printTableContent *cont, FILE *fout)
{
if (need_recordsep)
{
fputs(opt_recordsep, fout);
print_separator(cont->opt->recordSep, fout);
need_recordsep = false;
}
fputs(f->data, fout);
need_recordsep = true;
}
}
/* the last record needs to be concluded with a newline */
/*
* The last record is terminated by a newline, independent of the set
* record separator. But when the record separator is a zero byte, we
* use that (compatible with find -print0 and xargs).
*/
if (need_recordsep)
fputc('\n', fout);
{
if (cont->opt->recordSep.separator_zero)
print_separator(cont->opt->recordSep, fout);
else
fputc('\n', fout);
}
}
}
@ -359,8 +374,6 @@ print_unaligned_text(const printTableContent *cont, FILE *fout)
static void
print_unaligned_vertical(const printTableContent *cont, FILE *fout)
{
const char *opt_fieldsep = cont->opt->fieldSep;
const char *opt_recordsep = cont->opt->recordSep;
bool opt_tuples_only = cont->opt->tuples_only;
unsigned int i;
const char *const * ptr;
@ -369,11 +382,6 @@ print_unaligned_vertical(const printTableContent *cont, FILE *fout)
if (cancel_pressed)
return;
if (!opt_fieldsep)
opt_fieldsep = "";
if (!opt_recordsep)
opt_recordsep = "";
if (cont->opt->start_table)
{
/* print title */
@ -393,19 +401,19 @@ print_unaligned_vertical(const printTableContent *cont, FILE *fout)
if (need_recordsep)
{
/* record separator is 2 occurrences of recordsep in this mode */
fputs(opt_recordsep, fout);
fputs(opt_recordsep, fout);
print_separator(cont->opt->recordSep, fout);
print_separator(cont->opt->recordSep, fout);
need_recordsep = false;
if (cancel_pressed)
break;
}
fputs(cont->headers[i % cont->ncolumns], fout);
fputs(opt_fieldsep, fout);
print_separator(cont->opt->fieldSep, fout);
fputs(*ptr, fout);
if ((i + 1) % cont->ncolumns)
fputs(opt_recordsep, fout);
print_separator(cont->opt->recordSep, fout);
else
need_recordsep = true;
}
@ -417,15 +425,19 @@ print_unaligned_vertical(const printTableContent *cont, FILE *fout)
{
printTableFooter *f;
fputs(opt_recordsep, fout);
print_separator(cont->opt->recordSep, fout);
for (f = cont->footers; f; f = f->next)
{
fputs(opt_recordsep, fout);
print_separator(cont->opt->recordSep, fout);
fputs(f->data, fout);
}
}
fputc('\n', fout);
/* see above in print_unaligned_text() */
if (cont->opt->recordSep.separator_zero)
print_separator(cont->opt->recordSep, fout);
else
fputc('\n', fout);
}
}