I wrote:

> A proposed fix is attached. print_csv_vertical() is left unchanged
> because it's not possible currently to end up with \. alone
> on a line with the expanded display

On second thought, it is possible

postgres=# \pset format csv
Output format is csv.

postgres=# \pset fieldsep_csv '.'
Field separator for CSV is ".".

postgres=# \x
Expanded display is on.

postgres=# select '' as "\" ;
\.

PFA an upgraded fix.


Best regards,
-- 
Daniel Vérité
PostgreSQL-powered mailer: http://www.manitou-mail.org
Twitter: @DanielVerite
diff --git a/src/fe_utils/print.c b/src/fe_utils/print.c
index 3b07280..d9c701f 100644
--- a/src/fe_utils/print.c
+++ b/src/fe_utils/print.c
@@ -1793,7 +1793,16 @@ print_csv_text(const printTableContent *cont, FILE *fout)
        if (cont->opt->start_table && !cont->opt->tuples_only)
        {
                /* print headers */
-               for (ptr = cont->headers; *ptr; ptr++)
+
+               /*
+                * A \. alone on a line must be quoted to be compatible with 
COPY CSV,
+                * for which \. is an end-of-data marker.
+                */
+               if (cont->ncolumns == 1 && strcmp(*cont->headers, "\\.") == 0)
+               {
+                       csv_escaped_print(*cont->headers, fout);
+               }
+               else for (ptr = cont->headers; *ptr; ptr++)
                {
                        if (ptr != cont->headers)
                                fputs(cont->opt->fieldSepCsv, fout);
@@ -1805,7 +1814,14 @@ print_csv_text(const printTableContent *cont, FILE *fout)
        /* print cells */
        for (i = 0, ptr = cont->cells; *ptr; i++, ptr++)
        {
-               csv_print_field(*ptr, fout, cont->opt->fieldSepCsv);
+               /*
+                * A \. alone on a line must be quoted to be compatible with 
COPY CSV,
+                * for which \. is an end-of-data marker.
+                */
+               if (cont->ncolumns == 1 && strcmp(*ptr, "\\.") == 0)
+                       csv_escaped_print(*ptr, fout);
+               else
+                       csv_print_field(*ptr, fout, cont->opt->fieldSepCsv);
                if ((i + 1) % cont->ncolumns)
                        fputs(cont->opt->fieldSepCsv, fout);
                else
@@ -1825,16 +1841,28 @@ print_csv_vertical(const printTableContent *cont, FILE 
*fout)
                if (cancel_pressed)
                        return;
 
-               /* print name of column */
-               csv_print_field(cont->headers[i % cont->ncolumns], fout,
-                                               cont->opt->fieldSepCsv);
-
-               /* print field separator */
-               fputs(cont->opt->fieldSepCsv, fout);
+               /*
+                * A \. alone on a line must be quoted to be compatible with 
COPY CSV,
+                * for which \. is an end-of-data marker.
+                */
+               if (strcmp(cont->headers[i % cont->ncolumns], "\\") == 0
+                       && strcmp(cont->opt->fieldSepCsv, ".") == 0
+                       && **ptr == '\0')
+               {
+                       csv_escaped_print("\\.", fout);
+               }
+               else
+               {
+                       /* print name of column */
+                       csv_print_field(cont->headers[i % cont->ncolumns], fout,
+                                                       cont->opt->fieldSepCsv);
 
-               /* print field value */
-               csv_print_field(*ptr, fout, cont->opt->fieldSepCsv);
+                       /* print field separator */
+                       fputs(cont->opt->fieldSepCsv, fout);
 
+                       /* print field value */
+                       csv_print_field(*ptr, fout, cont->opt->fieldSepCsv);
+               }
                fputc('\n', fout);
        }
 }

Reply via email to