v1-0001-minor-refactor.no-cfbot

application/octet-stream

Filename: v1-0001-minor-refactor.no-cfbot
Type: application/octet-stream
Part: 0
Message: Re: POC PATCH: copy from ... exceptions to: (was Re: VLDB Features)
From 24583b558aa6be0d8a3cabffc9a9ce33c7af856b Mon Sep 17 00:00:00 2001
From: jian he <jian.universality@gmail.com>
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 { <replaceable class="parameter">table_name</replaceable> [ ( <replaceable
     <term><literal>SAVE_ERROR_TO</literal></term>
     <listitem>
      <para>
-      Specifies where to save error information when there are malformed data in
+      Specifies save error information to <replaceable
+      class="parameter">location</replaceable> when there are malformed data in
       the input. If this option is specified, <command>COPY</command> skips
       malformed data and continues copying data.
       Currently only <literal>none</literal> is supported.
+      If this option is omitted, <command>COPY</command> stops operation at the first error.
       This option is allowed only in <command>COPY FROM</command>, and only when
       not using <literal>binary</literal> format.
-      Note that this is only supported in current <command>COPY</command>
-      syntax.
      </para>
     </listitem>
    </varlistentry>
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