Add error about the use of FREEZE in COPY TO
authorBruce Momjian <[email protected]>
Mon, 13 Nov 2023 17:53:03 +0000 (12:53 -0500)
committerBruce Momjian <[email protected]>
Mon, 13 Nov 2023 17:53:03 +0000 (12:53 -0500)
Also clarify some other error wording.

Reported-by: Kyotaro Horiguchi
Discussion: https://postgr.es/m/20220802.133046.1941977979333284049[email protected]

Backpatch-through: master

doc/src/sgml/ref/copy.sgml
src/backend/commands/copy.c
src/test/regress/expected/copy2.out

index d12ba96497ae201527fbae2d17c1f1d8931eedc6..18ecc69c337d987bae48952b84ed06ec483eedb7 100644 (file)
@@ -224,6 +224,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 only allowed in <command>COPY FROM</command>.
      </para>
      <para>
       Note that all other sessions will immediately be able to see the data
index c5d7d78645adedc6768bee98527d5d3b982df4ec..cfad47b56224924436bb57a02d5cac1694ff220d 100644 (file)
@@ -671,7 +671,7 @@ ProcessCopyOptions(ParseState *pstate,
        if (!opts_out->csv_mode && opts_out->quote != NULL)
                ereport(ERROR,
                                (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
-                                errmsg("COPY quote available only in CSV mode")));
+                                errmsg("COPY QUOTE requires CSV mode")));
 
        if (opts_out->csv_mode && strlen(opts_out->quote) != 1)
                ereport(ERROR,
@@ -687,7 +687,7 @@ ProcessCopyOptions(ParseState *pstate,
        if (!opts_out->csv_mode && opts_out->escape != NULL)
                ereport(ERROR,
                                (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
-                                errmsg("COPY escape available only in CSV mode")));
+                                errmsg("COPY ESCAPE requires CSV mode")));
 
        if (opts_out->csv_mode && strlen(opts_out->escape) != 1)
                ereport(ERROR,
@@ -698,46 +698,52 @@ ProcessCopyOptions(ParseState *pstate,
        if (!opts_out->csv_mode && (opts_out->force_quote || opts_out->force_quote_all))
                ereport(ERROR,
                                (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
-                                errmsg("COPY force quote available only in CSV mode")));
+                                errmsg("COPY FORCE_QUOTE requires CSV mode")));
        if ((opts_out->force_quote || opts_out->force_quote_all) && is_from)
                ereport(ERROR,
                                (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
-                                errmsg("COPY force quote only available using COPY TO")));
+                                errmsg("COPY FORCE_QUOTE cannot be used with COPY FROM")));
 
        /* Check force_notnull */
        if (!opts_out->csv_mode && opts_out->force_notnull != NIL)
                ereport(ERROR,
                                (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
-                                errmsg("COPY force not null available only in CSV mode")));
+                                errmsg("COPY FORCE_NOT_NULL requires CSV mode")));
        if (opts_out->force_notnull != NIL && !is_from)
                ereport(ERROR,
-                               (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
-                                errmsg("COPY force not null only available using COPY FROM")));
+                               (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
+                                errmsg("COPY FORCE_NOT_NULL cannot be used with COPY TO")));
 
        /* Check force_null */
        if (!opts_out->csv_mode && opts_out->force_null != NIL)
                ereport(ERROR,
                                (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
-                                errmsg("COPY force null available only in CSV mode")));
+                                errmsg("COPY FORCE_NULL requires CSV mode")));
 
        if (opts_out->force_null != NIL && !is_from)
                ereport(ERROR,
-                               (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
-                                errmsg("COPY force null only available using COPY FROM")));
+                               (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
+                                errmsg("COPY FORCE_NULL cannot be used with COPY TO")));
 
        /* 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),
-                                errmsg("COPY delimiter must not appear in the NULL specification")));
+                               (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
+                                errmsg("COPY delimiter character 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_INVALID_PARAMETER_VALUE),
+                                errmsg("COPY FREEZE cannot be used with COPY TO")));
+
        if (opts_out->default_print)
        {
                if (!is_from)
index 95ec7363afcc5cde55c21d45e59b3eccefa63231..c4178b9c07ced7af4471214ddf18df906d93db3f 100644 (file)
@@ -83,17 +83,17 @@ ERROR:  cannot specify DELIMITER in BINARY mode
 COPY x to stdin (format BINARY, null 'x');
 ERROR:  cannot specify NULL in BINARY mode
 COPY x to stdin (format TEXT, force_quote(a));
-ERROR:  COPY force quote available only in CSV mode
+ERROR:  COPY FORCE_QUOTE requires CSV mode
 COPY x from stdin (format CSV, force_quote(a));
-ERROR:  COPY force quote only available using COPY TO
+ERROR:  COPY FORCE_QUOTE cannot be used with COPY FROM
 COPY x to stdout (format TEXT, force_not_null(a));
-ERROR:  COPY force not null available only in CSV mode
+ERROR:  COPY FORCE_NOT_NULL requires CSV mode
 COPY x to stdin (format CSV, force_not_null(a));
-ERROR:  COPY force not null only available using COPY FROM
+ERROR:  COPY FORCE_NOT_NULL cannot be used with COPY TO
 COPY x to stdout (format TEXT, force_null(a));
-ERROR:  COPY force null available only in CSV mode
+ERROR:  COPY FORCE_NULL requires CSV mode
 COPY x to stdin (format CSV, force_null(a));
-ERROR:  COPY force null only available using COPY FROM
+ERROR:  COPY FORCE_NULL cannot be used with COPY TO
 -- too many columns in column list: should fail
 COPY x (a, b, c, d, e, d, c) from stdin;
 ERROR:  column "d" specified more than once