1
0
mirror of https://github.com/postgres/postgres.git synced 2025-05-08 07:21:33 +03:00

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
This commit is contained in:
Michael Paquier 2024-10-17 08:44:50 +09:00
parent 03bf0d9a4b
commit 089aac631b
3 changed files with 26 additions and 4 deletions

View File

@ -805,12 +805,14 @@ ProcessCopyOptions(ParseState *pstate,
"COPY FROM"))); "COPY FROM")));
/* Check force_notnull */ /* Check force_notnull */
if (!opts_out->csv_mode && opts_out->force_notnull != NIL) if (!opts_out->csv_mode && (opts_out->force_notnull != NIL ||
opts_out->force_notnull_all))
ereport(ERROR, ereport(ERROR,
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED), (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
/*- translator: %s is the name of a COPY option, e.g. ON_ERROR */ /*- translator: %s is the name of a COPY option, e.g. ON_ERROR */
errmsg("COPY %s requires CSV mode", "FORCE_NOT_NULL"))); errmsg("COPY %s requires CSV mode", "FORCE_NOT_NULL")));
if (opts_out->force_notnull != NIL && !is_from) if ((opts_out->force_notnull != NIL || opts_out->force_notnull_all) &&
!is_from)
ereport(ERROR, ereport(ERROR,
(errcode(ERRCODE_INVALID_PARAMETER_VALUE), (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
/*- translator: first %s is the name of a COPY option, e.g. ON_ERROR, /*- translator: first %s is the name of a COPY option, e.g. ON_ERROR,
@ -819,13 +821,15 @@ ProcessCopyOptions(ParseState *pstate,
"COPY TO"))); "COPY TO")));
/* Check force_null */ /* Check force_null */
if (!opts_out->csv_mode && opts_out->force_null != NIL) if (!opts_out->csv_mode && (opts_out->force_null != NIL ||
opts_out->force_null_all))
ereport(ERROR, ereport(ERROR,
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED), (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
/*- translator: %s is the name of a COPY option, e.g. ON_ERROR */ /*- translator: %s is the name of a COPY option, e.g. ON_ERROR */
errmsg("COPY %s requires CSV mode", "FORCE_NULL"))); errmsg("COPY %s requires CSV mode", "FORCE_NULL")));
if (opts_out->force_null != NIL && !is_from) if ((opts_out->force_null != NIL || opts_out->force_null_all) &&
!is_from)
ereport(ERROR, ereport(ERROR,
(errcode(ERRCODE_INVALID_PARAMETER_VALUE), (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
/*- translator: first %s is the name of a COPY option, e.g. ON_ERROR, /*- translator: first %s is the name of a COPY option, e.g. ON_ERROR,

View File

@ -98,16 +98,28 @@ LINE 1: COPY x from stdin (on_error unsupported);
^ ^
COPY x from stdin (format TEXT, force_quote(a)); COPY x from stdin (format TEXT, force_quote(a));
ERROR: COPY FORCE_QUOTE requires CSV mode ERROR: COPY FORCE_QUOTE requires CSV mode
COPY x from stdin (format TEXT, force_quote *);
ERROR: COPY FORCE_QUOTE requires CSV mode
COPY x from stdin (format CSV, force_quote(a)); COPY x from stdin (format CSV, force_quote(a));
ERROR: COPY FORCE_QUOTE cannot be used with COPY FROM ERROR: COPY FORCE_QUOTE cannot be used with COPY FROM
COPY x from stdin (format CSV, force_quote *);
ERROR: COPY FORCE_QUOTE cannot be used with COPY FROM
COPY x from stdin (format TEXT, force_not_null(a)); COPY x from stdin (format TEXT, force_not_null(a));
ERROR: COPY FORCE_NOT_NULL requires CSV mode ERROR: COPY FORCE_NOT_NULL requires CSV mode
COPY x from stdin (format TEXT, force_not_null *);
ERROR: COPY FORCE_NOT_NULL requires CSV mode
COPY x to stdout (format CSV, force_not_null(a)); COPY x to stdout (format CSV, force_not_null(a));
ERROR: COPY FORCE_NOT_NULL cannot be used with COPY TO ERROR: COPY FORCE_NOT_NULL cannot be used with COPY TO
COPY x to stdout (format CSV, force_not_null *);
ERROR: COPY FORCE_NOT_NULL cannot be used with COPY TO
COPY x from stdin (format TEXT, force_null(a)); COPY x from stdin (format TEXT, force_null(a));
ERROR: COPY FORCE_NULL requires CSV mode ERROR: COPY FORCE_NULL requires CSV mode
COPY x from stdin (format TEXT, force_null *);
ERROR: COPY FORCE_NULL requires CSV mode
COPY x to stdout (format CSV, force_null(a)); COPY x to stdout (format CSV, force_null(a));
ERROR: COPY FORCE_NULL cannot be used with COPY TO ERROR: COPY FORCE_NULL cannot be used with COPY TO
COPY x to stdout (format CSV, force_null *);
ERROR: COPY FORCE_NULL cannot be used with COPY TO
COPY x to stdout (format BINARY, on_error unsupported); COPY x to stdout (format BINARY, on_error unsupported);
ERROR: COPY ON_ERROR cannot be used with COPY TO ERROR: COPY ON_ERROR cannot be used with COPY TO
LINE 1: COPY x to stdout (format BINARY, on_error unsupported); LINE 1: COPY x to stdout (format BINARY, on_error unsupported);

View File

@ -75,11 +75,17 @@ COPY x from stdin (format BINARY, null 'x');
COPY x from stdin (format BINARY, on_error ignore); COPY x from stdin (format BINARY, on_error ignore);
COPY x from stdin (on_error unsupported); COPY x from stdin (on_error unsupported);
COPY x from stdin (format TEXT, force_quote(a)); COPY x from stdin (format TEXT, force_quote(a));
COPY x from stdin (format TEXT, force_quote *);
COPY x from stdin (format CSV, force_quote(a)); COPY x from stdin (format CSV, force_quote(a));
COPY x from stdin (format CSV, force_quote *);
COPY x from stdin (format TEXT, force_not_null(a)); COPY x from stdin (format TEXT, force_not_null(a));
COPY x from stdin (format TEXT, force_not_null *);
COPY x to stdout (format CSV, force_not_null(a)); COPY x to stdout (format CSV, force_not_null(a));
COPY x to stdout (format CSV, force_not_null *);
COPY x from stdin (format TEXT, force_null(a)); COPY x from stdin (format TEXT, force_null(a));
COPY x from stdin (format TEXT, force_null *);
COPY x to stdout (format CSV, force_null(a)); COPY x to stdout (format CSV, force_null(a));
COPY x to stdout (format CSV, force_null *);
COPY x to stdout (format BINARY, on_error unsupported); COPY x to stdout (format BINARY, on_error unsupported);
COPY x from stdin (log_verbosity unsupported); COPY x from stdin (log_verbosity unsupported);
COPY x from stdin with (reject_limit 1); COPY x from stdin with (reject_limit 1);