diff --git a/src/backend/nodes/copyfuncs.c b/src/backend/nodes/copyfuncs.c
index 84f5e2e6ad..962baa40ce 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 ((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;
 }
 
@@ -176,8 +171,6 @@ _copyBitmapset(const Bitmapset *from)
 void *
 copyObjectImpl(const void *from)
 {
-	void	   *retval;
-
 	if (from == NULL)
 		return NULL;
 
@@ -189,7 +182,7 @@ copyObjectImpl(const void *from)
 #include "copyfuncs.switch.c"
 
 		case T_List:
-			retval = list_copy_deep(from);
+			return list_copy_deep(from);
 			break;
 
 			/*
@@ -199,14 +192,13 @@ copyObjectImpl(const void *from)
 		case T_IntList:
 		case T_OidList:
 		case T_XidList:
-			retval = list_copy(from);
+			return list_copy(from);
 			break;
 
 		default:
 			elog(ERROR, "unrecognized node type: %d", (int) nodeTag(from));
-			retval = 0;			/* keep compiler quiet */
 			break;
 	}
 
-	return retval;
+	return NULL;
 }
diff --git a/src/backend/nodes/equalfuncs.c b/src/backend/nodes/equalfuncs.c
index b2f07da62e..f3658e79a2 100644
--- a/src/backend/nodes/equalfuncs.c
+++ b/src/backend/nodes/equalfuncs.c
@@ -60,12 +60,12 @@
 
 /* Macro for comparing string fields that might be NULL */
 #define equalstr(a, b)	\
-	(((a) != NULL && (b) != NULL) ? (strcmp(a, b) == 0) : (a) == (b))
+	(((a) != NULL && (b) != NULL) ? (a[0] == b[0] && strcmp(a, b) == 0) : (a) == (b))
 
 /* Compare a field that is an inline array */
 #define COMPARE_ARRAY_FIELD(fldname) \
 	do { \
-		if (memcmp(a->fldname, b->fldname, sizeof(a->fldname)) != 0) \
+		if (a->fldname[0] != b->fldname[0] || memcmp(a->fldname, b->fldname, sizeof(a->fldname)) != 0) \
 			return false; \
 	} while (0)
 
@@ -224,9 +224,7 @@ _equalList(const List *a, const List *b)
 bool
 equal(const void *a, const void *b)
 {
-	bool		retval;
-
-	if (a == b)
+	if (unlikely(a == b))
 		return true;
 
 	/*
@@ -252,15 +250,14 @@ equal(const void *a, const void *b)
 		case T_IntList:
 		case T_OidList:
 		case T_XidList:
-			retval = _equalList(a, b);
+			return _equalList(a, b);
 			break;
 
 		default:
 			elog(ERROR, "unrecognized node type: %d",
 				 (int) nodeTag(a));
-			retval = false;		/* keep compiler quiet */
 			break;
 	}
 
-	return retval;
+	return false;
 }
diff --git a/src/backend/nodes/gen_node_support.pl b/src/backend/nodes/gen_node_support.pl
index b6f086e262..b02ce7bbb2 100644
--- a/src/backend/nodes/gen_node_support.pl
+++ b/src/backend/nodes/gen_node_support.pl
@@ -656,12 +656,12 @@ foreach my $n (@node_types)
 	next if $struct_no_copy && $struct_no_equal;
 
 	print $cfs "\t\tcase T_${n}:\n"
-	  . "\t\t\tretval = _copy${n}(from);\n"
+	  . "\t\t\treturn _copy${n}(from);\n"
 	  . "\t\t\tbreak;\n"
 	  unless $struct_no_copy;
 
 	print $efs "\t\tcase T_${n}:\n"
-	  . "\t\t\tretval = _equal${n}(a, b);\n"
+	  . "\t\t\treturn _equal${n}(a, b);\n"
 	  . "\t\t\tbreak;\n"
 	  unless $struct_no_equal;
 
@@ -680,6 +680,7 @@ static bool
 _equal${n}(const $n *a, const $n *b)
 {
 " unless $struct_no_equal;
+  my $memcpy_ignore = 0;
 
 	# print instructions for each field
 	foreach my $f (@{ $node_type_info{$n}->{fields} })
@@ -708,8 +709,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 copy_as is specified
-		if (defined $copy_as_field)
+		if (defined $copy_as_field && !$memcpy_ignore)
 		{
 			print $cff "\tnewnode->$f = $copy_as_field;\n"
 			  unless $copy_ignore;
@@ -730,12 +737,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
@@ -779,7 +786,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
@@ -792,7 +799,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*'
@@ -801,7 +808,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
diff --git a/src/backend/nodes/readfuncs.c b/src/backend/nodes/readfuncs.c
index 23776367c5..2ba2dc8358 100644
--- a/src/backend/nodes/readfuncs.c
+++ b/src/backend/nodes/readfuncs.c
@@ -58,74 +58,74 @@
 
 /* Read an integer field (anything written as ":fldname %d") */
 #define READ_INT_FIELD(fldname) \
-	token = pg_strtok(&length);		/* skip :fldname */ \
+	(void) pg_strtok(&length);			/* skip :fldname */ \
 	token = pg_strtok(&length);		/* get field value */ \
 	local_node->fldname = atoi(token)
 
 /* Read an unsigned integer field (anything written as ":fldname %u") */
 #define READ_UINT_FIELD(fldname) \
-	token = pg_strtok(&length);		/* skip :fldname */ \
+	(void) pg_strtok(&length);			/* skip :fldname */ \
 	token = pg_strtok(&length);		/* get field value */ \
 	local_node->fldname = atoui(token)
 
 /* Read an unsigned integer field (anything written using UINT64_FORMAT) */
 #define READ_UINT64_FIELD(fldname) \
-	token = pg_strtok(&length);		/* skip :fldname */ \
+	(void) pg_strtok(&length);			/* skip :fldname */ \
 	token = pg_strtok(&length);		/* get field value */ \
 	local_node->fldname = strtou64(token, NULL, 10)
 
 /* Read a long integer field (anything written as ":fldname %ld") */
 #define READ_LONG_FIELD(fldname) \
-	token = pg_strtok(&length);		/* skip :fldname */ \
+	(void) pg_strtok(&length);			/* skip :fldname */ \
 	token = pg_strtok(&length);		/* get field value */ \
 	local_node->fldname = atol(token)
 
 /* Read an OID field (don't hard-wire assumption that OID is same as uint) */
 #define READ_OID_FIELD(fldname) \
-	token = pg_strtok(&length);		/* skip :fldname */ \
+	(void) pg_strtok(&length);			/* skip :fldname */ \
 	token = pg_strtok(&length);		/* get field value */ \
 	local_node->fldname = atooid(token)
 
 /* Read a char field (ie, one ascii character) */
 #define READ_CHAR_FIELD(fldname) \
-	token = pg_strtok(&length);		/* skip :fldname */ \
+	(void) pg_strtok(&length);			/* skip :fldname */ \
 	token = pg_strtok(&length);		/* get field value */ \
 	/* avoid overhead of calling debackslash() for one char */ \
 	local_node->fldname = (length == 0) ? '\0' : (token[0] == '\\' ? token[1] : token[0])
 
 /* Read an enumerated-type field that was written as an integer code */
 #define READ_ENUM_FIELD(fldname, enumtype) \
-	token = pg_strtok(&length);		/* skip :fldname */ \
+	(void) pg_strtok(&length);			/* skip :fldname */ \
 	token = pg_strtok(&length);		/* get field value */ \
 	local_node->fldname = (enumtype) atoi(token)
 
 /* Read a float field */
 #define READ_FLOAT_FIELD(fldname) \
-	token = pg_strtok(&length);		/* skip :fldname */ \
+	(void) pg_strtok(&length);			/* skip :fldname */ \
 	token = pg_strtok(&length);		/* get field value */ \
 	local_node->fldname = atof(token)
 
 /* Read a boolean field */
 #define READ_BOOL_FIELD(fldname) \
-	token = pg_strtok(&length);		/* skip :fldname */ \
+	(void) pg_strtok(&length);			/* skip :fldname */ \
 	token = pg_strtok(&length);		/* get field value */ \
 	local_node->fldname = strtobool(token)
 
 /* Read a character-string field */
 #define READ_STRING_FIELD(fldname) \
-	token = pg_strtok(&length);		/* skip :fldname */ \
+	(void) pg_strtok(&length);			/* skip :fldname */ \
 	token = pg_strtok(&length);		/* get field value */ \
 	local_node->fldname = nullable_string(token, length)
 
 /* Read a parse location field (and possibly throw away the value) */
 #ifdef WRITE_READ_PARSE_PLAN_TREES
 #define READ_LOCATION_FIELD(fldname) \
-	token = pg_strtok(&length);		/* skip :fldname */ \
+	(void) pg_strtok(&length);			/* skip :fldname */ \
 	token = pg_strtok(&length);		/* get field value */ \
 	local_node->fldname = restore_location_fields ? atoi(token) : -1
 #else
 #define READ_LOCATION_FIELD(fldname) \
-	token = pg_strtok(&length);		/* skip :fldname */ \
+	(void) pg_strtok(&length);			/* skip :fldname */ \
 	token = pg_strtok(&length);		/* get field value */ \
 	(void) token;				/* in case not used elsewhere */ \
 	local_node->fldname = -1	/* set field to "unknown" */
@@ -145,22 +145,22 @@
 
 /* Read an attribute number array */
 #define READ_ATTRNUMBER_ARRAY(fldname, len) \
-	token = pg_strtok(&length);		/* skip :fldname */ \
+	(void) pg_strtok(&length);		/* skip :fldname */ \
 	local_node->fldname = readAttrNumberCols(len)
 
 /* Read an oid array */
 #define READ_OID_ARRAY(fldname, len) \
-	token = pg_strtok(&length);		/* skip :fldname */ \
+	(void) pg_strtok(&length);		/* skip :fldname */ \
 	local_node->fldname = readOidCols(len)
 
 /* Read an int array */
 #define READ_INT_ARRAY(fldname, len) \
-	token = pg_strtok(&length);		/* skip :fldname */ \
+	(void) pg_strtok(&length);		/* skip :fldname */ \
 	local_node->fldname = readIntCols(len)
 
 /* Read a bool array */
 #define READ_BOOL_ARRAY(fldname, len) \
-	token = pg_strtok(&length);		/* skip :fldname */ \
+	(void) pg_strtok(&length);		/* skip :fldname */ \
 	local_node->fldname = readBoolCols(len)
 
 /* Routine exit */
@@ -283,7 +283,7 @@ _readBoolExpr(void)
 	READ_LOCALS(BoolExpr);
 
 	/* do-it-yourself enum representation */
-	token = pg_strtok(&length); /* skip :boolop */
+	(void) pg_strtok(&length); /* skip :boolop */
 	token = pg_strtok(&length); /* get field value */
 	if (length == 3 && strncmp(token, "and", 3) == 0)
 		local_node->boolop = AND_EXPR;
@@ -333,7 +333,7 @@ _readConstraint(void)
 	READ_BOOL_FIELD(initdeferred);
 	READ_LOCATION_FIELD(location);
 
-	token = pg_strtok(&length); /* skip :contype */
+	(void) pg_strtok(&length); /* skip :contype */
 	token = pg_strtok(&length); /* get field value */
 	if (length == 4 && strncmp(token, "NULL", 4) == 0)
 		local_node->contype = CONSTR_NULL;
@@ -643,7 +643,7 @@ _readExtensibleNode(void)
 
 	READ_TEMP_LOCALS();
 
-	token = pg_strtok(&length); /* skip :extnodename */
+	(void) pg_strtok(&length); /* skip :extnodename */
 	token = pg_strtok(&length); /* get extnodename */
 
 	extnodename = nullable_string(token, length);