diff options
author | Peter Eisentraut | 2022-01-28 08:22:53 +0000 |
---|---|---|
committer | Peter Eisentraut | 2022-01-28 08:44:47 +0000 |
commit | 43f33dc018a4b77ced78a0a6df8ed5d450cfe5f4 (patch) | |
tree | f372e2f7e3f37ee968c08f6cc6220b6657f90394 | |
parent | 5553cbd4fe3eb177b3266ca4a7e80159323608c2 (diff) |
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 <[email protected]>
Discussion: https://www.postgresql.org/message-id/flat/CAF1-J-0PtCWMeLtswwGV2M70U26n4g33gpe1rcKQqe6wVQDrFA@mail.gmail.com
-rw-r--r-- | contrib/file_fdw/expected/file_fdw.out | 4 | ||||
-rw-r--r-- | contrib/file_fdw/sql/file_fdw.sql | 1 | ||||
-rw-r--r-- | doc/src/sgml/ref/copy.sgml | 2 | ||||
-rw-r--r-- | src/backend/commands/copy.c | 4 | ||||
-rw-r--r-- | src/backend/commands/copyto.c | 5 | ||||
-rw-r--r-- | src/include/commands/copy.h | 2 | ||||
-rw-r--r-- | src/test/regress/expected/copy.out | 8 | ||||
-rw-r--r-- | src/test/regress/sql/copy.sql | 12 |
8 files changed, 29 insertions, 9 deletions
diff --git a/contrib/file_fdw/expected/file_fdw.out b/contrib/file_fdw/expected/file_fdw.out index 891146fef3..0ac6e4e0d7 100644 --- a/contrib/file_fdw/expected/file_fdw.out +++ b/contrib/file_fdw/expected/file_fdw.out @@ -50,14 +50,12 @@ CREATE USER MAPPING FOR regress_no_priv_user SERVER file_server; -- validator tests CREATE FOREIGN TABLE tbl () SERVER file_server OPTIONS (format 'xml'); -- ERROR ERROR: COPY format "xml" not recognized -CREATE FOREIGN TABLE tbl () SERVER file_server OPTIONS (format 'text', header 'true'); -- ERROR -ERROR: COPY HEADER available only in CSV mode CREATE FOREIGN TABLE tbl () SERVER file_server OPTIONS (format 'text', quote ':'); -- ERROR ERROR: COPY quote available only in CSV mode CREATE FOREIGN TABLE tbl () SERVER file_server OPTIONS (format 'text', escape ':'); -- ERROR ERROR: COPY escape available only in CSV mode CREATE FOREIGN TABLE tbl () SERVER file_server OPTIONS (format 'binary', header 'true'); -- ERROR -ERROR: COPY HEADER available only in CSV mode +ERROR: cannot specify HEADER in BINARY mode CREATE FOREIGN TABLE tbl () SERVER file_server OPTIONS (format 'binary', quote ':'); -- ERROR ERROR: COPY quote available only in CSV mode CREATE FOREIGN TABLE tbl () SERVER file_server OPTIONS (format 'binary', escape ':'); -- ERROR diff --git a/contrib/file_fdw/sql/file_fdw.sql b/contrib/file_fdw/sql/file_fdw.sql index 0ea8b14508..86f876d565 100644 --- a/contrib/file_fdw/sql/file_fdw.sql +++ b/contrib/file_fdw/sql/file_fdw.sql @@ -56,7 +56,6 @@ CREATE USER MAPPING FOR regress_no_priv_user SERVER file_server; -- validator tests CREATE FOREIGN TABLE tbl () SERVER file_server OPTIONS (format 'xml'); -- ERROR -CREATE FOREIGN TABLE tbl () SERVER file_server OPTIONS (format 'text', header 'true'); -- ERROR CREATE FOREIGN TABLE tbl () SERVER file_server OPTIONS (format 'text', quote ':'); -- ERROR CREATE FOREIGN TABLE tbl () SERVER file_server OPTIONS (format 'text', escape ':'); -- ERROR CREATE FOREIGN TABLE tbl () SERVER file_server OPTIONS (format 'binary', header 'true'); -- ERROR diff --git a/doc/src/sgml/ref/copy.sgml b/doc/src/sgml/ref/copy.sgml index 4624c8f4c9..1b7d001963 100644 --- a/doc/src/sgml/ref/copy.sgml +++ b/doc/src/sgml/ref/copy.sgml @@ -277,7 +277,7 @@ COPY { <replaceable class="parameter">table_name</replaceable> [ ( <replaceable Specifies that the file contains a header line with the names of each column in the file. On output, the first line contains the column names from the table, and on input, the first line is ignored. - This option is allowed only when using <literal>CSV</literal> format. + This option is not allowed when using <literal>binary</literal> format. </para> </listitem> </varlistentry> diff --git a/src/backend/commands/copy.c b/src/backend/commands/copy.c index bb9c21bc6b..7da7105d44 100644 --- a/src/backend/commands/copy.c +++ b/src/backend/commands/copy.c @@ -555,10 +555,10 @@ ProcessCopyOptions(ParseState *pstate, errmsg("COPY delimiter cannot be \"%s\"", opts_out->delim))); /* Check header */ - if (!opts_out->csv_mode && opts_out->header_line) + if (opts_out->binary && opts_out->header_line) ereport(ERROR, (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), - errmsg("COPY HEADER available only in CSV mode"))); + errmsg("cannot specify HEADER in BINARY mode"))); /* Check quote */ if (!opts_out->csv_mode && opts_out->quote != NULL) diff --git a/src/backend/commands/copyto.c b/src/backend/commands/copyto.c index 20bfd49112..e793b64bda 100644 --- a/src/backend/commands/copyto.c +++ b/src/backend/commands/copyto.c @@ -863,8 +863,11 @@ DoCopyTo(CopyToState cstate) colname = NameStr(TupleDescAttr(tupDesc, attnum - 1)->attname); - CopyAttributeOutCSV(cstate, colname, false, + if (cstate->opts.csv_mode) + CopyAttributeOutCSV(cstate, colname, false, list_length(cstate->attnumlist) == 1); + else + CopyAttributeOutText(cstate, colname); } CopySendEndOfRow(cstate); diff --git a/src/include/commands/copy.h b/src/include/commands/copy.h index c01cf42bcd..8694da5004 100644 --- a/src/include/commands/copy.h +++ b/src/include/commands/copy.h @@ -32,7 +32,7 @@ typedef struct CopyFormatOptions bool binary; /* binary format? */ bool freeze; /* freeze rows on loading? */ bool csv_mode; /* Comma Separated Value format? */ - bool header_line; /* CSV header line? */ + bool header_line; /* header line? */ char *null_print; /* NULL marker string (server encoding!) */ int null_print_len; /* length of same */ char *null_print_client; /* same converted to file encoding */ diff --git a/src/test/regress/expected/copy.out b/src/test/regress/expected/copy.out index 931e7b2e69..851b9a4a2d 100644 --- a/src/test/regress/expected/copy.out +++ b/src/test/regress/expected/copy.out @@ -120,6 +120,14 @@ copy copytest3 to stdout csv header; c1,"col with , comma","col with "" quote" 1,a,1 2,b,2 +create temp table copytest4 ( + c1 int, + "colname with tab: " text); +copy copytest4 from stdin (header); +copy copytest4 to stdout (header); +c1 colname with tab: \t +1 a +2 b -- test copy from with a partitioned table create table parted_copytest ( a int, diff --git a/src/test/regress/sql/copy.sql b/src/test/regress/sql/copy.sql index 15e26517ec..016fedf675 100644 --- a/src/test/regress/sql/copy.sql +++ b/src/test/regress/sql/copy.sql @@ -160,6 +160,18 @@ this is just a line full of junk that would error out if parsed copy copytest3 to stdout csv header; +create temp table copytest4 ( + c1 int, + "colname with tab: " text); + +copy copytest4 from stdin (header); +this is just a line full of junk that would error out if parsed +1 a +2 b +\. + +copy copytest4 to stdout (header); + -- test copy from with a partitioned table create table parted_copytest ( a int, |