I noticed that COPY TO accepts FREEZE option but it is pointless. Don't we reject that option as the first-attached does? I tempted to add tests for those option combinations that are to be rejected but I didin't come up with a clean way to do that.
By the way, most of the invalid option combinations for COPY are marked as ERRCODE_FEATURE_NOT_SUPPORTED. I looks to me saying that "that feature is theoretically possible or actually realized elsewhere, but impossible now or here". If it is correct, aren't they better be ERRCODE_INVALID_PARAMETER_VALUE? The code is being used for similar messages "unrecognized parameter <name>" and "parameter <name> specified more than once" (or some others?). At least a quote string longer than a single character seems like to fit INVALID_PARAMETER_VALUE. (I believe we don't mean to support multicharacter (or even multibyte) escape/quote character anddelimiter). That being said, I'm not sure if the change will be worth the trouble. regards. -- Kyotaro Horiguchi NTT Open Source Software Center
diff --git a/doc/src/sgml/ref/copy.sgml b/doc/src/sgml/ref/copy.sgml index 8aae711b3b..0d93245e1a 100644 --- a/doc/src/sgml/ref/copy.sgml +++ b/doc/src/sgml/ref/copy.sgml @@ -223,6 +223,7 @@ COPY { <replaceable class="parameter">table_name</replaceable> [ ( <replaceable open and there are no older snapshots held by this transaction. It is currently not possible to perform a <command>COPY FREEZE</command> on a partitioned table. + This option is allowed only in <command>COPY FROM</command>. </para> <para> Note that all other sessions will immediately be able to see the data diff --git a/src/backend/commands/copy.c b/src/backend/commands/copy.c index 3ac731803b..10111d7166 100644 --- a/src/backend/commands/copy.c +++ b/src/backend/commands/copy.c @@ -695,6 +695,12 @@ ProcessCopyOptions(ParseState *pstate, ereport(ERROR, (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), errmsg("CSV quote character must not appear in the NULL specification"))); + + /* Check freeze */ + if (opts_out->freeze && !is_from) + ereport(ERROR, + (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), + errmsg("COPY freeze only available using COPY FROM"))); } /*
diff --git a/src/backend/commands/copy.c b/src/backend/commands/copy.c index 10111d7166..df6a592308 100644 --- a/src/backend/commands/copy.c +++ b/src/backend/commands/copy.c @@ -586,7 +586,7 @@ ProcessCopyOptions(ParseState *pstate, /* Only single-byte delimiter strings are supported. */ if (strlen(opts_out->delim) != 1) ereport(ERROR, - (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), + (errcode(ERRCODE_INVALID_PARAMETER_VALUE), errmsg("COPY delimiter must be a single one-byte character"))); /* Disallow end-of-line characters */ @@ -622,18 +622,18 @@ ProcessCopyOptions(ParseState *pstate, /* Check header */ if (opts_out->binary && opts_out->header_line) ereport(ERROR, - (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), + (errcode(ERRCODE_INVALID_PARAMETER_VALUE), errmsg("cannot specify HEADER in BINARY mode"))); /* Check quote */ if (!opts_out->csv_mode && opts_out->quote != NULL) ereport(ERROR, - (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), + (errcode(ERRCODE_INVALID_PARAMETER_VALUE), errmsg("COPY quote available only in CSV mode"))); if (opts_out->csv_mode && strlen(opts_out->quote) != 1) ereport(ERROR, - (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), + (errcode(ERRCODE_INVALID_PARAMETER_VALUE), errmsg("COPY quote must be a single one-byte character"))); if (opts_out->csv_mode && opts_out->delim[0] == opts_out->quote[0]) @@ -644,62 +644,62 @@ ProcessCopyOptions(ParseState *pstate, /* Check escape */ if (!opts_out->csv_mode && opts_out->escape != NULL) ereport(ERROR, - (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), + (errcode(ERRCODE_INVALID_PARAMETER_VALUE), errmsg("COPY escape available only in CSV mode"))); if (opts_out->csv_mode && strlen(opts_out->escape) != 1) ereport(ERROR, - (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), + (errcode(ERRCODE_INVALID_PARAMETER_VALUE), errmsg("COPY escape must be a single one-byte character"))); /* Check force_quote */ if (!opts_out->csv_mode && (opts_out->force_quote || opts_out->force_quote_all)) ereport(ERROR, - (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), + (errcode(ERRCODE_INVALID_PARAMETER_VALUE), errmsg("COPY force quote available only in CSV mode"))); if ((opts_out->force_quote || opts_out->force_quote_all) && is_from) ereport(ERROR, - (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), + (errcode(ERRCODE_INVALID_PARAMETER_VALUE), errmsg("COPY force quote only available using COPY TO"))); /* Check force_notnull */ if (!opts_out->csv_mode && opts_out->force_notnull != NIL) ereport(ERROR, - (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), + (errcode(ERRCODE_INVALID_PARAMETER_VALUE), errmsg("COPY force not null available only in CSV mode"))); if (opts_out->force_notnull != NIL && !is_from) ereport(ERROR, - (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), + (errcode(ERRCODE_INVALID_PARAMETER_VALUE), errmsg("COPY force not null only available using COPY FROM"))); /* Check force_null */ if (!opts_out->csv_mode && opts_out->force_null != NIL) ereport(ERROR, - (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), + (errcode(ERRCODE_INVALID_PARAMETER_VALUE), errmsg("COPY force null available only in CSV mode"))); if (opts_out->force_null != NIL && !is_from) ereport(ERROR, - (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), + (errcode(ERRCODE_INVALID_PARAMETER_VALUE), errmsg("COPY force null only available using COPY FROM"))); /* Don't allow the delimiter to appear in the null string. */ if (strchr(opts_out->null_print, opts_out->delim[0]) != NULL) ereport(ERROR, - (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), + (errcode(ERRCODE_INVALID_PARAMETER_VALUE), errmsg("COPY delimiter must not appear in the NULL specification"))); /* Don't allow the CSV quote char to appear in the null string. */ if (opts_out->csv_mode && strchr(opts_out->null_print, opts_out->quote[0]) != NULL) ereport(ERROR, - (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), + (errcode(ERRCODE_INVALID_PARAMETER_VALUE), errmsg("CSV quote character must not appear in the NULL specification"))); /* Check freeze */ if (opts_out->freeze && !is_from) ereport(ERROR, - (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), + (errcode(ERRCODE_INVALID_PARAMETER_VALUE), errmsg("COPY freeze only available using COPY FROM"))); }