index f2568ff5e6..8233c9b7d3 100644
--- a/src/backend/nodes/copyfuncs.c
+++ b/src/backend/nodes/copyfuncs.c
@@ -40,7 +40,10 @@
 
 /* Copy a field that is a pointer to a C string, or perhaps NULL */
 #define COPY_STRING_FIELD(fldname) \
-	(newnode->fldname = from->fldname ? pstrdup(from->fldname) : (char *) NULL)
+	do { \
+		if (from->fldname) \
+			newnode->fldname = pstrdup(from->fldname); \
+	} while (0)
 
 /* Copy a field that is an inline array */
 #define COPY_ARRAY_FIELD(fldname) \
@@ -49,11 +52,10 @@
 /* Copy a field that is a pointer to a simple palloc'd object of size sz */
 #define COPY_POINTER_FIELD(fldname, sz) \
 	do { \
-		Size	_size = (sz); \
-		if (_size > 0) \
+		if (from->fldname && (sz) > 0) \
 		{ \
-			newnode->fldname = palloc(_size); \
-			memcpy(newnode->fldname, from->fldname, _size); \
+			newnode->fldname = palloc((sz)); \
+			memcpy(newnode->fldname, from->fldname, (sz)); \
 		} \
 	} while (0)
 
@@ -74,10 +76,7 @@ _copyConst(const Const *from)
 {
 	Const	   *newnode = makeNode(Const);
 
-	COPY_SCALAR_FIELD(consttype);
-	COPY_SCALAR_FIELD(consttypmod);
-	COPY_SCALAR_FIELD(constcollid);
-	COPY_SCALAR_FIELD(constlen);
+	memcpy(newnode, from, sizeof(*from));
 
 	if (from->constbyval || from->constisnull)
 	{
@@ -97,10 +96,6 @@ _copyConst(const Const *from)
 										from->constlen);
 	}
 
-	COPY_SCALAR_FIELD(constisnull);
-	COPY_SCALAR_FIELD(constbyval);
-	COPY_LOCATION_FIELD(location);
-
 	return newnode;
 }
 
@@ -109,7 +104,8 @@ _copyA_Const(const A_Const *from)
 {
 	A_Const    *newnode = makeNode(A_Const);
 
-	COPY_SCALAR_FIELD(isnull);
+	memcpy(newnode, from, sizeof(*from));
+
 	if (!from->isnull)
 	{
 		/* This part must duplicate other _copy*() functions. */
@@ -138,8 +134,6 @@ _copyA_Const(const A_Const *from)
 		}
 	}
 
-	COPY_LOCATION_FIELD(location);
-
 	return newnode;
 }
 
diff --git a/src/backend/nodes/gen_node_support.pl b/src/backend/nodes/gen_node_support.pl
index b3c1ead496..39560fbd0e 100644
--- a/src/backend/nodes/gen_node_support.pl
+++ b/src/backend/nodes/gen_node_support.pl
@@ -680,6 +680,7 @@ static bool
 _equal${n}(const $n *a, const $n *b)
 {
 " unless $struct_no_equal;
+  my $memcpy_ignore = 0;
 
 	# track already-processed fields to support field order checks
 	my %previous_fields;
@@ -725,8 +726,14 @@ _equal${n}(const $n *a, const $n *b)
 			}
 		}
 
+		if (!$memcpy_ignore && $node_type_info{$n}->{fields} > 2)
+		{
+			print $cff "\tmemcpy(newnode, from, sizeof(*from));\n" unless $copy_ignore;
+			$memcpy_ignore = 1;
+		}
+
 		# override type-specific copy method if requested
-		if (defined $copy_as_field)
+		if (defined $copy_as_field && !$memcpy_ignore)
 		{
 			print $cff "\tnewnode->$f = $copy_as_field;\n"
 			  unless $copy_ignore;
@@ -735,7 +742,7 @@ _equal${n}(const $n *a, const $n *b)
 		elsif ($copy_as_scalar)
 		{
 			print $cff "\tCOPY_SCALAR_FIELD($f);\n"
-			  unless $copy_ignore;
+			  unless $copy_ignore || $memcpy_ignore;
 			$copy_ignore = 1;
 		}
 
@@ -761,12 +768,12 @@ _equal${n}(const $n *a, const $n *b)
 		}
 		elsif ($t eq 'int' && $f =~ 'location$')
 		{
-			print $cff "\tCOPY_LOCATION_FIELD($f);\n"    unless $copy_ignore;
+			print $cff "\tCOPY_LOCATION_FIELD($f);\n"    unless $copy_ignore || $memcpy_ignore;
 			print $eff "\tCOMPARE_LOCATION_FIELD($f);\n" unless $equal_ignore;
 		}
 		elsif (elem $t, @scalar_types or elem $t, @enum_types)
 		{
-			print $cff "\tCOPY_SCALAR_FIELD($f);\n" unless $copy_ignore;
+			print $cff "\tCOPY_SCALAR_FIELD($f);\n" unless $copy_ignore || $memcpy_ignore;
 			if (elem 'equal_ignore_if_zero', @a)
 			{
 				print $eff
@@ -810,7 +817,7 @@ _equal${n}(const $n *a, const $n *b)
 		elsif ($t eq 'function pointer')
 		{
 			# we can copy and compare as a scalar
-			print $cff "\tCOPY_SCALAR_FIELD($f);\n"    unless $copy_ignore;
+			print $cff "\tCOPY_SCALAR_FIELD($f);\n"    unless $copy_ignore || $memcpy_ignore;
 			print $eff "\tCOMPARE_SCALAR_FIELD($f);\n" unless $equal_ignore;
 		}
 		# node type
@@ -834,7 +841,7 @@ _equal${n}(const $n *a, const $n *b)
 		# array (inline)
 		elsif ($t =~ /^\w+\[\w+\]$/)
 		{
-			print $cff "\tCOPY_ARRAY_FIELD($f);\n"    unless $copy_ignore;
+			print $cff "\tCOPY_ARRAY_FIELD($f);\n"    unless $copy_ignore || $memcpy_ignore;
 			print $eff "\tCOMPARE_ARRAY_FIELD($f);\n" unless $equal_ignore;
 		}
 		elsif ($t eq 'struct CustomPathMethods*'
@@ -843,7 +850,7 @@ _equal${n}(const $n *a, const $n *b)
 			# Fields of these types are required to be a pointer to a
 			# static table of callback functions.  So we don't copy
 			# the table itself, just reference the original one.
-			print $cff "\tCOPY_SCALAR_FIELD($f);\n"    unless $copy_ignore;
+			print $cff "\tCOPY_SCALAR_FIELD($f);\n"    unless $copy_ignore || $memcpy_ignore;
 			print $eff "\tCOMPARE_SCALAR_FIELD($f);\n" unless $equal_ignore;
 		}
 		else
