Skip to content

Commit 43f33dc

Browse files
committed
Add HEADER support to COPY text format
The COPY CSV format supports the HEADER option to output a header line. This patch adds the same option to the default text format. On input, the HEADER option causes the first line to be skipped, same as with CSV. Author: Rémi Lapeyre <remi.lapeyre@lenstra.fr> Discussion: https://www.postgresql.org/message-id/flat/CAF1-J-0PtCWMeLtswwGV2M70U26n4g33gpe1rcKQqe6wVQDrFA@mail.gmail.com
1 parent 5553cbd commit 43f33dc

File tree

8 files changed

+29
-9
lines changed

8 files changed

+29
-9
lines changed

contrib/file_fdw/expected/file_fdw.out

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -50,14 +50,12 @@ CREATE USER MAPPING FOR regress_no_priv_user SERVER file_server;
5050
-- validator tests
5151
CREATE FOREIGN TABLE tbl () SERVER file_server OPTIONS (format 'xml'); -- ERROR
5252
ERROR: COPY format "xml" not recognized
53-
CREATE FOREIGN TABLE tbl () SERVER file_server OPTIONS (format 'text', header 'true'); -- ERROR
54-
ERROR: COPY HEADER available only in CSV mode
5553
CREATE FOREIGN TABLE tbl () SERVER file_server OPTIONS (format 'text', quote ':'); -- ERROR
5654
ERROR: COPY quote available only in CSV mode
5755
CREATE FOREIGN TABLE tbl () SERVER file_server OPTIONS (format 'text', escape ':'); -- ERROR
5856
ERROR: COPY escape available only in CSV mode
5957
CREATE FOREIGN TABLE tbl () SERVER file_server OPTIONS (format 'binary', header 'true'); -- ERROR
60-
ERROR: COPY HEADER available only in CSV mode
58+
ERROR: cannot specify HEADER in BINARY mode
6159
CREATE FOREIGN TABLE tbl () SERVER file_server OPTIONS (format 'binary', quote ':'); -- ERROR
6260
ERROR: COPY quote available only in CSV mode
6361
CREATE FOREIGN TABLE tbl () SERVER file_server OPTIONS (format 'binary', escape ':'); -- ERROR

contrib/file_fdw/sql/file_fdw.sql

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,6 @@ CREATE USER MAPPING FOR regress_no_priv_user SERVER file_server;
5656

5757
-- validator tests
5858
CREATE FOREIGN TABLE tbl () SERVER file_server OPTIONS (format 'xml'); -- ERROR
59-
CREATE FOREIGN TABLE tbl () SERVER file_server OPTIONS (format 'text', header 'true'); -- ERROR
6059
CREATE FOREIGN TABLE tbl () SERVER file_server OPTIONS (format 'text', quote ':'); -- ERROR
6160
CREATE FOREIGN TABLE tbl () SERVER file_server OPTIONS (format 'text', escape ':'); -- ERROR
6261
CREATE FOREIGN TABLE tbl () SERVER file_server OPTIONS (format 'binary', header 'true'); -- ERROR

doc/src/sgml/ref/copy.sgml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -277,7 +277,7 @@ COPY { <replaceable class="parameter">table_name</replaceable> [ ( <replaceable
277277
Specifies that the file contains a header line with the names of each
278278
column in the file. On output, the first line contains the column
279279
names from the table, and on input, the first line is ignored.
280-
This option is allowed only when using <literal>CSV</literal> format.
280+
This option is not allowed when using <literal>binary</literal> format.
281281
</para>
282282
</listitem>
283283
</varlistentry>

src/backend/commands/copy.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -555,10 +555,10 @@ ProcessCopyOptions(ParseState *pstate,
555555
errmsg("COPY delimiter cannot be \"%s\"", opts_out->delim)));
556556

557557
/* Check header */
558-
if (!opts_out->csv_mode && opts_out->header_line)
558+
if (opts_out->binary && opts_out->header_line)
559559
ereport(ERROR,
560560
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
561-
errmsg("COPY HEADER available only in CSV mode")));
561+
errmsg("cannot specify HEADER in BINARY mode")));
562562

563563
/* Check quote */
564564
if (!opts_out->csv_mode && opts_out->quote != NULL)

src/backend/commands/copyto.c

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -863,8 +863,11 @@ DoCopyTo(CopyToState cstate)
863863

864864
colname = NameStr(TupleDescAttr(tupDesc, attnum - 1)->attname);
865865

866-
CopyAttributeOutCSV(cstate, colname, false,
866+
if (cstate->opts.csv_mode)
867+
CopyAttributeOutCSV(cstate, colname, false,
867868
list_length(cstate->attnumlist) == 1);
869+
else
870+
CopyAttributeOutText(cstate, colname);
868871
}
869872

870873
CopySendEndOfRow(cstate);

src/include/commands/copy.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ typedef struct CopyFormatOptions
3232
bool binary; /* binary format? */
3333
bool freeze; /* freeze rows on loading? */
3434
bool csv_mode; /* Comma Separated Value format? */
35-
bool header_line; /* CSV header line? */
35+
bool header_line; /* header line? */
3636
char *null_print; /* NULL marker string (server encoding!) */
3737
int null_print_len; /* length of same */
3838
char *null_print_client; /* same converted to file encoding */

src/test/regress/expected/copy.out

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -120,6 +120,14 @@ copy copytest3 to stdout csv header;
120120
c1,"col with , comma","col with "" quote"
121121
1,a,1
122122
2,b,2
123+
create temp table copytest4 (
124+
c1 int,
125+
"colname with tab: " text);
126+
copy copytest4 from stdin (header);
127+
copy copytest4 to stdout (header);
128+
c1 colname with tab: \t
129+
1 a
130+
2 b
123131
-- test copy from with a partitioned table
124132
create table parted_copytest (
125133
a int,

src/test/regress/sql/copy.sql

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -160,6 +160,18 @@ this is just a line full of junk that would error out if parsed
160160

161161
copy copytest3 to stdout csv header;
162162

163+
create temp table copytest4 (
164+
c1 int,
165+
"colname with tab: " text);
166+
167+
copy copytest4 from stdin (header);
168+
this is just a line full of junk that would error out if parsed
169+
1 a
170+
2 b
171+
\.
172+
173+
copy copytest4 to stdout (header);
174+
163175
-- test copy from with a partitioned table
164176
create table parted_copytest (
165177
a int,

0 commit comments

Comments
 (0)