From 24583b558aa6be0d8a3cabffc9a9ce33c7af856b Mon Sep 17 00:00:00 2001 From: jian he Date: Thu, 11 Jan 2024 10:57:18 +0800 Subject: [PATCH v1 1/1] minor refactor. slightly changed the doc. other misc changes. --- doc/src/sgml/ref/copy.sgml | 6 ++-- src/backend/commands/copyfrom.c | 45 ++++++++++++++---------- src/backend/commands/copyfromparse.c | 3 +- src/include/commands/copyfrom_internal.h | 2 +- 4 files changed, 33 insertions(+), 23 deletions(-) diff --git a/doc/src/sgml/ref/copy.sgml b/doc/src/sgml/ref/copy.sgml index 87f2b3e7..a280e825 100644 --- a/doc/src/sgml/ref/copy.sgml +++ b/doc/src/sgml/ref/copy.sgml @@ -378,14 +378,14 @@ COPY { table_name [ ( SAVE_ERROR_TO - Specifies where to save error information when there are malformed data in + Specifies save error information to location when there are malformed data in the input. If this option is specified, COPY skips malformed data and continues copying data. Currently only none is supported. + If this option is omitted, COPY stops operation at the first error. This option is allowed only in COPY FROM, and only when not using binary format. - Note that this is only supported in current COPY - syntax. diff --git a/src/backend/commands/copyfrom.c b/src/backend/commands/copyfrom.c index d909123c..698e3ef6 100644 --- a/src/backend/commands/copyfrom.c +++ b/src/backend/commands/copyfrom.c @@ -657,6 +657,8 @@ CopyFrom(CopyFromState cstate) Assert(cstate->rel); Assert(list_length(cstate->range_table) == 1); + if (cstate->opts.save_error_to) + Assert(cstate->escontext); /* * The target must be a plain, foreign, or partitioned relation, or have * an INSTEAD OF INSERT row trigger. (Currently, such triggers are only @@ -753,14 +755,6 @@ CopyFrom(CopyFromState cstate) ti_options |= TABLE_INSERT_FROZEN; } - /* Set up soft error handler for SAVE_ERROR_TO */ - if (cstate->opts.save_error_to) - { - ErrorSaveContext escontext = {T_ErrorSaveContext}; - escontext.details_wanted = true; - cstate->escontext = escontext; - } - /* * We need a ResultRelInfo so we can use the regular executor's * index-entry-making machinery. (There used to be a huge amount of code @@ -1005,18 +999,16 @@ CopyFrom(CopyFromState cstate) * Soft error occured, skip this tuple and save error information * according to SAVE_ERROR_TO. */ - if (cstate->escontext.error_occurred) + if (cstate->opts.save_error_to && cstate->escontext->error_occurred) { - ErrorSaveContext new_escontext = {T_ErrorSaveContext}; - - /* Currently only "none" is supported */ + /* + * Currently we only "none" is supported. + * make ErrorSaveContext ready for the next NextCopyFrom. + * Since we never set details_wanted, we don't need to also reset error_data. + * + */ Assert(strcmp(cstate->opts.save_error_to, "none") == 0); - - ExecClearTuple(myslot); - - new_escontext.details_wanted = true; - cstate->escontext = new_escontext; - + cstate->escontext->error_occurred = false; continue; } @@ -1477,6 +1469,23 @@ BeginCopyFrom(ParseState *pstate, } } + /* Set up soft error handler for SAVE_ERROR_TO + * currenly we can only save_error to 'none', + * We can add other options later, but we need set the escontext properly. + */ + if (cstate->opts.save_error_to && strcmp(cstate->opts.save_error_to, "none") == 0) + { + cstate->escontext = makeNode(ErrorSaveContext); + cstate->escontext->type = T_ErrorSaveContext; + cstate->escontext->details_wanted = false; + cstate->escontext->error_occurred = false; + } + else + { + cstate->escontext = NULL; + } + cstate->num_errors = 0; + /* Convert convert_selectively name list to per-column flags */ if (cstate->opts.convert_selectively) { diff --git a/src/backend/commands/copyfromparse.c b/src/backend/commands/copyfromparse.c index 0dd49d85..6b5d9e39 100644 --- a/src/backend/commands/copyfromparse.c +++ b/src/backend/commands/copyfromparse.c @@ -962,10 +962,11 @@ NextCopyFrom(CopyFromState cstate, ExprContext *econtext, string, typioparams[m], att->atttypmod, - (Node *) &cstate->escontext, + (Node *) cstate->escontext, &values[m])) { cstate->num_errors++; + Assert(!cstate->escontext->details_wanted); return true; } diff --git a/src/include/commands/copyfrom_internal.h b/src/include/commands/copyfrom_internal.h index e2a8f9dd..ddcc04f6 100644 --- a/src/include/commands/copyfrom_internal.h +++ b/src/include/commands/copyfrom_internal.h @@ -95,7 +95,7 @@ typedef struct CopyFromStateData * default value */ FmgrInfo *in_functions; /* array of input functions for each attrs */ Oid *typioparams; /* array of element types for in_functions */ - ErrorSaveContext escontext; /* soft error trapper during in_functions execution */ + ErrorSaveContext *escontext; /* soft error trapper during in_functions execution */ uint64 num_errors; /* total number of rows which contained soft errors */ int *defmap; /* array of default att numbers related to * missing att */ -- 2.34.1