Skip to content

Commit c06a474

Browse files
committed
Fix validation of COPY FORCE_NOT_NULL/FORCE_NULL for the all-column cases
This commit adds missing checks for COPY FORCE_NOT_NULL and FORCE_NULL when applied to all columns via "*". These options now correctly require CSV mode and are disallowed in COPY TO, making their behavior consistent with FORCE_QUOTE. Some regression tests are added to verify the correct behavior for the all-columns case, including FORCE_QUOTE, which was not tested. Backpatch down to 17, where support for the all-column grammar with FORCE_NOT_NULL and FORCE_NULL has been added. Author: Joel Jacobson Reviewed-by: Zhang Mingli Discussion: https://postgr.es/m/65030d1d-5f90-4fa4-92eb-f5f50389858e@app.fastmail.com Backpatch-through: 17
1 parent a30c1ca commit c06a474

File tree

3 files changed

+26
-4
lines changed

3 files changed

+26
-4
lines changed

src/backend/commands/copy.c

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -783,12 +783,14 @@ ProcessCopyOptions(ParseState *pstate,
783783
"COPY FROM")));
784784

785785
/* Check force_notnull */
786-
if (!opts_out->csv_mode && opts_out->force_notnull != NIL)
786+
if (!opts_out->csv_mode && (opts_out->force_notnull != NIL ||
787+
opts_out->force_notnull_all))
787788
ereport(ERROR,
788789
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
789790
/*- translator: %s is the name of a COPY option, e.g. ON_ERROR */
790791
errmsg("COPY %s requires CSV mode", "FORCE_NOT_NULL")));
791-
if (opts_out->force_notnull != NIL && !is_from)
792+
if ((opts_out->force_notnull != NIL || opts_out->force_notnull_all) &&
793+
!is_from)
792794
ereport(ERROR,
793795
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
794796
/*- translator: first %s is the name of a COPY option, e.g. ON_ERROR,
@@ -797,13 +799,15 @@ ProcessCopyOptions(ParseState *pstate,
797799
"COPY TO")));
798800

799801
/* Check force_null */
800-
if (!opts_out->csv_mode && opts_out->force_null != NIL)
802+
if (!opts_out->csv_mode && (opts_out->force_null != NIL ||
803+
opts_out->force_null_all))
801804
ereport(ERROR,
802805
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
803806
/*- translator: %s is the name of a COPY option, e.g. ON_ERROR */
804807
errmsg("COPY %s requires CSV mode", "FORCE_NULL")));
805808

806-
if (opts_out->force_null != NIL && !is_from)
809+
if ((opts_out->force_null != NIL || opts_out->force_null_all) &&
810+
!is_from)
807811
ereport(ERROR,
808812
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
809813
/*- translator: first %s is the name of a COPY option, e.g. ON_ERROR,

src/test/regress/expected/copy2.out

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -98,16 +98,28 @@ LINE 1: COPY x from stdin (on_error unsupported);
9898
^
9999
COPY x from stdin (format TEXT, force_quote(a));
100100
ERROR: COPY FORCE_QUOTE requires CSV mode
101+
COPY x from stdin (format TEXT, force_quote *);
102+
ERROR: COPY FORCE_QUOTE requires CSV mode
101103
COPY x from stdin (format CSV, force_quote(a));
102104
ERROR: COPY FORCE_QUOTE cannot be used with COPY FROM
105+
COPY x from stdin (format CSV, force_quote *);
106+
ERROR: COPY FORCE_QUOTE cannot be used with COPY FROM
103107
COPY x from stdin (format TEXT, force_not_null(a));
104108
ERROR: COPY FORCE_NOT_NULL requires CSV mode
109+
COPY x from stdin (format TEXT, force_not_null *);
110+
ERROR: COPY FORCE_NOT_NULL requires CSV mode
105111
COPY x to stdout (format CSV, force_not_null(a));
106112
ERROR: COPY FORCE_NOT_NULL cannot be used with COPY TO
113+
COPY x to stdout (format CSV, force_not_null *);
114+
ERROR: COPY FORCE_NOT_NULL cannot be used with COPY TO
107115
COPY x from stdin (format TEXT, force_null(a));
108116
ERROR: COPY FORCE_NULL requires CSV mode
117+
COPY x from stdin (format TEXT, force_null *);
118+
ERROR: COPY FORCE_NULL requires CSV mode
109119
COPY x to stdout (format CSV, force_null(a));
110120
ERROR: COPY FORCE_NULL cannot be used with COPY TO
121+
COPY x to stdout (format CSV, force_null *);
122+
ERROR: COPY FORCE_NULL cannot be used with COPY TO
111123
COPY x to stdout (format BINARY, on_error unsupported);
112124
ERROR: COPY ON_ERROR cannot be used with COPY TO
113125
LINE 1: COPY x to stdout (format BINARY, on_error unsupported);

src/test/regress/sql/copy2.sql

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,11 +75,17 @@ COPY x from stdin (format BINARY, null 'x');
7575
COPY x from stdin (format BINARY, on_error ignore);
7676
COPY x from stdin (on_error unsupported);
7777
COPY x from stdin (format TEXT, force_quote(a));
78+
COPY x from stdin (format TEXT, force_quote *);
7879
COPY x from stdin (format CSV, force_quote(a));
80+
COPY x from stdin (format CSV, force_quote *);
7981
COPY x from stdin (format TEXT, force_not_null(a));
82+
COPY x from stdin (format TEXT, force_not_null *);
8083
COPY x to stdout (format CSV, force_not_null(a));
84+
COPY x to stdout (format CSV, force_not_null *);
8185
COPY x from stdin (format TEXT, force_null(a));
86+
COPY x from stdin (format TEXT, force_null *);
8287
COPY x to stdout (format CSV, force_null(a));
88+
COPY x to stdout (format CSV, force_null *);
8389
COPY x to stdout (format BINARY, on_error unsupported);
8490
COPY x from stdin (log_verbosity unsupported);
8591

0 commit comments

Comments
 (0)