diff --git a/doc/src/sgml/ref/copy.sgml b/doc/src/sgml/ref/copy.sgml
index 85881ca0ad..21a5c4a052 100644
--- a/doc/src/sgml/ref/copy.sgml
+++ b/doc/src/sgml/ref/copy.sgml
@@ -43,7 +43,7 @@ COPY { table_name [ ( column_name [, ...] ) | * }
FORCE_NOT_NULL { ( column_name [, ...] ) | * }
FORCE_NULL { ( column_name [, ...] ) | * }
- SAVE_ERROR_TO 'location'
+ ON_ERROR 'error_action'
ENCODING 'encoding_name'
@@ -375,20 +375,20 @@ COPY { table_name [ (
- SAVE_ERROR_TO
+ ON_ERROR
- Specifies to save error information to
- location when there is malformed data in the input.
- Currently, only error (default) and none
+ Specifies which
+ error_action to perform when there is malformed data in the input.
+ Currently, only stop (default) and ignore
values are supported.
- If the error value is specified,
+ If the stop value is specified,
COPY stops operation at the first error.
- If the none value is specified,
+ If the ignore value is specified,
COPY skips malformed data and continues copying data.
The option is allowed only in COPY FROM.
- The none value is allowed only when
- not using binary format.
+ Only stop value is allowed when
+ using binary format.
@@ -577,7 +577,7 @@ COPY count
COPY stops operation at the first error when
- SAVE_ERROR_TO is not specified. This
+ ON_ERROR is not specified. This
should not lead to problems in the event of a COPY
TO, but the target table will already have received
earlier rows in a COPY FROM. These rows will not
diff --git a/src/backend/commands/copy.c b/src/backend/commands/copy.c
index c36d7f1daa..cc0786c6f4 100644
--- a/src/backend/commands/copy.c
+++ b/src/backend/commands/copy.c
@@ -395,39 +395,39 @@ defGetCopyHeaderChoice(DefElem *def, bool is_from)
}
/*
- * Extract a CopySaveErrorToChoice value from a DefElem.
+ * Extract a CopyOnErrorChoice value from a DefElem.
*/
-static CopySaveErrorToChoice
-defGetCopySaveErrorToChoice(DefElem *def, ParseState *pstate, bool is_from)
+static CopyOnErrorChoice
+defGetCopyOnErrorChoice(DefElem *def, ParseState *pstate, bool is_from)
{
char *sval;
if (!is_from)
ereport(ERROR,
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
- errmsg("COPY SAVE_ERROR_TO cannot be used with COPY TO"),
+ errmsg("COPY ON_ERROR cannot be used with COPY TO"),
parser_errposition(pstate, def->location)));
/*
* If no parameter value given, assume the default value.
*/
if (def->arg == NULL)
- return COPY_SAVE_ERROR_TO_ERROR;
+ return COPY_ON_ERROR_STOP;
/*
- * Allow "error", or "none" values.
+ * Allow "stop", or "ignore" values.
*/
sval = defGetString(def);
- if (pg_strcasecmp(sval, "error") == 0)
- return COPY_SAVE_ERROR_TO_ERROR;
- if (pg_strcasecmp(sval, "none") == 0)
- return COPY_SAVE_ERROR_TO_NONE;
+ if (pg_strcasecmp(sval, "stop") == 0)
+ return COPY_ON_ERROR_STOP;
+ if (pg_strcasecmp(sval, "ignore") == 0)
+ return COPY_ON_ERROR_IGNORE;
ereport(ERROR,
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
- errmsg("COPY save_error_to \"%s\" not recognized", sval),
+ errmsg("COPY ON_ERROR \"%s\" not recognized", sval),
parser_errposition(pstate, def->location)));
- return COPY_SAVE_ERROR_TO_ERROR; /* keep compiler quiet */
+ return COPY_ON_ERROR_STOP; /* keep compiler quiet */
}
/*
@@ -455,7 +455,7 @@ ProcessCopyOptions(ParseState *pstate,
bool format_specified = false;
bool freeze_specified = false;
bool header_specified = false;
- bool save_error_to_specified = false;
+ bool on_error_specified = false;
ListCell *option;
/* Support external use for option sanity checking */
@@ -608,12 +608,12 @@ ProcessCopyOptions(ParseState *pstate,
defel->defname),
parser_errposition(pstate, defel->location)));
}
- else if (strcmp(defel->defname, "save_error_to") == 0)
+ else if (strcmp(defel->defname, "on_error") == 0)
{
- if (save_error_to_specified)
+ if (on_error_specified)
errorConflictingDefElem(defel, pstate);
- save_error_to_specified = true;
- opts_out->save_error_to = defGetCopySaveErrorToChoice(defel, pstate, is_from);
+ on_error_specified = true;
+ opts_out->on_error = defGetCopyOnErrorChoice(defel, pstate, is_from);
}
else
ereport(ERROR,
@@ -642,10 +642,10 @@ ProcessCopyOptions(ParseState *pstate,
(errcode(ERRCODE_SYNTAX_ERROR),
errmsg("cannot specify DEFAULT in BINARY mode")));
- if (opts_out->binary && opts_out->save_error_to != COPY_SAVE_ERROR_TO_ERROR)
+ if (opts_out->binary && opts_out->on_error != COPY_ON_ERROR_STOP)
ereport(ERROR,
(errcode(ERRCODE_SYNTAX_ERROR),
- errmsg("cannot specify SAVE_ERROR_TO in BINARY mode")));
+ errmsg("only ON_ERROR STOP is allowed in BINARY mode")));
/* Set defaults for omitted options */
if (!opts_out->delim)
diff --git a/src/backend/commands/copyfrom.c b/src/backend/commands/copyfrom.c
index 50e245d555..173a736ad5 100644
--- a/src/backend/commands/copyfrom.c
+++ b/src/backend/commands/copyfrom.c
@@ -657,7 +657,7 @@ CopyFrom(CopyFromState cstate)
Assert(cstate->rel);
Assert(list_length(cstate->range_table) == 1);
- if (cstate->opts.save_error_to != COPY_SAVE_ERROR_TO_ERROR)
+ if (cstate->opts.on_error != COPY_ON_ERROR_STOP)
Assert(cstate->escontext);
/*
@@ -996,14 +996,14 @@ CopyFrom(CopyFromState cstate)
if (!NextCopyFrom(cstate, econtext, myslot->tts_values, myslot->tts_isnull))
break;
- if (cstate->opts.save_error_to != COPY_SAVE_ERROR_TO_ERROR &&
+ if (cstate->opts.on_error != COPY_ON_ERROR_STOP &&
cstate->escontext->error_occurred)
{
/*
- * Soft error occured, skip this tuple and save error information
- * according to SAVE_ERROR_TO.
+ * Soft error occured, skip this tuple and deal with error
+ * information according to ON_ERROR.
*/
- if (cstate->opts.save_error_to == COPY_SAVE_ERROR_TO_NONE)
+ if (cstate->opts.on_error == COPY_ON_ERROR_IGNORE)
/*
* Just make ErrorSaveContext ready for the next NextCopyFrom.
@@ -1307,7 +1307,7 @@ CopyFrom(CopyFromState cstate)
/* Done, clean up */
error_context_stack = errcallback.previous;
- if (cstate->opts.save_error_to != COPY_SAVE_ERROR_TO_ERROR &&
+ if (cstate->opts.on_error != COPY_ON_ERROR_STOP &&
cstate->num_errors > 0)
ereport(NOTICE,
errmsg_plural("%llu row was skipped due to data type incompatibility",
@@ -1450,18 +1450,18 @@ BeginCopyFrom(ParseState *pstate,
}
}
- /* Set up soft error handler for SAVE_ERROR_TO */
- if (cstate->opts.save_error_to != COPY_SAVE_ERROR_TO_ERROR)
+ /* Set up soft error handler for ON_ERROR */
+ if (cstate->opts.on_error != COPY_ON_ERROR_STOP)
{
cstate->escontext = makeNode(ErrorSaveContext);
cstate->escontext->type = T_ErrorSaveContext;
cstate->escontext->error_occurred = false;
/*
- * Currently we only support COPY_SAVE_ERROR_TO_NONE. We'll add other
+ * Currently we only support COPY_ON_ERROR_IGNORE. We'll add other
* options later
*/
- if (cstate->opts.save_error_to == COPY_SAVE_ERROR_TO_NONE)
+ if (cstate->opts.on_error == COPY_ON_ERROR_IGNORE)
cstate->escontext->details_wanted = false;
}
else
diff --git a/src/backend/commands/copyfromparse.c b/src/backend/commands/copyfromparse.c
index 7207eb2698..7cacd0b752 100644
--- a/src/backend/commands/copyfromparse.c
+++ b/src/backend/commands/copyfromparse.c
@@ -956,7 +956,11 @@ NextCopyFrom(CopyFromState cstate, ExprContext *econtext,
values[m] = ExecEvalExpr(defexprs[m], econtext, &nulls[m]);
}
- /* If SAVE_ERROR_TO is specified, skip rows with soft errors */
+
+ /*
+ * If ON_ERROR is specified with IGNORE, skip rows with soft
+ * errors
+ */
else if (!InputFunctionCallSafe(&in_functions[m],
string,
typioparams[m],
diff --git a/src/bin/psql/tab-complete.c b/src/bin/psql/tab-complete.c
index 6bfdb5f008..ada711d02f 100644
--- a/src/bin/psql/tab-complete.c
+++ b/src/bin/psql/tab-complete.c
@@ -2899,15 +2899,15 @@ psql_completion(const char *text, int start, int end)
COMPLETE_WITH("FORMAT", "FREEZE", "DELIMITER", "NULL",
"HEADER", "QUOTE", "ESCAPE", "FORCE_QUOTE",
"FORCE_NOT_NULL", "FORCE_NULL", "ENCODING", "DEFAULT",
- "SAVE_ERROR_TO");
+ "ON_ERROR");
/* Complete COPY FROM|TO filename WITH (FORMAT */
else if (Matches("COPY|\\copy", MatchAny, "FROM|TO", MatchAny, "WITH", "(", "FORMAT"))
COMPLETE_WITH("binary", "csv", "text");
- /* Complete COPY FROM filename WITH (SAVE_ERROR_TO */
- else if (Matches("COPY|\\copy", MatchAny, "FROM|TO", MatchAny, "WITH", "(", "SAVE_ERROR_TO"))
- COMPLETE_WITH("error", "none");
+ /* Complete COPY FROM filename WITH (ON_ERROR */
+ else if (Matches("COPY|\\copy", MatchAny, "FROM|TO", MatchAny, "WITH", "(", "ON_ERROR"))
+ COMPLETE_WITH("stop", "ignore");
/* Complete COPY FROM WITH () */
else if (Matches("COPY|\\copy", MatchAny, "FROM", MatchAny, "WITH", MatchAny))
diff --git a/src/include/commands/copy.h b/src/include/commands/copy.h
index 8972c6180d..b3da3cb0be 100644
--- a/src/include/commands/copy.h
+++ b/src/include/commands/copy.h
@@ -34,11 +34,11 @@ typedef enum CopyHeaderChoice
* Represents where to save input processing errors. More values to be added
* in the future.
*/
-typedef enum CopySaveErrorToChoice
+typedef enum CopyOnErrorChoice
{
- COPY_SAVE_ERROR_TO_ERROR = 0, /* immediately throw errors */
- COPY_SAVE_ERROR_TO_NONE, /* ignore errors */
-} CopySaveErrorToChoice;
+ COPY_ON_ERROR_STOP = 0, /* immediately throw errors, default */
+ COPY_ON_ERROR_IGNORE, /* ignore errors */
+} CopyOnErrorChoice;
/*
* A struct to hold COPY options, in a parsed form. All of these are related
@@ -72,7 +72,7 @@ typedef struct CopyFormatOptions
bool force_null_all; /* FORCE_NULL *? */
bool *force_null_flags; /* per-column CSV FN flags */
bool convert_selectively; /* do selective binary conversion? */
- CopySaveErrorToChoice save_error_to; /* where to save error information */
+ CopyOnErrorChoice on_error; /* what to do when error happened */
List *convert_select; /* list of column names (can be NIL) */
} CopyFormatOptions;
diff --git a/src/test/regress/expected/copy2.out b/src/test/regress/expected/copy2.out
index 42cbcb2e92..25c401ce34 100644
--- a/src/test/regress/expected/copy2.out
+++ b/src/test/regress/expected/copy2.out
@@ -77,21 +77,21 @@ COPY x from stdin (encoding 'sql_ascii', encoding 'sql_ascii');
ERROR: conflicting or redundant options
LINE 1: COPY x from stdin (encoding 'sql_ascii', encoding 'sql_ascii...
^
-COPY x from stdin (save_error_to none,save_error_to none);
+COPY x from stdin (on_error ignore, on_error ignore);
ERROR: conflicting or redundant options
-LINE 1: COPY x from stdin (save_error_to none,save_error_to none);
- ^
+LINE 1: COPY x from stdin (on_error ignore, on_error ignore);
+ ^
-- incorrect options
COPY x to stdin (format BINARY, delimiter ',');
ERROR: cannot specify DELIMITER in BINARY mode
COPY x to stdin (format BINARY, null 'x');
ERROR: cannot specify NULL in BINARY mode
-COPY x from stdin (format BINARY, save_error_to none);
-ERROR: cannot specify SAVE_ERROR_TO in BINARY mode
-COPY x to stdin (save_error_to none);
-ERROR: COPY SAVE_ERROR_TO cannot be used with COPY TO
-LINE 1: COPY x to stdin (save_error_to none);
- ^
+COPY x from stdin (format BINARY, on_error ignore);
+ERROR: only ON_ERROR STOP is allowed in BINARY mode
+COPY x from stdin (on_error unsupported);
+ERROR: COPY ON_ERROR "unsupported" not recognized
+LINE 1: COPY x from stdin (on_error unsupported);
+ ^
COPY x to stdin (format TEXT, force_quote(a));
ERROR: COPY FORCE_QUOTE requires CSV mode
COPY x from stdin (format CSV, force_quote(a));
@@ -104,9 +104,9 @@ COPY x to stdout (format TEXT, force_null(a));
ERROR: COPY FORCE_NULL requires CSV mode
COPY x to stdin (format CSV, force_null(a));
ERROR: COPY FORCE_NULL cannot be used with COPY TO
-COPY x to stdin (format BINARY, save_error_to unsupported);
-ERROR: COPY SAVE_ERROR_TO cannot be used with COPY TO
-LINE 1: COPY x to stdin (format BINARY, save_error_to unsupported);
+COPY x to stdin (format BINARY, on_error unsupported);
+ERROR: COPY ON_ERROR cannot be used with COPY TO
+LINE 1: COPY x to stdin (format BINARY, on_error unsupported);
^
-- too many columns in column list: should fail
COPY x (a, b, c, d, e, d, c) from stdin;
@@ -724,12 +724,12 @@ SELECT * FROM instead_of_insert_tbl;
(2 rows)
COMMIT;
--- tests for SAVE_ERROR_TO option
+-- tests for on_error option
CREATE TABLE check_ign_err (n int, m int[], k int);
-COPY check_ign_err FROM STDIN WITH (save_error_to error);
+COPY check_ign_err FROM STDIN WITH (on_error stop);
ERROR: invalid input syntax for type integer: "a"
CONTEXT: COPY check_ign_err, line 2, column n: "a"
-COPY check_ign_err FROM STDIN WITH (save_error_to none);
+COPY check_ign_err FROM STDIN WITH (on_error ignore);
NOTICE: 4 rows were skipped due to data type incompatibility
SELECT * FROM check_ign_err;
n | m | k
@@ -740,15 +740,15 @@ SELECT * FROM check_ign_err;
-- test datatype error that can't be handled as soft: should fail
CREATE TABLE hard_err(foo widget);
-COPY hard_err FROM STDIN WITH (save_error_to none);
+COPY hard_err FROM STDIN WITH (on_error ignore);
ERROR: invalid input syntax for type widget: "1"
CONTEXT: COPY hard_err, line 1, column foo: "1"
-- test missing data: should fail
-COPY check_ign_err FROM STDIN WITH (save_error_to none);
+COPY check_ign_err FROM STDIN WITH (on_error ignore);
ERROR: missing data for column "k"
CONTEXT: COPY check_ign_err, line 1: "1 {1}"
-- test extra data: should fail
-COPY check_ign_err FROM STDIN WITH (save_error_to none);
+COPY check_ign_err FROM STDIN WITH (on_error ignore);
ERROR: extra data after last expected column
CONTEXT: COPY check_ign_err, line 1: "1 {1} 3 abc"
-- clean up
diff --git a/src/test/regress/sql/copy2.sql b/src/test/regress/sql/copy2.sql
index c48d556350..b5e549e856 100644
--- a/src/test/regress/sql/copy2.sql
+++ b/src/test/regress/sql/copy2.sql
@@ -66,20 +66,20 @@ COPY x from stdin (force_not_null (a), force_not_null (b));
COPY x from stdin (force_null (a), force_null (b));
COPY x from stdin (convert_selectively (a), convert_selectively (b));
COPY x from stdin (encoding 'sql_ascii', encoding 'sql_ascii');
-COPY x from stdin (save_error_to none,save_error_to none);
+COPY x from stdin (on_error ignore, on_error ignore);
-- incorrect options
COPY x to stdin (format BINARY, delimiter ',');
COPY x to stdin (format BINARY, null 'x');
-COPY x from stdin (format BINARY, save_error_to none);
-COPY x to stdin (save_error_to none);
+COPY x from stdin (format BINARY, on_error ignore);
+COPY x from stdin (on_error unsupported);
COPY x to stdin (format TEXT, force_quote(a));
COPY x from stdin (format CSV, force_quote(a));
COPY x to stdout (format TEXT, force_not_null(a));
COPY x to stdin (format CSV, force_not_null(a));
COPY x to stdout (format TEXT, force_null(a));
COPY x to stdin (format CSV, force_null(a));
-COPY x to stdin (format BINARY, save_error_to unsupported);
+COPY x to stdin (format BINARY, on_error unsupported);
-- too many columns in column list: should fail
COPY x (a, b, c, d, e, d, c) from stdin;
@@ -498,9 +498,9 @@ test1
SELECT * FROM instead_of_insert_tbl;
COMMIT;
--- tests for SAVE_ERROR_TO option
+-- tests for on_error option
CREATE TABLE check_ign_err (n int, m int[], k int);
-COPY check_ign_err FROM STDIN WITH (save_error_to error);
+COPY check_ign_err FROM STDIN WITH (on_error stop);
1 {1} 1
a {2} 2
3 {3} 3333333333
@@ -508,7 +508,7 @@ a {2} 2
5 {5} 5
\.
-COPY check_ign_err FROM STDIN WITH (save_error_to none);
+COPY check_ign_err FROM STDIN WITH (on_error ignore);
1 {1} 1
a {2} 2
3 {3} 3333333333
@@ -520,17 +520,17 @@ SELECT * FROM check_ign_err;
-- test datatype error that can't be handled as soft: should fail
CREATE TABLE hard_err(foo widget);
-COPY hard_err FROM STDIN WITH (save_error_to none);
+COPY hard_err FROM STDIN WITH (on_error ignore);
1
\.
-- test missing data: should fail
-COPY check_ign_err FROM STDIN WITH (save_error_to none);
+COPY check_ign_err FROM STDIN WITH (on_error ignore);
1 {1}
\.
-- test extra data: should fail
-COPY check_ign_err FROM STDIN WITH (save_error_to none);
+COPY check_ign_err FROM STDIN WITH (on_error ignore);
1 {1} 3 abc
\.
diff --git a/src/tools/pgindent/typedefs.list b/src/tools/pgindent/typedefs.list
index aa74ed695e..16421f034c 100644
--- a/src/tools/pgindent/typedefs.list
+++ b/src/tools/pgindent/typedefs.list
@@ -478,6 +478,7 @@ CopyHeaderChoice
CopyInsertMethod
CopyMultiInsertBuffer
CopyMultiInsertInfo
+CopyOnErrorChoice
CopySource
CopyStmt
CopyToState
@@ -4041,4 +4042,3 @@ manifest_writer
rfile
ws_options
ws_file_info
-CopySaveErrorToChoice