Proposal: Make use of C99 designated initialisers for nulls/values arrays

Started by Smith, Peterover 6 years ago62 messages
#1Smith, Peter
peters@fast.au.fujitsu.com
1 attachment(s)

Dear Hackers,

I have identified some OSS code which maybe can make use of C99 designated initialisers for nulls/values arrays.

~

Background:
There are lots of tuple operations where arrays of values and flags are being passed.
Typically these arrays are being previously initialised 0/false by memset.
By modifying code to use C99 designated initialiser syntax [1]REF C99 [$6.7.8/21] If there are fewer initializers in a brace-enclosed list than there are elements or members of an aggregate, or fewer characters in a string literal used to initialize an array of known size than there are elements in the array, the remainder of the aggregate shall be initialized implicitly the same as objects that have static storage duration, most of these memsets can become redundant.
Actually, this mechanism is already being used in some of the existing OSS code. This patch/proposal just propagates the same idea to all other similar places I could find.

~

Result:
Less code. Removes ~200 unnecessary memsets.
More consistent initialisation.

~

Typical Example:
Before:
Datum values[Natts_pg_attribute];
bool nulls[Natts_pg_attribute];
...
memset(values, 0, sizeof(values));
memset(nulls, false, sizeof(nulls));
After:
Datum values[Natts_pg_attribute] = {0};
bool nulls[Natts_pg_attribute] = {0};

---
[1]: REF C99 [$6.7.8/21] If there are fewer initializers in a brace-enclosed list than there are elements or members of an aggregate, or fewer characters in a string literal used to initialize an array of known size than there are elements in the array, the remainder of the aggregate shall be initialized implicitly the same as objects that have static storage duration
or fewer characters in a string literal used to initialize an array of known size than there are elements in the array,
the remainder of the aggregate shall be initialized implicitly the same as objects that have static storage duration

~

Please refer to the attached patch.

Kind Regards,

---
Peter Smith
Fujitsu Australia

Attachments:

init_nulls.patchapplication/octet-stream; name=init_nulls.patchDownload
diff --git a/src/backend/access/transam/commit_ts.c b/src/backend/access/transam/commit_ts.c
index 3316734..0d501e0 100644
--- a/src/backend/access/transam/commit_ts.c
+++ b/src/backend/access/transam/commit_ts.c
@@ -422,8 +422,8 @@ pg_last_committed_xact(PG_FUNCTION_ARGS)
 {
 	TransactionId xid;
 	TimestampTz ts;
-	Datum		values[2];
-	bool		nulls[2];
+	Datum		values[2] = {0};
+	bool		nulls[2] = {0};
 	TupleDesc	tupdesc;
 	HeapTuple	htup;
 
@@ -448,10 +448,7 @@ pg_last_committed_xact(PG_FUNCTION_ARGS)
 	else
 	{
 		values[0] = TransactionIdGetDatum(xid);
-		nulls[0] = false;
-
 		values[1] = TimestampTzGetDatum(ts);
-		nulls[1] = false;
 	}
 
 	htup = heap_form_tuple(tupdesc, values, nulls);
diff --git a/src/backend/access/transam/twophase.c b/src/backend/access/transam/twophase.c
index 546bd43..87f5824 100644
--- a/src/backend/access/transam/twophase.c
+++ b/src/backend/access/transam/twophase.c
@@ -770,8 +770,8 @@ pg_prepared_xact(PG_FUNCTION_ARGS)
 		GlobalTransaction gxact = &status->array[status->currIdx++];
 		PGPROC	   *proc = &ProcGlobal->allProcs[gxact->pgprocno];
 		PGXACT	   *pgxact = &ProcGlobal->allPgXact[gxact->pgprocno];
-		Datum		values[5];
-		bool		nulls[5];
+		Datum		values[5] = {0};
+		bool		nulls[5] = {0};
 		HeapTuple	tuple;
 		Datum		result;
 
@@ -781,9 +781,6 @@ pg_prepared_xact(PG_FUNCTION_ARGS)
 		/*
 		 * Form tuple with appropriate data.
 		 */
-		MemSet(values, 0, sizeof(values));
-		MemSet(nulls, 0, sizeof(nulls));
-
 		values[0] = TransactionIdGetDatum(pgxact->xid);
 		values[1] = CStringGetTextDatum(gxact->gid);
 		values[2] = TimestampTzGetDatum(gxact->prepared_at);
diff --git a/src/backend/access/transam/xlogfuncs.c b/src/backend/access/transam/xlogfuncs.c
index 8f17988..049f221 100644
--- a/src/backend/access/transam/xlogfuncs.c
+++ b/src/backend/access/transam/xlogfuncs.c
@@ -183,8 +183,8 @@ pg_stop_backup_v2(PG_FUNCTION_ARGS)
 	Tuplestorestate *tupstore;
 	MemoryContext per_query_ctx;
 	MemoryContext oldcontext;
-	Datum		values[3];
-	bool		nulls[3];
+	Datum		values[3] = {0};
+	bool		nulls[3] = {0};
 
 	bool		exclusive = PG_GETARG_BOOL(0);
 	bool		waitforarchive = PG_GETARG_BOOL(1);
@@ -216,9 +216,6 @@ pg_stop_backup_v2(PG_FUNCTION_ARGS)
 
 	MemoryContextSwitchTo(oldcontext);
 
-	MemSet(values, 0, sizeof(values));
-	MemSet(nulls, 0, sizeof(nulls));
-
 	if (exclusive)
 	{
 		if (status == SESSION_BACKUP_NON_EXCLUSIVE)
diff --git a/src/backend/catalog/aclchk.c b/src/backend/catalog/aclchk.c
index 88ce37c..8a6b669 100644
--- a/src/backend/catalog/aclchk.c
+++ b/src/backend/catalog/aclchk.c
@@ -1158,9 +1158,9 @@ SetDefaultACL(InternalDefaultACL *iacls)
 	Acl		   *old_acl;
 	Acl		   *new_acl;
 	HeapTuple	newtuple;
-	Datum		values[Natts_pg_default_acl];
-	bool		nulls[Natts_pg_default_acl];
-	bool		replaces[Natts_pg_default_acl];
+	Datum		values[Natts_pg_default_acl] = {0};
+	bool		nulls[Natts_pg_default_acl] = {0};
+	bool		replaces[Natts_pg_default_acl] = {0};
 	int			noldmembers;
 	int			nnewmembers;
 	Oid		   *oldmembers;
@@ -1314,9 +1314,6 @@ SetDefaultACL(InternalDefaultACL *iacls)
 		Oid			defAclOid;
 
 		/* Prepare to insert or update pg_default_acl entry */
-		MemSet(values, 0, sizeof(values));
-		MemSet(nulls, false, sizeof(nulls));
-		MemSet(replaces, false, sizeof(replaces));
 
 		if (isNew)
 		{
@@ -1659,9 +1656,9 @@ ExecGrant_Attribute(InternalGrant *istmt, Oid relOid, const char *relname,
 	AclMode		avail_goptions;
 	bool		need_update;
 	HeapTuple	newtuple;
-	Datum		values[Natts_pg_attribute];
-	bool		nulls[Natts_pg_attribute];
-	bool		replaces[Natts_pg_attribute];
+	Datum		values[Natts_pg_attribute] = {0};
+	bool		nulls[Natts_pg_attribute] = {0};
+	bool		replaces[Natts_pg_attribute] = {0};
 	int			noldmembers;
 	int			nnewmembers;
 	Oid		   *oldmembers;
@@ -1742,9 +1739,6 @@ ExecGrant_Attribute(InternalGrant *istmt, Oid relOid, const char *relname,
 	nnewmembers = aclmembers(new_acl, &newmembers);
 
 	/* finished building new ACL value, now insert it */
-	MemSet(values, 0, sizeof(values));
-	MemSet(nulls, false, sizeof(nulls));
-	MemSet(replaces, false, sizeof(replaces));
 
 	/*
 	 * If the updated ACL is empty, we can set attacl to null, and maybe even
@@ -1972,9 +1966,9 @@ ExecGrant_Relation(InternalGrant *istmt)
 			Acl		   *new_acl;
 			Oid			grantorId;
 			HeapTuple	newtuple;
-			Datum		values[Natts_pg_class];
-			bool		nulls[Natts_pg_class];
-			bool		replaces[Natts_pg_class];
+			Datum		values[Natts_pg_class] = {0};
+			bool		nulls[Natts_pg_class] = {0};
+			bool		replaces[Natts_pg_class] = {0};
 			int			nnewmembers;
 			Oid		   *newmembers;
 			ObjectType	objtype;
@@ -2024,9 +2018,6 @@ ExecGrant_Relation(InternalGrant *istmt)
 			nnewmembers = aclmembers(new_acl, &newmembers);
 
 			/* finished building new ACL value, now insert it */
-			MemSet(values, 0, sizeof(values));
-			MemSet(nulls, false, sizeof(nulls));
-			MemSet(replaces, false, sizeof(replaces));
 
 			replaces[Anum_pg_class_relacl - 1] = true;
 			values[Anum_pg_class_relacl - 1] = PointerGetDatum(new_acl);
@@ -2147,9 +2138,9 @@ ExecGrant_Database(InternalGrant *istmt)
 		Oid			grantorId;
 		Oid			ownerId;
 		HeapTuple	newtuple;
-		Datum		values[Natts_pg_database];
-		bool		nulls[Natts_pg_database];
-		bool		replaces[Natts_pg_database];
+		Datum		values[Natts_pg_database] = {0};
+		bool		nulls[Natts_pg_database] = {0};
+		bool		replaces[Natts_pg_database] = {0};
 		int			noldmembers;
 		int			nnewmembers;
 		Oid		   *oldmembers;
@@ -2214,9 +2205,6 @@ ExecGrant_Database(InternalGrant *istmt)
 		nnewmembers = aclmembers(new_acl, &newmembers);
 
 		/* finished building new ACL value, now insert it */
-		MemSet(values, 0, sizeof(values));
-		MemSet(nulls, false, sizeof(nulls));
-		MemSet(replaces, false, sizeof(replaces));
 
 		replaces[Anum_pg_database_datacl - 1] = true;
 		values[Anum_pg_database_datacl - 1] = PointerGetDatum(new_acl);
@@ -2268,9 +2256,9 @@ ExecGrant_Fdw(InternalGrant *istmt)
 		Oid			ownerId;
 		HeapTuple	tuple;
 		HeapTuple	newtuple;
-		Datum		values[Natts_pg_foreign_data_wrapper];
-		bool		nulls[Natts_pg_foreign_data_wrapper];
-		bool		replaces[Natts_pg_foreign_data_wrapper];
+		Datum		values[Natts_pg_foreign_data_wrapper] = {0};
+		bool		nulls[Natts_pg_foreign_data_wrapper] = {0};
+		bool		replaces[Natts_pg_foreign_data_wrapper] = {0};
 		int			noldmembers;
 		int			nnewmembers;
 		Oid		   *oldmembers;
@@ -2336,9 +2324,6 @@ ExecGrant_Fdw(InternalGrant *istmt)
 		nnewmembers = aclmembers(new_acl, &newmembers);
 
 		/* finished building new ACL value, now insert it */
-		MemSet(values, 0, sizeof(values));
-		MemSet(nulls, false, sizeof(nulls));
-		MemSet(replaces, false, sizeof(replaces));
 
 		replaces[Anum_pg_foreign_data_wrapper_fdwacl - 1] = true;
 		values[Anum_pg_foreign_data_wrapper_fdwacl - 1] = PointerGetDatum(new_acl);
@@ -2395,9 +2380,9 @@ ExecGrant_ForeignServer(InternalGrant *istmt)
 		Oid			ownerId;
 		HeapTuple	tuple;
 		HeapTuple	newtuple;
-		Datum		values[Natts_pg_foreign_server];
-		bool		nulls[Natts_pg_foreign_server];
-		bool		replaces[Natts_pg_foreign_server];
+		Datum		values[Natts_pg_foreign_server] = {0};
+		bool		nulls[Natts_pg_foreign_server] = {0};
+		bool		replaces[Natts_pg_foreign_server] = {0};
 		int			noldmembers;
 		int			nnewmembers;
 		Oid		   *oldmembers;
@@ -2462,9 +2447,6 @@ ExecGrant_ForeignServer(InternalGrant *istmt)
 		nnewmembers = aclmembers(new_acl, &newmembers);
 
 		/* finished building new ACL value, now insert it */
-		MemSet(values, 0, sizeof(values));
-		MemSet(nulls, false, sizeof(nulls));
-		MemSet(replaces, false, sizeof(replaces));
 
 		replaces[Anum_pg_foreign_server_srvacl - 1] = true;
 		values[Anum_pg_foreign_server_srvacl - 1] = PointerGetDatum(new_acl);
@@ -2520,9 +2502,9 @@ ExecGrant_Function(InternalGrant *istmt)
 		Oid			ownerId;
 		HeapTuple	tuple;
 		HeapTuple	newtuple;
-		Datum		values[Natts_pg_proc];
-		bool		nulls[Natts_pg_proc];
-		bool		replaces[Natts_pg_proc];
+		Datum		values[Natts_pg_proc] = {0};
+		bool		nulls[Natts_pg_proc] = {0};
+		bool		replaces[Natts_pg_proc] = {0};
 		int			noldmembers;
 		int			nnewmembers;
 		Oid		   *oldmembers;
@@ -2586,9 +2568,6 @@ ExecGrant_Function(InternalGrant *istmt)
 		nnewmembers = aclmembers(new_acl, &newmembers);
 
 		/* finished building new ACL value, now insert it */
-		MemSet(values, 0, sizeof(values));
-		MemSet(nulls, false, sizeof(nulls));
-		MemSet(replaces, false, sizeof(replaces));
 
 		replaces[Anum_pg_proc_proacl - 1] = true;
 		values[Anum_pg_proc_proacl - 1] = PointerGetDatum(new_acl);
@@ -2643,9 +2622,9 @@ ExecGrant_Language(InternalGrant *istmt)
 		Oid			ownerId;
 		HeapTuple	tuple;
 		HeapTuple	newtuple;
-		Datum		values[Natts_pg_language];
-		bool		nulls[Natts_pg_language];
-		bool		replaces[Natts_pg_language];
+		Datum		values[Natts_pg_language] = {0};
+		bool		nulls[Natts_pg_language] = {0};
+		bool		replaces[Natts_pg_language] = {0};
 		int			noldmembers;
 		int			nnewmembers;
 		Oid		   *oldmembers;
@@ -2717,9 +2696,6 @@ ExecGrant_Language(InternalGrant *istmt)
 		nnewmembers = aclmembers(new_acl, &newmembers);
 
 		/* finished building new ACL value, now insert it */
-		MemSet(values, 0, sizeof(values));
-		MemSet(nulls, false, sizeof(nulls));
-		MemSet(replaces, false, sizeof(replaces));
 
 		replaces[Anum_pg_language_lanacl - 1] = true;
 		values[Anum_pg_language_lanacl - 1] = PointerGetDatum(new_acl);
@@ -2775,9 +2751,9 @@ ExecGrant_Largeobject(InternalGrant *istmt)
 		Oid			grantorId;
 		Oid			ownerId;
 		HeapTuple	newtuple;
-		Datum		values[Natts_pg_largeobject_metadata];
-		bool		nulls[Natts_pg_largeobject_metadata];
-		bool		replaces[Natts_pg_largeobject_metadata];
+		Datum		values[Natts_pg_largeobject_metadata] = {0};
+		bool		nulls[Natts_pg_largeobject_metadata] = {0};
+		bool		replaces[Natts_pg_largeobject_metadata] = {0};
 		int			noldmembers;
 		int			nnewmembers;
 		Oid		   *oldmembers;
@@ -2855,9 +2831,6 @@ ExecGrant_Largeobject(InternalGrant *istmt)
 		nnewmembers = aclmembers(new_acl, &newmembers);
 
 		/* finished building new ACL value, now insert it */
-		MemSet(values, 0, sizeof(values));
-		MemSet(nulls, false, sizeof(nulls));
-		MemSet(replaces, false, sizeof(replaces));
 
 		replaces[Anum_pg_largeobject_metadata_lomacl - 1] = true;
 		values[Anum_pg_largeobject_metadata_lomacl - 1]
@@ -2914,9 +2887,9 @@ ExecGrant_Namespace(InternalGrant *istmt)
 		Oid			ownerId;
 		HeapTuple	tuple;
 		HeapTuple	newtuple;
-		Datum		values[Natts_pg_namespace];
-		bool		nulls[Natts_pg_namespace];
-		bool		replaces[Natts_pg_namespace];
+		Datum		values[Natts_pg_namespace] = {0};
+		bool		nulls[Natts_pg_namespace] = {0};
+		bool		replaces[Natts_pg_namespace] = {0};
 		int			noldmembers;
 		int			nnewmembers;
 		Oid		   *oldmembers;
@@ -2981,9 +2954,6 @@ ExecGrant_Namespace(InternalGrant *istmt)
 		nnewmembers = aclmembers(new_acl, &newmembers);
 
 		/* finished building new ACL value, now insert it */
-		MemSet(values, 0, sizeof(values));
-		MemSet(nulls, false, sizeof(nulls));
-		MemSet(replaces, false, sizeof(replaces));
 
 		replaces[Anum_pg_namespace_nspacl - 1] = true;
 		values[Anum_pg_namespace_nspacl - 1] = PointerGetDatum(new_acl);
@@ -3037,9 +3007,9 @@ ExecGrant_Tablespace(InternalGrant *istmt)
 		Oid			grantorId;
 		Oid			ownerId;
 		HeapTuple	newtuple;
-		Datum		values[Natts_pg_tablespace];
-		bool		nulls[Natts_pg_tablespace];
-		bool		replaces[Natts_pg_tablespace];
+		Datum		values[Natts_pg_tablespace] = {0};
+		bool		nulls[Natts_pg_tablespace] = {0};
+		bool		replaces[Natts_pg_tablespace] = {0};
 		int			noldmembers;
 		int			nnewmembers;
 		Oid		   *oldmembers;
@@ -3105,9 +3075,6 @@ ExecGrant_Tablespace(InternalGrant *istmt)
 		nnewmembers = aclmembers(new_acl, &newmembers);
 
 		/* finished building new ACL value, now insert it */
-		MemSet(values, 0, sizeof(values));
-		MemSet(nulls, false, sizeof(nulls));
-		MemSet(replaces, false, sizeof(replaces));
 
 		replaces[Anum_pg_tablespace_spcacl - 1] = true;
 		values[Anum_pg_tablespace_spcacl - 1] = PointerGetDatum(new_acl);
@@ -3157,9 +3124,9 @@ ExecGrant_Type(InternalGrant *istmt)
 		Oid			grantorId;
 		Oid			ownerId;
 		HeapTuple	newtuple;
-		Datum		values[Natts_pg_type];
-		bool		nulls[Natts_pg_type];
-		bool		replaces[Natts_pg_type];
+		Datum		values[Natts_pg_type] = {0};
+		bool		nulls[Natts_pg_type] = {0};
+		bool		replaces[Natts_pg_type] = {0};
 		int			noldmembers;
 		int			nnewmembers;
 		Oid		   *oldmembers;
@@ -3239,9 +3206,6 @@ ExecGrant_Type(InternalGrant *istmt)
 		nnewmembers = aclmembers(new_acl, &newmembers);
 
 		/* finished building new ACL value, now insert it */
-		MemSet(values, 0, sizeof(values));
-		MemSet(nulls, false, sizeof(nulls));
-		MemSet(replaces, false, sizeof(replaces));
 
 		replaces[Anum_pg_type_typacl - 1] = true;
 		values[Anum_pg_type_typacl - 1] = PointerGetDatum(new_acl);
@@ -5992,17 +5956,13 @@ recordExtensionInitPrivWorker(Oid objoid, Oid classoid, int objsubid, Acl *new_a
 	/* If we find an entry, update it with the latest ACL. */
 	if (HeapTupleIsValid(oldtuple))
 	{
-		Datum		values[Natts_pg_init_privs];
-		bool		nulls[Natts_pg_init_privs];
-		bool		replace[Natts_pg_init_privs];
+		Datum		values[Natts_pg_init_privs] = {0};
+		bool		nulls[Natts_pg_init_privs] = {0};
+		bool		replace[Natts_pg_init_privs] = {0};
 
 		/* If we have a new ACL to set, then update the row with it. */
 		if (new_acl)
 		{
-			MemSet(values, 0, sizeof(values));
-			MemSet(nulls, false, sizeof(nulls));
-			MemSet(replace, false, sizeof(replace));
-
 			values[Anum_pg_init_privs_initprivs - 1] = PointerGetDatum(new_acl);
 			replace[Anum_pg_init_privs_initprivs - 1] = true;
 
@@ -6020,7 +5980,7 @@ recordExtensionInitPrivWorker(Oid objoid, Oid classoid, int objsubid, Acl *new_a
 	else
 	{
 		Datum		values[Natts_pg_init_privs];
-		bool		nulls[Natts_pg_init_privs];
+		bool		nulls[Natts_pg_init_privs] = {0};
 
 		/*
 		 * Only add a new entry if the new ACL is non-NULL.
@@ -6031,8 +5991,6 @@ recordExtensionInitPrivWorker(Oid objoid, Oid classoid, int objsubid, Acl *new_a
 		if (new_acl)
 		{
 			/* No entry found, so add it. */
-			MemSet(nulls, false, sizeof(nulls));
-
 			values[Anum_pg_init_privs_objoid - 1] = ObjectIdGetDatum(objoid);
 			values[Anum_pg_init_privs_classoid - 1] = ObjectIdGetDatum(classoid);
 			values[Anum_pg_init_privs_objsubid - 1] = Int32GetDatum(objsubid);
diff --git a/src/backend/catalog/heap.c b/src/backend/catalog/heap.c
index b7bcdd9..235bc4e 100644
--- a/src/backend/catalog/heap.c
+++ b/src/backend/catalog/heap.c
@@ -695,14 +695,10 @@ InsertPgAttributeTuple(Relation pg_attribute_rel,
 					   Form_pg_attribute new_attribute,
 					   CatalogIndexState indstate)
 {
-	Datum		values[Natts_pg_attribute];
-	bool		nulls[Natts_pg_attribute];
+	Datum		values[Natts_pg_attribute] = {0};
+	bool		nulls[Natts_pg_attribute] = {0};
 	HeapTuple	tup;
 
-	/* This is a tad tedious, but way cleaner than what we used to do... */
-	memset(values, 0, sizeof(values));
-	memset(nulls, false, sizeof(nulls));
-
 	values[Anum_pg_attribute_attrelid - 1] = ObjectIdGetDatum(new_attribute->attrelid);
 	values[Anum_pg_attribute_attname - 1] = NameGetDatum(&new_attribute->attname);
 	values[Anum_pg_attribute_atttypid - 1] = ObjectIdGetDatum(new_attribute->atttypid);
@@ -852,14 +848,10 @@ InsertPgClassTuple(Relation pg_class_desc,
 				   Datum reloptions)
 {
 	Form_pg_class rd_rel = new_rel_desc->rd_rel;
-	Datum		values[Natts_pg_class];
-	bool		nulls[Natts_pg_class];
+	Datum		values[Natts_pg_class] = {0};
+	bool		nulls[Natts_pg_class] = {0};
 	HeapTuple	tup;
 
-	/* This is a tad tedious, but way cleaner than what we used to do... */
-	memset(values, 0, sizeof(values));
-	memset(nulls, false, sizeof(nulls));
-
 	values[Anum_pg_class_oid - 1] = ObjectIdGetDatum(new_rel_oid);
 	values[Anum_pg_class_relname - 1] = NameGetDatum(&rd_rel->relname);
 	values[Anum_pg_class_relnamespace - 1] = ObjectIdGetDatum(rd_rel->relnamespace);
@@ -1645,14 +1637,11 @@ RemoveAttributeById(Oid relid, AttrNumber attnum)
 		/* clear the missing value if any */
 		if (attStruct->atthasmissing)
 		{
-			Datum		valuesAtt[Natts_pg_attribute];
-			bool		nullsAtt[Natts_pg_attribute];
-			bool		replacesAtt[Natts_pg_attribute];
+			Datum		valuesAtt[Natts_pg_attribute] = {0};
+			bool		nullsAtt[Natts_pg_attribute] = {0};
+			bool		replacesAtt[Natts_pg_attribute] = {0};
 
 			/* update the tuple - set atthasmissing and attmissingval */
-			MemSet(valuesAtt, 0, sizeof(valuesAtt));
-			MemSet(nullsAtt, false, sizeof(nullsAtt));
-			MemSet(replacesAtt, false, sizeof(replacesAtt));
 
 			valuesAtt[Anum_pg_attribute_atthasmissing - 1] =
 				BoolGetDatum(false);
@@ -2064,9 +2053,9 @@ RelationClearMissing(Relation rel)
 void
 SetAttrMissing(Oid relid, char *attname, char *value)
 {
-	Datum		valuesAtt[Natts_pg_attribute];
-	bool		nullsAtt[Natts_pg_attribute];
-	bool		replacesAtt[Natts_pg_attribute];
+	Datum		valuesAtt[Natts_pg_attribute] = {0};
+	bool		nullsAtt[Natts_pg_attribute] = {0};
+	bool		replacesAtt[Natts_pg_attribute] = {0};
 	Datum		missingval;
 	Form_pg_attribute attStruct;
 	Relation	attrrel,
@@ -2092,10 +2081,7 @@ SetAttrMissing(Oid relid, char *attname, char *value)
 								  Int32GetDatum(attStruct->atttypmod));
 
 	/* update the tuple - set atthasmissing and attmissingval */
-	MemSet(valuesAtt, 0, sizeof(valuesAtt));
-	MemSet(nullsAtt, false, sizeof(nullsAtt));
-	MemSet(replacesAtt, false, sizeof(replacesAtt));
-
+	
 	valuesAtt[Anum_pg_attribute_atthasmissing - 1] = BoolGetDatum(true);
 	replacesAtt[Anum_pg_attribute_atthasmissing - 1] = true;
 	valuesAtt[Anum_pg_attribute_attmissingval - 1] = missingval;
@@ -2191,15 +2177,12 @@ StoreAttrDefault(Relation rel, AttrNumber attnum,
 		Expr	   *expr2 = (Expr *) expr;
 		EState	   *estate = NULL;
 		ExprContext *econtext;
-		Datum		valuesAtt[Natts_pg_attribute];
-		bool		nullsAtt[Natts_pg_attribute];
-		bool		replacesAtt[Natts_pg_attribute];
+		Datum		valuesAtt[Natts_pg_attribute] = {0};
+		bool		nullsAtt[Natts_pg_attribute] = {0};
+		bool		replacesAtt[Natts_pg_attribute] = {0};
 		Datum		missingval = (Datum) 0;
 		bool		missingIsNull = true;
 
-		MemSet(valuesAtt, 0, sizeof(valuesAtt));
-		MemSet(nullsAtt, false, sizeof(nullsAtt));
-		MemSet(replacesAtt, false, sizeof(replacesAtt));
 		valuesAtt[Anum_pg_attribute_atthasdef - 1] = true;
 		replacesAtt[Anum_pg_attribute_atthasdef - 1] = true;
 
@@ -3419,7 +3402,7 @@ StorePartitionKey(Relation rel,
 	Relation	pg_partitioned_table;
 	HeapTuple	tuple;
 	Datum		values[Natts_pg_partitioned_table];
-	bool		nulls[Natts_pg_partitioned_table];
+	bool		nulls[Natts_pg_partitioned_table] = {0};
 	ObjectAddress myself;
 	ObjectAddress referenced;
 
@@ -3444,8 +3427,6 @@ StorePartitionKey(Relation rel,
 
 	pg_partitioned_table = table_open(PartitionedRelationId, RowExclusiveLock);
 
-	MemSet(nulls, false, sizeof(nulls));
-
 	/* Only this can ever be NULL */
 	if (!partexprDatum)
 		nulls[Anum_pg_partitioned_table_partexprs - 1] = true;
diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c
index 098732c..b138fbe 100644
--- a/src/backend/catalog/index.c
+++ b/src/backend/catalog/index.c
@@ -546,7 +546,7 @@ UpdateIndexRelation(Oid indexoid,
 	Datum		exprsDatum;
 	Datum		predDatum;
 	Datum		values[Natts_pg_index];
-	bool		nulls[Natts_pg_index];
+	bool		nulls[Natts_pg_index] = {0};
 	Relation	pg_index;
 	HeapTuple	tuple;
 	int			i;
@@ -599,7 +599,6 @@ UpdateIndexRelation(Oid indexoid,
 	/*
 	 * Build a pg_index tuple
 	 */
-	MemSet(nulls, false, sizeof(nulls));
 
 	values[Anum_pg_index_indexrelid - 1] = ObjectIdGetDatum(indexoid);
 	values[Anum_pg_index_indrelid - 1] = ObjectIdGetDatum(heapoid);
diff --git a/src/backend/catalog/pg_collation.c b/src/backend/catalog/pg_collation.c
index dd99d53..54840de 100644
--- a/src/backend/catalog/pg_collation.c
+++ b/src/backend/catalog/pg_collation.c
@@ -57,7 +57,7 @@ CollationCreate(const char *collname, Oid collnamespace,
 	TupleDesc	tupDesc;
 	HeapTuple	tup;
 	Datum		values[Natts_pg_collation];
-	bool		nulls[Natts_pg_collation];
+	bool		nulls[Natts_pg_collation] = {0};
 	NameData	name_name,
 				name_collate,
 				name_ctype;
@@ -151,7 +151,6 @@ CollationCreate(const char *collname, Oid collnamespace,
 	tupDesc = RelationGetDescr(rel);
 
 	/* form a tuple */
-	memset(nulls, 0, sizeof(nulls));
 
 	namestrcpy(&name_name, collname);
 	oid = GetNewOidWithIndex(rel, CollationOidIndexId,
diff --git a/src/backend/catalog/pg_db_role_setting.c b/src/backend/catalog/pg_db_role_setting.c
index 20acac2..2632de9 100644
--- a/src/backend/catalog/pg_db_role_setting.c
+++ b/src/backend/catalog/pg_db_role_setting.c
@@ -136,11 +136,9 @@ AlterSetting(Oid databaseid, Oid roleid, VariableSetStmt *setstmt)
 		/* non-null valuestr means it's not RESET, so insert a new tuple */
 		HeapTuple	newtuple;
 		Datum		values[Natts_pg_db_role_setting];
-		bool		nulls[Natts_pg_db_role_setting];
+		bool		nulls[Natts_pg_db_role_setting] = {0};
 		ArrayType  *a;
 
-		memset(nulls, false, sizeof(nulls));
-
 		a = GUCArrayAdd(NULL, setstmt->name, valuestr);
 
 		values[Anum_pg_db_role_setting_setdatabase - 1] =
diff --git a/src/backend/catalog/pg_depend.c b/src/backend/catalog/pg_depend.c
index a060c25..c78fd38 100644
--- a/src/backend/catalog/pg_depend.c
+++ b/src/backend/catalog/pg_depend.c
@@ -61,7 +61,7 @@ recordMultipleDependencies(const ObjectAddress *depender,
 	CatalogIndexState indstate;
 	HeapTuple	tup;
 	int			i;
-	bool		nulls[Natts_pg_depend];
+	bool		nulls[Natts_pg_depend] = {0};
 	Datum		values[Natts_pg_depend];
 
 	if (nreferenced <= 0)
@@ -79,8 +79,6 @@ recordMultipleDependencies(const ObjectAddress *depender,
 	/* Don't open indexes unless we need to make an update */
 	indstate = NULL;
 
-	memset(nulls, false, sizeof(nulls));
-
 	for (i = 0; i < nreferenced; i++, referenced++)
 	{
 		/*
diff --git a/src/backend/catalog/pg_enum.c b/src/backend/catalog/pg_enum.c
index d0ff802..0ae47dd 100644
--- a/src/backend/catalog/pg_enum.c
+++ b/src/backend/catalog/pg_enum.c
@@ -66,7 +66,7 @@ EnumValuesCreate(Oid enumTypeOid, List *vals)
 	int			elemno,
 				num_elems;
 	Datum		values[Natts_pg_enum];
-	bool		nulls[Natts_pg_enum];
+	bool		nulls[Natts_pg_enum] = {0};
 	ListCell   *lc;
 	HeapTuple	tup;
 
@@ -111,8 +111,6 @@ EnumValuesCreate(Oid enumTypeOid, List *vals)
 	qsort(oids, num_elems, sizeof(Oid), oid_cmp);
 
 	/* and make the entries */
-	memset(nulls, false, sizeof(nulls));
-
 	elemno = 0;
 	foreach(lc, vals)
 	{
@@ -215,7 +213,7 @@ AddEnumLabel(Oid enumTypeOid,
 	Relation	pg_enum;
 	Oid			newOid;
 	Datum		values[Natts_pg_enum];
-	bool		nulls[Natts_pg_enum];
+	bool		nulls[Natts_pg_enum] = {0};
 	NameData	enumlabel;
 	HeapTuple	enum_tup;
 	float4		newelemorder;
@@ -480,7 +478,6 @@ restart:
 	ReleaseCatCacheList(list);
 
 	/* Create the new pg_enum entry */
-	memset(nulls, false, sizeof(nulls));
 	values[Anum_pg_enum_oid - 1] = ObjectIdGetDatum(newOid);
 	values[Anum_pg_enum_enumtypid - 1] = ObjectIdGetDatum(enumTypeOid);
 	values[Anum_pg_enum_enumsortorder - 1] = Float4GetDatum(newelemorder);
diff --git a/src/backend/catalog/pg_inherits.c b/src/backend/catalog/pg_inherits.c
index 59af162..e71e442 100644
--- a/src/backend/catalog/pg_inherits.c
+++ b/src/backend/catalog/pg_inherits.c
@@ -417,7 +417,7 @@ void
 StoreSingleInheritance(Oid relationId, Oid parentOid, int32 seqNumber)
 {
 	Datum		values[Natts_pg_inherits];
-	bool		nulls[Natts_pg_inherits];
+	bool		nulls[Natts_pg_inherits] = {0};
 	HeapTuple	tuple;
 	Relation	inhRelation;
 
@@ -430,8 +430,6 @@ StoreSingleInheritance(Oid relationId, Oid parentOid, int32 seqNumber)
 	values[Anum_pg_inherits_inhparent - 1] = ObjectIdGetDatum(parentOid);
 	values[Anum_pg_inherits_inhseqno - 1] = Int32GetDatum(seqNumber);
 
-	memset(nulls, 0, sizeof(nulls));
-
 	tuple = heap_form_tuple(RelationGetDescr(inhRelation), values, nulls);
 
 	CatalogTupleInsert(inhRelation, tuple);
diff --git a/src/backend/catalog/pg_largeobject.c b/src/backend/catalog/pg_largeobject.c
index 1a68702..ef8afb0 100644
--- a/src/backend/catalog/pg_largeobject.c
+++ b/src/backend/catalog/pg_largeobject.c
@@ -42,8 +42,8 @@ LargeObjectCreate(Oid loid)
 	Relation	pg_lo_meta;
 	HeapTuple	ntup;
 	Oid			loid_new;
-	Datum		values[Natts_pg_largeobject_metadata];
-	bool		nulls[Natts_pg_largeobject_metadata];
+	Datum		values[Natts_pg_largeobject_metadata] = {0};
+	bool		nulls[Natts_pg_largeobject_metadata] = {0};
 
 	pg_lo_meta = table_open(LargeObjectMetadataRelationId,
 							RowExclusiveLock);
@@ -51,8 +51,6 @@ LargeObjectCreate(Oid loid)
 	/*
 	 * Insert metadata of the largeobject
 	 */
-	memset(values, 0, sizeof(values));
-	memset(nulls, false, sizeof(nulls));
 
 	if (OidIsValid(loid))
 		loid_new = loid;
diff --git a/src/backend/catalog/pg_publication.c b/src/backend/catalog/pg_publication.c
index fd5da7d..6e996f9 100644
--- a/src/backend/catalog/pg_publication.c
+++ b/src/backend/catalog/pg_publication.c
@@ -154,8 +154,8 @@ publication_add_relation(Oid pubid, Relation targetrel,
 {
 	Relation	rel;
 	HeapTuple	tup;
-	Datum		values[Natts_pg_publication_rel];
-	bool		nulls[Natts_pg_publication_rel];
+	Datum		values[Natts_pg_publication_rel] = {0};
+	bool		nulls[Natts_pg_publication_rel] = {0};
 	Oid			relid = RelationGetRelid(targetrel);
 	Oid			prrelid;
 	Publication *pub = GetPublication(pubid);
@@ -186,8 +186,6 @@ publication_add_relation(Oid pubid, Relation targetrel,
 	check_publication_add_relation(targetrel);
 
 	/* Form a tuple. */
-	memset(values, 0, sizeof(values));
-	memset(nulls, false, sizeof(nulls));
 
 	prrelid = GetNewOidWithIndex(rel, PublicationRelObjectIndexId,
 								 Anum_pg_publication_rel_oid);
diff --git a/src/backend/catalog/pg_range.c b/src/backend/catalog/pg_range.c
index e6e138b..fe46639 100644
--- a/src/backend/catalog/pg_range.c
+++ b/src/backend/catalog/pg_range.c
@@ -39,15 +39,13 @@ RangeCreate(Oid rangeTypeOid, Oid rangeSubType, Oid rangeCollation,
 {
 	Relation	pg_range;
 	Datum		values[Natts_pg_range];
-	bool		nulls[Natts_pg_range];
+	bool		nulls[Natts_pg_range] = {0};
 	HeapTuple	tup;
 	ObjectAddress myself;
 	ObjectAddress referenced;
 
 	pg_range = table_open(RangeRelationId, RowExclusiveLock);
 
-	memset(nulls, 0, sizeof(nulls));
-
 	values[Anum_pg_range_rngtypid - 1] = ObjectIdGetDatum(rangeTypeOid);
 	values[Anum_pg_range_rngsubtype - 1] = ObjectIdGetDatum(rangeSubType);
 	values[Anum_pg_range_rngcollation - 1] = ObjectIdGetDatum(rangeCollation);
diff --git a/src/backend/catalog/pg_shdepend.c b/src/backend/catalog/pg_shdepend.c
index fb7f8dd..34c39b3 100644
--- a/src/backend/catalog/pg_shdepend.c
+++ b/src/backend/catalog/pg_shdepend.c
@@ -273,9 +273,7 @@ shdepChangeDep(Relation sdepRel,
 	{
 		/* Need to insert new entry */
 		Datum		values[Natts_pg_shdepend];
-		bool		nulls[Natts_pg_shdepend];
-
-		memset(nulls, false, sizeof(nulls));
+		bool		nulls[Natts_pg_shdepend] = {0};
 
 		values[Anum_pg_shdepend_dbid - 1] = ObjectIdGetDatum(dbid);
 		values[Anum_pg_shdepend_classid - 1] = ObjectIdGetDatum(classid);
@@ -801,9 +799,9 @@ copyTemplateDependencies(Oid templateDbId, Oid newDbId)
 	SysScanDesc scan;
 	HeapTuple	tup;
 	CatalogIndexState indstate;
-	Datum		values[Natts_pg_shdepend];
-	bool		nulls[Natts_pg_shdepend];
-	bool		replace[Natts_pg_shdepend];
+	Datum		values[Natts_pg_shdepend] = {0};
+	bool		nulls[Natts_pg_shdepend] = {0};
+	bool		replace[Natts_pg_shdepend] = {0};
 
 	sdepRel = table_open(SharedDependRelationId, RowExclusiveLock);
 	sdepDesc = RelationGetDescr(sdepRel);
@@ -820,10 +818,6 @@ copyTemplateDependencies(Oid templateDbId, Oid newDbId)
 							  NULL, 1, key);
 
 	/* Set up to copy the tuples except for inserting newDbId */
-	memset(values, 0, sizeof(values));
-	memset(nulls, false, sizeof(nulls));
-	memset(replace, false, sizeof(replace));
-
 	replace[Anum_pg_shdepend_dbid - 1] = true;
 	values[Anum_pg_shdepend_dbid - 1] = ObjectIdGetDatum(newDbId);
 
@@ -934,7 +928,7 @@ shdepAddDependency(Relation sdepRel,
 {
 	HeapTuple	tup;
 	Datum		values[Natts_pg_shdepend];
-	bool		nulls[Natts_pg_shdepend];
+	bool		nulls[Natts_pg_shdepend] = {0};
 
 	/*
 	 * Make sure the object doesn't go away while we record the dependency on
@@ -943,8 +937,6 @@ shdepAddDependency(Relation sdepRel,
 	 */
 	shdepLockAndCheckObject(refclassId, refobjId);
 
-	memset(nulls, false, sizeof(nulls));
-
 	/*
 	 * Form the new tuple and record the dependency.
 	 */
diff --git a/src/backend/catalog/pg_subscription.c b/src/backend/catalog/pg_subscription.c
index afee283..e3b9261 100644
--- a/src/backend/catalog/pg_subscription.c
+++ b/src/backend/catalog/pg_subscription.c
@@ -243,8 +243,8 @@ AddSubscriptionRelState(Oid subid, Oid relid, char state,
 {
 	Relation	rel;
 	HeapTuple	tup;
-	bool		nulls[Natts_pg_subscription_rel];
-	Datum		values[Natts_pg_subscription_rel];
+	bool		nulls[Natts_pg_subscription_rel] = {0};
+	Datum		values[Natts_pg_subscription_rel] = {0};
 
 	LockSharedObject(SubscriptionRelationId, subid, 0, AccessShareLock);
 
@@ -259,8 +259,6 @@ AddSubscriptionRelState(Oid subid, Oid relid, char state,
 			 relid, subid);
 
 	/* Form the tuple. */
-	memset(values, 0, sizeof(values));
-	memset(nulls, false, sizeof(nulls));
 	values[Anum_pg_subscription_rel_srsubid - 1] = ObjectIdGetDatum(subid);
 	values[Anum_pg_subscription_rel_srrelid - 1] = ObjectIdGetDatum(relid);
 	values[Anum_pg_subscription_rel_srsubstate - 1] = CharGetDatum(state);
@@ -289,9 +287,9 @@ UpdateSubscriptionRelState(Oid subid, Oid relid, char state,
 {
 	Relation	rel;
 	HeapTuple	tup;
-	bool		nulls[Natts_pg_subscription_rel];
-	Datum		values[Natts_pg_subscription_rel];
-	bool		replaces[Natts_pg_subscription_rel];
+	bool		nulls[Natts_pg_subscription_rel] = {0};
+	Datum		values[Natts_pg_subscription_rel] = {0};
+	bool		replaces[Natts_pg_subscription_rel] = {0};
 
 	LockSharedObject(SubscriptionRelationId, subid, 0, AccessShareLock);
 
@@ -306,10 +304,6 @@ UpdateSubscriptionRelState(Oid subid, Oid relid, char state,
 			 relid, subid);
 
 	/* Update the tuple. */
-	memset(values, 0, sizeof(values));
-	memset(nulls, false, sizeof(nulls));
-	memset(replaces, false, sizeof(replaces));
-
 	replaces[Anum_pg_subscription_rel_srsubstate - 1] = true;
 	values[Anum_pg_subscription_rel_srsubstate - 1] = CharGetDatum(state);
 
diff --git a/src/backend/commands/amcmds.c b/src/backend/commands/amcmds.c
index c0e4098..d4e0b1c 100644
--- a/src/backend/commands/amcmds.c
+++ b/src/backend/commands/amcmds.c
@@ -46,8 +46,8 @@ CreateAccessMethod(CreateAmStmt *stmt)
 	ObjectAddress referenced;
 	Oid			amoid;
 	Oid			amhandler;
-	bool		nulls[Natts_pg_am];
-	Datum		values[Natts_pg_am];
+	bool		nulls[Natts_pg_am] = {0};
+	Datum		values[Natts_pg_am] = {0};
 	HeapTuple	tup;
 
 	rel = table_open(AccessMethodRelationId, RowExclusiveLock);
@@ -79,9 +79,6 @@ CreateAccessMethod(CreateAmStmt *stmt)
 	/*
 	 * Insert tuple into pg_am.
 	 */
-	memset(values, 0, sizeof(values));
-	memset(nulls, false, sizeof(nulls));
-
 	amoid = GetNewOidWithIndex(rel, AmOidIndexId, Anum_pg_am_oid);
 	values[Anum_pg_am_oid - 1] = ObjectIdGetDatum(amoid);
 	values[Anum_pg_am_amname - 1] =
diff --git a/src/backend/commands/collationcmds.c b/src/backend/commands/collationcmds.c
index 919e092..8047ee6 100644
--- a/src/backend/commands/collationcmds.c
+++ b/src/backend/commands/collationcmds.c
@@ -315,18 +315,14 @@ AlterCollation(AlterCollationStmt *stmt)
 		elog(ERROR, "invalid collation version change");
 	else if (oldversion && newversion && strcmp(newversion, oldversion) != 0)
 	{
-		bool		nulls[Natts_pg_collation];
-		bool		replaces[Natts_pg_collation];
-		Datum		values[Natts_pg_collation];
+		bool		nulls[Natts_pg_collation] = {0};
+		bool		replaces[Natts_pg_collation] = {0};
+		Datum		values[Natts_pg_collation] = {0};
 
 		ereport(NOTICE,
 				(errmsg("changing version from %s to %s",
 						oldversion, newversion)));
 
-		memset(values, 0, sizeof(values));
-		memset(nulls, false, sizeof(nulls));
-		memset(replaces, false, sizeof(replaces));
-
 		values[Anum_pg_collation_collversion - 1] = CStringGetTextDatum(newversion);
 		replaces[Anum_pg_collation_collversion - 1] = true;
 
diff --git a/src/backend/commands/event_trigger.c b/src/backend/commands/event_trigger.c
index f7ee983..54e1122 100644
--- a/src/backend/commands/event_trigger.c
+++ b/src/backend/commands/event_trigger.c
@@ -381,7 +381,7 @@ insert_event_trigger_tuple(const char *trigname, const char *eventname, Oid evtO
 	Oid			trigoid;
 	HeapTuple	tuple;
 	Datum		values[Natts_pg_trigger];
-	bool		nulls[Natts_pg_trigger];
+	bool		nulls[Natts_pg_trigger] = {0};
 	NameData	evtnamedata,
 				evteventdata;
 	ObjectAddress myself,
@@ -394,7 +394,6 @@ insert_event_trigger_tuple(const char *trigname, const char *eventname, Oid evtO
 	trigoid = GetNewOidWithIndex(tgrel, EventTriggerOidIndexId,
 								 Anum_pg_event_trigger_oid);
 	values[Anum_pg_event_trigger_oid - 1] = ObjectIdGetDatum(trigoid);
-	memset(nulls, false, sizeof(nulls));
 	namestrcpy(&evtnamedata, trigname);
 	values[Anum_pg_event_trigger_evtname - 1] = NameGetDatum(&evtnamedata);
 	namestrcpy(&evteventdata, eventname);
@@ -1494,14 +1493,11 @@ pg_event_trigger_dropped_objects(PG_FUNCTION_ARGS)
 	{
 		SQLDropObject *obj;
 		int			i = 0;
-		Datum		values[12];
-		bool		nulls[12];
+		Datum		values[12] = {0};
+		bool		nulls[12] = {0};
 
 		obj = slist_container(SQLDropObject, next, iter.cur);
 
-		MemSet(values, 0, sizeof(values));
-		MemSet(nulls, 0, sizeof(nulls));
-
 		/* classid */
 		values[i++] = ObjectIdGetDatum(obj->address.classId);
 
@@ -2046,7 +2042,7 @@ pg_event_trigger_ddl_commands(PG_FUNCTION_ARGS)
 	{
 		CollectedCommand *cmd = lfirst(lc);
 		Datum		values[9];
-		bool		nulls[9];
+		bool		nulls[9] = {0};
 		ObjectAddress addr;
 		int			i = 0;
 
@@ -2064,8 +2060,6 @@ pg_event_trigger_ddl_commands(PG_FUNCTION_ARGS)
 			!OidIsValid(cmd->d.simple.address.objectId))
 			continue;
 
-		MemSet(nulls, 0, sizeof(nulls));
-
 		switch (cmd->type)
 		{
 			case SCT_Simple:
diff --git a/src/backend/commands/extension.c b/src/backend/commands/extension.c
index f7202cc..8e343fd 100644
--- a/src/backend/commands/extension.c
+++ b/src/backend/commands/extension.c
@@ -1771,8 +1771,8 @@ InsertExtensionTuple(const char *extName, Oid extOwner,
 {
 	Oid			extensionOid;
 	Relation	rel;
-	Datum		values[Natts_pg_extension];
-	bool		nulls[Natts_pg_extension];
+	Datum		values[Natts_pg_extension] = {0};
+	bool		nulls[Natts_pg_extension] = {0};
 	HeapTuple	tuple;
 	ObjectAddress myself;
 	ObjectAddress nsp;
@@ -1783,9 +1783,6 @@ InsertExtensionTuple(const char *extName, Oid extOwner,
 	 */
 	rel = table_open(ExtensionRelationId, RowExclusiveLock);
 
-	memset(values, 0, sizeof(values));
-	memset(nulls, 0, sizeof(nulls));
-
 	extensionOid = GetNewOidWithIndex(rel, ExtensionOidIndexId,
 									  Anum_pg_extension_oid);
 	values[Anum_pg_extension_oid - 1] = ObjectIdGetDatum(extensionOid);
@@ -1960,8 +1957,8 @@ pg_available_extensions(PG_FUNCTION_ARGS)
 		{
 			ExtensionControlFile *control;
 			char	   *extname;
-			Datum		values[3];
-			bool		nulls[3];
+			Datum		values[3] = {0};
+			bool		nulls[3] = {0};
 
 			if (!is_extension_control_filename(de->d_name))
 				continue;
@@ -1976,9 +1973,6 @@ pg_available_extensions(PG_FUNCTION_ARGS)
 
 			control = read_extension_control_file(extname);
 
-			memset(values, 0, sizeof(values));
-			memset(nulls, 0, sizeof(nulls));
-
 			/* name */
 			values[0] = DirectFunctionCall1(namein,
 											CStringGetDatum(control->name));
@@ -2117,8 +2111,8 @@ get_available_versions_for_extension(ExtensionControlFile *pcontrol,
 	{
 		ExtensionVersionInfo *evi = (ExtensionVersionInfo *) lfirst(lc);
 		ExtensionControlFile *control;
-		Datum		values[7];
-		bool		nulls[7];
+		Datum		values[7] = {0};
+		bool		nulls[7] = {0};
 		ListCell   *lc2;
 
 		if (!evi->installable)
@@ -2129,9 +2123,6 @@ get_available_versions_for_extension(ExtensionControlFile *pcontrol,
 		 */
 		control = read_extension_aux_control_file(pcontrol, evi->name);
 
-		memset(values, 0, sizeof(values));
-		memset(nulls, 0, sizeof(nulls));
-
 		/* name */
 		values[0] = DirectFunctionCall1(namein,
 										CStringGetDatum(control->name));
@@ -2292,8 +2283,8 @@ pg_extension_update_paths(PG_FUNCTION_ARGS)
 		{
 			ExtensionVersionInfo *evi2 = (ExtensionVersionInfo *) lfirst(lc2);
 			List	   *path;
-			Datum		values[3];
-			bool		nulls[3];
+			Datum		values[3] = {0};
+			bool		nulls[3] = {0};
 
 			if (evi1 == evi2)
 				continue;
@@ -2302,8 +2293,6 @@ pg_extension_update_paths(PG_FUNCTION_ARGS)
 			path = find_update_path(evi_list, evi1, evi2, false, true);
 
 			/* Emit result row */
-			memset(values, 0, sizeof(values));
-			memset(nulls, 0, sizeof(nulls));
 
 			/* source */
 			values[0] = CStringGetTextDatum(evi1->name);
@@ -3061,9 +3050,9 @@ ApplyExtensionUpdates(Oid extensionOid,
 		SysScanDesc extScan;
 		HeapTuple	extTup;
 		Form_pg_extension extForm;
-		Datum		values[Natts_pg_extension];
-		bool		nulls[Natts_pg_extension];
-		bool		repl[Natts_pg_extension];
+		Datum		values[Natts_pg_extension] = {0};
+		bool		nulls[Natts_pg_extension] = {0};
+		bool		repl[Natts_pg_extension] = {0};
 		ObjectAddress myself;
 		ListCell   *lc;
 
@@ -3100,10 +3089,6 @@ ApplyExtensionUpdates(Oid extensionOid,
 		/*
 		 * Modify extrelocatable and extversion in the pg_extension tuple
 		 */
-		memset(values, 0, sizeof(values));
-		memset(nulls, 0, sizeof(nulls));
-		memset(repl, 0, sizeof(repl));
-
 		values[Anum_pg_extension_extrelocatable - 1] =
 			BoolGetDatum(control->relocatable);
 		repl[Anum_pg_extension_extrelocatable - 1] = true;
diff --git a/src/backend/commands/foreigncmds.c b/src/backend/commands/foreigncmds.c
index f96c278..9588554 100644
--- a/src/backend/commands/foreigncmds.c
+++ b/src/backend/commands/foreigncmds.c
@@ -563,8 +563,8 @@ ObjectAddress
 CreateForeignDataWrapper(CreateFdwStmt *stmt)
 {
 	Relation	rel;
-	Datum		values[Natts_pg_foreign_data_wrapper];
-	bool		nulls[Natts_pg_foreign_data_wrapper];
+	Datum		values[Natts_pg_foreign_data_wrapper] = {0};
+	bool		nulls[Natts_pg_foreign_data_wrapper] = {0};
 	HeapTuple	tuple;
 	Oid			fdwId;
 	bool		handler_given;
@@ -601,9 +601,6 @@ CreateForeignDataWrapper(CreateFdwStmt *stmt)
 	/*
 	 * Insert tuple into pg_foreign_data_wrapper.
 	 */
-	memset(values, 0, sizeof(values));
-	memset(nulls, false, sizeof(nulls));
-
 	fdwId = GetNewOidWithIndex(rel, ForeignDataWrapperOidIndexId,
 							   Anum_pg_foreign_data_wrapper_oid);
 	values[Anum_pg_foreign_data_wrapper_oid - 1] = ObjectIdGetDatum(fdwId);
@@ -868,8 +865,8 @@ CreateForeignServer(CreateForeignServerStmt *stmt)
 {
 	Relation	rel;
 	Datum		srvoptions;
-	Datum		values[Natts_pg_foreign_server];
-	bool		nulls[Natts_pg_foreign_server];
+	Datum		values[Natts_pg_foreign_server] = {0};
+	bool		nulls[Natts_pg_foreign_server] = {0};
 	HeapTuple	tuple;
 	Oid			srvId;
 	Oid			ownerId;
@@ -918,9 +915,6 @@ CreateForeignServer(CreateForeignServerStmt *stmt)
 	/*
 	 * Insert tuple into pg_foreign_server.
 	 */
-	memset(values, 0, sizeof(values));
-	memset(nulls, false, sizeof(nulls));
-
 	srvId = GetNewOidWithIndex(rel, ForeignServerOidIndexId,
 							   Anum_pg_foreign_server_oid);
 	values[Anum_pg_foreign_server_oid - 1] = ObjectIdGetDatum(srvId);
@@ -1145,8 +1139,8 @@ CreateUserMapping(CreateUserMappingStmt *stmt)
 {
 	Relation	rel;
 	Datum		useoptions;
-	Datum		values[Natts_pg_user_mapping];
-	bool		nulls[Natts_pg_user_mapping];
+	Datum		values[Natts_pg_user_mapping] = {0};
+	bool		nulls[Natts_pg_user_mapping] = {0};
 	HeapTuple	tuple;
 	Oid			useId;
 	Oid			umId;
@@ -1201,9 +1195,6 @@ CreateUserMapping(CreateUserMappingStmt *stmt)
 	/*
 	 * Insert tuple into pg_user_mapping.
 	 */
-	memset(values, 0, sizeof(values));
-	memset(nulls, false, sizeof(nulls));
-
 	umId = GetNewOidWithIndex(rel, UserMappingOidIndexId,
 							  Anum_pg_user_mapping_oid);
 	values[Anum_pg_user_mapping_oid - 1] = ObjectIdGetDatum(umId);
@@ -1465,8 +1456,8 @@ CreateForeignTable(CreateForeignTableStmt *stmt, Oid relid)
 {
 	Relation	ftrel;
 	Datum		ftoptions;
-	Datum		values[Natts_pg_foreign_table];
-	bool		nulls[Natts_pg_foreign_table];
+	Datum		values[Natts_pg_foreign_table] = {0};
+	bool		nulls[Natts_pg_foreign_table] = {0};
 	HeapTuple	tuple;
 	AclResult	aclresult;
 	ObjectAddress myself;
@@ -1502,9 +1493,6 @@ CreateForeignTable(CreateForeignTableStmt *stmt, Oid relid)
 	/*
 	 * Insert tuple into pg_foreign_table.
 	 */
-	memset(values, 0, sizeof(values));
-	memset(nulls, false, sizeof(nulls));
-
 	values[Anum_pg_foreign_table_ftrelid - 1] = ObjectIdGetDatum(relid);
 	values[Anum_pg_foreign_table_ftserver - 1] = ObjectIdGetDatum(server->serverid);
 	/* Add table generic options */
diff --git a/src/backend/commands/functioncmds.c b/src/backend/commands/functioncmds.c
index 40f1f9a..a6c7394 100644
--- a/src/backend/commands/functioncmds.c
+++ b/src/backend/commands/functioncmds.c
@@ -1504,7 +1504,7 @@ CreateCast(CreateCastStmt *stmt)
 	Relation	relation;
 	HeapTuple	tuple;
 	Datum		values[Natts_pg_cast];
-	bool		nulls[Natts_pg_cast];
+	bool		nulls[Natts_pg_cast] = {0};
 	ObjectAddress myself,
 				referenced;
 	AclResult	aclresult;
@@ -1757,8 +1757,6 @@ CreateCast(CreateCastStmt *stmt)
 	values[Anum_pg_cast_castcontext - 1] = CharGetDatum(castcontext);
 	values[Anum_pg_cast_castmethod - 1] = CharGetDatum(castmethod);
 
-	MemSet(nulls, false, sizeof(nulls));
-
 	tuple = heap_form_tuple(RelationGetDescr(relation), values, nulls);
 
 	CatalogTupleInsert(relation, tuple);
@@ -1893,8 +1891,8 @@ CreateTransform(CreateTransformStmt *stmt)
 	AclResult	aclresult;
 	Form_pg_proc procstruct;
 	Datum		values[Natts_pg_transform];
-	bool		nulls[Natts_pg_transform];
-	bool		replaces[Natts_pg_transform];
+	bool		nulls[Natts_pg_transform] = {0};
+	bool		replaces[Natts_pg_transform] = {0};
 	Oid			transformid;
 	HeapTuple	tuple;
 	HeapTuple	newtuple;
@@ -1999,8 +1997,6 @@ CreateTransform(CreateTransformStmt *stmt)
 	values[Anum_pg_transform_trffromsql - 1] = ObjectIdGetDatum(fromsqlfuncid);
 	values[Anum_pg_transform_trftosql - 1] = ObjectIdGetDatum(tosqlfuncid);
 
-	MemSet(nulls, false, sizeof(nulls));
-
 	relation = table_open(TransformRelationId, RowExclusiveLock);
 
 	tuple = SearchSysCache2(TRFTYPELANG,
@@ -2017,7 +2013,6 @@ CreateTransform(CreateTransformStmt *stmt)
 							format_type_be(typeid),
 							stmt->lang)));
 
-		MemSet(replaces, false, sizeof(replaces));
 		replaces[Anum_pg_transform_trffromsql - 1] = true;
 		replaces[Anum_pg_transform_trftosql - 1] = true;
 
diff --git a/src/backend/commands/opclasscmds.c b/src/backend/commands/opclasscmds.c
index 6a1ccde..8272733 100644
--- a/src/backend/commands/opclasscmds.c
+++ b/src/backend/commands/opclasscmds.c
@@ -248,8 +248,8 @@ CreateOpFamily(const char *amname, const char *opfname, Oid namespaceoid, Oid am
 	Oid			opfamilyoid;
 	Relation	rel;
 	HeapTuple	tup;
-	Datum		values[Natts_pg_opfamily];
-	bool		nulls[Natts_pg_opfamily];
+	Datum		values[Natts_pg_opfamily] = {0};
+	bool		nulls[Natts_pg_opfamily] = {0};
 	NameData	opfName;
 	ObjectAddress myself,
 				referenced;
@@ -272,9 +272,6 @@ CreateOpFamily(const char *amname, const char *opfname, Oid namespaceoid, Oid am
 	/*
 	 * Okay, let's create the pg_opfamily entry.
 	 */
-	memset(values, 0, sizeof(values));
-	memset(nulls, false, sizeof(nulls));
-
 	opfamilyoid = GetNewOidWithIndex(rel, OpfamilyOidIndexId,
 									 Anum_pg_opfamily_oid);
 	values[Anum_pg_opfamily_oid - 1] = ObjectIdGetDatum(opfamilyoid);
@@ -347,8 +344,8 @@ DefineOpClass(CreateOpClassStmt *stmt)
 	HeapTuple	tup;
 	Form_pg_am	amform;
 	IndexAmRoutine *amroutine;
-	Datum		values[Natts_pg_opclass];
-	bool		nulls[Natts_pg_opclass];
+	Datum		values[Natts_pg_opclass] = {0};
+	bool		nulls[Natts_pg_opclass] = {0};
 	AclResult	aclresult;
 	NameData	opcName;
 	ObjectAddress myself,
@@ -639,9 +636,6 @@ DefineOpClass(CreateOpClassStmt *stmt)
 	/*
 	 * Okay, let's create the pg_opclass entry.
 	 */
-	memset(values, 0, sizeof(values));
-	memset(nulls, false, sizeof(nulls));
-
 	opclassoid = GetNewOidWithIndex(rel, OpclassOidIndexId,
 									Anum_pg_opclass_oid);
 	values[Anum_pg_opclass_oid - 1] = ObjectIdGetDatum(opclassoid);
@@ -1308,8 +1302,8 @@ storeOperators(List *opfamilyname, Oid amoid,
 			   List *operators, bool isAdd)
 {
 	Relation	rel;
-	Datum		values[Natts_pg_amop];
-	bool		nulls[Natts_pg_amop];
+	Datum		values[Natts_pg_amop] = {0};
+	bool		nulls[Natts_pg_amop] = {0};
 	HeapTuple	tup;
 	Oid			entryoid;
 	ObjectAddress myself,
@@ -1344,8 +1338,6 @@ storeOperators(List *opfamilyname, Oid amoid,
 		oppurpose = OidIsValid(op->sortfamily) ? AMOP_ORDER : AMOP_SEARCH;
 
 		/* Create the pg_amop entry */
-		memset(values, 0, sizeof(values));
-		memset(nulls, false, sizeof(nulls));
 
 		entryoid = GetNewOidWithIndex(rel, AccessMethodOperatorOidIndexId,
 									  Anum_pg_amop_oid);
@@ -1426,8 +1418,8 @@ storeProcedures(List *opfamilyname, Oid amoid,
 				List *procedures, bool isAdd)
 {
 	Relation	rel;
-	Datum		values[Natts_pg_amproc];
-	bool		nulls[Natts_pg_amproc];
+	Datum		values[Natts_pg_amproc] = {0};
+	bool		nulls[Natts_pg_amproc] = {0};
 	HeapTuple	tup;
 	Oid			entryoid;
 	ObjectAddress myself,
@@ -1459,9 +1451,6 @@ storeProcedures(List *opfamilyname, Oid amoid,
 							NameListToString(opfamilyname))));
 
 		/* Create the pg_amproc entry */
-		memset(values, 0, sizeof(values));
-		memset(nulls, false, sizeof(nulls));
-
 		entryoid = GetNewOidWithIndex(rel, AccessMethodProcedureOidIndexId,
 									  Anum_pg_amproc_oid);
 		values[Anum_pg_amproc_oid - 1] = ObjectIdGetDatum(entryoid);
diff --git a/src/backend/commands/prepare.c b/src/backend/commands/prepare.c
index 7e0a041..8998686 100644
--- a/src/backend/commands/prepare.c
+++ b/src/backend/commands/prepare.c
@@ -757,9 +757,7 @@ pg_prepared_statement(PG_FUNCTION_ARGS)
 		while ((prep_stmt = hash_seq_search(&hash_seq)) != NULL)
 		{
 			Datum		values[5];
-			bool		nulls[5];
-
-			MemSet(nulls, 0, sizeof(nulls));
+			bool		nulls[5] = {0};
 
 			values[0] = CStringGetTextDatum(prep_stmt->stmt_name);
 			values[1] = CStringGetTextDatum(prep_stmt->plansource->query_string);
diff --git a/src/backend/commands/proclang.c b/src/backend/commands/proclang.c
index 343cd1d..057b474 100644
--- a/src/backend/commands/proclang.c
+++ b/src/backend/commands/proclang.c
@@ -325,8 +325,8 @@ create_proc_lang(const char *languageName, bool replace,
 {
 	Relation	rel;
 	TupleDesc	tupDesc;
-	Datum		values[Natts_pg_language];
-	bool		nulls[Natts_pg_language];
+	Datum		values[Natts_pg_language] = {0};
+	bool		nulls[Natts_pg_language] = {0};
 	bool		replaces[Natts_pg_language];
 	NameData	langname;
 	HeapTuple	oldtup;
@@ -340,8 +340,6 @@ create_proc_lang(const char *languageName, bool replace,
 	tupDesc = RelationGetDescr(rel);
 
 	/* Prepare data to be inserted */
-	memset(values, 0, sizeof(values));
-	memset(nulls, false, sizeof(nulls));
 	memset(replaces, true, sizeof(replaces));
 
 	namestrcpy(&langname, languageName);
diff --git a/src/backend/commands/publicationcmds.c b/src/backend/commands/publicationcmds.c
index f115d4b..8104ce8 100644
--- a/src/backend/commands/publicationcmds.c
+++ b/src/backend/commands/publicationcmds.c
@@ -142,8 +142,8 @@ CreatePublication(CreatePublicationStmt *stmt)
 	Relation	rel;
 	ObjectAddress myself;
 	Oid			puboid;
-	bool		nulls[Natts_pg_publication];
-	Datum		values[Natts_pg_publication];
+	bool		nulls[Natts_pg_publication] = {0};
+	Datum		values[Natts_pg_publication] = {0};
 	HeapTuple	tup;
 	bool		publish_given;
 	bool		publish_insert;
@@ -178,9 +178,6 @@ CreatePublication(CreatePublicationStmt *stmt)
 	}
 
 	/* Form a tuple. */
-	memset(values, 0, sizeof(values));
-	memset(nulls, false, sizeof(nulls));
-
 	values[Anum_pg_publication_pubname - 1] =
 		DirectFunctionCall1(namein, CStringGetDatum(stmt->pubname));
 	values[Anum_pg_publication_pubowner - 1] = ObjectIdGetDatum(GetUserId());
@@ -250,9 +247,9 @@ static void
 AlterPublicationOptions(AlterPublicationStmt *stmt, Relation rel,
 						HeapTuple tup)
 {
-	bool		nulls[Natts_pg_publication];
-	bool		replaces[Natts_pg_publication];
-	Datum		values[Natts_pg_publication];
+	bool		nulls[Natts_pg_publication] = {0};
+	bool		replaces[Natts_pg_publication] = {0};
+	Datum		values[Natts_pg_publication] = {0};
 	bool		publish_given;
 	bool		publish_insert;
 	bool		publish_update;
@@ -267,10 +264,6 @@ AlterPublicationOptions(AlterPublicationStmt *stmt, Relation rel,
 							  &publish_truncate);
 
 	/* Everything ok, form a new tuple. */
-	memset(values, 0, sizeof(values));
-	memset(nulls, false, sizeof(nulls));
-	memset(replaces, false, sizeof(replaces));
-
 	if (publish_given)
 	{
 		values[Anum_pg_publication_pubinsert - 1] = BoolGetDatum(publish_insert);
diff --git a/src/backend/commands/seclabel.c b/src/backend/commands/seclabel.c
index 63219ad..be9d11d 100644
--- a/src/backend/commands/seclabel.c
+++ b/src/backend/commands/seclabel.c
@@ -258,12 +258,10 @@ SetSharedSecurityLabel(const ObjectAddress *object,
 	HeapTuple	oldtup;
 	HeapTuple	newtup = NULL;
 	Datum		values[Natts_pg_shseclabel];
-	bool		nulls[Natts_pg_shseclabel];
-	bool		replaces[Natts_pg_shseclabel];
+	bool		nulls[Natts_pg_shseclabel] = {0};
+	bool		replaces[Natts_pg_shseclabel] = {0};
 
 	/* Prepare to form or update a tuple, if necessary. */
-	memset(nulls, false, sizeof(nulls));
-	memset(replaces, false, sizeof(replaces));
 	values[Anum_pg_shseclabel_objoid - 1] = ObjectIdGetDatum(object->objectId);
 	values[Anum_pg_shseclabel_classoid - 1] = ObjectIdGetDatum(object->classId);
 	values[Anum_pg_shseclabel_provider - 1] = CStringGetTextDatum(provider);
@@ -333,8 +331,8 @@ SetSecurityLabel(const ObjectAddress *object,
 	HeapTuple	oldtup;
 	HeapTuple	newtup = NULL;
 	Datum		values[Natts_pg_seclabel];
-	bool		nulls[Natts_pg_seclabel];
-	bool		replaces[Natts_pg_seclabel];
+	bool		nulls[Natts_pg_seclabel] = {0};
+	bool		replaces[Natts_pg_seclabel] = {0};
 
 	/* Shared objects have their own security label catalog. */
 	if (IsSharedRelation(object->classId))
@@ -344,8 +342,6 @@ SetSecurityLabel(const ObjectAddress *object,
 	}
 
 	/* Prepare to form or update a tuple, if necessary. */
-	memset(nulls, false, sizeof(nulls));
-	memset(replaces, false, sizeof(replaces));
 	values[Anum_pg_seclabel_objoid - 1] = ObjectIdGetDatum(object->objectId);
 	values[Anum_pg_seclabel_classoid - 1] = ObjectIdGetDatum(object->classId);
 	values[Anum_pg_seclabel_objsubid - 1] = Int32GetDatum(object->objectSubId);
diff --git a/src/backend/commands/statscmds.c b/src/backend/commands/statscmds.c
index f51eb7b..c5ab619 100644
--- a/src/backend/commands/statscmds.c
+++ b/src/backend/commands/statscmds.c
@@ -69,10 +69,10 @@ CreateStatistics(CreateStatsStmt *stmt)
 	Oid			namespaceId;
 	Oid			stxowner = GetUserId();
 	HeapTuple	htup;
-	Datum		values[Natts_pg_statistic_ext];
-	bool		nulls[Natts_pg_statistic_ext];
-	Datum		datavalues[Natts_pg_statistic_ext_data];
-	bool		datanulls[Natts_pg_statistic_ext_data];
+	Datum		values[Natts_pg_statistic_ext] = {0};
+	bool		nulls[Natts_pg_statistic_ext] = {0};
+	Datum		datavalues[Natts_pg_statistic_ext_data] = {0};
+	bool		datanulls[Natts_pg_statistic_ext_data] = {0};
 	int2vector *stxkeys;
 	Relation	statrel;
 	Relation	datarel;
@@ -330,9 +330,6 @@ CreateStatistics(CreateStatsStmt *stmt)
 	/*
 	 * Everything seems fine, so let's build the pg_statistic_ext tuple.
 	 */
-	memset(values, 0, sizeof(values));
-	memset(nulls, false, sizeof(nulls));
-
 	statoid = GetNewOidWithIndex(statrel, StatisticExtOidIndexId,
 								 Anum_pg_statistic_ext_oid);
 	values[Anum_pg_statistic_ext_oid - 1] = ObjectIdGetDatum(statoid);
@@ -357,9 +354,6 @@ CreateStatistics(CreateStatsStmt *stmt)
 	 */
 	datarel = table_open(StatisticExtDataRelationId, RowExclusiveLock);
 
-	memset(datavalues, 0, sizeof(datavalues));
-	memset(datanulls, false, sizeof(datanulls));
-
 	datavalues[Anum_pg_statistic_ext_data_stxoid - 1] = ObjectIdGetDatum(statoid);
 
 	/* no statistics built yet */
@@ -607,9 +601,9 @@ UpdateStatisticsForTypeChange(Oid statsOid, Oid relationOid, int attnum,
 
 	Relation	rel;
 
-	Datum		values[Natts_pg_statistic_ext_data];
-	bool		nulls[Natts_pg_statistic_ext_data];
-	bool		replaces[Natts_pg_statistic_ext_data];
+	Datum		values[Natts_pg_statistic_ext_data] = {0};
+	bool		nulls[Natts_pg_statistic_ext_data] = {0};
+	bool		replaces[Natts_pg_statistic_ext_data] = {0};
 
 	oldtup = SearchSysCache1(STATEXTDATASTXOID, ObjectIdGetDatum(statsOid));
 	if (!HeapTupleIsValid(oldtup))
@@ -630,10 +624,6 @@ UpdateStatisticsForTypeChange(Oid statsOid, Oid relationOid, int attnum,
 	 * OK, we need to reset some statistics. So let's build the new tuple,
 	 * replacing the affected statistics types with NULL.
 	 */
-	memset(nulls, 0, Natts_pg_statistic_ext_data * sizeof(bool));
-	memset(replaces, 0, Natts_pg_statistic_ext_data * sizeof(bool));
-	memset(values, 0, Natts_pg_statistic_ext_data * sizeof(Datum));
-
 	replaces[Anum_pg_statistic_ext_data_stxdmcv - 1] = true;
 	nulls[Anum_pg_statistic_ext_data_stxdmcv - 1] = true;
 
diff --git a/src/backend/commands/subscriptioncmds.c b/src/backend/commands/subscriptioncmds.c
index 2e67a58..aacbf48 100644
--- a/src/backend/commands/subscriptioncmds.c
+++ b/src/backend/commands/subscriptioncmds.c
@@ -317,8 +317,8 @@ CreateSubscription(CreateSubscriptionStmt *stmt, bool isTopLevel)
 	Relation	rel;
 	ObjectAddress myself;
 	Oid			subid;
-	bool		nulls[Natts_pg_subscription];
-	Datum		values[Natts_pg_subscription];
+	bool		nulls[Natts_pg_subscription] = {0};
+	Datum		values[Natts_pg_subscription] = {0};
 	Oid			owner = GetUserId();
 	HeapTuple	tup;
 	bool		connect;
@@ -396,9 +396,6 @@ CreateSubscription(CreateSubscriptionStmt *stmt, bool isTopLevel)
 	walrcv_check_conninfo(conninfo);
 
 	/* Everything ok, form a new tuple. */
-	memset(values, 0, sizeof(values));
-	memset(nulls, false, sizeof(nulls));
-
 	subid = GetNewOidWithIndex(rel, SubscriptionObjectIndexId,
 							   Anum_pg_subscription_oid);
 	values[Anum_pg_subscription_oid - 1] = ObjectIdGetDatum(subid);
@@ -636,9 +633,9 @@ AlterSubscription(AlterSubscriptionStmt *stmt)
 {
 	Relation	rel;
 	ObjectAddress myself;
-	bool		nulls[Natts_pg_subscription];
-	bool		replaces[Natts_pg_subscription];
-	Datum		values[Natts_pg_subscription];
+	bool		nulls[Natts_pg_subscription] = {0};
+	bool		replaces[Natts_pg_subscription] = {0};
+	Datum		values[Natts_pg_subscription] = {0};
 	HeapTuple	tup;
 	Oid			subid;
 	bool		update_tuple = false;
@@ -671,9 +668,6 @@ AlterSubscription(AlterSubscriptionStmt *stmt)
 	LockSharedObject(SubscriptionRelationId, subid, 0, AccessExclusiveLock);
 
 	/* Form a new tuple. */
-	memset(values, 0, sizeof(values));
-	memset(nulls, false, sizeof(nulls));
-	memset(replaces, false, sizeof(replaces));
 
 	switch (stmt->kind)
 	{
diff --git a/src/backend/commands/tablespace.c b/src/backend/commands/tablespace.c
index 84efb41..7411475 100644
--- a/src/backend/commands/tablespace.c
+++ b/src/backend/commands/tablespace.c
@@ -236,7 +236,7 @@ CreateTableSpace(CreateTableSpaceStmt *stmt)
 #ifdef HAVE_SYMLINK
 	Relation	rel;
 	Datum		values[Natts_pg_tablespace];
-	bool		nulls[Natts_pg_tablespace];
+	bool		nulls[Natts_pg_tablespace] = {0};
 	HeapTuple	tuple;
 	Oid			tablespaceoid;
 	char	   *location;
@@ -334,8 +334,6 @@ CreateTableSpace(CreateTableSpaceStmt *stmt)
 	 */
 	rel = table_open(TableSpaceRelationId, RowExclusiveLock);
 
-	MemSet(nulls, false, sizeof(nulls));
-
 	tablespaceoid = GetNewOidWithIndex(rel, TablespaceOidIndexId,
 									   Anum_pg_tablespace_oid);
 	values[Anum_pg_tablespace_oid - 1] = ObjectIdGetDatum(tablespaceoid);
diff --git a/src/backend/commands/trigger.c b/src/backend/commands/trigger.c
index cdb1105..0ceadbc 100644
--- a/src/backend/commands/trigger.c
+++ b/src/backend/commands/trigger.c
@@ -171,7 +171,7 @@ CreateTrigger(CreateTrigStmt *stmt, const char *queryString,
 	List	   *whenRtable;
 	char	   *qual;
 	Datum		values[Natts_pg_trigger];
-	bool		nulls[Natts_pg_trigger];
+	bool		nulls[Natts_pg_trigger] = {0};
 	Relation	rel;
 	AclResult	aclresult;
 	Relation	tgrel;
@@ -844,8 +844,6 @@ CreateTrigger(CreateTrigStmt *stmt, const char *queryString,
 	 * makes the triggers in partitions identical to the ones in the
 	 * partitioned tables, except that they are marked internal.
 	 */
-	memset(nulls, false, sizeof(nulls));
-
 	values[Anum_pg_trigger_oid - 1] = ObjectIdGetDatum(trigoid);
 	values[Anum_pg_trigger_tgrelid - 1] = ObjectIdGetDatum(RelationGetRelid(rel));
 	values[Anum_pg_trigger_tgname - 1] = DirectFunctionCall1(namein,
diff --git a/src/backend/commands/tsearchcmds.c b/src/backend/commands/tsearchcmds.c
index 5d6528f..1739e65 100644
--- a/src/backend/commands/tsearchcmds.c
+++ b/src/backend/commands/tsearchcmds.c
@@ -179,8 +179,8 @@ DefineTSParser(List *names, List *parameters)
 	ListCell   *pl;
 	Relation	prsRel;
 	HeapTuple	tup;
-	Datum		values[Natts_pg_ts_parser];
-	bool		nulls[Natts_pg_ts_parser];
+	Datum		values[Natts_pg_ts_parser] = {0};
+	bool		nulls[Natts_pg_ts_parser] = {0};
 	NameData	pname;
 	Oid			prsOid;
 	Oid			namespaceoid;
@@ -197,9 +197,6 @@ DefineTSParser(List *names, List *parameters)
 	namespaceoid = QualifiedNameGetCreationNamespace(names, &prsname);
 
 	/* initialize tuple fields with name/namespace */
-	memset(values, 0, sizeof(values));
-	memset(nulls, false, sizeof(nulls));
-
 	prsOid = GetNewOidWithIndex(prsRel, TSParserOidIndexId,
 								Anum_pg_ts_parser_oid);
 	values[Anum_pg_ts_parser_oid - 1] = ObjectIdGetDatum(prsOid);
@@ -414,8 +411,8 @@ DefineTSDictionary(List *names, List *parameters)
 	ListCell   *pl;
 	Relation	dictRel;
 	HeapTuple	tup;
-	Datum		values[Natts_pg_ts_dict];
-	bool		nulls[Natts_pg_ts_dict];
+	Datum		values[Natts_pg_ts_dict] = {0};
+	bool		nulls[Natts_pg_ts_dict] = {0};
 	NameData	dname;
 	Oid			templId = InvalidOid;
 	List	   *dictoptions = NIL;
@@ -468,9 +465,6 @@ DefineTSDictionary(List *names, List *parameters)
 	/*
 	 * Looks good, insert
 	 */
-	memset(values, 0, sizeof(values));
-	memset(nulls, false, sizeof(nulls));
-
 	dictOid = GetNewOidWithIndex(dictRel, TSDictionaryOidIndexId,
 								 Anum_pg_ts_dict_oid);
 	values[Anum_pg_ts_dict_oid - 1] = ObjectIdGetDatum(dictOid);
@@ -733,7 +727,7 @@ DefineTSTemplate(List *names, List *parameters)
 	Relation	tmplRel;
 	HeapTuple	tup;
 	Datum		values[Natts_pg_ts_template];
-	bool		nulls[Natts_pg_ts_template];
+	bool		nulls[Natts_pg_ts_template] = {0};
 	NameData	dname;
 	int			i;
 	Oid			tmplOid;
@@ -753,7 +747,6 @@ DefineTSTemplate(List *names, List *parameters)
 
 	for (i = 0; i < Natts_pg_ts_template; i++)
 	{
-		nulls[i] = false;
 		values[i] = ObjectIdGetDatum(InvalidOid);
 	}
 
@@ -965,8 +958,8 @@ DefineTSConfiguration(List *names, List *parameters, ObjectAddress *copied)
 	Relation	cfgRel;
 	Relation	mapRel = NULL;
 	HeapTuple	tup;
-	Datum		values[Natts_pg_ts_config];
-	bool		nulls[Natts_pg_ts_config];
+	Datum		values[Natts_pg_ts_config] = {0};
+	bool		nulls[Natts_pg_ts_config] = {0};
 	AclResult	aclresult;
 	Oid			namespaceoid;
 	char	   *cfgname;
@@ -1050,9 +1043,6 @@ DefineTSConfiguration(List *names, List *parameters, ObjectAddress *copied)
 	/*
 	 * Looks good, build tuple and insert
 	 */
-	memset(values, 0, sizeof(values));
-	memset(nulls, false, sizeof(nulls));
-
 	cfgOid = GetNewOidWithIndex(cfgRel, TSConfigOidIndexId,
 								Anum_pg_ts_config_oid);
 	values[Anum_pg_ts_config_oid - 1] = ObjectIdGetDatum(cfgOid);
@@ -1089,11 +1079,8 @@ DefineTSConfiguration(List *names, List *parameters, ObjectAddress *copied)
 		{
 			Form_pg_ts_config_map cfgmap = (Form_pg_ts_config_map) GETSTRUCT(maptup);
 			HeapTuple	newmaptup;
-			Datum		mapvalues[Natts_pg_ts_config_map];
-			bool		mapnulls[Natts_pg_ts_config_map];
-
-			memset(mapvalues, 0, sizeof(mapvalues));
-			memset(mapnulls, false, sizeof(mapnulls));
+			Datum		mapvalues[Natts_pg_ts_config_map] = {0};
+			bool		mapnulls[Natts_pg_ts_config_map] = {0};
 
 			mapvalues[Anum_pg_ts_config_map_mapcfg - 1] = cfgOid;
 			mapvalues[Anum_pg_ts_config_map_maptokentype - 1] = cfgmap->maptokentype;
@@ -1420,9 +1407,8 @@ MakeConfigurationMapping(AlterTSConfigurationStmt *stmt,
 			for (j = 0; j < ndict; j++)
 			{
 				Datum		values[Natts_pg_ts_config_map];
-				bool		nulls[Natts_pg_ts_config_map];
+				bool		nulls[Natts_pg_ts_config_map] = {0};
 
-				memset(nulls, false, sizeof(nulls));
 				values[Anum_pg_ts_config_map_mapcfg - 1] = ObjectIdGetDatum(cfgId);
 				values[Anum_pg_ts_config_map_maptokentype - 1] = Int32GetDatum(tokens[i]);
 				values[Anum_pg_ts_config_map_mapseqno - 1] = Int32GetDatum(j + 1);
diff --git a/src/backend/libpq/hba.c b/src/backend/libpq/hba.c
index 2221c04..a259bb2 100644
--- a/src/backend/libpq/hba.c
+++ b/src/backend/libpq/hba.c
@@ -2414,8 +2414,8 @@ static void
 fill_hba_line(Tuplestorestate *tuple_store, TupleDesc tupdesc,
 			  int lineno, HbaLine *hba, const char *err_msg)
 {
-	Datum		values[NUM_PG_HBA_FILE_RULES_ATTS];
-	bool		nulls[NUM_PG_HBA_FILE_RULES_ATTS];
+	Datum		values[NUM_PG_HBA_FILE_RULES_ATTS] = {0};
+	bool		nulls[NUM_PG_HBA_FILE_RULES_ATTS] = {0};
 	char		buffer[NI_MAXHOST];
 	HeapTuple	tuple;
 	int			index;
@@ -2427,8 +2427,6 @@ fill_hba_line(Tuplestorestate *tuple_store, TupleDesc tupdesc,
 
 	Assert(tupdesc->natts == NUM_PG_HBA_FILE_RULES_ATTS);
 
-	memset(values, 0, sizeof(values));
-	memset(nulls, 0, sizeof(nulls));
 	index = 0;
 
 	/* line_number */
diff --git a/src/backend/replication/logical/launcher.c b/src/backend/replication/logical/launcher.c
index 186057b..8ea0052 100644
--- a/src/backend/replication/logical/launcher.c
+++ b/src/backend/replication/logical/launcher.c
@@ -1136,8 +1136,8 @@ pg_stat_get_subscription(PG_FUNCTION_ARGS)
 	for (i = 0; i <= max_logical_replication_workers; i++)
 	{
 		/* for each row */
-		Datum		values[PG_STAT_GET_SUBSCRIPTION_COLS];
-		bool		nulls[PG_STAT_GET_SUBSCRIPTION_COLS];
+		Datum		values[PG_STAT_GET_SUBSCRIPTION_COLS] = {0};
+		bool		nulls[PG_STAT_GET_SUBSCRIPTION_COLS] = {0};
 		int			worker_pid;
 		LogicalRepWorker worker;
 
@@ -1151,9 +1151,6 @@ pg_stat_get_subscription(PG_FUNCTION_ARGS)
 
 		worker_pid = worker.proc->pid;
 
-		MemSet(values, 0, sizeof(values));
-		MemSet(nulls, 0, sizeof(nulls));
-
 		values[0] = ObjectIdGetDatum(worker.subid);
 		if (OidIsValid(worker.relid))
 			values[1] = ObjectIdGetDatum(worker.relid);
diff --git a/src/backend/replication/logical/logicalfuncs.c b/src/backend/replication/logical/logicalfuncs.c
index d1cf80d..4b26757 100644
--- a/src/backend/replication/logical/logicalfuncs.c
+++ b/src/backend/replication/logical/logicalfuncs.c
@@ -75,7 +75,7 @@ LogicalOutputWrite(LogicalDecodingContext *ctx, XLogRecPtr lsn, TransactionId xi
 				   bool last_write)
 {
 	Datum		values[3];
-	bool		nulls[3];
+	bool		nulls[3] = {0};
 	DecodingOutputState *p;
 
 	/* SQL Datums can only be of a limited length... */
@@ -84,7 +84,6 @@ LogicalOutputWrite(LogicalDecodingContext *ctx, XLogRecPtr lsn, TransactionId xi
 
 	p = (DecodingOutputState *) ctx->output_writer_private;
 
-	memset(nulls, 0, sizeof(nulls));
 	values[0] = LSNGetDatum(lsn);
 	values[1] = TransactionIdGetDatum(xid);
 
diff --git a/src/backend/replication/logical/origin.c b/src/backend/replication/logical/origin.c
index 07ae613..f02992a 100644
--- a/src/backend/replication/logical/origin.c
+++ b/src/backend/replication/logical/origin.c
@@ -275,7 +275,7 @@ replorigin_create(char *roname)
 
 	for (roident = InvalidOid + 1; roident < PG_UINT16_MAX; roident++)
 	{
-		bool		nulls[Natts_pg_replication_origin];
+		bool		nulls[Natts_pg_replication_origin] = {0};
 		Datum		values[Natts_pg_replication_origin];
 		bool		collides;
 
@@ -301,8 +301,6 @@ replorigin_create(char *roname)
 			 * Ok, found an unused roident, insert the new row and do a CCI,
 			 * so our callers can look it up if they want to.
 			 */
-			memset(&nulls, 0, sizeof(nulls));
-
 			values[Anum_pg_replication_origin_roident - 1] = ObjectIdGetDatum(roident);
 			values[Anum_pg_replication_origin_roname - 1] = roname_d;
 
@@ -1517,7 +1515,7 @@ pg_show_replication_origin_status(PG_FUNCTION_ARGS)
 	for (i = 0; i < max_replication_slots; i++)
 	{
 		ReplicationState *state;
-		Datum		values[REPLICATION_ORIGIN_PROGRESS_COLS];
+		Datum		values[REPLICATION_ORIGIN_PROGRESS_COLS] = {0};
 		bool		nulls[REPLICATION_ORIGIN_PROGRESS_COLS];
 		char	   *roname;
 
@@ -1527,7 +1525,6 @@ pg_show_replication_origin_status(PG_FUNCTION_ARGS)
 		if (state->roident == InvalidRepOriginId)
 			continue;
 
-		memset(values, 0, sizeof(values));
 		memset(nulls, 1, sizeof(nulls));
 
 		values[0] = ObjectIdGetDatum(state->roident);
diff --git a/src/backend/replication/slotfuncs.c b/src/backend/replication/slotfuncs.c
index 42da631..3ca45e2 100644
--- a/src/backend/replication/slotfuncs.c
+++ b/src/backend/replication/slotfuncs.c
@@ -77,7 +77,7 @@ pg_create_physical_replication_slot(PG_FUNCTION_ARGS)
 	bool		immediately_reserve = PG_GETARG_BOOL(1);
 	bool		temporary = PG_GETARG_BOOL(2);
 	Datum		values[2];
-	bool		nulls[2];
+	bool		nulls[2] = {0};
 	TupleDesc	tupdesc;
 	HeapTuple	tuple;
 	Datum		result;
@@ -95,12 +95,10 @@ pg_create_physical_replication_slot(PG_FUNCTION_ARGS)
 									 InvalidXLogRecPtr);
 
 	values[0] = NameGetDatum(&MyReplicationSlot->data.name);
-	nulls[0] = false;
 
 	if (immediately_reserve)
 	{
 		values[1] = LSNGetDatum(MyReplicationSlot->data.restart_lsn);
-		nulls[1] = false;
 	}
 	else
 		nulls[1] = true;
@@ -167,7 +165,7 @@ pg_create_logical_replication_slot(PG_FUNCTION_ARGS)
 	TupleDesc	tupdesc;
 	HeapTuple	tuple;
 	Datum		values[2];
-	bool		nulls[2];
+	bool		nulls[2] = {0};
 
 	if (get_call_result_type(fcinfo, NULL, &tupdesc) != TYPEFUNC_COMPOSITE)
 		elog(ERROR, "return type must be a row type");
@@ -184,8 +182,6 @@ pg_create_logical_replication_slot(PG_FUNCTION_ARGS)
 	values[0] = NameGetDatum(&MyReplicationSlot->data.name);
 	values[1] = LSNGetDatum(MyReplicationSlot->data.confirmed_flush);
 
-	memset(nulls, 0, sizeof(nulls));
-
 	tuple = heap_form_tuple(tupdesc, values, nulls);
 	result = HeapTupleGetDatum(tuple);
 
@@ -265,7 +261,7 @@ pg_get_replication_slots(PG_FUNCTION_ARGS)
 	{
 		ReplicationSlot *slot = &ReplicationSlotCtl->replication_slots[slotno];
 		Datum		values[PG_GET_REPLICATION_SLOTS_COLS];
-		bool		nulls[PG_GET_REPLICATION_SLOTS_COLS];
+		bool		nulls[PG_GET_REPLICATION_SLOTS_COLS] = {0};
 
 		ReplicationSlotPersistency persistency;
 		TransactionId xmin;
@@ -295,8 +291,6 @@ pg_get_replication_slots(PG_FUNCTION_ARGS)
 
 		SpinLockRelease(&slot->mutex);
 
-		memset(nulls, 0, sizeof(nulls));
-
 		i = 0;
 		values[i++] = NameGetDatum(&slot_name);
 
@@ -513,7 +507,7 @@ pg_replication_slot_advance(PG_FUNCTION_ARGS)
 	XLogRecPtr	minlsn;
 	TupleDesc	tupdesc;
 	Datum		values[2];
-	bool		nulls[2];
+	bool		nulls[2] = {0};
 	HeapTuple	tuple;
 	Datum		result;
 
@@ -572,7 +566,6 @@ pg_replication_slot_advance(PG_FUNCTION_ARGS)
 		endlsn = pg_physical_replication_slot_advance(moveto);
 
 	values[0] = NameGetDatum(&MyReplicationSlot->data.name);
-	nulls[0] = false;
 
 	/* Update the on disk state when lsn was updated. */
 	if (XLogRecPtrIsInvalid(endlsn))
@@ -587,7 +580,6 @@ pg_replication_slot_advance(PG_FUNCTION_ARGS)
 
 	/* Return the reached position. */
 	values[1] = LSNGetDatum(endlsn);
-	nulls[1] = false;
 
 	tuple = heap_form_tuple(tupdesc, values, nulls);
 	result = HeapTupleGetDatum(tuple);
@@ -609,7 +601,7 @@ copy_replication_slot(FunctionCallInfo fcinfo, bool logical_slot)
 	bool		temporary;
 	char	   *plugin;
 	Datum		values[2];
-	bool		nulls[2];
+	bool		nulls[2] = {0};
 	Datum		result;
 	TupleDesc	tupdesc;
 	HeapTuple	tuple;
@@ -779,11 +771,9 @@ copy_replication_slot(FunctionCallInfo fcinfo, bool logical_slot)
 
 	/* All done.  Set up the return values */
 	values[0] = NameGetDatum(dst_name);
-	nulls[0] = false;
 	if (!XLogRecPtrIsInvalid(MyReplicationSlot->data.confirmed_flush))
 	{
 		values[1] = LSNGetDatum(MyReplicationSlot->data.confirmed_flush);
-		nulls[1] = false;
 	}
 	else
 		nulls[1] = true;
diff --git a/src/backend/replication/walsender.c b/src/backend/replication/walsender.c
index eb4a98c..78e1ecf 100644
--- a/src/backend/replication/walsender.c
+++ b/src/backend/replication/walsender.c
@@ -351,7 +351,7 @@ IdentifySystem(void)
 	TupOutputState *tstate;
 	TupleDesc	tupdesc;
 	Datum		values[4];
-	bool		nulls[4];
+	bool		nulls[4] = {0};
 
 	/*
 	 * Reply with a result set with one row, four columns. First col is system
@@ -388,7 +388,6 @@ IdentifySystem(void)
 	}
 
 	dest = CreateDestReceiver(DestRemoteSimple);
-	MemSet(nulls, false, sizeof(nulls));
 
 	/* need a tuple descriptor representing four columns */
 	tupdesc = CreateTemplateTupleDesc(4);
@@ -717,14 +716,13 @@ StartReplication(StartReplicationCmd *cmd)
 		TupOutputState *tstate;
 		TupleDesc	tupdesc;
 		Datum		values[2];
-		bool		nulls[2];
+		bool		nulls[2] = {0};
 
 		snprintf(startpos_str, sizeof(startpos_str), "%X/%X",
 				 (uint32) (sendTimeLineValidUpto >> 32),
 				 (uint32) sendTimeLineValidUpto);
 
 		dest = CreateDestReceiver(DestRemoteSimple);
-		MemSet(nulls, false, sizeof(nulls));
 
 		/*
 		 * Need a tuple descriptor representing two columns. int8 may seem
@@ -859,7 +857,7 @@ CreateReplicationSlot(CreateReplicationSlotCmd *cmd)
 	TupOutputState *tstate;
 	TupleDesc	tupdesc;
 	Datum		values[4];
-	bool		nulls[4];
+	bool		nulls[4] = {0};
 
 	Assert(!MyReplicationSlot);
 
@@ -995,7 +993,6 @@ CreateReplicationSlot(CreateReplicationSlotCmd *cmd)
 			 (uint32) MyReplicationSlot->data.confirmed_flush);
 
 	dest = CreateDestReceiver(DestRemoteSimple);
-	MemSet(nulls, false, sizeof(nulls));
 
 	/*----------
 	 * Need a tuple descriptor representing four columns:
@@ -3286,7 +3283,7 @@ pg_stat_get_wal_senders(PG_FUNCTION_ARGS)
 		WalSndState state;
 		TimestampTz replyTime;
 		Datum		values[PG_STAT_GET_WAL_SENDERS_COLS];
-		bool		nulls[PG_STAT_GET_WAL_SENDERS_COLS];
+		bool		nulls[PG_STAT_GET_WAL_SENDERS_COLS] = {0};
 
 		SpinLockAcquire(&walsnd->mutex);
 		if (walsnd->pid == 0)
@@ -3307,7 +3304,6 @@ pg_stat_get_wal_senders(PG_FUNCTION_ARGS)
 		replyTime = walsnd->replyTime;
 		SpinLockRelease(&walsnd->mutex);
 
-		memset(nulls, 0, sizeof(nulls));
 		values[0] = Int32GetDatum(pid);
 
 		if (!is_member_of_role(GetUserId(), DEFAULT_ROLE_READ_ALL_STATS))
diff --git a/src/backend/rewrite/rewriteDefine.c b/src/backend/rewrite/rewriteDefine.c
index 7df2b61..a6d9ddb 100644
--- a/src/backend/rewrite/rewriteDefine.c
+++ b/src/backend/rewrite/rewriteDefine.c
@@ -67,8 +67,8 @@ InsertRule(const char *rulname,
 	char	   *evqual = nodeToString(event_qual);
 	char	   *actiontree = nodeToString((Node *) action);
 	Datum		values[Natts_pg_rewrite];
-	bool		nulls[Natts_pg_rewrite];
-	bool		replaces[Natts_pg_rewrite];
+	bool		nulls[Natts_pg_rewrite] = {0};
+	bool		replaces[Natts_pg_rewrite] = {0};
 	NameData	rname;
 	Relation	pg_rewrite_desc;
 	HeapTuple	tup,
@@ -79,10 +79,8 @@ InsertRule(const char *rulname,
 	bool		is_update = false;
 
 	/*
-	 * Set up *nulls and *values arrays
+	 * Set up *values array
 	 */
-	MemSet(nulls, false, sizeof(nulls));
-
 	namestrcpy(&rname, rulname);
 	values[Anum_pg_rewrite_rulename - 1] = NameGetDatum(&rname);
 	values[Anum_pg_rewrite_ev_class - 1] = ObjectIdGetDatum(eventrel_oid);
@@ -115,7 +113,6 @@ InsertRule(const char *rulname,
 		/*
 		 * When replacing, we don't need to replace every attribute
 		 */
-		MemSet(replaces, false, sizeof(replaces));
 		replaces[Anum_pg_rewrite_ev_type - 1] = true;
 		replaces[Anum_pg_rewrite_is_instead - 1] = true;
 		replaces[Anum_pg_rewrite_ev_qual - 1] = true;
diff --git a/src/backend/statistics/extended_stats.c b/src/backend/statistics/extended_stats.c
index 207ee31..ee0a623 100644
--- a/src/backend/statistics/extended_stats.c
+++ b/src/backend/statistics/extended_stats.c
@@ -471,14 +471,12 @@ statext_store(Oid statOid,
 {
 	HeapTuple	stup,
 				oldtup;
-	Datum		values[Natts_pg_statistic_ext_data];
+	Datum		values[Natts_pg_statistic_ext_data] = {0};
 	bool		nulls[Natts_pg_statistic_ext_data];
-	bool		replaces[Natts_pg_statistic_ext_data];
+	bool		replaces[Natts_pg_statistic_ext_data] = {0};
 	Relation	pg_stextdata;
 
 	memset(nulls, true, sizeof(nulls));
-	memset(replaces, false, sizeof(replaces));
-	memset(values, 0, sizeof(values));
 
 	/*
 	 * Construct a new pg_statistic_ext_data tuple, replacing the calculated
diff --git a/src/backend/storage/large_object/inv_api.c b/src/backend/storage/large_object/inv_api.c
index e591236..bd3f033 100644
--- a/src/backend/storage/large_object/inv_api.c
+++ b/src/backend/storage/large_object/inv_api.c
@@ -608,9 +608,6 @@ inv_write(LargeObjectDesc *obj_desc, const char *buf, int nbytes)
 	}			workbuf;
 	char	   *workb = VARDATA(&workbuf.hdr);
 	HeapTuple	newtup;
-	Datum		values[Natts_pg_largeobject];
-	bool		nulls[Natts_pg_largeobject];
-	bool		replace[Natts_pg_largeobject];
 	CatalogIndexState indstate;
 
 	Assert(PointerIsValid(obj_desc));
@@ -656,6 +653,10 @@ inv_write(LargeObjectDesc *obj_desc, const char *buf, int nbytes)
 
 	while (nwritten < nbytes)
 	{
+	       Datum           values[Natts_pg_largeobject] = {0};
+	       bool            nulls[Natts_pg_largeobject] = {0};
+	       bool            replace[Natts_pg_largeobject] = {0};
+
 		/*
 		 * If possible, get next pre-existing page of the LO.  We expect the
 		 * indexscan will deliver these in order --- but there may be holes.
@@ -711,9 +712,6 @@ inv_write(LargeObjectDesc *obj_desc, const char *buf, int nbytes)
 			/*
 			 * Form and insert updated tuple
 			 */
-			memset(values, 0, sizeof(values));
-			memset(nulls, false, sizeof(nulls));
-			memset(replace, false, sizeof(replace));
 			values[Anum_pg_largeobject_data - 1] = PointerGetDatum(&workbuf);
 			replace[Anum_pg_largeobject_data - 1] = true;
 			newtup = heap_modify_tuple(oldtuple, RelationGetDescr(lo_heap_r),
@@ -755,8 +753,6 @@ inv_write(LargeObjectDesc *obj_desc, const char *buf, int nbytes)
 			/*
 			 * Form and insert updated tuple
 			 */
-			memset(values, 0, sizeof(values));
-			memset(nulls, false, sizeof(nulls));
 			values[Anum_pg_largeobject_loid - 1] = ObjectIdGetDatum(obj_desc->id);
 			values[Anum_pg_largeobject_pageno - 1] = Int32GetDatum(pageno);
 			values[Anum_pg_largeobject_data - 1] = PointerGetDatum(&workbuf);
@@ -799,9 +795,9 @@ inv_truncate(LargeObjectDesc *obj_desc, int64 len)
 	}			workbuf;
 	char	   *workb = VARDATA(&workbuf.hdr);
 	HeapTuple	newtup;
-	Datum		values[Natts_pg_largeobject];
-	bool		nulls[Natts_pg_largeobject];
-	bool		replace[Natts_pg_largeobject];
+	Datum		values[Natts_pg_largeobject] = {0};
+	bool		nulls[Natts_pg_largeobject] = {0};
+	bool		replace[Natts_pg_largeobject] = {0};
 	CatalogIndexState indstate;
 
 	Assert(PointerIsValid(obj_desc));
@@ -886,9 +882,6 @@ inv_truncate(LargeObjectDesc *obj_desc, int64 len)
 		/*
 		 * Form and insert updated tuple
 		 */
-		memset(values, 0, sizeof(values));
-		memset(nulls, false, sizeof(nulls));
-		memset(replace, false, sizeof(replace));
 		values[Anum_pg_largeobject_data - 1] = PointerGetDatum(&workbuf);
 		replace[Anum_pg_largeobject_data - 1] = true;
 		newtup = heap_modify_tuple(oldtuple, RelationGetDescr(lo_heap_r),
@@ -925,8 +918,6 @@ inv_truncate(LargeObjectDesc *obj_desc, int64 len)
 		/*
 		 * Form and insert new tuple
 		 */
-		memset(values, 0, sizeof(values));
-		memset(nulls, false, sizeof(nulls));
 		values[Anum_pg_largeobject_loid - 1] = ObjectIdGetDatum(obj_desc->id);
 		values[Anum_pg_largeobject_pageno - 1] = Int32GetDatum(pageno);
 		values[Anum_pg_largeobject_data - 1] = PointerGetDatum(&workbuf);
diff --git a/src/backend/utils/adt/acl.c b/src/backend/utils/adt/acl.c
index d7e6100..dbe4ef4 100644
--- a/src/backend/utils/adt/acl.c
+++ b/src/backend/utils/adt/acl.c
@@ -1810,7 +1810,7 @@ aclexplode(PG_FUNCTION_ARGS)
 		{
 			Datum		result;
 			Datum		values[4];
-			bool		nulls[4];
+			bool		nulls[4] = {0};
 			HeapTuple	tuple;
 
 			values[0] = ObjectIdGetDatum(aidata->ai_grantor);
@@ -1818,8 +1818,6 @@ aclexplode(PG_FUNCTION_ARGS)
 			values[2] = CStringGetTextDatum(convert_aclright_to_string(priv_bit));
 			values[3] = BoolGetDatum((ACLITEM_GET_GOPTIONS(*aidata) & priv_bit) != 0);
 
-			MemSet(nulls, 0, sizeof(nulls));
-
 			tuple = heap_form_tuple(funcctx->tuple_desc, values, nulls);
 			result = HeapTupleGetDatum(tuple);
 
diff --git a/src/backend/utils/adt/arrayfuncs.c b/src/backend/utils/adt/arrayfuncs.c
index 8079b13..afc3f08 100644
--- a/src/backend/utils/adt/arrayfuncs.c
+++ b/src/backend/utils/adt/arrayfuncs.c
@@ -738,11 +738,10 @@ ReadArrayStr(char *arrayStr,
 	bool		eoArray = false;
 	bool		hasnull;
 	int32		totbytes;
-	int			indx[MAXDIM],
+	int			indx[MAXDIM] = {0},
 				prod[MAXDIM];
 
 	mda_get_prod(ndim, dim, prod);
-	MemSet(indx, 0, sizeof(indx));
 
 	/* Initialize is-null markers to true */
 	memset(nulls, true, nitems * sizeof(bool));
diff --git a/src/backend/utils/adt/datetime.c b/src/backend/utils/adt/datetime.c
index e38bd93..0b18793 100644
--- a/src/backend/utils/adt/datetime.c
+++ b/src/backend/utils/adt/datetime.c
@@ -4635,7 +4635,7 @@ pg_timezone_abbrevs(PG_FUNCTION_ARGS)
 	Datum		result;
 	HeapTuple	tuple;
 	Datum		values[3];
-	bool		nulls[3];
+	bool		nulls[3] = {0};
 	const datetkn *tp;
 	char		buffer[TOKMAXLEN + 1];
 	int			gmtoffset;
@@ -4722,8 +4722,6 @@ pg_timezone_abbrevs(PG_FUNCTION_ARGS)
 			break;
 	}
 
-	MemSet(nulls, 0, sizeof(nulls));
-
 	/*
 	 * Convert name to text, using upcasing conversion that is the inverse of
 	 * what ParseDateTime() uses.
@@ -4765,7 +4763,7 @@ pg_timezone_names(PG_FUNCTION_ARGS)
 	Datum		result;
 	HeapTuple	tuple;
 	Datum		values[4];
-	bool		nulls[4];
+	bool		nulls[4] = {0};
 	int			tzoff;
 	struct pg_tm tm;
 	fsec_t		fsec;
@@ -4847,8 +4845,6 @@ pg_timezone_names(PG_FUNCTION_ARGS)
 		break;
 	}
 
-	MemSet(nulls, 0, sizeof(nulls));
-
 	values[0] = CStringGetTextDatum(pg_get_timezone_name(tz));
 	values[1] = CStringGetTextDatum(tzn ? tzn : "");
 
diff --git a/src/backend/utils/adt/genfile.c b/src/backend/utils/adt/genfile.c
index 5d4f26a..04f85e7 100644
--- a/src/backend/utils/adt/genfile.c
+++ b/src/backend/utils/adt/genfile.c
@@ -576,7 +576,7 @@ pg_ls_dir_files(FunctionCallInfo fcinfo, const char *dir, bool missing_ok)
 	while ((de = ReadDir(fctx->dirdesc, fctx->location)) != NULL)
 	{
 		Datum		values[3];
-		bool		nulls[3];
+		bool		nulls[3] = {0};
 		char		path[MAXPGPATH * 2];
 		struct stat attrib;
 		HeapTuple	tuple;
@@ -599,7 +599,6 @@ pg_ls_dir_files(FunctionCallInfo fcinfo, const char *dir, bool missing_ok)
 		values[0] = CStringGetTextDatum(de->d_name);
 		values[1] = Int64GetDatum((int64) attrib.st_size);
 		values[2] = TimestampTzGetDatum(time_t_to_timestamptz(attrib.st_mtime));
-		memset(nulls, 0, sizeof(nulls));
 
 		tuple = heap_form_tuple(funcctx->tuple_desc, values, nulls);
 		SRF_RETURN_NEXT(funcctx, HeapTupleGetDatum(tuple));
diff --git a/src/backend/utils/adt/lockfuncs.c b/src/backend/utils/adt/lockfuncs.c
index bc62c6e..1b47b48 100644
--- a/src/backend/utils/adt/lockfuncs.c
+++ b/src/backend/utils/adt/lockfuncs.c
@@ -160,8 +160,8 @@ pg_lock_status(PG_FUNCTION_ARGS)
 		LOCKMODE	mode = 0;
 		const char *locktypename;
 		char		tnbuf[32];
-		Datum		values[NUM_LOCK_STATUS_COLUMNS];
-		bool		nulls[NUM_LOCK_STATUS_COLUMNS];
+		Datum		values[NUM_LOCK_STATUS_COLUMNS] = {0};
+		bool		nulls[NUM_LOCK_STATUS_COLUMNS] = {0};
 		HeapTuple	tuple;
 		Datum		result;
 		LockInstanceData *instance;
@@ -218,9 +218,6 @@ pg_lock_status(PG_FUNCTION_ARGS)
 		/*
 		 * Form tuple with appropriate data.
 		 */
-		MemSet(values, 0, sizeof(values));
-		MemSet(nulls, false, sizeof(nulls));
-
 		if (instance->locktag.locktag_type <= LOCKTAG_LAST_TYPE)
 			locktypename = LockTagTypeNames[instance->locktag.locktag_type];
 		else
@@ -332,8 +329,8 @@ pg_lock_status(PG_FUNCTION_ARGS)
 
 		PREDICATELOCKTARGETTAG *predTag = &(predLockData->locktags[mystatus->predLockIdx]);
 		SERIALIZABLEXACT *xact = &(predLockData->xacts[mystatus->predLockIdx]);
-		Datum		values[NUM_LOCK_STATUS_COLUMNS];
-		bool		nulls[NUM_LOCK_STATUS_COLUMNS];
+		Datum		values[NUM_LOCK_STATUS_COLUMNS] = {0};
+		bool		nulls[NUM_LOCK_STATUS_COLUMNS] = {0};
 		HeapTuple	tuple;
 		Datum		result;
 
@@ -342,8 +339,6 @@ pg_lock_status(PG_FUNCTION_ARGS)
 		/*
 		 * Form tuple with appropriate data.
 		 */
-		MemSet(values, 0, sizeof(values));
-		MemSet(nulls, false, sizeof(nulls));
 
 		/* lock type */
 		lockType = GET_PREDICATELOCKTARGETTAG_TYPE(*predTag);
diff --git a/src/backend/utils/adt/pgstatfuncs.c b/src/backend/utils/adt/pgstatfuncs.c
index 05240bf..61d0fa3 100644
--- a/src/backend/utils/adt/pgstatfuncs.c
+++ b/src/backend/utils/adt/pgstatfuncs.c
@@ -492,13 +492,10 @@ pg_stat_get_progress_info(PG_FUNCTION_ARGS)
 	{
 		LocalPgBackendStatus *local_beentry;
 		PgBackendStatus *beentry;
-		Datum		values[PG_STAT_GET_PROGRESS_COLS];
-		bool		nulls[PG_STAT_GET_PROGRESS_COLS];
+		Datum		values[PG_STAT_GET_PROGRESS_COLS] = {0};
+		bool		nulls[PG_STAT_GET_PROGRESS_COLS] = {0};
 		int			i;
 
-		MemSet(values, 0, sizeof(values));
-		MemSet(nulls, 0, sizeof(nulls));
-
 		local_beentry = pgstat_fetch_stat_local_beentry(curr_backend);
 
 		if (!local_beentry)
@@ -585,17 +582,14 @@ pg_stat_get_activity(PG_FUNCTION_ARGS)
 	for (curr_backend = 1; curr_backend <= num_backends; curr_backend++)
 	{
 		/* for each row */
-		Datum		values[PG_STAT_GET_ACTIVITY_COLS];
-		bool		nulls[PG_STAT_GET_ACTIVITY_COLS];
+		Datum		values[PG_STAT_GET_ACTIVITY_COLS] = {0};
+		bool		nulls[PG_STAT_GET_ACTIVITY_COLS] = {0};
 		LocalPgBackendStatus *local_beentry;
 		PgBackendStatus *beentry;
 		PGPROC	   *proc;
 		const char *wait_event_type = NULL;
 		const char *wait_event = NULL;
 
-		MemSet(values, 0, sizeof(values));
-		MemSet(nulls, 0, sizeof(nulls));
-
 		/* Get the next one in the list */
 		local_beentry = pgstat_fetch_stat_local_beentry(curr_backend);
 		if (!local_beentry)
@@ -1908,14 +1902,10 @@ Datum
 pg_stat_get_archiver(PG_FUNCTION_ARGS)
 {
 	TupleDesc	tupdesc;
-	Datum		values[7];
-	bool		nulls[7];
+	Datum		values[7] = {0};
+	bool		nulls[7] = {0};
 	PgStat_ArchiverStats *archiver_stats;
 
-	/* Initialise values and NULL flags arrays */
-	MemSet(values, 0, sizeof(values));
-	MemSet(nulls, 0, sizeof(nulls));
-
 	/* Initialise attributes information in the tuple descriptor */
 	tupdesc = CreateTemplateTupleDesc(7);
 	TupleDescInitEntry(tupdesc, (AttrNumber) 1, "archived_count",
diff --git a/src/backend/utils/misc/guc.c b/src/backend/utils/misc/guc.c
index 2178e1c..489d084 100644
--- a/src/backend/utils/misc/guc.c
+++ b/src/backend/utils/misc/guc.c
@@ -9483,11 +9483,8 @@ show_all_file_settings(PG_FUNCTION_ARGS)
 	/* Process the results and create a tuplestore */
 	for (seqno = 1; conf != NULL; conf = conf->next, seqno++)
 	{
-		Datum		values[NUM_PG_FILE_SETTINGS_ATTS];
-		bool		nulls[NUM_PG_FILE_SETTINGS_ATTS];
-
-		memset(values, 0, sizeof(values));
-		memset(nulls, 0, sizeof(nulls));
+		Datum		values[NUM_PG_FILE_SETTINGS_ATTS] = {0};
+		bool		nulls[NUM_PG_FILE_SETTINGS_ATTS] = {0};
 
 		/* sourcefile */
 		if (conf->filename)
diff --git a/src/backend/utils/mmgr/portalmem.c b/src/backend/utils/mmgr/portalmem.c
index 334e35b..2022c89 100644
--- a/src/backend/utils/mmgr/portalmem.c
+++ b/src/backend/utils/mmgr/portalmem.c
@@ -1176,14 +1176,12 @@ pg_cursor(PG_FUNCTION_ARGS)
 	{
 		Portal		portal = hentry->portal;
 		Datum		values[6];
-		bool		nulls[6];
+		bool		nulls[6] = {0};
 
 		/* report only "visible" entries */
 		if (!portal->visible)
 			continue;
 
-		MemSet(nulls, 0, sizeof(nulls));
-
 		values[0] = CStringGetTextDatum(portal->name);
 		values[1] = CStringGetTextDatum(portal->sourceText);
 		values[2] = BoolGetDatum(portal->cursorOptions & CURSOR_OPT_HOLD);
#2Amit Kapila
amit.kapila16@gmail.com
In reply to: Smith, Peter (#1)
Re: Proposal: Make use of C99 designated initialisers for nulls/values arrays

On Tue, Oct 1, 2019 at 1:25 PM Smith, Peter <peters@fast.au.fujitsu.com> wrote:

Dear Hackers,

I have identified some OSS code which maybe can make use of C99 designated initialisers for nulls/values arrays.

~

Background:
There are lots of tuple operations where arrays of values and flags are being passed.
Typically these arrays are being previously initialised 0/false by memset.
By modifying code to use C99 designated initialiser syntax [1], most of these memsets can become redundant.
Actually, this mechanism is already being used in some of the existing OSS code. This patch/proposal just propagates the same idea to all other similar places I could find.

~

Result:
Less code. Removes ~200 unnecessary memsets.
More consistent initialisation.

+1. This seems like an improvement. I can review and take this
forward unless there are objections from others.

--
With Regards,
Amit Kapila.
EnterpriseDB: http://www.enterprisedb.com

#3Andrew Dunstan
andrew.dunstan@2ndquadrant.com
In reply to: Amit Kapila (#2)
Re: Proposal: Make use of C99 designated initialisers for nulls/values arrays

On 10/1/19 6:12 AM, Amit Kapila wrote:

On Tue, Oct 1, 2019 at 1:25 PM Smith, Peter <peters@fast.au.fujitsu.com> wrote:

Dear Hackers,

I have identified some OSS code which maybe can make use of C99 designated initialisers for nulls/values arrays.

~

Background:
There are lots of tuple operations where arrays of values and flags are being passed.
Typically these arrays are being previously initialised 0/false by memset.
By modifying code to use C99 designated initialiser syntax [1], most of these memsets can become redundant.
Actually, this mechanism is already being used in some of the existing OSS code. This patch/proposal just propagates the same idea to all other similar places I could find.

~

Result:
Less code. Removes ~200 unnecessary memsets.
More consistent initialisation.

+1. This seems like an improvement. I can review and take this
forward unless there are objections from others.

+1.

cheers

andrew

--
Andrew Dunstan https://www.2ndQuadrant.com
PostgreSQL Development, 24x7 Support, Remote DBA, Training & Services

#4Isaac Morland
isaac.morland@gmail.com
In reply to: Smith, Peter (#1)
Re: Proposal: Make use of C99 designated initialisers for nulls/values arrays

On Tue, 1 Oct 2019 at 03:55, Smith, Peter <peters@fast.au.fujitsu.com>
wrote:

Typical Example:
Before:
Datum values[Natts_pg_attribute];
bool nulls[Natts_pg_attribute];
...
memset(values, 0, sizeof(values));
memset(nulls, false, sizeof(nulls));
After:
Datum values[Natts_pg_attribute] = {0};
bool nulls[Natts_pg_attribute] = {0};

I hope you'll forgive a noob question. Why does the "After" initialization
for the boolean array have {0} rather than {false}?

#5Bruce Momjian
bruce@momjian.us
In reply to: Andrew Dunstan (#3)
Re: Proposal: Make use of C99 designated initialisers for nulls/values arrays

On Tue, Oct 1, 2019 at 08:40:26AM -0400, Andrew Dunstan wrote:

On 10/1/19 6:12 AM, Amit Kapila wrote:

On Tue, Oct 1, 2019 at 1:25 PM Smith, Peter <peters@fast.au.fujitsu.com> wrote:

Dear Hackers,

I have identified some OSS code which maybe can make use of C99 designated initialisers for nulls/values arrays.

~

Background:
There are lots of tuple operations where arrays of values and flags are being passed.
Typically these arrays are being previously initialised 0/false by memset.
By modifying code to use C99 designated initialiser syntax [1], most of these memsets can become redundant.
Actually, this mechanism is already being used in some of the existing OSS code. This patch/proposal just propagates the same idea to all other similar places I could find.

~

Result:
Less code. Removes ~200 unnecessary memsets.
More consistent initialisation.

+1. This seems like an improvement. I can review and take this
forward unless there are objections from others.

+1.

I like it!

--
Bruce Momjian <bruce@momjian.us> http://momjian.us
EnterpriseDB http://enterprisedb.com

+ As you are, so once was I.  As I am, so you will be. +
+                      Ancient Roman grave inscription +
#6Tom Lane
tgl@sss.pgh.pa.us
In reply to: Bruce Momjian (#5)
Re: Proposal: Make use of C99 designated initialisers for nulls/values arrays

Bruce Momjian <bruce@momjian.us> writes:

On Tue, Oct 1, 2019 at 1:25 PM Smith, Peter <peters@fast.au.fujitsu.com> wrote:

There are lots of tuple operations where arrays of values and flags are being passed.
Typically these arrays are being previously initialised 0/false by memset.
By modifying code to use C99 designated initialiser syntax [1], most of these memsets can become redundant.

I like it!

FYI, I checked into whether this would result in worse generated code.
In the one place I checked (InsertPgAttributeTuple, which hopefully
is representative), I got *exactly the same* assembly code before
and after, on both a somewhat-aging gcc and fairly modern clang.
Hadn't quite expected that, but it removes any worries about whether
we might be losing anything.

Note though that InsertPgAttributeTuple uses memset(), while some of
these other places use MemSet(). The code I see being generated for
MemSet() is also the same(!) on clang, but it is different and
probably worse on gcc. I wonder if it isn't time to kick MemSet to
the curb. We have not re-evaluated that macro in more than a dozen
years, and compilers have surely changed.

regards, tom lane

#7Andres Freund
andres@anarazel.de
In reply to: Tom Lane (#6)
Re: Proposal: Make use of C99 designated initialisers for nulls/values arrays

Hi,

On 2019-10-01 12:17:08 -0400, Tom Lane wrote:

FYI, I checked into whether this would result in worse generated code.
In the one place I checked (InsertPgAttributeTuple, which hopefully
is representative), I got *exactly the same* assembly code before
and after, on both a somewhat-aging gcc and fairly modern clang.
Hadn't quite expected that, but it removes any worries about whether
we might be losing anything.

I think the only case where it's plausible to be really worse is where
we intentionally leave part of such allocations uninitialized - which we
can't easily do in these cases because the rest of the struct will also
get zeroed out. The compiler will probably figure it out in some cases,
but there's plenty where it can't. But I don't think there's many
places like that in our code though.

Note though that InsertPgAttributeTuple uses memset(), while some of
these other places use MemSet(). The code I see being generated for
MemSet() is also the same(!) on clang, but it is different and
probably worse on gcc. I wonder if it isn't time to kick MemSet to
the curb. We have not re-evaluated that macro in more than a dozen
years, and compilers have surely changed.

Yes, we really should!

- Andres

#8Thomas Munro
thomas.munro@gmail.com
In reply to: Andres Freund (#7)
Re: Proposal: Make use of C99 designated initialisers for nulls/values arrays

On Wed, Oct 2, 2019 at 5:49 AM Andres Freund <andres@anarazel.de> wrote:

On 2019-10-01 12:17:08 -0400, Tom Lane wrote:

Note though that InsertPgAttributeTuple uses memset(), while some of
these other places use MemSet(). The code I see being generated for
MemSet() is also the same(!) on clang, but it is different and
probably worse on gcc. I wonder if it isn't time to kick MemSet to
the curb. We have not re-evaluated that macro in more than a dozen
years, and compilers have surely changed.

Yes, we really should!

+1

FWIW I experimented with that over here:

/messages/by-id/CA+hUKGLfa6ANa0vs7Lf0op0XBH05HE8SyX8NFhDyT7k2CHYLXw@mail.gmail.com

#9Smith, Peter
peters@fast.au.fujitsu.com
In reply to: Isaac Morland (#4)
RE: Proposal: Make use of C99 designated initialisers for nulls/values arrays

From: Isaac Morland <isaac.morland@gmail.com> Sent: Tuesday, 1 October 2019 11:32 PM

Typical Example:
Before:
        Datum           values[Natts_pg_attribute];
        bool            nulls[Natts_pg_attribute];
        ...
        memset(values, 0, sizeof(values));
        memset(nulls, false, sizeof(nulls));
After:
        Datum           values[Natts_pg_attribute] = {0};
        bool            nulls[Natts_pg_attribute] = {0};

I hope you'll forgive a noob question. Why does the "After" initialization for the boolean array have {0} rather than {false}? 

It is a valid question.

I found that the original memsets that this patch replaces were already using 0 and false interchangeably. So I just picked one.
Reasons I chose {0} over {false} are: (a) laziness, and (b) consistency with the values[] initialiser.

But it is no problem to change the bool initialisers to {false} if that becomes a committer review issue.

Kind Regards
--
Peter Smith
Fujitsu Australia

#10Amit Kapila
amit.kapila16@gmail.com
In reply to: Smith, Peter (#9)
Re: Proposal: Make use of C99 designated initialisers for nulls/values arrays

On Wed, Oct 2, 2019 at 4:53 AM Smith, Peter <peters@fast.au.fujitsu.com>
wrote:

From: Isaac Morland <isaac.morland@gmail.com> Sent: Tuesday, 1 October
2019 11:32 PM

Typical Example:
Before:
Datum values[Natts_pg_attribute];
bool nulls[Natts_pg_attribute];
...
memset(values, 0, sizeof(values));
memset(nulls, false, sizeof(nulls));
After:
Datum values[Natts_pg_attribute] = {0};
bool nulls[Natts_pg_attribute] = {0};

I hope you'll forgive a noob question. Why does the "After"

initialization for the boolean array have {0} rather than {false}?

It is a valid question.

I found that the original memsets that this patch replaces were already
using 0 and false interchangeably. So I just picked one.
Reasons I chose {0} over {false} are: (a) laziness, and (b) consistency
with the values[] initialiser.

In this case, I think it is better to be consistent in all the places. As
of now (without patch), we are using 'false' or '0' to initialize the
boolean array. See below two instances from the patch:
1.
@@ -607,9 +601,9 @@ UpdateStatisticsForTypeChange(Oid statsOid, Oid
relationOid, int attnum,

Relation rel;

- Datum values[Natts_pg_statistic_ext_data];
- bool nulls[Natts_pg_statistic_ext_data];
- bool replaces[Natts_pg_statistic_ext_data];
+ Datum values[Natts_pg_statistic_ext_data] = {0};
+ bool nulls[Natts_pg_statistic_ext_data] = {0};
+ bool replaces[Natts_pg_statistic_ext_data] = {0};
  oldtup = SearchSysCache1(STATEXTDATASTXOID, ObjectIdGetDatum(statsOid));
  if (!HeapTupleIsValid(oldtup))
@@ -630,10 +624,6 @@ UpdateStatisticsForTypeChange(Oid statsOid, Oid
relationOid, int attnum,
  * OK, we need to reset some statistics. So let's build the new tuple,
  * replacing the affected statistics types with NULL.
  */
- memset(nulls, 0, Natts_pg_statistic_ext_data * sizeof(bool));
- memset(replaces, 0, Natts_pg_statistic_ext_data * sizeof(bool));
- memset(values, 0, Natts_pg_statistic_ext_data * sizeof(Datum));
2.
@@ -69,10 +69,10 @@ CreateStatistics(CreateStatsStmt *stmt)
  Oid namespaceId;
  Oid stxowner = GetUserId();
  HeapTuple htup;
- Datum values[Natts_pg_statistic_ext];
- bool nulls[Natts_pg_statistic_ext];
- Datum datavalues[Natts_pg_statistic_ext_data];
- bool datanulls[Natts_pg_statistic_ext_data];
+ Datum values[Natts_pg_statistic_ext] = {0};
+ bool nulls[Natts_pg_statistic_ext] = {0};
+ Datum datavalues[Natts_pg_statistic_ext_data] = {0};
+ bool datanulls[Natts_pg_statistic_ext_data] = {0};
  int2vector *stxkeys;
  Relation statrel;
  Relation datarel;
@@ -330,9 +330,6 @@ CreateStatistics(CreateStatsStmt *stmt)
  /*
  * Everything seems fine, so let's build the pg_statistic_ext tuple.
  */
- memset(values, 0, sizeof(values));
- memset(nulls, false, sizeof(nulls));
-
  statoid = GetNewOidWithIndex(statrel, StatisticExtOidIndexId,
  Anum_pg_statistic_ext_oid);
  values[Anum_pg_statistic_ext_oid - 1] = ObjectIdGetDatum(statoid);
@@ -357,9 +354,6 @@ CreateStatistics(CreateStatsStmt *stmt)
  */
  datarel = table_open(StatisticExtDataRelationId, RowExclusiveLock);

- memset(datavalues, 0, sizeof(datavalues));
- memset(datanulls, false, sizeof(datanulls));

In the first usage, we are initializing the boolean array with 0 and in the
second case, we are using false. The patch changes it to use 0 at all the
places which I think is better.

I don't have any strong opinion on this, but I would mildly prefer to
initialize boolean array with false just for the sake of readability (we
generally initializing booleans with false).

--
With Regards,
Amit Kapila.
EnterpriseDB: http://www.enterprisedb.com

#11Smith, Peter
peters@fast.au.fujitsu.com
In reply to: Amit Kapila (#2)
RE: Proposal: Make use of C99 designated initialisers for nulls/values arrays

From: Amit Kapila <amit.kapila16@gmail.com> Sent: Tuesday, 1 October 2019 8:12 PM

+1. This seems like an improvement. I can review and take this forward unless there are objections from others.

FYI - I created a Commitfest entry for this here: https://commitfest.postgresql.org/25/2290/

Kind Regards
--
Peter Smith
Fujitsu Australia

#12Smith, Peter
peters@fast.au.fujitsu.com
In reply to: Amit Kapila (#10)
1 attachment(s)
RE: Proposal: Make use of C99 designated initialisers for nulls/values arrays

From: Amit Kapila <amit.kapila16@gmail.com> Sent: Wednesday, 2 October 2019 9:42 AM

I don't have any strong opinion on this, but I would mildly prefer to initialize boolean array with false just for the sake of readability (we generally initializing booleans with false).

Done. Please see attached updated patch.

Kind Regards
--
Peter Smith
Fujitsu Australia

Attachments:

c99_init_nulls_2.patchapplication/octet-stream; name=c99_init_nulls_2.patchDownload
diff --git a/src/backend/access/transam/commit_ts.c b/src/backend/access/transam/commit_ts.c
index 3316734..13abd0a 100644
--- a/src/backend/access/transam/commit_ts.c
+++ b/src/backend/access/transam/commit_ts.c
@@ -422,8 +422,8 @@ pg_last_committed_xact(PG_FUNCTION_ARGS)
 {
 	TransactionId xid;
 	TimestampTz ts;
-	Datum		values[2];
-	bool		nulls[2];
+	Datum		values[2] = {0};
+	bool		nulls[2] = {false};
 	TupleDesc	tupdesc;
 	HeapTuple	htup;
 
@@ -448,10 +448,7 @@ pg_last_committed_xact(PG_FUNCTION_ARGS)
 	else
 	{
 		values[0] = TransactionIdGetDatum(xid);
-		nulls[0] = false;
-
 		values[1] = TimestampTzGetDatum(ts);
-		nulls[1] = false;
 	}
 
 	htup = heap_form_tuple(tupdesc, values, nulls);
diff --git a/src/backend/access/transam/twophase.c b/src/backend/access/transam/twophase.c
index 546bd43..009d0fb 100644
--- a/src/backend/access/transam/twophase.c
+++ b/src/backend/access/transam/twophase.c
@@ -770,8 +770,8 @@ pg_prepared_xact(PG_FUNCTION_ARGS)
 		GlobalTransaction gxact = &status->array[status->currIdx++];
 		PGPROC	   *proc = &ProcGlobal->allProcs[gxact->pgprocno];
 		PGXACT	   *pgxact = &ProcGlobal->allPgXact[gxact->pgprocno];
-		Datum		values[5];
-		bool		nulls[5];
+		Datum		values[5] = {0};
+		bool		nulls[5] = {false};
 		HeapTuple	tuple;
 		Datum		result;
 
@@ -781,9 +781,6 @@ pg_prepared_xact(PG_FUNCTION_ARGS)
 		/*
 		 * Form tuple with appropriate data.
 		 */
-		MemSet(values, 0, sizeof(values));
-		MemSet(nulls, 0, sizeof(nulls));
-
 		values[0] = TransactionIdGetDatum(pgxact->xid);
 		values[1] = CStringGetTextDatum(gxact->gid);
 		values[2] = TimestampTzGetDatum(gxact->prepared_at);
diff --git a/src/backend/access/transam/xlogfuncs.c b/src/backend/access/transam/xlogfuncs.c
index 8f17988..eccfa58 100644
--- a/src/backend/access/transam/xlogfuncs.c
+++ b/src/backend/access/transam/xlogfuncs.c
@@ -183,8 +183,8 @@ pg_stop_backup_v2(PG_FUNCTION_ARGS)
 	Tuplestorestate *tupstore;
 	MemoryContext per_query_ctx;
 	MemoryContext oldcontext;
-	Datum		values[3];
-	bool		nulls[3];
+	Datum		values[3] = {0};
+	bool		nulls[3] = {false};
 
 	bool		exclusive = PG_GETARG_BOOL(0);
 	bool		waitforarchive = PG_GETARG_BOOL(1);
@@ -216,9 +216,6 @@ pg_stop_backup_v2(PG_FUNCTION_ARGS)
 
 	MemoryContextSwitchTo(oldcontext);
 
-	MemSet(values, 0, sizeof(values));
-	MemSet(nulls, 0, sizeof(nulls));
-
 	if (exclusive)
 	{
 		if (status == SESSION_BACKUP_NON_EXCLUSIVE)
diff --git a/src/backend/catalog/aclchk.c b/src/backend/catalog/aclchk.c
index 88ce37c..89fe031 100644
--- a/src/backend/catalog/aclchk.c
+++ b/src/backend/catalog/aclchk.c
@@ -1158,9 +1158,9 @@ SetDefaultACL(InternalDefaultACL *iacls)
 	Acl		   *old_acl;
 	Acl		   *new_acl;
 	HeapTuple	newtuple;
-	Datum		values[Natts_pg_default_acl];
-	bool		nulls[Natts_pg_default_acl];
-	bool		replaces[Natts_pg_default_acl];
+	Datum		values[Natts_pg_default_acl] = {0};
+	bool		nulls[Natts_pg_default_acl] = {false};
+	bool		replaces[Natts_pg_default_acl] = {false};
 	int			noldmembers;
 	int			nnewmembers;
 	Oid		   *oldmembers;
@@ -1314,9 +1314,6 @@ SetDefaultACL(InternalDefaultACL *iacls)
 		Oid			defAclOid;
 
 		/* Prepare to insert or update pg_default_acl entry */
-		MemSet(values, 0, sizeof(values));
-		MemSet(nulls, false, sizeof(nulls));
-		MemSet(replaces, false, sizeof(replaces));
 
 		if (isNew)
 		{
@@ -1659,9 +1656,9 @@ ExecGrant_Attribute(InternalGrant *istmt, Oid relOid, const char *relname,
 	AclMode		avail_goptions;
 	bool		need_update;
 	HeapTuple	newtuple;
-	Datum		values[Natts_pg_attribute];
-	bool		nulls[Natts_pg_attribute];
-	bool		replaces[Natts_pg_attribute];
+	Datum		values[Natts_pg_attribute] = {0};
+	bool		nulls[Natts_pg_attribute] = {false};
+	bool		replaces[Natts_pg_attribute] = {false};
 	int			noldmembers;
 	int			nnewmembers;
 	Oid		   *oldmembers;
@@ -1742,9 +1739,6 @@ ExecGrant_Attribute(InternalGrant *istmt, Oid relOid, const char *relname,
 	nnewmembers = aclmembers(new_acl, &newmembers);
 
 	/* finished building new ACL value, now insert it */
-	MemSet(values, 0, sizeof(values));
-	MemSet(nulls, false, sizeof(nulls));
-	MemSet(replaces, false, sizeof(replaces));
 
 	/*
 	 * If the updated ACL is empty, we can set attacl to null, and maybe even
@@ -1972,9 +1966,9 @@ ExecGrant_Relation(InternalGrant *istmt)
 			Acl		   *new_acl;
 			Oid			grantorId;
 			HeapTuple	newtuple;
-			Datum		values[Natts_pg_class];
-			bool		nulls[Natts_pg_class];
-			bool		replaces[Natts_pg_class];
+			Datum		values[Natts_pg_class] = {0};
+			bool		nulls[Natts_pg_class] = {false};
+			bool		replaces[Natts_pg_class] = {false};
 			int			nnewmembers;
 			Oid		   *newmembers;
 			ObjectType	objtype;
@@ -2024,9 +2018,6 @@ ExecGrant_Relation(InternalGrant *istmt)
 			nnewmembers = aclmembers(new_acl, &newmembers);
 
 			/* finished building new ACL value, now insert it */
-			MemSet(values, 0, sizeof(values));
-			MemSet(nulls, false, sizeof(nulls));
-			MemSet(replaces, false, sizeof(replaces));
 
 			replaces[Anum_pg_class_relacl - 1] = true;
 			values[Anum_pg_class_relacl - 1] = PointerGetDatum(new_acl);
@@ -2147,9 +2138,9 @@ ExecGrant_Database(InternalGrant *istmt)
 		Oid			grantorId;
 		Oid			ownerId;
 		HeapTuple	newtuple;
-		Datum		values[Natts_pg_database];
-		bool		nulls[Natts_pg_database];
-		bool		replaces[Natts_pg_database];
+		Datum		values[Natts_pg_database] = {0};
+		bool		nulls[Natts_pg_database] = {false};
+		bool		replaces[Natts_pg_database] = {false};
 		int			noldmembers;
 		int			nnewmembers;
 		Oid		   *oldmembers;
@@ -2214,9 +2205,6 @@ ExecGrant_Database(InternalGrant *istmt)
 		nnewmembers = aclmembers(new_acl, &newmembers);
 
 		/* finished building new ACL value, now insert it */
-		MemSet(values, 0, sizeof(values));
-		MemSet(nulls, false, sizeof(nulls));
-		MemSet(replaces, false, sizeof(replaces));
 
 		replaces[Anum_pg_database_datacl - 1] = true;
 		values[Anum_pg_database_datacl - 1] = PointerGetDatum(new_acl);
@@ -2268,9 +2256,9 @@ ExecGrant_Fdw(InternalGrant *istmt)
 		Oid			ownerId;
 		HeapTuple	tuple;
 		HeapTuple	newtuple;
-		Datum		values[Natts_pg_foreign_data_wrapper];
-		bool		nulls[Natts_pg_foreign_data_wrapper];
-		bool		replaces[Natts_pg_foreign_data_wrapper];
+		Datum		values[Natts_pg_foreign_data_wrapper] = {0};
+		bool		nulls[Natts_pg_foreign_data_wrapper] = {false};
+		bool		replaces[Natts_pg_foreign_data_wrapper] = {false};
 		int			noldmembers;
 		int			nnewmembers;
 		Oid		   *oldmembers;
@@ -2336,9 +2324,6 @@ ExecGrant_Fdw(InternalGrant *istmt)
 		nnewmembers = aclmembers(new_acl, &newmembers);
 
 		/* finished building new ACL value, now insert it */
-		MemSet(values, 0, sizeof(values));
-		MemSet(nulls, false, sizeof(nulls));
-		MemSet(replaces, false, sizeof(replaces));
 
 		replaces[Anum_pg_foreign_data_wrapper_fdwacl - 1] = true;
 		values[Anum_pg_foreign_data_wrapper_fdwacl - 1] = PointerGetDatum(new_acl);
@@ -2395,9 +2380,9 @@ ExecGrant_ForeignServer(InternalGrant *istmt)
 		Oid			ownerId;
 		HeapTuple	tuple;
 		HeapTuple	newtuple;
-		Datum		values[Natts_pg_foreign_server];
-		bool		nulls[Natts_pg_foreign_server];
-		bool		replaces[Natts_pg_foreign_server];
+		Datum		values[Natts_pg_foreign_server] = {0};
+		bool		nulls[Natts_pg_foreign_server] = {false};
+		bool		replaces[Natts_pg_foreign_server] = {false};
 		int			noldmembers;
 		int			nnewmembers;
 		Oid		   *oldmembers;
@@ -2462,9 +2447,6 @@ ExecGrant_ForeignServer(InternalGrant *istmt)
 		nnewmembers = aclmembers(new_acl, &newmembers);
 
 		/* finished building new ACL value, now insert it */
-		MemSet(values, 0, sizeof(values));
-		MemSet(nulls, false, sizeof(nulls));
-		MemSet(replaces, false, sizeof(replaces));
 
 		replaces[Anum_pg_foreign_server_srvacl - 1] = true;
 		values[Anum_pg_foreign_server_srvacl - 1] = PointerGetDatum(new_acl);
@@ -2520,9 +2502,9 @@ ExecGrant_Function(InternalGrant *istmt)
 		Oid			ownerId;
 		HeapTuple	tuple;
 		HeapTuple	newtuple;
-		Datum		values[Natts_pg_proc];
-		bool		nulls[Natts_pg_proc];
-		bool		replaces[Natts_pg_proc];
+		Datum		values[Natts_pg_proc] = {0};
+		bool		nulls[Natts_pg_proc] = {false};
+		bool		replaces[Natts_pg_proc] = {false};
 		int			noldmembers;
 		int			nnewmembers;
 		Oid		   *oldmembers;
@@ -2586,9 +2568,6 @@ ExecGrant_Function(InternalGrant *istmt)
 		nnewmembers = aclmembers(new_acl, &newmembers);
 
 		/* finished building new ACL value, now insert it */
-		MemSet(values, 0, sizeof(values));
-		MemSet(nulls, false, sizeof(nulls));
-		MemSet(replaces, false, sizeof(replaces));
 
 		replaces[Anum_pg_proc_proacl - 1] = true;
 		values[Anum_pg_proc_proacl - 1] = PointerGetDatum(new_acl);
@@ -2643,9 +2622,9 @@ ExecGrant_Language(InternalGrant *istmt)
 		Oid			ownerId;
 		HeapTuple	tuple;
 		HeapTuple	newtuple;
-		Datum		values[Natts_pg_language];
-		bool		nulls[Natts_pg_language];
-		bool		replaces[Natts_pg_language];
+		Datum		values[Natts_pg_language] = {0};
+		bool		nulls[Natts_pg_language] = {false};
+		bool		replaces[Natts_pg_language] = {false};
 		int			noldmembers;
 		int			nnewmembers;
 		Oid		   *oldmembers;
@@ -2717,9 +2696,6 @@ ExecGrant_Language(InternalGrant *istmt)
 		nnewmembers = aclmembers(new_acl, &newmembers);
 
 		/* finished building new ACL value, now insert it */
-		MemSet(values, 0, sizeof(values));
-		MemSet(nulls, false, sizeof(nulls));
-		MemSet(replaces, false, sizeof(replaces));
 
 		replaces[Anum_pg_language_lanacl - 1] = true;
 		values[Anum_pg_language_lanacl - 1] = PointerGetDatum(new_acl);
@@ -2775,9 +2751,9 @@ ExecGrant_Largeobject(InternalGrant *istmt)
 		Oid			grantorId;
 		Oid			ownerId;
 		HeapTuple	newtuple;
-		Datum		values[Natts_pg_largeobject_metadata];
-		bool		nulls[Natts_pg_largeobject_metadata];
-		bool		replaces[Natts_pg_largeobject_metadata];
+		Datum		values[Natts_pg_largeobject_metadata] = {0};
+		bool		nulls[Natts_pg_largeobject_metadata] = {false};
+		bool		replaces[Natts_pg_largeobject_metadata] = {false};
 		int			noldmembers;
 		int			nnewmembers;
 		Oid		   *oldmembers;
@@ -2855,9 +2831,6 @@ ExecGrant_Largeobject(InternalGrant *istmt)
 		nnewmembers = aclmembers(new_acl, &newmembers);
 
 		/* finished building new ACL value, now insert it */
-		MemSet(values, 0, sizeof(values));
-		MemSet(nulls, false, sizeof(nulls));
-		MemSet(replaces, false, sizeof(replaces));
 
 		replaces[Anum_pg_largeobject_metadata_lomacl - 1] = true;
 		values[Anum_pg_largeobject_metadata_lomacl - 1]
@@ -2914,9 +2887,9 @@ ExecGrant_Namespace(InternalGrant *istmt)
 		Oid			ownerId;
 		HeapTuple	tuple;
 		HeapTuple	newtuple;
-		Datum		values[Natts_pg_namespace];
-		bool		nulls[Natts_pg_namespace];
-		bool		replaces[Natts_pg_namespace];
+		Datum		values[Natts_pg_namespace] = {0};
+		bool		nulls[Natts_pg_namespace] = {false};
+		bool		replaces[Natts_pg_namespace] = {false};
 		int			noldmembers;
 		int			nnewmembers;
 		Oid		   *oldmembers;
@@ -2981,9 +2954,6 @@ ExecGrant_Namespace(InternalGrant *istmt)
 		nnewmembers = aclmembers(new_acl, &newmembers);
 
 		/* finished building new ACL value, now insert it */
-		MemSet(values, 0, sizeof(values));
-		MemSet(nulls, false, sizeof(nulls));
-		MemSet(replaces, false, sizeof(replaces));
 
 		replaces[Anum_pg_namespace_nspacl - 1] = true;
 		values[Anum_pg_namespace_nspacl - 1] = PointerGetDatum(new_acl);
@@ -3037,9 +3007,9 @@ ExecGrant_Tablespace(InternalGrant *istmt)
 		Oid			grantorId;
 		Oid			ownerId;
 		HeapTuple	newtuple;
-		Datum		values[Natts_pg_tablespace];
-		bool		nulls[Natts_pg_tablespace];
-		bool		replaces[Natts_pg_tablespace];
+		Datum		values[Natts_pg_tablespace] = {0};
+		bool		nulls[Natts_pg_tablespace] = {false};
+		bool		replaces[Natts_pg_tablespace] = {false};
 		int			noldmembers;
 		int			nnewmembers;
 		Oid		   *oldmembers;
@@ -3105,9 +3075,6 @@ ExecGrant_Tablespace(InternalGrant *istmt)
 		nnewmembers = aclmembers(new_acl, &newmembers);
 
 		/* finished building new ACL value, now insert it */
-		MemSet(values, 0, sizeof(values));
-		MemSet(nulls, false, sizeof(nulls));
-		MemSet(replaces, false, sizeof(replaces));
 
 		replaces[Anum_pg_tablespace_spcacl - 1] = true;
 		values[Anum_pg_tablespace_spcacl - 1] = PointerGetDatum(new_acl);
@@ -3157,9 +3124,9 @@ ExecGrant_Type(InternalGrant *istmt)
 		Oid			grantorId;
 		Oid			ownerId;
 		HeapTuple	newtuple;
-		Datum		values[Natts_pg_type];
-		bool		nulls[Natts_pg_type];
-		bool		replaces[Natts_pg_type];
+		Datum		values[Natts_pg_type] = {0};
+		bool		nulls[Natts_pg_type] = {false};
+		bool		replaces[Natts_pg_type] = {false};
 		int			noldmembers;
 		int			nnewmembers;
 		Oid		   *oldmembers;
@@ -3239,9 +3206,6 @@ ExecGrant_Type(InternalGrant *istmt)
 		nnewmembers = aclmembers(new_acl, &newmembers);
 
 		/* finished building new ACL value, now insert it */
-		MemSet(values, 0, sizeof(values));
-		MemSet(nulls, false, sizeof(nulls));
-		MemSet(replaces, false, sizeof(replaces));
 
 		replaces[Anum_pg_type_typacl - 1] = true;
 		values[Anum_pg_type_typacl - 1] = PointerGetDatum(new_acl);
@@ -5992,17 +5956,13 @@ recordExtensionInitPrivWorker(Oid objoid, Oid classoid, int objsubid, Acl *new_a
 	/* If we find an entry, update it with the latest ACL. */
 	if (HeapTupleIsValid(oldtuple))
 	{
-		Datum		values[Natts_pg_init_privs];
-		bool		nulls[Natts_pg_init_privs];
-		bool		replace[Natts_pg_init_privs];
+		Datum		values[Natts_pg_init_privs] = {0};
+		bool		nulls[Natts_pg_init_privs] = {false};
+		bool		replace[Natts_pg_init_privs] = {false};
 
 		/* If we have a new ACL to set, then update the row with it. */
 		if (new_acl)
 		{
-			MemSet(values, 0, sizeof(values));
-			MemSet(nulls, false, sizeof(nulls));
-			MemSet(replace, false, sizeof(replace));
-
 			values[Anum_pg_init_privs_initprivs - 1] = PointerGetDatum(new_acl);
 			replace[Anum_pg_init_privs_initprivs - 1] = true;
 
@@ -6020,7 +5980,7 @@ recordExtensionInitPrivWorker(Oid objoid, Oid classoid, int objsubid, Acl *new_a
 	else
 	{
 		Datum		values[Natts_pg_init_privs];
-		bool		nulls[Natts_pg_init_privs];
+		bool		nulls[Natts_pg_init_privs] = {false};
 
 		/*
 		 * Only add a new entry if the new ACL is non-NULL.
@@ -6031,8 +5991,6 @@ recordExtensionInitPrivWorker(Oid objoid, Oid classoid, int objsubid, Acl *new_a
 		if (new_acl)
 		{
 			/* No entry found, so add it. */
-			MemSet(nulls, false, sizeof(nulls));
-
 			values[Anum_pg_init_privs_objoid - 1] = ObjectIdGetDatum(objoid);
 			values[Anum_pg_init_privs_classoid - 1] = ObjectIdGetDatum(classoid);
 			values[Anum_pg_init_privs_objsubid - 1] = Int32GetDatum(objsubid);
diff --git a/src/backend/catalog/heap.c b/src/backend/catalog/heap.c
index b7bcdd9..cc43f98 100644
--- a/src/backend/catalog/heap.c
+++ b/src/backend/catalog/heap.c
@@ -695,14 +695,10 @@ InsertPgAttributeTuple(Relation pg_attribute_rel,
 					   Form_pg_attribute new_attribute,
 					   CatalogIndexState indstate)
 {
-	Datum		values[Natts_pg_attribute];
-	bool		nulls[Natts_pg_attribute];
+	Datum		values[Natts_pg_attribute] = {0};
+	bool		nulls[Natts_pg_attribute] = {false};
 	HeapTuple	tup;
 
-	/* This is a tad tedious, but way cleaner than what we used to do... */
-	memset(values, 0, sizeof(values));
-	memset(nulls, false, sizeof(nulls));
-
 	values[Anum_pg_attribute_attrelid - 1] = ObjectIdGetDatum(new_attribute->attrelid);
 	values[Anum_pg_attribute_attname - 1] = NameGetDatum(&new_attribute->attname);
 	values[Anum_pg_attribute_atttypid - 1] = ObjectIdGetDatum(new_attribute->atttypid);
@@ -852,14 +848,10 @@ InsertPgClassTuple(Relation pg_class_desc,
 				   Datum reloptions)
 {
 	Form_pg_class rd_rel = new_rel_desc->rd_rel;
-	Datum		values[Natts_pg_class];
-	bool		nulls[Natts_pg_class];
+	Datum		values[Natts_pg_class] = {0};
+	bool		nulls[Natts_pg_class] = {false};
 	HeapTuple	tup;
 
-	/* This is a tad tedious, but way cleaner than what we used to do... */
-	memset(values, 0, sizeof(values));
-	memset(nulls, false, sizeof(nulls));
-
 	values[Anum_pg_class_oid - 1] = ObjectIdGetDatum(new_rel_oid);
 	values[Anum_pg_class_relname - 1] = NameGetDatum(&rd_rel->relname);
 	values[Anum_pg_class_relnamespace - 1] = ObjectIdGetDatum(rd_rel->relnamespace);
@@ -1645,14 +1637,11 @@ RemoveAttributeById(Oid relid, AttrNumber attnum)
 		/* clear the missing value if any */
 		if (attStruct->atthasmissing)
 		{
-			Datum		valuesAtt[Natts_pg_attribute];
-			bool		nullsAtt[Natts_pg_attribute];
-			bool		replacesAtt[Natts_pg_attribute];
+			Datum		valuesAtt[Natts_pg_attribute] = {0};
+			bool		nullsAtt[Natts_pg_attribute] = {false};
+			bool		replacesAtt[Natts_pg_attribute] = {false};
 
 			/* update the tuple - set atthasmissing and attmissingval */
-			MemSet(valuesAtt, 0, sizeof(valuesAtt));
-			MemSet(nullsAtt, false, sizeof(nullsAtt));
-			MemSet(replacesAtt, false, sizeof(replacesAtt));
 
 			valuesAtt[Anum_pg_attribute_atthasmissing - 1] =
 				BoolGetDatum(false);
@@ -2064,9 +2053,9 @@ RelationClearMissing(Relation rel)
 void
 SetAttrMissing(Oid relid, char *attname, char *value)
 {
-	Datum		valuesAtt[Natts_pg_attribute];
-	bool		nullsAtt[Natts_pg_attribute];
-	bool		replacesAtt[Natts_pg_attribute];
+	Datum		valuesAtt[Natts_pg_attribute] = {0};
+	bool		nullsAtt[Natts_pg_attribute] = {false};
+	bool		replacesAtt[Natts_pg_attribute] = {false};
 	Datum		missingval;
 	Form_pg_attribute attStruct;
 	Relation	attrrel,
@@ -2092,9 +2081,6 @@ SetAttrMissing(Oid relid, char *attname, char *value)
 								  Int32GetDatum(attStruct->atttypmod));
 
 	/* update the tuple - set atthasmissing and attmissingval */
-	MemSet(valuesAtt, 0, sizeof(valuesAtt));
-	MemSet(nullsAtt, false, sizeof(nullsAtt));
-	MemSet(replacesAtt, false, sizeof(replacesAtt));
 
 	valuesAtt[Anum_pg_attribute_atthasmissing - 1] = BoolGetDatum(true);
 	replacesAtt[Anum_pg_attribute_atthasmissing - 1] = true;
@@ -2191,15 +2177,12 @@ StoreAttrDefault(Relation rel, AttrNumber attnum,
 		Expr	   *expr2 = (Expr *) expr;
 		EState	   *estate = NULL;
 		ExprContext *econtext;
-		Datum		valuesAtt[Natts_pg_attribute];
-		bool		nullsAtt[Natts_pg_attribute];
-		bool		replacesAtt[Natts_pg_attribute];
+		Datum		valuesAtt[Natts_pg_attribute] = {0};
+		bool		nullsAtt[Natts_pg_attribute] = {false};
+		bool		replacesAtt[Natts_pg_attribute] = {false};
 		Datum		missingval = (Datum) 0;
 		bool		missingIsNull = true;
 
-		MemSet(valuesAtt, 0, sizeof(valuesAtt));
-		MemSet(nullsAtt, false, sizeof(nullsAtt));
-		MemSet(replacesAtt, false, sizeof(replacesAtt));
 		valuesAtt[Anum_pg_attribute_atthasdef - 1] = true;
 		replacesAtt[Anum_pg_attribute_atthasdef - 1] = true;
 
@@ -3419,7 +3402,7 @@ StorePartitionKey(Relation rel,
 	Relation	pg_partitioned_table;
 	HeapTuple	tuple;
 	Datum		values[Natts_pg_partitioned_table];
-	bool		nulls[Natts_pg_partitioned_table];
+	bool		nulls[Natts_pg_partitioned_table] = {false};
 	ObjectAddress myself;
 	ObjectAddress referenced;
 
@@ -3444,8 +3427,6 @@ StorePartitionKey(Relation rel,
 
 	pg_partitioned_table = table_open(PartitionedRelationId, RowExclusiveLock);
 
-	MemSet(nulls, false, sizeof(nulls));
-
 	/* Only this can ever be NULL */
 	if (!partexprDatum)
 		nulls[Anum_pg_partitioned_table_partexprs - 1] = true;
diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c
index 098732c..1a35940 100644
--- a/src/backend/catalog/index.c
+++ b/src/backend/catalog/index.c
@@ -546,7 +546,7 @@ UpdateIndexRelation(Oid indexoid,
 	Datum		exprsDatum;
 	Datum		predDatum;
 	Datum		values[Natts_pg_index];
-	bool		nulls[Natts_pg_index];
+	bool		nulls[Natts_pg_index] = {false};
 	Relation	pg_index;
 	HeapTuple	tuple;
 	int			i;
@@ -599,7 +599,6 @@ UpdateIndexRelation(Oid indexoid,
 	/*
 	 * Build a pg_index tuple
 	 */
-	MemSet(nulls, false, sizeof(nulls));
 
 	values[Anum_pg_index_indexrelid - 1] = ObjectIdGetDatum(indexoid);
 	values[Anum_pg_index_indrelid - 1] = ObjectIdGetDatum(heapoid);
diff --git a/src/backend/catalog/pg_collation.c b/src/backend/catalog/pg_collation.c
index dd99d53..0043096 100644
--- a/src/backend/catalog/pg_collation.c
+++ b/src/backend/catalog/pg_collation.c
@@ -57,7 +57,7 @@ CollationCreate(const char *collname, Oid collnamespace,
 	TupleDesc	tupDesc;
 	HeapTuple	tup;
 	Datum		values[Natts_pg_collation];
-	bool		nulls[Natts_pg_collation];
+	bool		nulls[Natts_pg_collation] = {false};
 	NameData	name_name,
 				name_collate,
 				name_ctype;
@@ -151,7 +151,6 @@ CollationCreate(const char *collname, Oid collnamespace,
 	tupDesc = RelationGetDescr(rel);
 
 	/* form a tuple */
-	memset(nulls, 0, sizeof(nulls));
 
 	namestrcpy(&name_name, collname);
 	oid = GetNewOidWithIndex(rel, CollationOidIndexId,
diff --git a/src/backend/catalog/pg_db_role_setting.c b/src/backend/catalog/pg_db_role_setting.c
index 20acac2..343929b 100644
--- a/src/backend/catalog/pg_db_role_setting.c
+++ b/src/backend/catalog/pg_db_role_setting.c
@@ -136,11 +136,9 @@ AlterSetting(Oid databaseid, Oid roleid, VariableSetStmt *setstmt)
 		/* non-null valuestr means it's not RESET, so insert a new tuple */
 		HeapTuple	newtuple;
 		Datum		values[Natts_pg_db_role_setting];
-		bool		nulls[Natts_pg_db_role_setting];
+		bool		nulls[Natts_pg_db_role_setting] = {false};
 		ArrayType  *a;
 
-		memset(nulls, false, sizeof(nulls));
-
 		a = GUCArrayAdd(NULL, setstmt->name, valuestr);
 
 		values[Anum_pg_db_role_setting_setdatabase - 1] =
diff --git a/src/backend/catalog/pg_depend.c b/src/backend/catalog/pg_depend.c
index a060c25..9acfa70 100644
--- a/src/backend/catalog/pg_depend.c
+++ b/src/backend/catalog/pg_depend.c
@@ -61,7 +61,7 @@ recordMultipleDependencies(const ObjectAddress *depender,
 	CatalogIndexState indstate;
 	HeapTuple	tup;
 	int			i;
-	bool		nulls[Natts_pg_depend];
+	bool		nulls[Natts_pg_depend] = {false};
 	Datum		values[Natts_pg_depend];
 
 	if (nreferenced <= 0)
@@ -79,8 +79,6 @@ recordMultipleDependencies(const ObjectAddress *depender,
 	/* Don't open indexes unless we need to make an update */
 	indstate = NULL;
 
-	memset(nulls, false, sizeof(nulls));
-
 	for (i = 0; i < nreferenced; i++, referenced++)
 	{
 		/*
diff --git a/src/backend/catalog/pg_enum.c b/src/backend/catalog/pg_enum.c
index d0ff802..93549bc 100644
--- a/src/backend/catalog/pg_enum.c
+++ b/src/backend/catalog/pg_enum.c
@@ -66,7 +66,7 @@ EnumValuesCreate(Oid enumTypeOid, List *vals)
 	int			elemno,
 				num_elems;
 	Datum		values[Natts_pg_enum];
-	bool		nulls[Natts_pg_enum];
+	bool		nulls[Natts_pg_enum] = {false};
 	ListCell   *lc;
 	HeapTuple	tup;
 
@@ -111,8 +111,6 @@ EnumValuesCreate(Oid enumTypeOid, List *vals)
 	qsort(oids, num_elems, sizeof(Oid), oid_cmp);
 
 	/* and make the entries */
-	memset(nulls, false, sizeof(nulls));
-
 	elemno = 0;
 	foreach(lc, vals)
 	{
@@ -215,7 +213,7 @@ AddEnumLabel(Oid enumTypeOid,
 	Relation	pg_enum;
 	Oid			newOid;
 	Datum		values[Natts_pg_enum];
-	bool		nulls[Natts_pg_enum];
+	bool		nulls[Natts_pg_enum] = {false};
 	NameData	enumlabel;
 	HeapTuple	enum_tup;
 	float4		newelemorder;
@@ -480,7 +478,6 @@ restart:
 	ReleaseCatCacheList(list);
 
 	/* Create the new pg_enum entry */
-	memset(nulls, false, sizeof(nulls));
 	values[Anum_pg_enum_oid - 1] = ObjectIdGetDatum(newOid);
 	values[Anum_pg_enum_enumtypid - 1] = ObjectIdGetDatum(enumTypeOid);
 	values[Anum_pg_enum_enumsortorder - 1] = Float4GetDatum(newelemorder);
diff --git a/src/backend/catalog/pg_inherits.c b/src/backend/catalog/pg_inherits.c
index 59af162..23b34fb 100644
--- a/src/backend/catalog/pg_inherits.c
+++ b/src/backend/catalog/pg_inherits.c
@@ -417,7 +417,7 @@ void
 StoreSingleInheritance(Oid relationId, Oid parentOid, int32 seqNumber)
 {
 	Datum		values[Natts_pg_inherits];
-	bool		nulls[Natts_pg_inherits];
+	bool		nulls[Natts_pg_inherits] = {false};
 	HeapTuple	tuple;
 	Relation	inhRelation;
 
@@ -430,8 +430,6 @@ StoreSingleInheritance(Oid relationId, Oid parentOid, int32 seqNumber)
 	values[Anum_pg_inherits_inhparent - 1] = ObjectIdGetDatum(parentOid);
 	values[Anum_pg_inherits_inhseqno - 1] = Int32GetDatum(seqNumber);
 
-	memset(nulls, 0, sizeof(nulls));
-
 	tuple = heap_form_tuple(RelationGetDescr(inhRelation), values, nulls);
 
 	CatalogTupleInsert(inhRelation, tuple);
diff --git a/src/backend/catalog/pg_largeobject.c b/src/backend/catalog/pg_largeobject.c
index 1a68702..c58a499 100644
--- a/src/backend/catalog/pg_largeobject.c
+++ b/src/backend/catalog/pg_largeobject.c
@@ -42,8 +42,8 @@ LargeObjectCreate(Oid loid)
 	Relation	pg_lo_meta;
 	HeapTuple	ntup;
 	Oid			loid_new;
-	Datum		values[Natts_pg_largeobject_metadata];
-	bool		nulls[Natts_pg_largeobject_metadata];
+	Datum		values[Natts_pg_largeobject_metadata] = {0};
+	bool		nulls[Natts_pg_largeobject_metadata] = {false};
 
 	pg_lo_meta = table_open(LargeObjectMetadataRelationId,
 							RowExclusiveLock);
@@ -51,8 +51,6 @@ LargeObjectCreate(Oid loid)
 	/*
 	 * Insert metadata of the largeobject
 	 */
-	memset(values, 0, sizeof(values));
-	memset(nulls, false, sizeof(nulls));
 
 	if (OidIsValid(loid))
 		loid_new = loid;
diff --git a/src/backend/catalog/pg_publication.c b/src/backend/catalog/pg_publication.c
index fd5da7d..adccd77 100644
--- a/src/backend/catalog/pg_publication.c
+++ b/src/backend/catalog/pg_publication.c
@@ -154,8 +154,8 @@ publication_add_relation(Oid pubid, Relation targetrel,
 {
 	Relation	rel;
 	HeapTuple	tup;
-	Datum		values[Natts_pg_publication_rel];
-	bool		nulls[Natts_pg_publication_rel];
+	Datum		values[Natts_pg_publication_rel] = {0};
+	bool		nulls[Natts_pg_publication_rel] = {false};
 	Oid			relid = RelationGetRelid(targetrel);
 	Oid			prrelid;
 	Publication *pub = GetPublication(pubid);
@@ -186,8 +186,6 @@ publication_add_relation(Oid pubid, Relation targetrel,
 	check_publication_add_relation(targetrel);
 
 	/* Form a tuple. */
-	memset(values, 0, sizeof(values));
-	memset(nulls, false, sizeof(nulls));
 
 	prrelid = GetNewOidWithIndex(rel, PublicationRelObjectIndexId,
 								 Anum_pg_publication_rel_oid);
diff --git a/src/backend/catalog/pg_range.c b/src/backend/catalog/pg_range.c
index e6e138b..d9f9576 100644
--- a/src/backend/catalog/pg_range.c
+++ b/src/backend/catalog/pg_range.c
@@ -39,15 +39,13 @@ RangeCreate(Oid rangeTypeOid, Oid rangeSubType, Oid rangeCollation,
 {
 	Relation	pg_range;
 	Datum		values[Natts_pg_range];
-	bool		nulls[Natts_pg_range];
+	bool		nulls[Natts_pg_range] = {false};
 	HeapTuple	tup;
 	ObjectAddress myself;
 	ObjectAddress referenced;
 
 	pg_range = table_open(RangeRelationId, RowExclusiveLock);
 
-	memset(nulls, 0, sizeof(nulls));
-
 	values[Anum_pg_range_rngtypid - 1] = ObjectIdGetDatum(rangeTypeOid);
 	values[Anum_pg_range_rngsubtype - 1] = ObjectIdGetDatum(rangeSubType);
 	values[Anum_pg_range_rngcollation - 1] = ObjectIdGetDatum(rangeCollation);
diff --git a/src/backend/catalog/pg_shdepend.c b/src/backend/catalog/pg_shdepend.c
index fb7f8dd..d537557 100644
--- a/src/backend/catalog/pg_shdepend.c
+++ b/src/backend/catalog/pg_shdepend.c
@@ -273,9 +273,7 @@ shdepChangeDep(Relation sdepRel,
 	{
 		/* Need to insert new entry */
 		Datum		values[Natts_pg_shdepend];
-		bool		nulls[Natts_pg_shdepend];
-
-		memset(nulls, false, sizeof(nulls));
+		bool		nulls[Natts_pg_shdepend] = {false};
 
 		values[Anum_pg_shdepend_dbid - 1] = ObjectIdGetDatum(dbid);
 		values[Anum_pg_shdepend_classid - 1] = ObjectIdGetDatum(classid);
@@ -801,9 +799,9 @@ copyTemplateDependencies(Oid templateDbId, Oid newDbId)
 	SysScanDesc scan;
 	HeapTuple	tup;
 	CatalogIndexState indstate;
-	Datum		values[Natts_pg_shdepend];
-	bool		nulls[Natts_pg_shdepend];
-	bool		replace[Natts_pg_shdepend];
+	Datum		values[Natts_pg_shdepend] = {0};
+	bool		nulls[Natts_pg_shdepend] = {false};
+	bool		replace[Natts_pg_shdepend] = {false};
 
 	sdepRel = table_open(SharedDependRelationId, RowExclusiveLock);
 	sdepDesc = RelationGetDescr(sdepRel);
@@ -820,10 +818,6 @@ copyTemplateDependencies(Oid templateDbId, Oid newDbId)
 							  NULL, 1, key);
 
 	/* Set up to copy the tuples except for inserting newDbId */
-	memset(values, 0, sizeof(values));
-	memset(nulls, false, sizeof(nulls));
-	memset(replace, false, sizeof(replace));
-
 	replace[Anum_pg_shdepend_dbid - 1] = true;
 	values[Anum_pg_shdepend_dbid - 1] = ObjectIdGetDatum(newDbId);
 
@@ -934,7 +928,7 @@ shdepAddDependency(Relation sdepRel,
 {
 	HeapTuple	tup;
 	Datum		values[Natts_pg_shdepend];
-	bool		nulls[Natts_pg_shdepend];
+	bool		nulls[Natts_pg_shdepend] = {false};
 
 	/*
 	 * Make sure the object doesn't go away while we record the dependency on
@@ -943,8 +937,6 @@ shdepAddDependency(Relation sdepRel,
 	 */
 	shdepLockAndCheckObject(refclassId, refobjId);
 
-	memset(nulls, false, sizeof(nulls));
-
 	/*
 	 * Form the new tuple and record the dependency.
 	 */
diff --git a/src/backend/catalog/pg_subscription.c b/src/backend/catalog/pg_subscription.c
index afee283..4af39f4 100644
--- a/src/backend/catalog/pg_subscription.c
+++ b/src/backend/catalog/pg_subscription.c
@@ -243,8 +243,8 @@ AddSubscriptionRelState(Oid subid, Oid relid, char state,
 {
 	Relation	rel;
 	HeapTuple	tup;
-	bool		nulls[Natts_pg_subscription_rel];
-	Datum		values[Natts_pg_subscription_rel];
+	bool		nulls[Natts_pg_subscription_rel] = {false};
+	Datum		values[Natts_pg_subscription_rel] = {0};
 
 	LockSharedObject(SubscriptionRelationId, subid, 0, AccessShareLock);
 
@@ -259,8 +259,6 @@ AddSubscriptionRelState(Oid subid, Oid relid, char state,
 			 relid, subid);
 
 	/* Form the tuple. */
-	memset(values, 0, sizeof(values));
-	memset(nulls, false, sizeof(nulls));
 	values[Anum_pg_subscription_rel_srsubid - 1] = ObjectIdGetDatum(subid);
 	values[Anum_pg_subscription_rel_srrelid - 1] = ObjectIdGetDatum(relid);
 	values[Anum_pg_subscription_rel_srsubstate - 1] = CharGetDatum(state);
@@ -289,9 +287,9 @@ UpdateSubscriptionRelState(Oid subid, Oid relid, char state,
 {
 	Relation	rel;
 	HeapTuple	tup;
-	bool		nulls[Natts_pg_subscription_rel];
-	Datum		values[Natts_pg_subscription_rel];
-	bool		replaces[Natts_pg_subscription_rel];
+	bool		nulls[Natts_pg_subscription_rel] = {false};
+	Datum		values[Natts_pg_subscription_rel] = {0};
+	bool		replaces[Natts_pg_subscription_rel] = {false};
 
 	LockSharedObject(SubscriptionRelationId, subid, 0, AccessShareLock);
 
@@ -306,10 +304,6 @@ UpdateSubscriptionRelState(Oid subid, Oid relid, char state,
 			 relid, subid);
 
 	/* Update the tuple. */
-	memset(values, 0, sizeof(values));
-	memset(nulls, false, sizeof(nulls));
-	memset(replaces, false, sizeof(replaces));
-
 	replaces[Anum_pg_subscription_rel_srsubstate - 1] = true;
 	values[Anum_pg_subscription_rel_srsubstate - 1] = CharGetDatum(state);
 
diff --git a/src/backend/commands/amcmds.c b/src/backend/commands/amcmds.c
index c0e4098..c37cce9 100644
--- a/src/backend/commands/amcmds.c
+++ b/src/backend/commands/amcmds.c
@@ -46,8 +46,8 @@ CreateAccessMethod(CreateAmStmt *stmt)
 	ObjectAddress referenced;
 	Oid			amoid;
 	Oid			amhandler;
-	bool		nulls[Natts_pg_am];
-	Datum		values[Natts_pg_am];
+	bool		nulls[Natts_pg_am] = {false};
+	Datum		values[Natts_pg_am] = {0};
 	HeapTuple	tup;
 
 	rel = table_open(AccessMethodRelationId, RowExclusiveLock);
@@ -79,9 +79,6 @@ CreateAccessMethod(CreateAmStmt *stmt)
 	/*
 	 * Insert tuple into pg_am.
 	 */
-	memset(values, 0, sizeof(values));
-	memset(nulls, false, sizeof(nulls));
-
 	amoid = GetNewOidWithIndex(rel, AmOidIndexId, Anum_pg_am_oid);
 	values[Anum_pg_am_oid - 1] = ObjectIdGetDatum(amoid);
 	values[Anum_pg_am_amname - 1] =
diff --git a/src/backend/commands/collationcmds.c b/src/backend/commands/collationcmds.c
index 919e092..9624ce8 100644
--- a/src/backend/commands/collationcmds.c
+++ b/src/backend/commands/collationcmds.c
@@ -315,18 +315,14 @@ AlterCollation(AlterCollationStmt *stmt)
 		elog(ERROR, "invalid collation version change");
 	else if (oldversion && newversion && strcmp(newversion, oldversion) != 0)
 	{
-		bool		nulls[Natts_pg_collation];
-		bool		replaces[Natts_pg_collation];
-		Datum		values[Natts_pg_collation];
+		bool		nulls[Natts_pg_collation] = {false};
+		bool		replaces[Natts_pg_collation] = {false};
+		Datum		values[Natts_pg_collation] = {0};
 
 		ereport(NOTICE,
 				(errmsg("changing version from %s to %s",
 						oldversion, newversion)));
 
-		memset(values, 0, sizeof(values));
-		memset(nulls, false, sizeof(nulls));
-		memset(replaces, false, sizeof(replaces));
-
 		values[Anum_pg_collation_collversion - 1] = CStringGetTextDatum(newversion);
 		replaces[Anum_pg_collation_collversion - 1] = true;
 
diff --git a/src/backend/commands/event_trigger.c b/src/backend/commands/event_trigger.c
index f7ee983..ee6f234 100644
--- a/src/backend/commands/event_trigger.c
+++ b/src/backend/commands/event_trigger.c
@@ -381,7 +381,7 @@ insert_event_trigger_tuple(const char *trigname, const char *eventname, Oid evtO
 	Oid			trigoid;
 	HeapTuple	tuple;
 	Datum		values[Natts_pg_trigger];
-	bool		nulls[Natts_pg_trigger];
+	bool		nulls[Natts_pg_trigger] = {false};
 	NameData	evtnamedata,
 				evteventdata;
 	ObjectAddress myself,
@@ -394,7 +394,6 @@ insert_event_trigger_tuple(const char *trigname, const char *eventname, Oid evtO
 	trigoid = GetNewOidWithIndex(tgrel, EventTriggerOidIndexId,
 								 Anum_pg_event_trigger_oid);
 	values[Anum_pg_event_trigger_oid - 1] = ObjectIdGetDatum(trigoid);
-	memset(nulls, false, sizeof(nulls));
 	namestrcpy(&evtnamedata, trigname);
 	values[Anum_pg_event_trigger_evtname - 1] = NameGetDatum(&evtnamedata);
 	namestrcpy(&evteventdata, eventname);
@@ -1494,14 +1493,11 @@ pg_event_trigger_dropped_objects(PG_FUNCTION_ARGS)
 	{
 		SQLDropObject *obj;
 		int			i = 0;
-		Datum		values[12];
-		bool		nulls[12];
+		Datum		values[12] = {0};
+		bool		nulls[12] = {false};
 
 		obj = slist_container(SQLDropObject, next, iter.cur);
 
-		MemSet(values, 0, sizeof(values));
-		MemSet(nulls, 0, sizeof(nulls));
-
 		/* classid */
 		values[i++] = ObjectIdGetDatum(obj->address.classId);
 
@@ -2046,7 +2042,7 @@ pg_event_trigger_ddl_commands(PG_FUNCTION_ARGS)
 	{
 		CollectedCommand *cmd = lfirst(lc);
 		Datum		values[9];
-		bool		nulls[9];
+		bool		nulls[9] = {false};
 		ObjectAddress addr;
 		int			i = 0;
 
@@ -2064,8 +2060,6 @@ pg_event_trigger_ddl_commands(PG_FUNCTION_ARGS)
 			!OidIsValid(cmd->d.simple.address.objectId))
 			continue;
 
-		MemSet(nulls, 0, sizeof(nulls));
-
 		switch (cmd->type)
 		{
 			case SCT_Simple:
diff --git a/src/backend/commands/extension.c b/src/backend/commands/extension.c
index f7202cc..c98a0cd 100644
--- a/src/backend/commands/extension.c
+++ b/src/backend/commands/extension.c
@@ -1771,8 +1771,8 @@ InsertExtensionTuple(const char *extName, Oid extOwner,
 {
 	Oid			extensionOid;
 	Relation	rel;
-	Datum		values[Natts_pg_extension];
-	bool		nulls[Natts_pg_extension];
+	Datum		values[Natts_pg_extension] = {0};
+	bool		nulls[Natts_pg_extension] = {false};
 	HeapTuple	tuple;
 	ObjectAddress myself;
 	ObjectAddress nsp;
@@ -1783,9 +1783,6 @@ InsertExtensionTuple(const char *extName, Oid extOwner,
 	 */
 	rel = table_open(ExtensionRelationId, RowExclusiveLock);
 
-	memset(values, 0, sizeof(values));
-	memset(nulls, 0, sizeof(nulls));
-
 	extensionOid = GetNewOidWithIndex(rel, ExtensionOidIndexId,
 									  Anum_pg_extension_oid);
 	values[Anum_pg_extension_oid - 1] = ObjectIdGetDatum(extensionOid);
@@ -1960,8 +1957,8 @@ pg_available_extensions(PG_FUNCTION_ARGS)
 		{
 			ExtensionControlFile *control;
 			char	   *extname;
-			Datum		values[3];
-			bool		nulls[3];
+			Datum		values[3] = {0};
+			bool		nulls[3] = {false};
 
 			if (!is_extension_control_filename(de->d_name))
 				continue;
@@ -1976,9 +1973,6 @@ pg_available_extensions(PG_FUNCTION_ARGS)
 
 			control = read_extension_control_file(extname);
 
-			memset(values, 0, sizeof(values));
-			memset(nulls, 0, sizeof(nulls));
-
 			/* name */
 			values[0] = DirectFunctionCall1(namein,
 											CStringGetDatum(control->name));
@@ -2117,8 +2111,8 @@ get_available_versions_for_extension(ExtensionControlFile *pcontrol,
 	{
 		ExtensionVersionInfo *evi = (ExtensionVersionInfo *) lfirst(lc);
 		ExtensionControlFile *control;
-		Datum		values[7];
-		bool		nulls[7];
+		Datum		values[7] = {0};
+		bool		nulls[7] = {false};
 		ListCell   *lc2;
 
 		if (!evi->installable)
@@ -2129,9 +2123,6 @@ get_available_versions_for_extension(ExtensionControlFile *pcontrol,
 		 */
 		control = read_extension_aux_control_file(pcontrol, evi->name);
 
-		memset(values, 0, sizeof(values));
-		memset(nulls, 0, sizeof(nulls));
-
 		/* name */
 		values[0] = DirectFunctionCall1(namein,
 										CStringGetDatum(control->name));
@@ -2292,8 +2283,8 @@ pg_extension_update_paths(PG_FUNCTION_ARGS)
 		{
 			ExtensionVersionInfo *evi2 = (ExtensionVersionInfo *) lfirst(lc2);
 			List	   *path;
-			Datum		values[3];
-			bool		nulls[3];
+			Datum		values[3] = {0};
+			bool		nulls[3] = {false};
 
 			if (evi1 == evi2)
 				continue;
@@ -2302,8 +2293,6 @@ pg_extension_update_paths(PG_FUNCTION_ARGS)
 			path = find_update_path(evi_list, evi1, evi2, false, true);
 
 			/* Emit result row */
-			memset(values, 0, sizeof(values));
-			memset(nulls, 0, sizeof(nulls));
 
 			/* source */
 			values[0] = CStringGetTextDatum(evi1->name);
@@ -3061,9 +3050,9 @@ ApplyExtensionUpdates(Oid extensionOid,
 		SysScanDesc extScan;
 		HeapTuple	extTup;
 		Form_pg_extension extForm;
-		Datum		values[Natts_pg_extension];
-		bool		nulls[Natts_pg_extension];
-		bool		repl[Natts_pg_extension];
+		Datum		values[Natts_pg_extension] = {0};
+		bool		nulls[Natts_pg_extension] = {false};
+		bool		repl[Natts_pg_extension] = {false};
 		ObjectAddress myself;
 		ListCell   *lc;
 
@@ -3100,10 +3089,6 @@ ApplyExtensionUpdates(Oid extensionOid,
 		/*
 		 * Modify extrelocatable and extversion in the pg_extension tuple
 		 */
-		memset(values, 0, sizeof(values));
-		memset(nulls, 0, sizeof(nulls));
-		memset(repl, 0, sizeof(repl));
-
 		values[Anum_pg_extension_extrelocatable - 1] =
 			BoolGetDatum(control->relocatable);
 		repl[Anum_pg_extension_extrelocatable - 1] = true;
diff --git a/src/backend/commands/foreigncmds.c b/src/backend/commands/foreigncmds.c
index f96c278..6eccfdc 100644
--- a/src/backend/commands/foreigncmds.c
+++ b/src/backend/commands/foreigncmds.c
@@ -563,8 +563,8 @@ ObjectAddress
 CreateForeignDataWrapper(CreateFdwStmt *stmt)
 {
 	Relation	rel;
-	Datum		values[Natts_pg_foreign_data_wrapper];
-	bool		nulls[Natts_pg_foreign_data_wrapper];
+	Datum		values[Natts_pg_foreign_data_wrapper] = {0};
+	bool		nulls[Natts_pg_foreign_data_wrapper] = {false};
 	HeapTuple	tuple;
 	Oid			fdwId;
 	bool		handler_given;
@@ -601,9 +601,6 @@ CreateForeignDataWrapper(CreateFdwStmt *stmt)
 	/*
 	 * Insert tuple into pg_foreign_data_wrapper.
 	 */
-	memset(values, 0, sizeof(values));
-	memset(nulls, false, sizeof(nulls));
-
 	fdwId = GetNewOidWithIndex(rel, ForeignDataWrapperOidIndexId,
 							   Anum_pg_foreign_data_wrapper_oid);
 	values[Anum_pg_foreign_data_wrapper_oid - 1] = ObjectIdGetDatum(fdwId);
@@ -868,8 +865,8 @@ CreateForeignServer(CreateForeignServerStmt *stmt)
 {
 	Relation	rel;
 	Datum		srvoptions;
-	Datum		values[Natts_pg_foreign_server];
-	bool		nulls[Natts_pg_foreign_server];
+	Datum		values[Natts_pg_foreign_server] = {0};
+	bool		nulls[Natts_pg_foreign_server] = {false};
 	HeapTuple	tuple;
 	Oid			srvId;
 	Oid			ownerId;
@@ -918,9 +915,6 @@ CreateForeignServer(CreateForeignServerStmt *stmt)
 	/*
 	 * Insert tuple into pg_foreign_server.
 	 */
-	memset(values, 0, sizeof(values));
-	memset(nulls, false, sizeof(nulls));
-
 	srvId = GetNewOidWithIndex(rel, ForeignServerOidIndexId,
 							   Anum_pg_foreign_server_oid);
 	values[Anum_pg_foreign_server_oid - 1] = ObjectIdGetDatum(srvId);
@@ -1145,8 +1139,8 @@ CreateUserMapping(CreateUserMappingStmt *stmt)
 {
 	Relation	rel;
 	Datum		useoptions;
-	Datum		values[Natts_pg_user_mapping];
-	bool		nulls[Natts_pg_user_mapping];
+	Datum		values[Natts_pg_user_mapping] = {0};
+	bool		nulls[Natts_pg_user_mapping] = {false};
 	HeapTuple	tuple;
 	Oid			useId;
 	Oid			umId;
@@ -1201,9 +1195,6 @@ CreateUserMapping(CreateUserMappingStmt *stmt)
 	/*
 	 * Insert tuple into pg_user_mapping.
 	 */
-	memset(values, 0, sizeof(values));
-	memset(nulls, false, sizeof(nulls));
-
 	umId = GetNewOidWithIndex(rel, UserMappingOidIndexId,
 							  Anum_pg_user_mapping_oid);
 	values[Anum_pg_user_mapping_oid - 1] = ObjectIdGetDatum(umId);
@@ -1465,8 +1456,8 @@ CreateForeignTable(CreateForeignTableStmt *stmt, Oid relid)
 {
 	Relation	ftrel;
 	Datum		ftoptions;
-	Datum		values[Natts_pg_foreign_table];
-	bool		nulls[Natts_pg_foreign_table];
+	Datum		values[Natts_pg_foreign_table] = {0};
+	bool		nulls[Natts_pg_foreign_table] = {false};
 	HeapTuple	tuple;
 	AclResult	aclresult;
 	ObjectAddress myself;
@@ -1502,9 +1493,6 @@ CreateForeignTable(CreateForeignTableStmt *stmt, Oid relid)
 	/*
 	 * Insert tuple into pg_foreign_table.
 	 */
-	memset(values, 0, sizeof(values));
-	memset(nulls, false, sizeof(nulls));
-
 	values[Anum_pg_foreign_table_ftrelid - 1] = ObjectIdGetDatum(relid);
 	values[Anum_pg_foreign_table_ftserver - 1] = ObjectIdGetDatum(server->serverid);
 	/* Add table generic options */
diff --git a/src/backend/commands/functioncmds.c b/src/backend/commands/functioncmds.c
index 40f1f9a..756e4e8 100644
--- a/src/backend/commands/functioncmds.c
+++ b/src/backend/commands/functioncmds.c
@@ -1504,7 +1504,7 @@ CreateCast(CreateCastStmt *stmt)
 	Relation	relation;
 	HeapTuple	tuple;
 	Datum		values[Natts_pg_cast];
-	bool		nulls[Natts_pg_cast];
+	bool		nulls[Natts_pg_cast] = {false};
 	ObjectAddress myself,
 				referenced;
 	AclResult	aclresult;
@@ -1757,8 +1757,6 @@ CreateCast(CreateCastStmt *stmt)
 	values[Anum_pg_cast_castcontext - 1] = CharGetDatum(castcontext);
 	values[Anum_pg_cast_castmethod - 1] = CharGetDatum(castmethod);
 
-	MemSet(nulls, false, sizeof(nulls));
-
 	tuple = heap_form_tuple(RelationGetDescr(relation), values, nulls);
 
 	CatalogTupleInsert(relation, tuple);
@@ -1893,8 +1891,8 @@ CreateTransform(CreateTransformStmt *stmt)
 	AclResult	aclresult;
 	Form_pg_proc procstruct;
 	Datum		values[Natts_pg_transform];
-	bool		nulls[Natts_pg_transform];
-	bool		replaces[Natts_pg_transform];
+	bool		nulls[Natts_pg_transform] = {false};
+	bool		replaces[Natts_pg_transform] = {false};
 	Oid			transformid;
 	HeapTuple	tuple;
 	HeapTuple	newtuple;
@@ -1999,8 +1997,6 @@ CreateTransform(CreateTransformStmt *stmt)
 	values[Anum_pg_transform_trffromsql - 1] = ObjectIdGetDatum(fromsqlfuncid);
 	values[Anum_pg_transform_trftosql - 1] = ObjectIdGetDatum(tosqlfuncid);
 
-	MemSet(nulls, false, sizeof(nulls));
-
 	relation = table_open(TransformRelationId, RowExclusiveLock);
 
 	tuple = SearchSysCache2(TRFTYPELANG,
@@ -2017,7 +2013,6 @@ CreateTransform(CreateTransformStmt *stmt)
 							format_type_be(typeid),
 							stmt->lang)));
 
-		MemSet(replaces, false, sizeof(replaces));
 		replaces[Anum_pg_transform_trffromsql - 1] = true;
 		replaces[Anum_pg_transform_trftosql - 1] = true;
 
diff --git a/src/backend/commands/opclasscmds.c b/src/backend/commands/opclasscmds.c
index 6a1ccde..88dbc7d 100644
--- a/src/backend/commands/opclasscmds.c
+++ b/src/backend/commands/opclasscmds.c
@@ -248,8 +248,8 @@ CreateOpFamily(const char *amname, const char *opfname, Oid namespaceoid, Oid am
 	Oid			opfamilyoid;
 	Relation	rel;
 	HeapTuple	tup;
-	Datum		values[Natts_pg_opfamily];
-	bool		nulls[Natts_pg_opfamily];
+	Datum		values[Natts_pg_opfamily] = {0};
+	bool		nulls[Natts_pg_opfamily] = {false};
 	NameData	opfName;
 	ObjectAddress myself,
 				referenced;
@@ -272,9 +272,6 @@ CreateOpFamily(const char *amname, const char *opfname, Oid namespaceoid, Oid am
 	/*
 	 * Okay, let's create the pg_opfamily entry.
 	 */
-	memset(values, 0, sizeof(values));
-	memset(nulls, false, sizeof(nulls));
-
 	opfamilyoid = GetNewOidWithIndex(rel, OpfamilyOidIndexId,
 									 Anum_pg_opfamily_oid);
 	values[Anum_pg_opfamily_oid - 1] = ObjectIdGetDatum(opfamilyoid);
@@ -347,8 +344,8 @@ DefineOpClass(CreateOpClassStmt *stmt)
 	HeapTuple	tup;
 	Form_pg_am	amform;
 	IndexAmRoutine *amroutine;
-	Datum		values[Natts_pg_opclass];
-	bool		nulls[Natts_pg_opclass];
+	Datum		values[Natts_pg_opclass] = {0};
+	bool		nulls[Natts_pg_opclass] = {false};
 	AclResult	aclresult;
 	NameData	opcName;
 	ObjectAddress myself,
@@ -639,9 +636,6 @@ DefineOpClass(CreateOpClassStmt *stmt)
 	/*
 	 * Okay, let's create the pg_opclass entry.
 	 */
-	memset(values, 0, sizeof(values));
-	memset(nulls, false, sizeof(nulls));
-
 	opclassoid = GetNewOidWithIndex(rel, OpclassOidIndexId,
 									Anum_pg_opclass_oid);
 	values[Anum_pg_opclass_oid - 1] = ObjectIdGetDatum(opclassoid);
@@ -1308,8 +1302,8 @@ storeOperators(List *opfamilyname, Oid amoid,
 			   List *operators, bool isAdd)
 {
 	Relation	rel;
-	Datum		values[Natts_pg_amop];
-	bool		nulls[Natts_pg_amop];
+	Datum		values[Natts_pg_amop] = {0};
+	bool		nulls[Natts_pg_amop] = {false};
 	HeapTuple	tup;
 	Oid			entryoid;
 	ObjectAddress myself,
@@ -1344,8 +1338,6 @@ storeOperators(List *opfamilyname, Oid amoid,
 		oppurpose = OidIsValid(op->sortfamily) ? AMOP_ORDER : AMOP_SEARCH;
 
 		/* Create the pg_amop entry */
-		memset(values, 0, sizeof(values));
-		memset(nulls, false, sizeof(nulls));
 
 		entryoid = GetNewOidWithIndex(rel, AccessMethodOperatorOidIndexId,
 									  Anum_pg_amop_oid);
@@ -1426,8 +1418,8 @@ storeProcedures(List *opfamilyname, Oid amoid,
 				List *procedures, bool isAdd)
 {
 	Relation	rel;
-	Datum		values[Natts_pg_amproc];
-	bool		nulls[Natts_pg_amproc];
+	Datum		values[Natts_pg_amproc] = {0};
+	bool		nulls[Natts_pg_amproc] = {false};
 	HeapTuple	tup;
 	Oid			entryoid;
 	ObjectAddress myself,
@@ -1459,9 +1451,6 @@ storeProcedures(List *opfamilyname, Oid amoid,
 							NameListToString(opfamilyname))));
 
 		/* Create the pg_amproc entry */
-		memset(values, 0, sizeof(values));
-		memset(nulls, false, sizeof(nulls));
-
 		entryoid = GetNewOidWithIndex(rel, AccessMethodProcedureOidIndexId,
 									  Anum_pg_amproc_oid);
 		values[Anum_pg_amproc_oid - 1] = ObjectIdGetDatum(entryoid);
diff --git a/src/backend/commands/prepare.c b/src/backend/commands/prepare.c
index 7e0a041..e1eb06e 100644
--- a/src/backend/commands/prepare.c
+++ b/src/backend/commands/prepare.c
@@ -757,9 +757,7 @@ pg_prepared_statement(PG_FUNCTION_ARGS)
 		while ((prep_stmt = hash_seq_search(&hash_seq)) != NULL)
 		{
 			Datum		values[5];
-			bool		nulls[5];
-
-			MemSet(nulls, 0, sizeof(nulls));
+			bool		nulls[5] = {false};
 
 			values[0] = CStringGetTextDatum(prep_stmt->stmt_name);
 			values[1] = CStringGetTextDatum(prep_stmt->plansource->query_string);
diff --git a/src/backend/commands/proclang.c b/src/backend/commands/proclang.c
index 343cd1d..99a6087 100644
--- a/src/backend/commands/proclang.c
+++ b/src/backend/commands/proclang.c
@@ -325,8 +325,8 @@ create_proc_lang(const char *languageName, bool replace,
 {
 	Relation	rel;
 	TupleDesc	tupDesc;
-	Datum		values[Natts_pg_language];
-	bool		nulls[Natts_pg_language];
+	Datum		values[Natts_pg_language] = {0};
+	bool		nulls[Natts_pg_language] = {false};
 	bool		replaces[Natts_pg_language];
 	NameData	langname;
 	HeapTuple	oldtup;
@@ -340,8 +340,6 @@ create_proc_lang(const char *languageName, bool replace,
 	tupDesc = RelationGetDescr(rel);
 
 	/* Prepare data to be inserted */
-	memset(values, 0, sizeof(values));
-	memset(nulls, false, sizeof(nulls));
 	memset(replaces, true, sizeof(replaces));
 
 	namestrcpy(&langname, languageName);
diff --git a/src/backend/commands/publicationcmds.c b/src/backend/commands/publicationcmds.c
index f115d4b..fccc357 100644
--- a/src/backend/commands/publicationcmds.c
+++ b/src/backend/commands/publicationcmds.c
@@ -142,8 +142,8 @@ CreatePublication(CreatePublicationStmt *stmt)
 	Relation	rel;
 	ObjectAddress myself;
 	Oid			puboid;
-	bool		nulls[Natts_pg_publication];
-	Datum		values[Natts_pg_publication];
+	bool		nulls[Natts_pg_publication] = {false};
+	Datum		values[Natts_pg_publication] = {0};
 	HeapTuple	tup;
 	bool		publish_given;
 	bool		publish_insert;
@@ -178,9 +178,6 @@ CreatePublication(CreatePublicationStmt *stmt)
 	}
 
 	/* Form a tuple. */
-	memset(values, 0, sizeof(values));
-	memset(nulls, false, sizeof(nulls));
-
 	values[Anum_pg_publication_pubname - 1] =
 		DirectFunctionCall1(namein, CStringGetDatum(stmt->pubname));
 	values[Anum_pg_publication_pubowner - 1] = ObjectIdGetDatum(GetUserId());
@@ -250,9 +247,9 @@ static void
 AlterPublicationOptions(AlterPublicationStmt *stmt, Relation rel,
 						HeapTuple tup)
 {
-	bool		nulls[Natts_pg_publication];
-	bool		replaces[Natts_pg_publication];
-	Datum		values[Natts_pg_publication];
+	bool		nulls[Natts_pg_publication] = {false};
+	bool		replaces[Natts_pg_publication] = {false};
+	Datum		values[Natts_pg_publication] = {0};
 	bool		publish_given;
 	bool		publish_insert;
 	bool		publish_update;
@@ -267,10 +264,6 @@ AlterPublicationOptions(AlterPublicationStmt *stmt, Relation rel,
 							  &publish_truncate);
 
 	/* Everything ok, form a new tuple. */
-	memset(values, 0, sizeof(values));
-	memset(nulls, false, sizeof(nulls));
-	memset(replaces, false, sizeof(replaces));
-
 	if (publish_given)
 	{
 		values[Anum_pg_publication_pubinsert - 1] = BoolGetDatum(publish_insert);
diff --git a/src/backend/commands/seclabel.c b/src/backend/commands/seclabel.c
index 63219ad..de15630 100644
--- a/src/backend/commands/seclabel.c
+++ b/src/backend/commands/seclabel.c
@@ -258,12 +258,10 @@ SetSharedSecurityLabel(const ObjectAddress *object,
 	HeapTuple	oldtup;
 	HeapTuple	newtup = NULL;
 	Datum		values[Natts_pg_shseclabel];
-	bool		nulls[Natts_pg_shseclabel];
-	bool		replaces[Natts_pg_shseclabel];
+	bool		nulls[Natts_pg_shseclabel] = {false};
+	bool		replaces[Natts_pg_shseclabel] = {false};
 
 	/* Prepare to form or update a tuple, if necessary. */
-	memset(nulls, false, sizeof(nulls));
-	memset(replaces, false, sizeof(replaces));
 	values[Anum_pg_shseclabel_objoid - 1] = ObjectIdGetDatum(object->objectId);
 	values[Anum_pg_shseclabel_classoid - 1] = ObjectIdGetDatum(object->classId);
 	values[Anum_pg_shseclabel_provider - 1] = CStringGetTextDatum(provider);
@@ -333,8 +331,8 @@ SetSecurityLabel(const ObjectAddress *object,
 	HeapTuple	oldtup;
 	HeapTuple	newtup = NULL;
 	Datum		values[Natts_pg_seclabel];
-	bool		nulls[Natts_pg_seclabel];
-	bool		replaces[Natts_pg_seclabel];
+	bool		nulls[Natts_pg_seclabel] = {false};
+	bool		replaces[Natts_pg_seclabel] = {false};
 
 	/* Shared objects have their own security label catalog. */
 	if (IsSharedRelation(object->classId))
@@ -344,8 +342,6 @@ SetSecurityLabel(const ObjectAddress *object,
 	}
 
 	/* Prepare to form or update a tuple, if necessary. */
-	memset(nulls, false, sizeof(nulls));
-	memset(replaces, false, sizeof(replaces));
 	values[Anum_pg_seclabel_objoid - 1] = ObjectIdGetDatum(object->objectId);
 	values[Anum_pg_seclabel_classoid - 1] = ObjectIdGetDatum(object->classId);
 	values[Anum_pg_seclabel_objsubid - 1] = Int32GetDatum(object->objectSubId);
diff --git a/src/backend/commands/statscmds.c b/src/backend/commands/statscmds.c
index f51eb7b..e9a8f9e 100644
--- a/src/backend/commands/statscmds.c
+++ b/src/backend/commands/statscmds.c
@@ -69,10 +69,10 @@ CreateStatistics(CreateStatsStmt *stmt)
 	Oid			namespaceId;
 	Oid			stxowner = GetUserId();
 	HeapTuple	htup;
-	Datum		values[Natts_pg_statistic_ext];
-	bool		nulls[Natts_pg_statistic_ext];
-	Datum		datavalues[Natts_pg_statistic_ext_data];
-	bool		datanulls[Natts_pg_statistic_ext_data];
+	Datum		values[Natts_pg_statistic_ext] = {0};
+	bool		nulls[Natts_pg_statistic_ext] = {false};
+	Datum		datavalues[Natts_pg_statistic_ext_data] = {0};
+	bool		datanulls[Natts_pg_statistic_ext_data] = {false};
 	int2vector *stxkeys;
 	Relation	statrel;
 	Relation	datarel;
@@ -330,9 +330,6 @@ CreateStatistics(CreateStatsStmt *stmt)
 	/*
 	 * Everything seems fine, so let's build the pg_statistic_ext tuple.
 	 */
-	memset(values, 0, sizeof(values));
-	memset(nulls, false, sizeof(nulls));
-
 	statoid = GetNewOidWithIndex(statrel, StatisticExtOidIndexId,
 								 Anum_pg_statistic_ext_oid);
 	values[Anum_pg_statistic_ext_oid - 1] = ObjectIdGetDatum(statoid);
@@ -357,9 +354,6 @@ CreateStatistics(CreateStatsStmt *stmt)
 	 */
 	datarel = table_open(StatisticExtDataRelationId, RowExclusiveLock);
 
-	memset(datavalues, 0, sizeof(datavalues));
-	memset(datanulls, false, sizeof(datanulls));
-
 	datavalues[Anum_pg_statistic_ext_data_stxoid - 1] = ObjectIdGetDatum(statoid);
 
 	/* no statistics built yet */
@@ -607,9 +601,9 @@ UpdateStatisticsForTypeChange(Oid statsOid, Oid relationOid, int attnum,
 
 	Relation	rel;
 
-	Datum		values[Natts_pg_statistic_ext_data];
-	bool		nulls[Natts_pg_statistic_ext_data];
-	bool		replaces[Natts_pg_statistic_ext_data];
+	Datum		values[Natts_pg_statistic_ext_data] = {0};
+	bool		nulls[Natts_pg_statistic_ext_data] = {false};
+	bool		replaces[Natts_pg_statistic_ext_data] = {false};
 
 	oldtup = SearchSysCache1(STATEXTDATASTXOID, ObjectIdGetDatum(statsOid));
 	if (!HeapTupleIsValid(oldtup))
@@ -630,10 +624,6 @@ UpdateStatisticsForTypeChange(Oid statsOid, Oid relationOid, int attnum,
 	 * OK, we need to reset some statistics. So let's build the new tuple,
 	 * replacing the affected statistics types with NULL.
 	 */
-	memset(nulls, 0, Natts_pg_statistic_ext_data * sizeof(bool));
-	memset(replaces, 0, Natts_pg_statistic_ext_data * sizeof(bool));
-	memset(values, 0, Natts_pg_statistic_ext_data * sizeof(Datum));
-
 	replaces[Anum_pg_statistic_ext_data_stxdmcv - 1] = true;
 	nulls[Anum_pg_statistic_ext_data_stxdmcv - 1] = true;
 
diff --git a/src/backend/commands/subscriptioncmds.c b/src/backend/commands/subscriptioncmds.c
index 2e67a58..4cabcc3 100644
--- a/src/backend/commands/subscriptioncmds.c
+++ b/src/backend/commands/subscriptioncmds.c
@@ -317,8 +317,8 @@ CreateSubscription(CreateSubscriptionStmt *stmt, bool isTopLevel)
 	Relation	rel;
 	ObjectAddress myself;
 	Oid			subid;
-	bool		nulls[Natts_pg_subscription];
-	Datum		values[Natts_pg_subscription];
+	bool		nulls[Natts_pg_subscription] = {false};
+	Datum		values[Natts_pg_subscription] = {0};
 	Oid			owner = GetUserId();
 	HeapTuple	tup;
 	bool		connect;
@@ -396,9 +396,6 @@ CreateSubscription(CreateSubscriptionStmt *stmt, bool isTopLevel)
 	walrcv_check_conninfo(conninfo);
 
 	/* Everything ok, form a new tuple. */
-	memset(values, 0, sizeof(values));
-	memset(nulls, false, sizeof(nulls));
-
 	subid = GetNewOidWithIndex(rel, SubscriptionObjectIndexId,
 							   Anum_pg_subscription_oid);
 	values[Anum_pg_subscription_oid - 1] = ObjectIdGetDatum(subid);
@@ -636,9 +633,9 @@ AlterSubscription(AlterSubscriptionStmt *stmt)
 {
 	Relation	rel;
 	ObjectAddress myself;
-	bool		nulls[Natts_pg_subscription];
-	bool		replaces[Natts_pg_subscription];
-	Datum		values[Natts_pg_subscription];
+	bool		nulls[Natts_pg_subscription] = {false};
+	bool		replaces[Natts_pg_subscription] = {false};
+	Datum		values[Natts_pg_subscription] = {0};
 	HeapTuple	tup;
 	Oid			subid;
 	bool		update_tuple = false;
@@ -671,9 +668,6 @@ AlterSubscription(AlterSubscriptionStmt *stmt)
 	LockSharedObject(SubscriptionRelationId, subid, 0, AccessExclusiveLock);
 
 	/* Form a new tuple. */
-	memset(values, 0, sizeof(values));
-	memset(nulls, false, sizeof(nulls));
-	memset(replaces, false, sizeof(replaces));
 
 	switch (stmt->kind)
 	{
diff --git a/src/backend/commands/tablespace.c b/src/backend/commands/tablespace.c
index 84efb41..3c01980 100644
--- a/src/backend/commands/tablespace.c
+++ b/src/backend/commands/tablespace.c
@@ -236,7 +236,7 @@ CreateTableSpace(CreateTableSpaceStmt *stmt)
 #ifdef HAVE_SYMLINK
 	Relation	rel;
 	Datum		values[Natts_pg_tablespace];
-	bool		nulls[Natts_pg_tablespace];
+	bool		nulls[Natts_pg_tablespace] = {false};
 	HeapTuple	tuple;
 	Oid			tablespaceoid;
 	char	   *location;
@@ -334,8 +334,6 @@ CreateTableSpace(CreateTableSpaceStmt *stmt)
 	 */
 	rel = table_open(TableSpaceRelationId, RowExclusiveLock);
 
-	MemSet(nulls, false, sizeof(nulls));
-
 	tablespaceoid = GetNewOidWithIndex(rel, TablespaceOidIndexId,
 									   Anum_pg_tablespace_oid);
 	values[Anum_pg_tablespace_oid - 1] = ObjectIdGetDatum(tablespaceoid);
diff --git a/src/backend/commands/trigger.c b/src/backend/commands/trigger.c
index cdb1105..56ff802 100644
--- a/src/backend/commands/trigger.c
+++ b/src/backend/commands/trigger.c
@@ -171,7 +171,7 @@ CreateTrigger(CreateTrigStmt *stmt, const char *queryString,
 	List	   *whenRtable;
 	char	   *qual;
 	Datum		values[Natts_pg_trigger];
-	bool		nulls[Natts_pg_trigger];
+	bool		nulls[Natts_pg_trigger] = {false};
 	Relation	rel;
 	AclResult	aclresult;
 	Relation	tgrel;
@@ -844,8 +844,6 @@ CreateTrigger(CreateTrigStmt *stmt, const char *queryString,
 	 * makes the triggers in partitions identical to the ones in the
 	 * partitioned tables, except that they are marked internal.
 	 */
-	memset(nulls, false, sizeof(nulls));
-
 	values[Anum_pg_trigger_oid - 1] = ObjectIdGetDatum(trigoid);
 	values[Anum_pg_trigger_tgrelid - 1] = ObjectIdGetDatum(RelationGetRelid(rel));
 	values[Anum_pg_trigger_tgname - 1] = DirectFunctionCall1(namein,
diff --git a/src/backend/commands/tsearchcmds.c b/src/backend/commands/tsearchcmds.c
index 5d6528f..77270aa 100644
--- a/src/backend/commands/tsearchcmds.c
+++ b/src/backend/commands/tsearchcmds.c
@@ -179,8 +179,8 @@ DefineTSParser(List *names, List *parameters)
 	ListCell   *pl;
 	Relation	prsRel;
 	HeapTuple	tup;
-	Datum		values[Natts_pg_ts_parser];
-	bool		nulls[Natts_pg_ts_parser];
+	Datum		values[Natts_pg_ts_parser] = {0};
+	bool		nulls[Natts_pg_ts_parser] = {false};
 	NameData	pname;
 	Oid			prsOid;
 	Oid			namespaceoid;
@@ -197,9 +197,6 @@ DefineTSParser(List *names, List *parameters)
 	namespaceoid = QualifiedNameGetCreationNamespace(names, &prsname);
 
 	/* initialize tuple fields with name/namespace */
-	memset(values, 0, sizeof(values));
-	memset(nulls, false, sizeof(nulls));
-
 	prsOid = GetNewOidWithIndex(prsRel, TSParserOidIndexId,
 								Anum_pg_ts_parser_oid);
 	values[Anum_pg_ts_parser_oid - 1] = ObjectIdGetDatum(prsOid);
@@ -414,8 +411,8 @@ DefineTSDictionary(List *names, List *parameters)
 	ListCell   *pl;
 	Relation	dictRel;
 	HeapTuple	tup;
-	Datum		values[Natts_pg_ts_dict];
-	bool		nulls[Natts_pg_ts_dict];
+	Datum		values[Natts_pg_ts_dict] = {0};
+	bool		nulls[Natts_pg_ts_dict] = {false};
 	NameData	dname;
 	Oid			templId = InvalidOid;
 	List	   *dictoptions = NIL;
@@ -468,9 +465,6 @@ DefineTSDictionary(List *names, List *parameters)
 	/*
 	 * Looks good, insert
 	 */
-	memset(values, 0, sizeof(values));
-	memset(nulls, false, sizeof(nulls));
-
 	dictOid = GetNewOidWithIndex(dictRel, TSDictionaryOidIndexId,
 								 Anum_pg_ts_dict_oid);
 	values[Anum_pg_ts_dict_oid - 1] = ObjectIdGetDatum(dictOid);
@@ -733,7 +727,7 @@ DefineTSTemplate(List *names, List *parameters)
 	Relation	tmplRel;
 	HeapTuple	tup;
 	Datum		values[Natts_pg_ts_template];
-	bool		nulls[Natts_pg_ts_template];
+	bool		nulls[Natts_pg_ts_template] = {false};
 	NameData	dname;
 	int			i;
 	Oid			tmplOid;
@@ -753,7 +747,6 @@ DefineTSTemplate(List *names, List *parameters)
 
 	for (i = 0; i < Natts_pg_ts_template; i++)
 	{
-		nulls[i] = false;
 		values[i] = ObjectIdGetDatum(InvalidOid);
 	}
 
@@ -965,8 +958,8 @@ DefineTSConfiguration(List *names, List *parameters, ObjectAddress *copied)
 	Relation	cfgRel;
 	Relation	mapRel = NULL;
 	HeapTuple	tup;
-	Datum		values[Natts_pg_ts_config];
-	bool		nulls[Natts_pg_ts_config];
+	Datum		values[Natts_pg_ts_config] = {0};
+	bool		nulls[Natts_pg_ts_config] = {false};
 	AclResult	aclresult;
 	Oid			namespaceoid;
 	char	   *cfgname;
@@ -1050,9 +1043,6 @@ DefineTSConfiguration(List *names, List *parameters, ObjectAddress *copied)
 	/*
 	 * Looks good, build tuple and insert
 	 */
-	memset(values, 0, sizeof(values));
-	memset(nulls, false, sizeof(nulls));
-
 	cfgOid = GetNewOidWithIndex(cfgRel, TSConfigOidIndexId,
 								Anum_pg_ts_config_oid);
 	values[Anum_pg_ts_config_oid - 1] = ObjectIdGetDatum(cfgOid);
@@ -1089,11 +1079,8 @@ DefineTSConfiguration(List *names, List *parameters, ObjectAddress *copied)
 		{
 			Form_pg_ts_config_map cfgmap = (Form_pg_ts_config_map) GETSTRUCT(maptup);
 			HeapTuple	newmaptup;
-			Datum		mapvalues[Natts_pg_ts_config_map];
-			bool		mapnulls[Natts_pg_ts_config_map];
-
-			memset(mapvalues, 0, sizeof(mapvalues));
-			memset(mapnulls, false, sizeof(mapnulls));
+			Datum		mapvalues[Natts_pg_ts_config_map] = {0};
+			bool		mapnulls[Natts_pg_ts_config_map] = {false};
 
 			mapvalues[Anum_pg_ts_config_map_mapcfg - 1] = cfgOid;
 			mapvalues[Anum_pg_ts_config_map_maptokentype - 1] = cfgmap->maptokentype;
@@ -1420,9 +1407,8 @@ MakeConfigurationMapping(AlterTSConfigurationStmt *stmt,
 			for (j = 0; j < ndict; j++)
 			{
 				Datum		values[Natts_pg_ts_config_map];
-				bool		nulls[Natts_pg_ts_config_map];
+				bool		nulls[Natts_pg_ts_config_map] = {false};
 
-				memset(nulls, false, sizeof(nulls));
 				values[Anum_pg_ts_config_map_mapcfg - 1] = ObjectIdGetDatum(cfgId);
 				values[Anum_pg_ts_config_map_maptokentype - 1] = Int32GetDatum(tokens[i]);
 				values[Anum_pg_ts_config_map_mapseqno - 1] = Int32GetDatum(j + 1);
diff --git a/src/backend/libpq/hba.c b/src/backend/libpq/hba.c
index 2221c04..9f4e71c 100644
--- a/src/backend/libpq/hba.c
+++ b/src/backend/libpq/hba.c
@@ -2414,8 +2414,8 @@ static void
 fill_hba_line(Tuplestorestate *tuple_store, TupleDesc tupdesc,
 			  int lineno, HbaLine *hba, const char *err_msg)
 {
-	Datum		values[NUM_PG_HBA_FILE_RULES_ATTS];
-	bool		nulls[NUM_PG_HBA_FILE_RULES_ATTS];
+	Datum		values[NUM_PG_HBA_FILE_RULES_ATTS] = {0};
+	bool		nulls[NUM_PG_HBA_FILE_RULES_ATTS] = {false};
 	char		buffer[NI_MAXHOST];
 	HeapTuple	tuple;
 	int			index;
@@ -2427,8 +2427,6 @@ fill_hba_line(Tuplestorestate *tuple_store, TupleDesc tupdesc,
 
 	Assert(tupdesc->natts == NUM_PG_HBA_FILE_RULES_ATTS);
 
-	memset(values, 0, sizeof(values));
-	memset(nulls, 0, sizeof(nulls));
 	index = 0;
 
 	/* line_number */
diff --git a/src/backend/replication/logical/launcher.c b/src/backend/replication/logical/launcher.c
index 186057b..83e646e 100644
--- a/src/backend/replication/logical/launcher.c
+++ b/src/backend/replication/logical/launcher.c
@@ -1136,8 +1136,8 @@ pg_stat_get_subscription(PG_FUNCTION_ARGS)
 	for (i = 0; i <= max_logical_replication_workers; i++)
 	{
 		/* for each row */
-		Datum		values[PG_STAT_GET_SUBSCRIPTION_COLS];
-		bool		nulls[PG_STAT_GET_SUBSCRIPTION_COLS];
+		Datum		values[PG_STAT_GET_SUBSCRIPTION_COLS] = {0};
+		bool		nulls[PG_STAT_GET_SUBSCRIPTION_COLS] = {false};
 		int			worker_pid;
 		LogicalRepWorker worker;
 
@@ -1151,9 +1151,6 @@ pg_stat_get_subscription(PG_FUNCTION_ARGS)
 
 		worker_pid = worker.proc->pid;
 
-		MemSet(values, 0, sizeof(values));
-		MemSet(nulls, 0, sizeof(nulls));
-
 		values[0] = ObjectIdGetDatum(worker.subid);
 		if (OidIsValid(worker.relid))
 			values[1] = ObjectIdGetDatum(worker.relid);
diff --git a/src/backend/replication/logical/logicalfuncs.c b/src/backend/replication/logical/logicalfuncs.c
index d1cf80d..2e3026c 100644
--- a/src/backend/replication/logical/logicalfuncs.c
+++ b/src/backend/replication/logical/logicalfuncs.c
@@ -75,7 +75,7 @@ LogicalOutputWrite(LogicalDecodingContext *ctx, XLogRecPtr lsn, TransactionId xi
 				   bool last_write)
 {
 	Datum		values[3];
-	bool		nulls[3];
+	bool		nulls[3] = {false};
 	DecodingOutputState *p;
 
 	/* SQL Datums can only be of a limited length... */
@@ -84,7 +84,6 @@ LogicalOutputWrite(LogicalDecodingContext *ctx, XLogRecPtr lsn, TransactionId xi
 
 	p = (DecodingOutputState *) ctx->output_writer_private;
 
-	memset(nulls, 0, sizeof(nulls));
 	values[0] = LSNGetDatum(lsn);
 	values[1] = TransactionIdGetDatum(xid);
 
diff --git a/src/backend/replication/logical/origin.c b/src/backend/replication/logical/origin.c
index 07ae613..b5c1fc9 100644
--- a/src/backend/replication/logical/origin.c
+++ b/src/backend/replication/logical/origin.c
@@ -275,7 +275,7 @@ replorigin_create(char *roname)
 
 	for (roident = InvalidOid + 1; roident < PG_UINT16_MAX; roident++)
 	{
-		bool		nulls[Natts_pg_replication_origin];
+		bool		nulls[Natts_pg_replication_origin] = {false};
 		Datum		values[Natts_pg_replication_origin];
 		bool		collides;
 
@@ -301,8 +301,6 @@ replorigin_create(char *roname)
 			 * Ok, found an unused roident, insert the new row and do a CCI,
 			 * so our callers can look it up if they want to.
 			 */
-			memset(&nulls, 0, sizeof(nulls));
-
 			values[Anum_pg_replication_origin_roident - 1] = ObjectIdGetDatum(roident);
 			values[Anum_pg_replication_origin_roname - 1] = roname_d;
 
@@ -1517,7 +1515,7 @@ pg_show_replication_origin_status(PG_FUNCTION_ARGS)
 	for (i = 0; i < max_replication_slots; i++)
 	{
 		ReplicationState *state;
-		Datum		values[REPLICATION_ORIGIN_PROGRESS_COLS];
+		Datum		values[REPLICATION_ORIGIN_PROGRESS_COLS] = {0};
 		bool		nulls[REPLICATION_ORIGIN_PROGRESS_COLS];
 		char	   *roname;
 
@@ -1527,7 +1525,6 @@ pg_show_replication_origin_status(PG_FUNCTION_ARGS)
 		if (state->roident == InvalidRepOriginId)
 			continue;
 
-		memset(values, 0, sizeof(values));
 		memset(nulls, 1, sizeof(nulls));
 
 		values[0] = ObjectIdGetDatum(state->roident);
diff --git a/src/backend/replication/slotfuncs.c b/src/backend/replication/slotfuncs.c
index 42da631..1cad40a 100644
--- a/src/backend/replication/slotfuncs.c
+++ b/src/backend/replication/slotfuncs.c
@@ -77,7 +77,7 @@ pg_create_physical_replication_slot(PG_FUNCTION_ARGS)
 	bool		immediately_reserve = PG_GETARG_BOOL(1);
 	bool		temporary = PG_GETARG_BOOL(2);
 	Datum		values[2];
-	bool		nulls[2];
+	bool		nulls[2] = {false};
 	TupleDesc	tupdesc;
 	HeapTuple	tuple;
 	Datum		result;
@@ -95,12 +95,10 @@ pg_create_physical_replication_slot(PG_FUNCTION_ARGS)
 									 InvalidXLogRecPtr);
 
 	values[0] = NameGetDatum(&MyReplicationSlot->data.name);
-	nulls[0] = false;
 
 	if (immediately_reserve)
 	{
 		values[1] = LSNGetDatum(MyReplicationSlot->data.restart_lsn);
-		nulls[1] = false;
 	}
 	else
 		nulls[1] = true;
@@ -167,7 +165,7 @@ pg_create_logical_replication_slot(PG_FUNCTION_ARGS)
 	TupleDesc	tupdesc;
 	HeapTuple	tuple;
 	Datum		values[2];
-	bool		nulls[2];
+	bool		nulls[2] = {false};
 
 	if (get_call_result_type(fcinfo, NULL, &tupdesc) != TYPEFUNC_COMPOSITE)
 		elog(ERROR, "return type must be a row type");
@@ -184,8 +182,6 @@ pg_create_logical_replication_slot(PG_FUNCTION_ARGS)
 	values[0] = NameGetDatum(&MyReplicationSlot->data.name);
 	values[1] = LSNGetDatum(MyReplicationSlot->data.confirmed_flush);
 
-	memset(nulls, 0, sizeof(nulls));
-
 	tuple = heap_form_tuple(tupdesc, values, nulls);
 	result = HeapTupleGetDatum(tuple);
 
@@ -265,7 +261,7 @@ pg_get_replication_slots(PG_FUNCTION_ARGS)
 	{
 		ReplicationSlot *slot = &ReplicationSlotCtl->replication_slots[slotno];
 		Datum		values[PG_GET_REPLICATION_SLOTS_COLS];
-		bool		nulls[PG_GET_REPLICATION_SLOTS_COLS];
+		bool		nulls[PG_GET_REPLICATION_SLOTS_COLS] = {false};
 
 		ReplicationSlotPersistency persistency;
 		TransactionId xmin;
@@ -295,8 +291,6 @@ pg_get_replication_slots(PG_FUNCTION_ARGS)
 
 		SpinLockRelease(&slot->mutex);
 
-		memset(nulls, 0, sizeof(nulls));
-
 		i = 0;
 		values[i++] = NameGetDatum(&slot_name);
 
@@ -513,7 +507,7 @@ pg_replication_slot_advance(PG_FUNCTION_ARGS)
 	XLogRecPtr	minlsn;
 	TupleDesc	tupdesc;
 	Datum		values[2];
-	bool		nulls[2];
+	bool		nulls[2] = {false};
 	HeapTuple	tuple;
 	Datum		result;
 
@@ -572,7 +566,6 @@ pg_replication_slot_advance(PG_FUNCTION_ARGS)
 		endlsn = pg_physical_replication_slot_advance(moveto);
 
 	values[0] = NameGetDatum(&MyReplicationSlot->data.name);
-	nulls[0] = false;
 
 	/* Update the on disk state when lsn was updated. */
 	if (XLogRecPtrIsInvalid(endlsn))
@@ -587,7 +580,6 @@ pg_replication_slot_advance(PG_FUNCTION_ARGS)
 
 	/* Return the reached position. */
 	values[1] = LSNGetDatum(endlsn);
-	nulls[1] = false;
 
 	tuple = heap_form_tuple(tupdesc, values, nulls);
 	result = HeapTupleGetDatum(tuple);
@@ -609,7 +601,7 @@ copy_replication_slot(FunctionCallInfo fcinfo, bool logical_slot)
 	bool		temporary;
 	char	   *plugin;
 	Datum		values[2];
-	bool		nulls[2];
+	bool		nulls[2] = {false};
 	Datum		result;
 	TupleDesc	tupdesc;
 	HeapTuple	tuple;
@@ -779,11 +771,9 @@ copy_replication_slot(FunctionCallInfo fcinfo, bool logical_slot)
 
 	/* All done.  Set up the return values */
 	values[0] = NameGetDatum(dst_name);
-	nulls[0] = false;
 	if (!XLogRecPtrIsInvalid(MyReplicationSlot->data.confirmed_flush))
 	{
 		values[1] = LSNGetDatum(MyReplicationSlot->data.confirmed_flush);
-		nulls[1] = false;
 	}
 	else
 		nulls[1] = true;
diff --git a/src/backend/replication/walsender.c b/src/backend/replication/walsender.c
index eb4a98c..d17ab54 100644
--- a/src/backend/replication/walsender.c
+++ b/src/backend/replication/walsender.c
@@ -351,7 +351,7 @@ IdentifySystem(void)
 	TupOutputState *tstate;
 	TupleDesc	tupdesc;
 	Datum		values[4];
-	bool		nulls[4];
+	bool		nulls[4] = {false};
 
 	/*
 	 * Reply with a result set with one row, four columns. First col is system
@@ -388,7 +388,6 @@ IdentifySystem(void)
 	}
 
 	dest = CreateDestReceiver(DestRemoteSimple);
-	MemSet(nulls, false, sizeof(nulls));
 
 	/* need a tuple descriptor representing four columns */
 	tupdesc = CreateTemplateTupleDesc(4);
@@ -717,14 +716,13 @@ StartReplication(StartReplicationCmd *cmd)
 		TupOutputState *tstate;
 		TupleDesc	tupdesc;
 		Datum		values[2];
-		bool		nulls[2];
+		bool		nulls[2] = {false};
 
 		snprintf(startpos_str, sizeof(startpos_str), "%X/%X",
 				 (uint32) (sendTimeLineValidUpto >> 32),
 				 (uint32) sendTimeLineValidUpto);
 
 		dest = CreateDestReceiver(DestRemoteSimple);
-		MemSet(nulls, false, sizeof(nulls));
 
 		/*
 		 * Need a tuple descriptor representing two columns. int8 may seem
@@ -859,7 +857,7 @@ CreateReplicationSlot(CreateReplicationSlotCmd *cmd)
 	TupOutputState *tstate;
 	TupleDesc	tupdesc;
 	Datum		values[4];
-	bool		nulls[4];
+	bool		nulls[4] = {false};
 
 	Assert(!MyReplicationSlot);
 
@@ -995,7 +993,6 @@ CreateReplicationSlot(CreateReplicationSlotCmd *cmd)
 			 (uint32) MyReplicationSlot->data.confirmed_flush);
 
 	dest = CreateDestReceiver(DestRemoteSimple);
-	MemSet(nulls, false, sizeof(nulls));
 
 	/*----------
 	 * Need a tuple descriptor representing four columns:
@@ -3286,7 +3283,7 @@ pg_stat_get_wal_senders(PG_FUNCTION_ARGS)
 		WalSndState state;
 		TimestampTz replyTime;
 		Datum		values[PG_STAT_GET_WAL_SENDERS_COLS];
-		bool		nulls[PG_STAT_GET_WAL_SENDERS_COLS];
+		bool		nulls[PG_STAT_GET_WAL_SENDERS_COLS] = {false};
 
 		SpinLockAcquire(&walsnd->mutex);
 		if (walsnd->pid == 0)
@@ -3307,7 +3304,6 @@ pg_stat_get_wal_senders(PG_FUNCTION_ARGS)
 		replyTime = walsnd->replyTime;
 		SpinLockRelease(&walsnd->mutex);
 
-		memset(nulls, 0, sizeof(nulls));
 		values[0] = Int32GetDatum(pid);
 
 		if (!is_member_of_role(GetUserId(), DEFAULT_ROLE_READ_ALL_STATS))
diff --git a/src/backend/rewrite/rewriteDefine.c b/src/backend/rewrite/rewriteDefine.c
index 7df2b61..179e283 100644
--- a/src/backend/rewrite/rewriteDefine.c
+++ b/src/backend/rewrite/rewriteDefine.c
@@ -67,8 +67,8 @@ InsertRule(const char *rulname,
 	char	   *evqual = nodeToString(event_qual);
 	char	   *actiontree = nodeToString((Node *) action);
 	Datum		values[Natts_pg_rewrite];
-	bool		nulls[Natts_pg_rewrite];
-	bool		replaces[Natts_pg_rewrite];
+	bool		nulls[Natts_pg_rewrite] = {false};
+	bool		replaces[Natts_pg_rewrite] = {false};
 	NameData	rname;
 	Relation	pg_rewrite_desc;
 	HeapTuple	tup,
@@ -79,10 +79,8 @@ InsertRule(const char *rulname,
 	bool		is_update = false;
 
 	/*
-	 * Set up *nulls and *values arrays
+	 * Set up *values array
 	 */
-	MemSet(nulls, false, sizeof(nulls));
-
 	namestrcpy(&rname, rulname);
 	values[Anum_pg_rewrite_rulename - 1] = NameGetDatum(&rname);
 	values[Anum_pg_rewrite_ev_class - 1] = ObjectIdGetDatum(eventrel_oid);
@@ -115,7 +113,6 @@ InsertRule(const char *rulname,
 		/*
 		 * When replacing, we don't need to replace every attribute
 		 */
-		MemSet(replaces, false, sizeof(replaces));
 		replaces[Anum_pg_rewrite_ev_type - 1] = true;
 		replaces[Anum_pg_rewrite_is_instead - 1] = true;
 		replaces[Anum_pg_rewrite_ev_qual - 1] = true;
diff --git a/src/backend/statistics/extended_stats.c b/src/backend/statistics/extended_stats.c
index 207ee31..1ee9127 100644
--- a/src/backend/statistics/extended_stats.c
+++ b/src/backend/statistics/extended_stats.c
@@ -471,14 +471,12 @@ statext_store(Oid statOid,
 {
 	HeapTuple	stup,
 				oldtup;
-	Datum		values[Natts_pg_statistic_ext_data];
+	Datum		values[Natts_pg_statistic_ext_data] = {0};
 	bool		nulls[Natts_pg_statistic_ext_data];
-	bool		replaces[Natts_pg_statistic_ext_data];
+	bool		replaces[Natts_pg_statistic_ext_data] = {false};
 	Relation	pg_stextdata;
 
 	memset(nulls, true, sizeof(nulls));
-	memset(replaces, false, sizeof(replaces));
-	memset(values, 0, sizeof(values));
 
 	/*
 	 * Construct a new pg_statistic_ext_data tuple, replacing the calculated
diff --git a/src/backend/storage/large_object/inv_api.c b/src/backend/storage/large_object/inv_api.c
index e591236..f773a59 100644
--- a/src/backend/storage/large_object/inv_api.c
+++ b/src/backend/storage/large_object/inv_api.c
@@ -608,9 +608,6 @@ inv_write(LargeObjectDesc *obj_desc, const char *buf, int nbytes)
 	}			workbuf;
 	char	   *workb = VARDATA(&workbuf.hdr);
 	HeapTuple	newtup;
-	Datum		values[Natts_pg_largeobject];
-	bool		nulls[Natts_pg_largeobject];
-	bool		replace[Natts_pg_largeobject];
 	CatalogIndexState indstate;
 
 	Assert(PointerIsValid(obj_desc));
@@ -656,6 +653,10 @@ inv_write(LargeObjectDesc *obj_desc, const char *buf, int nbytes)
 
 	while (nwritten < nbytes)
 	{
+		Datum           values[Natts_pg_largeobject] = {0};
+		bool            nulls[Natts_pg_largeobject] = {false};
+		bool            replace[Natts_pg_largeobject] = {false};
+
 		/*
 		 * If possible, get next pre-existing page of the LO.  We expect the
 		 * indexscan will deliver these in order --- but there may be holes.
@@ -711,9 +712,6 @@ inv_write(LargeObjectDesc *obj_desc, const char *buf, int nbytes)
 			/*
 			 * Form and insert updated tuple
 			 */
-			memset(values, 0, sizeof(values));
-			memset(nulls, false, sizeof(nulls));
-			memset(replace, false, sizeof(replace));
 			values[Anum_pg_largeobject_data - 1] = PointerGetDatum(&workbuf);
 			replace[Anum_pg_largeobject_data - 1] = true;
 			newtup = heap_modify_tuple(oldtuple, RelationGetDescr(lo_heap_r),
@@ -755,8 +753,6 @@ inv_write(LargeObjectDesc *obj_desc, const char *buf, int nbytes)
 			/*
 			 * Form and insert updated tuple
 			 */
-			memset(values, 0, sizeof(values));
-			memset(nulls, false, sizeof(nulls));
 			values[Anum_pg_largeobject_loid - 1] = ObjectIdGetDatum(obj_desc->id);
 			values[Anum_pg_largeobject_pageno - 1] = Int32GetDatum(pageno);
 			values[Anum_pg_largeobject_data - 1] = PointerGetDatum(&workbuf);
@@ -799,9 +795,9 @@ inv_truncate(LargeObjectDesc *obj_desc, int64 len)
 	}			workbuf;
 	char	   *workb = VARDATA(&workbuf.hdr);
 	HeapTuple	newtup;
-	Datum		values[Natts_pg_largeobject];
-	bool		nulls[Natts_pg_largeobject];
-	bool		replace[Natts_pg_largeobject];
+	Datum		values[Natts_pg_largeobject] = {0};
+	bool		nulls[Natts_pg_largeobject] = {false};
+	bool		replace[Natts_pg_largeobject] = {false};
 	CatalogIndexState indstate;
 
 	Assert(PointerIsValid(obj_desc));
@@ -886,9 +882,6 @@ inv_truncate(LargeObjectDesc *obj_desc, int64 len)
 		/*
 		 * Form and insert updated tuple
 		 */
-		memset(values, 0, sizeof(values));
-		memset(nulls, false, sizeof(nulls));
-		memset(replace, false, sizeof(replace));
 		values[Anum_pg_largeobject_data - 1] = PointerGetDatum(&workbuf);
 		replace[Anum_pg_largeobject_data - 1] = true;
 		newtup = heap_modify_tuple(oldtuple, RelationGetDescr(lo_heap_r),
@@ -925,8 +918,6 @@ inv_truncate(LargeObjectDesc *obj_desc, int64 len)
 		/*
 		 * Form and insert new tuple
 		 */
-		memset(values, 0, sizeof(values));
-		memset(nulls, false, sizeof(nulls));
 		values[Anum_pg_largeobject_loid - 1] = ObjectIdGetDatum(obj_desc->id);
 		values[Anum_pg_largeobject_pageno - 1] = Int32GetDatum(pageno);
 		values[Anum_pg_largeobject_data - 1] = PointerGetDatum(&workbuf);
diff --git a/src/backend/utils/adt/acl.c b/src/backend/utils/adt/acl.c
index d7e6100..f6be73e 100644
--- a/src/backend/utils/adt/acl.c
+++ b/src/backend/utils/adt/acl.c
@@ -1810,7 +1810,7 @@ aclexplode(PG_FUNCTION_ARGS)
 		{
 			Datum		result;
 			Datum		values[4];
-			bool		nulls[4];
+			bool		nulls[4] = {false};
 			HeapTuple	tuple;
 
 			values[0] = ObjectIdGetDatum(aidata->ai_grantor);
@@ -1818,8 +1818,6 @@ aclexplode(PG_FUNCTION_ARGS)
 			values[2] = CStringGetTextDatum(convert_aclright_to_string(priv_bit));
 			values[3] = BoolGetDatum((ACLITEM_GET_GOPTIONS(*aidata) & priv_bit) != 0);
 
-			MemSet(nulls, 0, sizeof(nulls));
-
 			tuple = heap_form_tuple(funcctx->tuple_desc, values, nulls);
 			result = HeapTupleGetDatum(tuple);
 
diff --git a/src/backend/utils/adt/arrayfuncs.c b/src/backend/utils/adt/arrayfuncs.c
index 8079b13..afc3f08 100644
--- a/src/backend/utils/adt/arrayfuncs.c
+++ b/src/backend/utils/adt/arrayfuncs.c
@@ -738,11 +738,10 @@ ReadArrayStr(char *arrayStr,
 	bool		eoArray = false;
 	bool		hasnull;
 	int32		totbytes;
-	int			indx[MAXDIM],
+	int			indx[MAXDIM] = {0},
 				prod[MAXDIM];
 
 	mda_get_prod(ndim, dim, prod);
-	MemSet(indx, 0, sizeof(indx));
 
 	/* Initialize is-null markers to true */
 	memset(nulls, true, nitems * sizeof(bool));
diff --git a/src/backend/utils/adt/datetime.c b/src/backend/utils/adt/datetime.c
index e38bd93..2fdd9c6 100644
--- a/src/backend/utils/adt/datetime.c
+++ b/src/backend/utils/adt/datetime.c
@@ -4635,7 +4635,7 @@ pg_timezone_abbrevs(PG_FUNCTION_ARGS)
 	Datum		result;
 	HeapTuple	tuple;
 	Datum		values[3];
-	bool		nulls[3];
+	bool		nulls[3] = {false};
 	const datetkn *tp;
 	char		buffer[TOKMAXLEN + 1];
 	int			gmtoffset;
@@ -4722,8 +4722,6 @@ pg_timezone_abbrevs(PG_FUNCTION_ARGS)
 			break;
 	}
 
-	MemSet(nulls, 0, sizeof(nulls));
-
 	/*
 	 * Convert name to text, using upcasing conversion that is the inverse of
 	 * what ParseDateTime() uses.
@@ -4765,7 +4763,7 @@ pg_timezone_names(PG_FUNCTION_ARGS)
 	Datum		result;
 	HeapTuple	tuple;
 	Datum		values[4];
-	bool		nulls[4];
+	bool		nulls[4] = {false};
 	int			tzoff;
 	struct pg_tm tm;
 	fsec_t		fsec;
@@ -4847,8 +4845,6 @@ pg_timezone_names(PG_FUNCTION_ARGS)
 		break;
 	}
 
-	MemSet(nulls, 0, sizeof(nulls));
-
 	values[0] = CStringGetTextDatum(pg_get_timezone_name(tz));
 	values[1] = CStringGetTextDatum(tzn ? tzn : "");
 
diff --git a/src/backend/utils/adt/genfile.c b/src/backend/utils/adt/genfile.c
index 5d4f26a..8537085 100644
--- a/src/backend/utils/adt/genfile.c
+++ b/src/backend/utils/adt/genfile.c
@@ -576,7 +576,7 @@ pg_ls_dir_files(FunctionCallInfo fcinfo, const char *dir, bool missing_ok)
 	while ((de = ReadDir(fctx->dirdesc, fctx->location)) != NULL)
 	{
 		Datum		values[3];
-		bool		nulls[3];
+		bool		nulls[3] = {false};
 		char		path[MAXPGPATH * 2];
 		struct stat attrib;
 		HeapTuple	tuple;
@@ -599,7 +599,6 @@ pg_ls_dir_files(FunctionCallInfo fcinfo, const char *dir, bool missing_ok)
 		values[0] = CStringGetTextDatum(de->d_name);
 		values[1] = Int64GetDatum((int64) attrib.st_size);
 		values[2] = TimestampTzGetDatum(time_t_to_timestamptz(attrib.st_mtime));
-		memset(nulls, 0, sizeof(nulls));
 
 		tuple = heap_form_tuple(funcctx->tuple_desc, values, nulls);
 		SRF_RETURN_NEXT(funcctx, HeapTupleGetDatum(tuple));
diff --git a/src/backend/utils/adt/lockfuncs.c b/src/backend/utils/adt/lockfuncs.c
index bc62c6e..19c5437 100644
--- a/src/backend/utils/adt/lockfuncs.c
+++ b/src/backend/utils/adt/lockfuncs.c
@@ -160,8 +160,8 @@ pg_lock_status(PG_FUNCTION_ARGS)
 		LOCKMODE	mode = 0;
 		const char *locktypename;
 		char		tnbuf[32];
-		Datum		values[NUM_LOCK_STATUS_COLUMNS];
-		bool		nulls[NUM_LOCK_STATUS_COLUMNS];
+		Datum		values[NUM_LOCK_STATUS_COLUMNS] = {0};
+		bool		nulls[NUM_LOCK_STATUS_COLUMNS] = {false};
 		HeapTuple	tuple;
 		Datum		result;
 		LockInstanceData *instance;
@@ -218,9 +218,6 @@ pg_lock_status(PG_FUNCTION_ARGS)
 		/*
 		 * Form tuple with appropriate data.
 		 */
-		MemSet(values, 0, sizeof(values));
-		MemSet(nulls, false, sizeof(nulls));
-
 		if (instance->locktag.locktag_type <= LOCKTAG_LAST_TYPE)
 			locktypename = LockTagTypeNames[instance->locktag.locktag_type];
 		else
@@ -332,8 +329,8 @@ pg_lock_status(PG_FUNCTION_ARGS)
 
 		PREDICATELOCKTARGETTAG *predTag = &(predLockData->locktags[mystatus->predLockIdx]);
 		SERIALIZABLEXACT *xact = &(predLockData->xacts[mystatus->predLockIdx]);
-		Datum		values[NUM_LOCK_STATUS_COLUMNS];
-		bool		nulls[NUM_LOCK_STATUS_COLUMNS];
+		Datum		values[NUM_LOCK_STATUS_COLUMNS] = {0};
+		bool		nulls[NUM_LOCK_STATUS_COLUMNS] = {false};
 		HeapTuple	tuple;
 		Datum		result;
 
@@ -342,8 +339,6 @@ pg_lock_status(PG_FUNCTION_ARGS)
 		/*
 		 * Form tuple with appropriate data.
 		 */
-		MemSet(values, 0, sizeof(values));
-		MemSet(nulls, false, sizeof(nulls));
 
 		/* lock type */
 		lockType = GET_PREDICATELOCKTARGETTAG_TYPE(*predTag);
diff --git a/src/backend/utils/adt/pgstatfuncs.c b/src/backend/utils/adt/pgstatfuncs.c
index 05240bf..fa24d56 100644
--- a/src/backend/utils/adt/pgstatfuncs.c
+++ b/src/backend/utils/adt/pgstatfuncs.c
@@ -492,13 +492,10 @@ pg_stat_get_progress_info(PG_FUNCTION_ARGS)
 	{
 		LocalPgBackendStatus *local_beentry;
 		PgBackendStatus *beentry;
-		Datum		values[PG_STAT_GET_PROGRESS_COLS];
-		bool		nulls[PG_STAT_GET_PROGRESS_COLS];
+		Datum		values[PG_STAT_GET_PROGRESS_COLS] = {0};
+		bool		nulls[PG_STAT_GET_PROGRESS_COLS] = {false};
 		int			i;
 
-		MemSet(values, 0, sizeof(values));
-		MemSet(nulls, 0, sizeof(nulls));
-
 		local_beentry = pgstat_fetch_stat_local_beentry(curr_backend);
 
 		if (!local_beentry)
@@ -585,17 +582,14 @@ pg_stat_get_activity(PG_FUNCTION_ARGS)
 	for (curr_backend = 1; curr_backend <= num_backends; curr_backend++)
 	{
 		/* for each row */
-		Datum		values[PG_STAT_GET_ACTIVITY_COLS];
-		bool		nulls[PG_STAT_GET_ACTIVITY_COLS];
+		Datum		values[PG_STAT_GET_ACTIVITY_COLS] = {0};
+		bool		nulls[PG_STAT_GET_ACTIVITY_COLS] = {false};
 		LocalPgBackendStatus *local_beentry;
 		PgBackendStatus *beentry;
 		PGPROC	   *proc;
 		const char *wait_event_type = NULL;
 		const char *wait_event = NULL;
 
-		MemSet(values, 0, sizeof(values));
-		MemSet(nulls, 0, sizeof(nulls));
-
 		/* Get the next one in the list */
 		local_beentry = pgstat_fetch_stat_local_beentry(curr_backend);
 		if (!local_beentry)
@@ -1908,14 +1902,10 @@ Datum
 pg_stat_get_archiver(PG_FUNCTION_ARGS)
 {
 	TupleDesc	tupdesc;
-	Datum		values[7];
-	bool		nulls[7];
+	Datum		values[7] = {0};
+	bool		nulls[7] = {false};
 	PgStat_ArchiverStats *archiver_stats;
 
-	/* Initialise values and NULL flags arrays */
-	MemSet(values, 0, sizeof(values));
-	MemSet(nulls, 0, sizeof(nulls));
-
 	/* Initialise attributes information in the tuple descriptor */
 	tupdesc = CreateTemplateTupleDesc(7);
 	TupleDescInitEntry(tupdesc, (AttrNumber) 1, "archived_count",
diff --git a/src/backend/utils/misc/guc.c b/src/backend/utils/misc/guc.c
index 2178e1c..52a1ed8 100644
--- a/src/backend/utils/misc/guc.c
+++ b/src/backend/utils/misc/guc.c
@@ -9483,11 +9483,8 @@ show_all_file_settings(PG_FUNCTION_ARGS)
 	/* Process the results and create a tuplestore */
 	for (seqno = 1; conf != NULL; conf = conf->next, seqno++)
 	{
-		Datum		values[NUM_PG_FILE_SETTINGS_ATTS];
-		bool		nulls[NUM_PG_FILE_SETTINGS_ATTS];
-
-		memset(values, 0, sizeof(values));
-		memset(nulls, 0, sizeof(nulls));
+		Datum		values[NUM_PG_FILE_SETTINGS_ATTS] = {0};
+		bool		nulls[NUM_PG_FILE_SETTINGS_ATTS] = {false};
 
 		/* sourcefile */
 		if (conf->filename)
diff --git a/src/backend/utils/mmgr/portalmem.c b/src/backend/utils/mmgr/portalmem.c
index 334e35b..0ecbeb7 100644
--- a/src/backend/utils/mmgr/portalmem.c
+++ b/src/backend/utils/mmgr/portalmem.c
@@ -1176,14 +1176,12 @@ pg_cursor(PG_FUNCTION_ARGS)
 	{
 		Portal		portal = hentry->portal;
 		Datum		values[6];
-		bool		nulls[6];
+		bool		nulls[6] = {false};
 
 		/* report only "visible" entries */
 		if (!portal->visible)
 			continue;
 
-		MemSet(nulls, 0, sizeof(nulls));
-
 		values[0] = CStringGetTextDatum(portal->name);
 		values[1] = CStringGetTextDatum(portal->sourceText);
 		values[2] = BoolGetDatum(portal->cursorOptions & CURSOR_OPT_HOLD);
#13Joe Nelson
joe@begriffs.com
In reply to: Isaac Morland (#4)
Re: Proposal: Make use of C99 designated initialisers for nulls/values arrays

Isaac Morland wrote:

I hope you'll forgive a noob question. Why does the "After"
initialization for the boolean array have {0} rather than {false}?

I think using a value other than {0} potentially gives the incorrect
impression that the value is used for *all* elements of the
array/structure, whereas it is only used for the first element. "The
remainder of the aggregate shall be initialized implicitly the same as
objects that have static storage duration."

The rest of the elements are being initialized to zero as interpreted by
their types (so NULL for pointers, 0.0 for floats, even though neither
of them need be bitwise zero). Setting the first item to 0 matches that
exactly.

Using {false} may encourage the unwary to try

bool foo[2] = {true};

which will not set all elements to true.

#14Tom Lane
tgl@sss.pgh.pa.us
In reply to: Joe Nelson (#13)
Re: Proposal: Make use of C99 designated initialisers for nulls/values arrays

Joe Nelson <joe@begriffs.com> writes:

Isaac Morland wrote:

I hope you'll forgive a noob question. Why does the "After"
initialization for the boolean array have {0} rather than {false}?

I think using a value other than {0} potentially gives the incorrect
impression that the value is used for *all* elements of the
array/structure, whereas it is only used for the first element.

There's been something vaguely bothering me about this proposal,
and I think you just crystallized it.

Using {false} may encourage the unwary to try
bool foo[2] = {true};
which will not set all elements to true.

Right. I think that in general it's bad practice for an initializer
to not specify all fields/elements of the target. It is okay in the
specific case that we're substituting for a memset(..., 0, ...).
Perhaps we could make this explicit by using a coding style like

/* in c.h or some such place: */
#define INIT_ALL_ZEROES {0}

/* in code: */
Datum values[N] = INIT_ALL_ZEROES;

and then decreeing that it's not project style to use a partial
initializer other than in this way.

regards, tom lane

#15Isaac Morland
isaac.morland@gmail.com
In reply to: Joe Nelson (#13)
Re: Proposal: Make use of C99 designated initialisers for nulls/values arrays

On Wed, 2 Oct 2019 at 11:34, Joe Nelson <joe@begriffs.com> wrote:

Isaac Morland wrote:

I hope you'll forgive a noob question. Why does the "After"
initialization for the boolean array have {0} rather than {false}?

I think using a value other than {0} potentially gives the incorrect
impression that the value is used for *all* elements of the
array/structure, whereas it is only used for the first element. "The
remainder of the aggregate shall be initialized implicitly the same as
objects that have static storage duration."

The rest of the elements are being initialized to zero as interpreted by
their types (so NULL for pointers, 0.0 for floats, even though neither
of them need be bitwise zero). Setting the first item to 0 matches that
exactly.

Using {false} may encourage the unwary to try

bool foo[2] = {true};

which will not set all elements to true.

Thanks for the explanation. So the first however many elements are in curly
braces get initialized to those values, then the rest get initialized to
blank/0/0.0/false/...?

If so, I don't suppose it's possible to give empty braces:

bool nulls[Natts_pg_attribute] = {};

#16Joe Nelson
joe@begriffs.com
In reply to: Isaac Morland (#15)
Re: Proposal: Make use of C99 designated initialisers for nulls/values arrays

If so, I don't suppose it's possible to give empty braces:

bool nulls[Natts_pg_attribute] = {};

GNU does add this capability as a nonstandard language extension, but
according to the C99 standard, no.

#17Mark Dilger
hornschnorter@gmail.com
In reply to: Tom Lane (#14)
Re: Proposal: Make use of C99 designated initialisers for nulls/values arrays

On 10/2/19 8:46 AM, Tom Lane wrote:

Joe Nelson <joe@begriffs.com> writes:

Isaac Morland wrote:

I hope you'll forgive a noob question. Why does the "After"
initialization for the boolean array have {0} rather than {false}?

I think using a value other than {0} potentially gives the incorrect
impression that the value is used for *all* elements of the
array/structure, whereas it is only used for the first element.

There's been something vaguely bothering me about this proposal,
and I think you just crystallized it.

Using {false} may encourage the unwary to try
bool foo[2] = {true};
which will not set all elements to true.

Right. I think that in general it's bad practice for an initializer
to not specify all fields/elements of the target. It is okay in the
specific case that we're substituting for a memset(..., 0, ...).
Perhaps we could make this explicit by using a coding style like

/* in c.h or some such place: */
#define INIT_ALL_ZEROES {0}

/* in code: */
Datum values[N] = INIT_ALL_ZEROES;

and then decreeing that it's not project style to use a partial
initializer other than in this way.

There are numerous locations in the code that raise warnings when
-Wmissing-field-initializers is handed to gcc. See, for example,
src/backend/utils/adt/formatting.c where

static const KeyWord NUM_keywords[]

is initialized, and the code comment above that disclaims the need to
initialize is_digit and date_mode. Are you proposing cleaning up all
such incomplete initializations within the project?

I understand that your INIT_ALL_ZEROS macro does nothing to change
whether -Wmissing-field-initializers would raise a warning. I'm
just asking about the decree you propose, and I used that warning flag
to get the compiler to spit out relevant examples.

mark

#18Tom Lane
tgl@sss.pgh.pa.us
In reply to: Mark Dilger (#17)
Re: Proposal: Make use of C99 designated initialisers for nulls/values arrays

Mark Dilger <hornschnorter@gmail.com> writes:

On 10/2/19 8:46 AM, Tom Lane wrote:

Right. I think that in general it's bad practice for an initializer
to not specify all fields/elements of the target.

There are numerous locations in the code that raise warnings when
-Wmissing-field-initializers is handed to gcc. See, for example,
src/backend/utils/adt/formatting.c where
static const KeyWord NUM_keywords[]
is initialized, and the code comment above that disclaims the need to
initialize is_digit and date_mode. Are you proposing cleaning up all
such incomplete initializations within the project?

Hmm. Maybe it's worth doing as a code beautification effort, but
I'm not volunteering. At the same time, I wouldn't like to make a
change like this, if it introduces dozens/hundreds of new cases.

I understand that your INIT_ALL_ZEROS macro does nothing to change
whether -Wmissing-field-initializers would raise a warning.

Not sure --- the name of that option suggests that maybe it only
complains about omitted *struct fields* not omitted *array elements*.

If it does complain, is there any way that we could extend the macro
to annotate usages of it to suppress the warning?

regards, tom lane

#19Mark Dilger
hornschnorter@gmail.com
In reply to: Tom Lane (#18)
Re: Proposal: Make use of C99 designated initialisers for nulls/values arrays

On 10/2/19 11:02 AM, Tom Lane wrote:

Mark Dilger <hornschnorter@gmail.com> writes:

On 10/2/19 8:46 AM, Tom Lane wrote:

Right. I think that in general it's bad practice for an initializer
to not specify all fields/elements of the target.

There are numerous locations in the code that raise warnings when
-Wmissing-field-initializers is handed to gcc. See, for example,
src/backend/utils/adt/formatting.c where
static const KeyWord NUM_keywords[]
is initialized, and the code comment above that disclaims the need to
initialize is_digit and date_mode. Are you proposing cleaning up all
such incomplete initializations within the project?

Hmm. Maybe it's worth doing as a code beautification effort, but
I'm not volunteering. At the same time, I wouldn't like to make a
change like this, if it introduces dozens/hundreds of new cases.

I understand that your INIT_ALL_ZEROS macro does nothing to change
whether -Wmissing-field-initializers would raise a warning.

Not sure --- the name of that option suggests that maybe it only
complains about omitted *struct fields* not omitted *array elements*.

With gcc (Debian 8.3.0-6) 8.3.0

int foo[6] = {0, 1, 2};

does not draw a warning when compiled with this flag.

If it does complain, is there any way that we could extend the macro
to annotate usages of it to suppress the warning?

Neither initializing a struct with {0} nor with INIT_ALL_ZEROS draws a
warning either, with my gcc. There are reports online that older
versions of the compiler did, see

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=36750

but I don't have an older version to test with just now.

Note that initializing a multi-element struct with {1} does still draw a
warning, and reading the thread above suggests that gcc made a specific
effort to allow initialization to {0} to work without warning as a
special case.

So your proposal for using INIT_ALL_ZEROS is probably good with
sufficiently new compilers, and I'm generally in favor of the proposal,
but I don't think the decree you propose can work unless somebody cleans
up all these other cases that I indicated in my prior email.

(I'm sitting on a few patches until v12 goes out the door from some
conversations with you several months ago, and perhaps I'll include a
patch for this cleanup, too, when time comes for v13 patch sets to be
submitted. My past experience submitting patches shortly before a
release was that they get ignored.)

mark

#20Tom Lane
tgl@sss.pgh.pa.us
In reply to: Mark Dilger (#19)
Re: Proposal: Make use of C99 designated initialisers for nulls/values arrays

Mark Dilger <hornschnorter@gmail.com> writes:

(I'm sitting on a few patches until v12 goes out the door from some
conversations with you several months ago, and perhaps I'll include a
patch for this cleanup, too, when time comes for v13 patch sets to be
submitted.

That would be now. We already ran one CF for v13.

My past experience submitting patches shortly before a
release was that they get ignored.)

What you need to do is add 'em to the commitfest app. They might
still get ignored for awhile, but we won't forget about them.

regards, tom lane

#21Michael Paquier
michael@paquier.xyz
In reply to: Tom Lane (#20)
Re: Proposal: Make use of C99 designated initialisers for nulls/values arrays

On Wed, Oct 02, 2019 at 02:55:39PM -0400, Tom Lane wrote:

Mark Dilger <hornschnorter@gmail.com> writes:

(I'm sitting on a few patches until v12 goes out the door from some
conversations with you several months ago, and perhaps I'll include a
patch for this cleanup, too, when time comes for v13 patch sets to be
submitted.

That would be now. We already ran one CF for v13.

+1.

My past experience submitting patches shortly before a
release was that they get ignored.)

What you need to do is add 'em to the commitfest app. They might
still get ignored for awhile, but we won't forget about them.

The last commit fest of v13 will begin on March, and the next one is
planned for the beginning of November:
https://commitfest.postgresql.org/25/
So you still have plently of time to get something into 13.

Here are also some guidelines:
https://wiki.postgresql.org/wiki/Submitting_a_Patch
But you are already aware of anyway, right? :p
--
Michael

#22Smith, Peter
peters@fast.au.fujitsu.com
In reply to: Tom Lane (#14)
1 attachment(s)
RE: Proposal: Make use of C99 designated initialisers for nulls/values arrays

-----Original Message-----
From: Tom Lane <tgl@sss.pgh.pa.us> Sent: Thursday, 3 October 2019 1:46 AM

Right. I think that in general it's bad practice for an initializer to not specify all fields/elements of the target.
It is okay in the specific case that we're substituting for a memset(..., 0, ...).
Perhaps we could make this explicit by using a coding style like

/* in c.h or some such place: */
#define INIT_ALL_ZEROES {0}

/* in code: */
Datum values[N] = INIT_ALL_ZEROES;

The patch has been updated per your suggestion. Now using macros for these partial initialisers.

Please see attachment.

Kind Regards
---
Peter Smith
Fujitsu Australia

Attachments:

c99_init_nulls_3.patchapplication/octet-stream; name=c99_init_nulls_3.patchDownload
diff --git a/src/backend/access/transam/commit_ts.c b/src/backend/access/transam/commit_ts.c
index 3316734..6715fe0 100644
--- a/src/backend/access/transam/commit_ts.c
+++ b/src/backend/access/transam/commit_ts.c
@@ -422,8 +422,8 @@ pg_last_committed_xact(PG_FUNCTION_ARGS)
 {
 	TransactionId xid;
 	TimestampTz ts;
-	Datum		values[2];
-	bool		nulls[2];
+	Datum		values[2] = INIT_ALL_ELEMS_ZERO;
+	bool		nulls[2] = INIT_ALL_ELEMS_FALSE;
 	TupleDesc	tupdesc;
 	HeapTuple	htup;
 
@@ -448,10 +448,7 @@ pg_last_committed_xact(PG_FUNCTION_ARGS)
 	else
 	{
 		values[0] = TransactionIdGetDatum(xid);
-		nulls[0] = false;
-
 		values[1] = TimestampTzGetDatum(ts);
-		nulls[1] = false;
 	}
 
 	htup = heap_form_tuple(tupdesc, values, nulls);
diff --git a/src/backend/access/transam/twophase.c b/src/backend/access/transam/twophase.c
index 546bd43..aefaa89 100644
--- a/src/backend/access/transam/twophase.c
+++ b/src/backend/access/transam/twophase.c
@@ -770,8 +770,8 @@ pg_prepared_xact(PG_FUNCTION_ARGS)
 		GlobalTransaction gxact = &status->array[status->currIdx++];
 		PGPROC	   *proc = &ProcGlobal->allProcs[gxact->pgprocno];
 		PGXACT	   *pgxact = &ProcGlobal->allPgXact[gxact->pgprocno];
-		Datum		values[5];
-		bool		nulls[5];
+		Datum		values[5] = INIT_ALL_ELEMS_ZERO;
+		bool		nulls[5] = INIT_ALL_ELEMS_FALSE;
 		HeapTuple	tuple;
 		Datum		result;
 
@@ -781,9 +781,6 @@ pg_prepared_xact(PG_FUNCTION_ARGS)
 		/*
 		 * Form tuple with appropriate data.
 		 */
-		MemSet(values, 0, sizeof(values));
-		MemSet(nulls, 0, sizeof(nulls));
-
 		values[0] = TransactionIdGetDatum(pgxact->xid);
 		values[1] = CStringGetTextDatum(gxact->gid);
 		values[2] = TimestampTzGetDatum(gxact->prepared_at);
diff --git a/src/backend/access/transam/xlogfuncs.c b/src/backend/access/transam/xlogfuncs.c
index 8f17988..fda4ac3 100644
--- a/src/backend/access/transam/xlogfuncs.c
+++ b/src/backend/access/transam/xlogfuncs.c
@@ -183,8 +183,8 @@ pg_stop_backup_v2(PG_FUNCTION_ARGS)
 	Tuplestorestate *tupstore;
 	MemoryContext per_query_ctx;
 	MemoryContext oldcontext;
-	Datum		values[3];
-	bool		nulls[3];
+	Datum		values[3] = INIT_ALL_ELEMS_ZERO;
+	bool		nulls[3] = INIT_ALL_ELEMS_FALSE;
 
 	bool		exclusive = PG_GETARG_BOOL(0);
 	bool		waitforarchive = PG_GETARG_BOOL(1);
@@ -216,9 +216,6 @@ pg_stop_backup_v2(PG_FUNCTION_ARGS)
 
 	MemoryContextSwitchTo(oldcontext);
 
-	MemSet(values, 0, sizeof(values));
-	MemSet(nulls, 0, sizeof(nulls));
-
 	if (exclusive)
 	{
 		if (status == SESSION_BACKUP_NON_EXCLUSIVE)
diff --git a/src/backend/catalog/aclchk.c b/src/backend/catalog/aclchk.c
index 88ce37c..40d39ca 100644
--- a/src/backend/catalog/aclchk.c
+++ b/src/backend/catalog/aclchk.c
@@ -1158,9 +1158,9 @@ SetDefaultACL(InternalDefaultACL *iacls)
 	Acl		   *old_acl;
 	Acl		   *new_acl;
 	HeapTuple	newtuple;
-	Datum		values[Natts_pg_default_acl];
-	bool		nulls[Natts_pg_default_acl];
-	bool		replaces[Natts_pg_default_acl];
+	Datum		values[Natts_pg_default_acl] = INIT_ALL_ELEMS_ZERO;
+	bool		nulls[Natts_pg_default_acl] = INIT_ALL_ELEMS_FALSE;
+	bool		replaces[Natts_pg_default_acl] = INIT_ALL_ELEMS_FALSE;
 	int			noldmembers;
 	int			nnewmembers;
 	Oid		   *oldmembers;
@@ -1314,9 +1314,6 @@ SetDefaultACL(InternalDefaultACL *iacls)
 		Oid			defAclOid;
 
 		/* Prepare to insert or update pg_default_acl entry */
-		MemSet(values, 0, sizeof(values));
-		MemSet(nulls, false, sizeof(nulls));
-		MemSet(replaces, false, sizeof(replaces));
 
 		if (isNew)
 		{
@@ -1659,9 +1656,9 @@ ExecGrant_Attribute(InternalGrant *istmt, Oid relOid, const char *relname,
 	AclMode		avail_goptions;
 	bool		need_update;
 	HeapTuple	newtuple;
-	Datum		values[Natts_pg_attribute];
-	bool		nulls[Natts_pg_attribute];
-	bool		replaces[Natts_pg_attribute];
+	Datum		values[Natts_pg_attribute] = INIT_ALL_ELEMS_ZERO;
+	bool		nulls[Natts_pg_attribute] = INIT_ALL_ELEMS_FALSE;
+	bool		replaces[Natts_pg_attribute] = INIT_ALL_ELEMS_FALSE;
 	int			noldmembers;
 	int			nnewmembers;
 	Oid		   *oldmembers;
@@ -1742,9 +1739,6 @@ ExecGrant_Attribute(InternalGrant *istmt, Oid relOid, const char *relname,
 	nnewmembers = aclmembers(new_acl, &newmembers);
 
 	/* finished building new ACL value, now insert it */
-	MemSet(values, 0, sizeof(values));
-	MemSet(nulls, false, sizeof(nulls));
-	MemSet(replaces, false, sizeof(replaces));
 
 	/*
 	 * If the updated ACL is empty, we can set attacl to null, and maybe even
@@ -1972,9 +1966,9 @@ ExecGrant_Relation(InternalGrant *istmt)
 			Acl		   *new_acl;
 			Oid			grantorId;
 			HeapTuple	newtuple;
-			Datum		values[Natts_pg_class];
-			bool		nulls[Natts_pg_class];
-			bool		replaces[Natts_pg_class];
+			Datum		values[Natts_pg_class] = INIT_ALL_ELEMS_ZERO;
+			bool		nulls[Natts_pg_class] = INIT_ALL_ELEMS_FALSE;
+			bool		replaces[Natts_pg_class] = INIT_ALL_ELEMS_FALSE;
 			int			nnewmembers;
 			Oid		   *newmembers;
 			ObjectType	objtype;
@@ -2024,9 +2018,6 @@ ExecGrant_Relation(InternalGrant *istmt)
 			nnewmembers = aclmembers(new_acl, &newmembers);
 
 			/* finished building new ACL value, now insert it */
-			MemSet(values, 0, sizeof(values));
-			MemSet(nulls, false, sizeof(nulls));
-			MemSet(replaces, false, sizeof(replaces));
 
 			replaces[Anum_pg_class_relacl - 1] = true;
 			values[Anum_pg_class_relacl - 1] = PointerGetDatum(new_acl);
@@ -2147,9 +2138,9 @@ ExecGrant_Database(InternalGrant *istmt)
 		Oid			grantorId;
 		Oid			ownerId;
 		HeapTuple	newtuple;
-		Datum		values[Natts_pg_database];
-		bool		nulls[Natts_pg_database];
-		bool		replaces[Natts_pg_database];
+		Datum		values[Natts_pg_database] = INIT_ALL_ELEMS_ZERO;
+		bool		nulls[Natts_pg_database] = INIT_ALL_ELEMS_FALSE;
+		bool		replaces[Natts_pg_database] = INIT_ALL_ELEMS_FALSE;
 		int			noldmembers;
 		int			nnewmembers;
 		Oid		   *oldmembers;
@@ -2214,9 +2205,6 @@ ExecGrant_Database(InternalGrant *istmt)
 		nnewmembers = aclmembers(new_acl, &newmembers);
 
 		/* finished building new ACL value, now insert it */
-		MemSet(values, 0, sizeof(values));
-		MemSet(nulls, false, sizeof(nulls));
-		MemSet(replaces, false, sizeof(replaces));
 
 		replaces[Anum_pg_database_datacl - 1] = true;
 		values[Anum_pg_database_datacl - 1] = PointerGetDatum(new_acl);
@@ -2268,9 +2256,9 @@ ExecGrant_Fdw(InternalGrant *istmt)
 		Oid			ownerId;
 		HeapTuple	tuple;
 		HeapTuple	newtuple;
-		Datum		values[Natts_pg_foreign_data_wrapper];
-		bool		nulls[Natts_pg_foreign_data_wrapper];
-		bool		replaces[Natts_pg_foreign_data_wrapper];
+		Datum		values[Natts_pg_foreign_data_wrapper] = INIT_ALL_ELEMS_ZERO;
+		bool		nulls[Natts_pg_foreign_data_wrapper] = INIT_ALL_ELEMS_FALSE;
+		bool		replaces[Natts_pg_foreign_data_wrapper] = INIT_ALL_ELEMS_FALSE;
 		int			noldmembers;
 		int			nnewmembers;
 		Oid		   *oldmembers;
@@ -2336,9 +2324,6 @@ ExecGrant_Fdw(InternalGrant *istmt)
 		nnewmembers = aclmembers(new_acl, &newmembers);
 
 		/* finished building new ACL value, now insert it */
-		MemSet(values, 0, sizeof(values));
-		MemSet(nulls, false, sizeof(nulls));
-		MemSet(replaces, false, sizeof(replaces));
 
 		replaces[Anum_pg_foreign_data_wrapper_fdwacl - 1] = true;
 		values[Anum_pg_foreign_data_wrapper_fdwacl - 1] = PointerGetDatum(new_acl);
@@ -2395,9 +2380,9 @@ ExecGrant_ForeignServer(InternalGrant *istmt)
 		Oid			ownerId;
 		HeapTuple	tuple;
 		HeapTuple	newtuple;
-		Datum		values[Natts_pg_foreign_server];
-		bool		nulls[Natts_pg_foreign_server];
-		bool		replaces[Natts_pg_foreign_server];
+		Datum		values[Natts_pg_foreign_server] = INIT_ALL_ELEMS_ZERO;
+		bool		nulls[Natts_pg_foreign_server] = INIT_ALL_ELEMS_FALSE;
+		bool		replaces[Natts_pg_foreign_server] = INIT_ALL_ELEMS_FALSE;
 		int			noldmembers;
 		int			nnewmembers;
 		Oid		   *oldmembers;
@@ -2462,9 +2447,6 @@ ExecGrant_ForeignServer(InternalGrant *istmt)
 		nnewmembers = aclmembers(new_acl, &newmembers);
 
 		/* finished building new ACL value, now insert it */
-		MemSet(values, 0, sizeof(values));
-		MemSet(nulls, false, sizeof(nulls));
-		MemSet(replaces, false, sizeof(replaces));
 
 		replaces[Anum_pg_foreign_server_srvacl - 1] = true;
 		values[Anum_pg_foreign_server_srvacl - 1] = PointerGetDatum(new_acl);
@@ -2520,9 +2502,9 @@ ExecGrant_Function(InternalGrant *istmt)
 		Oid			ownerId;
 		HeapTuple	tuple;
 		HeapTuple	newtuple;
-		Datum		values[Natts_pg_proc];
-		bool		nulls[Natts_pg_proc];
-		bool		replaces[Natts_pg_proc];
+		Datum		values[Natts_pg_proc] = INIT_ALL_ELEMS_ZERO;
+		bool		nulls[Natts_pg_proc] = INIT_ALL_ELEMS_FALSE;
+		bool		replaces[Natts_pg_proc] = INIT_ALL_ELEMS_FALSE;
 		int			noldmembers;
 		int			nnewmembers;
 		Oid		   *oldmembers;
@@ -2586,9 +2568,6 @@ ExecGrant_Function(InternalGrant *istmt)
 		nnewmembers = aclmembers(new_acl, &newmembers);
 
 		/* finished building new ACL value, now insert it */
-		MemSet(values, 0, sizeof(values));
-		MemSet(nulls, false, sizeof(nulls));
-		MemSet(replaces, false, sizeof(replaces));
 
 		replaces[Anum_pg_proc_proacl - 1] = true;
 		values[Anum_pg_proc_proacl - 1] = PointerGetDatum(new_acl);
@@ -2643,9 +2622,9 @@ ExecGrant_Language(InternalGrant *istmt)
 		Oid			ownerId;
 		HeapTuple	tuple;
 		HeapTuple	newtuple;
-		Datum		values[Natts_pg_language];
-		bool		nulls[Natts_pg_language];
-		bool		replaces[Natts_pg_language];
+		Datum		values[Natts_pg_language] = INIT_ALL_ELEMS_ZERO;
+		bool		nulls[Natts_pg_language] = INIT_ALL_ELEMS_FALSE;
+		bool		replaces[Natts_pg_language] = INIT_ALL_ELEMS_FALSE;
 		int			noldmembers;
 		int			nnewmembers;
 		Oid		   *oldmembers;
@@ -2717,9 +2696,6 @@ ExecGrant_Language(InternalGrant *istmt)
 		nnewmembers = aclmembers(new_acl, &newmembers);
 
 		/* finished building new ACL value, now insert it */
-		MemSet(values, 0, sizeof(values));
-		MemSet(nulls, false, sizeof(nulls));
-		MemSet(replaces, false, sizeof(replaces));
 
 		replaces[Anum_pg_language_lanacl - 1] = true;
 		values[Anum_pg_language_lanacl - 1] = PointerGetDatum(new_acl);
@@ -2775,9 +2751,9 @@ ExecGrant_Largeobject(InternalGrant *istmt)
 		Oid			grantorId;
 		Oid			ownerId;
 		HeapTuple	newtuple;
-		Datum		values[Natts_pg_largeobject_metadata];
-		bool		nulls[Natts_pg_largeobject_metadata];
-		bool		replaces[Natts_pg_largeobject_metadata];
+		Datum		values[Natts_pg_largeobject_metadata] = INIT_ALL_ELEMS_ZERO;
+		bool		nulls[Natts_pg_largeobject_metadata] = INIT_ALL_ELEMS_FALSE;
+		bool		replaces[Natts_pg_largeobject_metadata] = INIT_ALL_ELEMS_FALSE;
 		int			noldmembers;
 		int			nnewmembers;
 		Oid		   *oldmembers;
@@ -2855,9 +2831,6 @@ ExecGrant_Largeobject(InternalGrant *istmt)
 		nnewmembers = aclmembers(new_acl, &newmembers);
 
 		/* finished building new ACL value, now insert it */
-		MemSet(values, 0, sizeof(values));
-		MemSet(nulls, false, sizeof(nulls));
-		MemSet(replaces, false, sizeof(replaces));
 
 		replaces[Anum_pg_largeobject_metadata_lomacl - 1] = true;
 		values[Anum_pg_largeobject_metadata_lomacl - 1]
@@ -2914,9 +2887,9 @@ ExecGrant_Namespace(InternalGrant *istmt)
 		Oid			ownerId;
 		HeapTuple	tuple;
 		HeapTuple	newtuple;
-		Datum		values[Natts_pg_namespace];
-		bool		nulls[Natts_pg_namespace];
-		bool		replaces[Natts_pg_namespace];
+		Datum		values[Natts_pg_namespace] = INIT_ALL_ELEMS_ZERO;
+		bool		nulls[Natts_pg_namespace] = INIT_ALL_ELEMS_FALSE;
+		bool		replaces[Natts_pg_namespace] = INIT_ALL_ELEMS_FALSE;
 		int			noldmembers;
 		int			nnewmembers;
 		Oid		   *oldmembers;
@@ -2981,9 +2954,6 @@ ExecGrant_Namespace(InternalGrant *istmt)
 		nnewmembers = aclmembers(new_acl, &newmembers);
 
 		/* finished building new ACL value, now insert it */
-		MemSet(values, 0, sizeof(values));
-		MemSet(nulls, false, sizeof(nulls));
-		MemSet(replaces, false, sizeof(replaces));
 
 		replaces[Anum_pg_namespace_nspacl - 1] = true;
 		values[Anum_pg_namespace_nspacl - 1] = PointerGetDatum(new_acl);
@@ -3037,9 +3007,9 @@ ExecGrant_Tablespace(InternalGrant *istmt)
 		Oid			grantorId;
 		Oid			ownerId;
 		HeapTuple	newtuple;
-		Datum		values[Natts_pg_tablespace];
-		bool		nulls[Natts_pg_tablespace];
-		bool		replaces[Natts_pg_tablespace];
+		Datum		values[Natts_pg_tablespace] = INIT_ALL_ELEMS_ZERO;
+		bool		nulls[Natts_pg_tablespace] = INIT_ALL_ELEMS_FALSE;
+		bool		replaces[Natts_pg_tablespace] = INIT_ALL_ELEMS_FALSE;
 		int			noldmembers;
 		int			nnewmembers;
 		Oid		   *oldmembers;
@@ -3105,9 +3075,6 @@ ExecGrant_Tablespace(InternalGrant *istmt)
 		nnewmembers = aclmembers(new_acl, &newmembers);
 
 		/* finished building new ACL value, now insert it */
-		MemSet(values, 0, sizeof(values));
-		MemSet(nulls, false, sizeof(nulls));
-		MemSet(replaces, false, sizeof(replaces));
 
 		replaces[Anum_pg_tablespace_spcacl - 1] = true;
 		values[Anum_pg_tablespace_spcacl - 1] = PointerGetDatum(new_acl);
@@ -3157,9 +3124,9 @@ ExecGrant_Type(InternalGrant *istmt)
 		Oid			grantorId;
 		Oid			ownerId;
 		HeapTuple	newtuple;
-		Datum		values[Natts_pg_type];
-		bool		nulls[Natts_pg_type];
-		bool		replaces[Natts_pg_type];
+		Datum		values[Natts_pg_type] = INIT_ALL_ELEMS_ZERO;
+		bool		nulls[Natts_pg_type] = INIT_ALL_ELEMS_FALSE;
+		bool		replaces[Natts_pg_type] = INIT_ALL_ELEMS_FALSE;
 		int			noldmembers;
 		int			nnewmembers;
 		Oid		   *oldmembers;
@@ -3239,9 +3206,6 @@ ExecGrant_Type(InternalGrant *istmt)
 		nnewmembers = aclmembers(new_acl, &newmembers);
 
 		/* finished building new ACL value, now insert it */
-		MemSet(values, 0, sizeof(values));
-		MemSet(nulls, false, sizeof(nulls));
-		MemSet(replaces, false, sizeof(replaces));
 
 		replaces[Anum_pg_type_typacl - 1] = true;
 		values[Anum_pg_type_typacl - 1] = PointerGetDatum(new_acl);
@@ -5992,17 +5956,13 @@ recordExtensionInitPrivWorker(Oid objoid, Oid classoid, int objsubid, Acl *new_a
 	/* If we find an entry, update it with the latest ACL. */
 	if (HeapTupleIsValid(oldtuple))
 	{
-		Datum		values[Natts_pg_init_privs];
-		bool		nulls[Natts_pg_init_privs];
-		bool		replace[Natts_pg_init_privs];
+		Datum		values[Natts_pg_init_privs] = INIT_ALL_ELEMS_ZERO;
+		bool		nulls[Natts_pg_init_privs] = INIT_ALL_ELEMS_FALSE;
+		bool		replace[Natts_pg_init_privs] = INIT_ALL_ELEMS_FALSE;
 
 		/* If we have a new ACL to set, then update the row with it. */
 		if (new_acl)
 		{
-			MemSet(values, 0, sizeof(values));
-			MemSet(nulls, false, sizeof(nulls));
-			MemSet(replace, false, sizeof(replace));
-
 			values[Anum_pg_init_privs_initprivs - 1] = PointerGetDatum(new_acl);
 			replace[Anum_pg_init_privs_initprivs - 1] = true;
 
@@ -6020,7 +5980,7 @@ recordExtensionInitPrivWorker(Oid objoid, Oid classoid, int objsubid, Acl *new_a
 	else
 	{
 		Datum		values[Natts_pg_init_privs];
-		bool		nulls[Natts_pg_init_privs];
+		bool		nulls[Natts_pg_init_privs] = INIT_ALL_ELEMS_FALSE;
 
 		/*
 		 * Only add a new entry if the new ACL is non-NULL.
@@ -6031,8 +5991,6 @@ recordExtensionInitPrivWorker(Oid objoid, Oid classoid, int objsubid, Acl *new_a
 		if (new_acl)
 		{
 			/* No entry found, so add it. */
-			MemSet(nulls, false, sizeof(nulls));
-
 			values[Anum_pg_init_privs_objoid - 1] = ObjectIdGetDatum(objoid);
 			values[Anum_pg_init_privs_classoid - 1] = ObjectIdGetDatum(classoid);
 			values[Anum_pg_init_privs_objsubid - 1] = Int32GetDatum(objsubid);
diff --git a/src/backend/catalog/heap.c b/src/backend/catalog/heap.c
index b7bcdd9..a0cb3a6 100644
--- a/src/backend/catalog/heap.c
+++ b/src/backend/catalog/heap.c
@@ -695,14 +695,10 @@ InsertPgAttributeTuple(Relation pg_attribute_rel,
 					   Form_pg_attribute new_attribute,
 					   CatalogIndexState indstate)
 {
-	Datum		values[Natts_pg_attribute];
-	bool		nulls[Natts_pg_attribute];
+	Datum		values[Natts_pg_attribute] = INIT_ALL_ELEMS_ZERO;
+	bool		nulls[Natts_pg_attribute] = INIT_ALL_ELEMS_FALSE;
 	HeapTuple	tup;
 
-	/* This is a tad tedious, but way cleaner than what we used to do... */
-	memset(values, 0, sizeof(values));
-	memset(nulls, false, sizeof(nulls));
-
 	values[Anum_pg_attribute_attrelid - 1] = ObjectIdGetDatum(new_attribute->attrelid);
 	values[Anum_pg_attribute_attname - 1] = NameGetDatum(&new_attribute->attname);
 	values[Anum_pg_attribute_atttypid - 1] = ObjectIdGetDatum(new_attribute->atttypid);
@@ -852,14 +848,10 @@ InsertPgClassTuple(Relation pg_class_desc,
 				   Datum reloptions)
 {
 	Form_pg_class rd_rel = new_rel_desc->rd_rel;
-	Datum		values[Natts_pg_class];
-	bool		nulls[Natts_pg_class];
+	Datum		values[Natts_pg_class] = INIT_ALL_ELEMS_ZERO;
+	bool		nulls[Natts_pg_class] = INIT_ALL_ELEMS_FALSE;
 	HeapTuple	tup;
 
-	/* This is a tad tedious, but way cleaner than what we used to do... */
-	memset(values, 0, sizeof(values));
-	memset(nulls, false, sizeof(nulls));
-
 	values[Anum_pg_class_oid - 1] = ObjectIdGetDatum(new_rel_oid);
 	values[Anum_pg_class_relname - 1] = NameGetDatum(&rd_rel->relname);
 	values[Anum_pg_class_relnamespace - 1] = ObjectIdGetDatum(rd_rel->relnamespace);
@@ -1645,14 +1637,11 @@ RemoveAttributeById(Oid relid, AttrNumber attnum)
 		/* clear the missing value if any */
 		if (attStruct->atthasmissing)
 		{
-			Datum		valuesAtt[Natts_pg_attribute];
-			bool		nullsAtt[Natts_pg_attribute];
-			bool		replacesAtt[Natts_pg_attribute];
+			Datum		valuesAtt[Natts_pg_attribute] = INIT_ALL_ELEMS_ZERO;
+			bool		nullsAtt[Natts_pg_attribute] = INIT_ALL_ELEMS_FALSE;
+			bool		replacesAtt[Natts_pg_attribute] = INIT_ALL_ELEMS_FALSE;
 
 			/* update the tuple - set atthasmissing and attmissingval */
-			MemSet(valuesAtt, 0, sizeof(valuesAtt));
-			MemSet(nullsAtt, false, sizeof(nullsAtt));
-			MemSet(replacesAtt, false, sizeof(replacesAtt));
 
 			valuesAtt[Anum_pg_attribute_atthasmissing - 1] =
 				BoolGetDatum(false);
@@ -2064,9 +2053,9 @@ RelationClearMissing(Relation rel)
 void
 SetAttrMissing(Oid relid, char *attname, char *value)
 {
-	Datum		valuesAtt[Natts_pg_attribute];
-	bool		nullsAtt[Natts_pg_attribute];
-	bool		replacesAtt[Natts_pg_attribute];
+	Datum		valuesAtt[Natts_pg_attribute] = INIT_ALL_ELEMS_ZERO;
+	bool		nullsAtt[Natts_pg_attribute] = INIT_ALL_ELEMS_FALSE;
+	bool		replacesAtt[Natts_pg_attribute] = INIT_ALL_ELEMS_FALSE;
 	Datum		missingval;
 	Form_pg_attribute attStruct;
 	Relation	attrrel,
@@ -2092,9 +2081,6 @@ SetAttrMissing(Oid relid, char *attname, char *value)
 								  Int32GetDatum(attStruct->atttypmod));
 
 	/* update the tuple - set atthasmissing and attmissingval */
-	MemSet(valuesAtt, 0, sizeof(valuesAtt));
-	MemSet(nullsAtt, false, sizeof(nullsAtt));
-	MemSet(replacesAtt, false, sizeof(replacesAtt));
 
 	valuesAtt[Anum_pg_attribute_atthasmissing - 1] = BoolGetDatum(true);
 	replacesAtt[Anum_pg_attribute_atthasmissing - 1] = true;
@@ -2191,15 +2177,12 @@ StoreAttrDefault(Relation rel, AttrNumber attnum,
 		Expr	   *expr2 = (Expr *) expr;
 		EState	   *estate = NULL;
 		ExprContext *econtext;
-		Datum		valuesAtt[Natts_pg_attribute];
-		bool		nullsAtt[Natts_pg_attribute];
-		bool		replacesAtt[Natts_pg_attribute];
+		Datum		valuesAtt[Natts_pg_attribute] = INIT_ALL_ELEMS_ZERO;
+		bool		nullsAtt[Natts_pg_attribute] = INIT_ALL_ELEMS_FALSE;
+		bool		replacesAtt[Natts_pg_attribute] = INIT_ALL_ELEMS_FALSE;
 		Datum		missingval = (Datum) 0;
 		bool		missingIsNull = true;
 
-		MemSet(valuesAtt, 0, sizeof(valuesAtt));
-		MemSet(nullsAtt, false, sizeof(nullsAtt));
-		MemSet(replacesAtt, false, sizeof(replacesAtt));
 		valuesAtt[Anum_pg_attribute_atthasdef - 1] = true;
 		replacesAtt[Anum_pg_attribute_atthasdef - 1] = true;
 
@@ -3419,7 +3402,7 @@ StorePartitionKey(Relation rel,
 	Relation	pg_partitioned_table;
 	HeapTuple	tuple;
 	Datum		values[Natts_pg_partitioned_table];
-	bool		nulls[Natts_pg_partitioned_table];
+	bool		nulls[Natts_pg_partitioned_table] = INIT_ALL_ELEMS_FALSE;
 	ObjectAddress myself;
 	ObjectAddress referenced;
 
@@ -3444,8 +3427,6 @@ StorePartitionKey(Relation rel,
 
 	pg_partitioned_table = table_open(PartitionedRelationId, RowExclusiveLock);
 
-	MemSet(nulls, false, sizeof(nulls));
-
 	/* Only this can ever be NULL */
 	if (!partexprDatum)
 		nulls[Anum_pg_partitioned_table_partexprs - 1] = true;
diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c
index 098732c..2298856 100644
--- a/src/backend/catalog/index.c
+++ b/src/backend/catalog/index.c
@@ -546,7 +546,7 @@ UpdateIndexRelation(Oid indexoid,
 	Datum		exprsDatum;
 	Datum		predDatum;
 	Datum		values[Natts_pg_index];
-	bool		nulls[Natts_pg_index];
+	bool		nulls[Natts_pg_index] = INIT_ALL_ELEMS_FALSE;
 	Relation	pg_index;
 	HeapTuple	tuple;
 	int			i;
@@ -599,7 +599,6 @@ UpdateIndexRelation(Oid indexoid,
 	/*
 	 * Build a pg_index tuple
 	 */
-	MemSet(nulls, false, sizeof(nulls));
 
 	values[Anum_pg_index_indexrelid - 1] = ObjectIdGetDatum(indexoid);
 	values[Anum_pg_index_indrelid - 1] = ObjectIdGetDatum(heapoid);
diff --git a/src/backend/catalog/pg_collation.c b/src/backend/catalog/pg_collation.c
index dd99d53..e216dd6 100644
--- a/src/backend/catalog/pg_collation.c
+++ b/src/backend/catalog/pg_collation.c
@@ -57,7 +57,7 @@ CollationCreate(const char *collname, Oid collnamespace,
 	TupleDesc	tupDesc;
 	HeapTuple	tup;
 	Datum		values[Natts_pg_collation];
-	bool		nulls[Natts_pg_collation];
+	bool		nulls[Natts_pg_collation] = INIT_ALL_ELEMS_FALSE;
 	NameData	name_name,
 				name_collate,
 				name_ctype;
@@ -151,7 +151,6 @@ CollationCreate(const char *collname, Oid collnamespace,
 	tupDesc = RelationGetDescr(rel);
 
 	/* form a tuple */
-	memset(nulls, 0, sizeof(nulls));
 
 	namestrcpy(&name_name, collname);
 	oid = GetNewOidWithIndex(rel, CollationOidIndexId,
diff --git a/src/backend/catalog/pg_db_role_setting.c b/src/backend/catalog/pg_db_role_setting.c
index 20acac2..d71328a 100644
--- a/src/backend/catalog/pg_db_role_setting.c
+++ b/src/backend/catalog/pg_db_role_setting.c
@@ -136,11 +136,9 @@ AlterSetting(Oid databaseid, Oid roleid, VariableSetStmt *setstmt)
 		/* non-null valuestr means it's not RESET, so insert a new tuple */
 		HeapTuple	newtuple;
 		Datum		values[Natts_pg_db_role_setting];
-		bool		nulls[Natts_pg_db_role_setting];
+		bool		nulls[Natts_pg_db_role_setting] = INIT_ALL_ELEMS_FALSE;
 		ArrayType  *a;
 
-		memset(nulls, false, sizeof(nulls));
-
 		a = GUCArrayAdd(NULL, setstmt->name, valuestr);
 
 		values[Anum_pg_db_role_setting_setdatabase - 1] =
diff --git a/src/backend/catalog/pg_depend.c b/src/backend/catalog/pg_depend.c
index a060c25..e80b8a7 100644
--- a/src/backend/catalog/pg_depend.c
+++ b/src/backend/catalog/pg_depend.c
@@ -61,7 +61,7 @@ recordMultipleDependencies(const ObjectAddress *depender,
 	CatalogIndexState indstate;
 	HeapTuple	tup;
 	int			i;
-	bool		nulls[Natts_pg_depend];
+	bool		nulls[Natts_pg_depend] = INIT_ALL_ELEMS_FALSE;
 	Datum		values[Natts_pg_depend];
 
 	if (nreferenced <= 0)
@@ -79,8 +79,6 @@ recordMultipleDependencies(const ObjectAddress *depender,
 	/* Don't open indexes unless we need to make an update */
 	indstate = NULL;
 
-	memset(nulls, false, sizeof(nulls));
-
 	for (i = 0; i < nreferenced; i++, referenced++)
 	{
 		/*
diff --git a/src/backend/catalog/pg_enum.c b/src/backend/catalog/pg_enum.c
index d0ff802..b174e12 100644
--- a/src/backend/catalog/pg_enum.c
+++ b/src/backend/catalog/pg_enum.c
@@ -66,7 +66,7 @@ EnumValuesCreate(Oid enumTypeOid, List *vals)
 	int			elemno,
 				num_elems;
 	Datum		values[Natts_pg_enum];
-	bool		nulls[Natts_pg_enum];
+	bool		nulls[Natts_pg_enum] = INIT_ALL_ELEMS_FALSE;
 	ListCell   *lc;
 	HeapTuple	tup;
 
@@ -111,8 +111,6 @@ EnumValuesCreate(Oid enumTypeOid, List *vals)
 	qsort(oids, num_elems, sizeof(Oid), oid_cmp);
 
 	/* and make the entries */
-	memset(nulls, false, sizeof(nulls));
-
 	elemno = 0;
 	foreach(lc, vals)
 	{
@@ -215,7 +213,7 @@ AddEnumLabel(Oid enumTypeOid,
 	Relation	pg_enum;
 	Oid			newOid;
 	Datum		values[Natts_pg_enum];
-	bool		nulls[Natts_pg_enum];
+	bool		nulls[Natts_pg_enum] = INIT_ALL_ELEMS_FALSE;
 	NameData	enumlabel;
 	HeapTuple	enum_tup;
 	float4		newelemorder;
@@ -480,7 +478,6 @@ restart:
 	ReleaseCatCacheList(list);
 
 	/* Create the new pg_enum entry */
-	memset(nulls, false, sizeof(nulls));
 	values[Anum_pg_enum_oid - 1] = ObjectIdGetDatum(newOid);
 	values[Anum_pg_enum_enumtypid - 1] = ObjectIdGetDatum(enumTypeOid);
 	values[Anum_pg_enum_enumsortorder - 1] = Float4GetDatum(newelemorder);
diff --git a/src/backend/catalog/pg_inherits.c b/src/backend/catalog/pg_inherits.c
index 59af162..27d709d 100644
--- a/src/backend/catalog/pg_inherits.c
+++ b/src/backend/catalog/pg_inherits.c
@@ -417,7 +417,7 @@ void
 StoreSingleInheritance(Oid relationId, Oid parentOid, int32 seqNumber)
 {
 	Datum		values[Natts_pg_inherits];
-	bool		nulls[Natts_pg_inherits];
+	bool		nulls[Natts_pg_inherits] = INIT_ALL_ELEMS_FALSE;
 	HeapTuple	tuple;
 	Relation	inhRelation;
 
@@ -430,8 +430,6 @@ StoreSingleInheritance(Oid relationId, Oid parentOid, int32 seqNumber)
 	values[Anum_pg_inherits_inhparent - 1] = ObjectIdGetDatum(parentOid);
 	values[Anum_pg_inherits_inhseqno - 1] = Int32GetDatum(seqNumber);
 
-	memset(nulls, 0, sizeof(nulls));
-
 	tuple = heap_form_tuple(RelationGetDescr(inhRelation), values, nulls);
 
 	CatalogTupleInsert(inhRelation, tuple);
diff --git a/src/backend/catalog/pg_largeobject.c b/src/backend/catalog/pg_largeobject.c
index 1a68702..3489ec5 100644
--- a/src/backend/catalog/pg_largeobject.c
+++ b/src/backend/catalog/pg_largeobject.c
@@ -42,8 +42,8 @@ LargeObjectCreate(Oid loid)
 	Relation	pg_lo_meta;
 	HeapTuple	ntup;
 	Oid			loid_new;
-	Datum		values[Natts_pg_largeobject_metadata];
-	bool		nulls[Natts_pg_largeobject_metadata];
+	Datum		values[Natts_pg_largeobject_metadata] = INIT_ALL_ELEMS_ZERO;
+	bool		nulls[Natts_pg_largeobject_metadata] = INIT_ALL_ELEMS_FALSE;
 
 	pg_lo_meta = table_open(LargeObjectMetadataRelationId,
 							RowExclusiveLock);
@@ -51,8 +51,6 @@ LargeObjectCreate(Oid loid)
 	/*
 	 * Insert metadata of the largeobject
 	 */
-	memset(values, 0, sizeof(values));
-	memset(nulls, false, sizeof(nulls));
 
 	if (OidIsValid(loid))
 		loid_new = loid;
diff --git a/src/backend/catalog/pg_publication.c b/src/backend/catalog/pg_publication.c
index fd5da7d..6c62771 100644
--- a/src/backend/catalog/pg_publication.c
+++ b/src/backend/catalog/pg_publication.c
@@ -154,8 +154,8 @@ publication_add_relation(Oid pubid, Relation targetrel,
 {
 	Relation	rel;
 	HeapTuple	tup;
-	Datum		values[Natts_pg_publication_rel];
-	bool		nulls[Natts_pg_publication_rel];
+	Datum		values[Natts_pg_publication_rel] = INIT_ALL_ELEMS_ZERO;
+	bool		nulls[Natts_pg_publication_rel] = INIT_ALL_ELEMS_FALSE;
 	Oid			relid = RelationGetRelid(targetrel);
 	Oid			prrelid;
 	Publication *pub = GetPublication(pubid);
@@ -186,8 +186,6 @@ publication_add_relation(Oid pubid, Relation targetrel,
 	check_publication_add_relation(targetrel);
 
 	/* Form a tuple. */
-	memset(values, 0, sizeof(values));
-	memset(nulls, false, sizeof(nulls));
 
 	prrelid = GetNewOidWithIndex(rel, PublicationRelObjectIndexId,
 								 Anum_pg_publication_rel_oid);
diff --git a/src/backend/catalog/pg_range.c b/src/backend/catalog/pg_range.c
index e6e138b..3796cda 100644
--- a/src/backend/catalog/pg_range.c
+++ b/src/backend/catalog/pg_range.c
@@ -39,15 +39,13 @@ RangeCreate(Oid rangeTypeOid, Oid rangeSubType, Oid rangeCollation,
 {
 	Relation	pg_range;
 	Datum		values[Natts_pg_range];
-	bool		nulls[Natts_pg_range];
+	bool		nulls[Natts_pg_range] = INIT_ALL_ELEMS_FALSE;
 	HeapTuple	tup;
 	ObjectAddress myself;
 	ObjectAddress referenced;
 
 	pg_range = table_open(RangeRelationId, RowExclusiveLock);
 
-	memset(nulls, 0, sizeof(nulls));
-
 	values[Anum_pg_range_rngtypid - 1] = ObjectIdGetDatum(rangeTypeOid);
 	values[Anum_pg_range_rngsubtype - 1] = ObjectIdGetDatum(rangeSubType);
 	values[Anum_pg_range_rngcollation - 1] = ObjectIdGetDatum(rangeCollation);
diff --git a/src/backend/catalog/pg_shdepend.c b/src/backend/catalog/pg_shdepend.c
index fb7f8dd..66bac64 100644
--- a/src/backend/catalog/pg_shdepend.c
+++ b/src/backend/catalog/pg_shdepend.c
@@ -273,9 +273,7 @@ shdepChangeDep(Relation sdepRel,
 	{
 		/* Need to insert new entry */
 		Datum		values[Natts_pg_shdepend];
-		bool		nulls[Natts_pg_shdepend];
-
-		memset(nulls, false, sizeof(nulls));
+		bool		nulls[Natts_pg_shdepend] = INIT_ALL_ELEMS_FALSE;
 
 		values[Anum_pg_shdepend_dbid - 1] = ObjectIdGetDatum(dbid);
 		values[Anum_pg_shdepend_classid - 1] = ObjectIdGetDatum(classid);
@@ -801,9 +799,9 @@ copyTemplateDependencies(Oid templateDbId, Oid newDbId)
 	SysScanDesc scan;
 	HeapTuple	tup;
 	CatalogIndexState indstate;
-	Datum		values[Natts_pg_shdepend];
-	bool		nulls[Natts_pg_shdepend];
-	bool		replace[Natts_pg_shdepend];
+	Datum		values[Natts_pg_shdepend] = INIT_ALL_ELEMS_ZERO;
+	bool		nulls[Natts_pg_shdepend] = INIT_ALL_ELEMS_FALSE;
+	bool		replace[Natts_pg_shdepend] = INIT_ALL_ELEMS_FALSE;
 
 	sdepRel = table_open(SharedDependRelationId, RowExclusiveLock);
 	sdepDesc = RelationGetDescr(sdepRel);
@@ -820,10 +818,6 @@ copyTemplateDependencies(Oid templateDbId, Oid newDbId)
 							  NULL, 1, key);
 
 	/* Set up to copy the tuples except for inserting newDbId */
-	memset(values, 0, sizeof(values));
-	memset(nulls, false, sizeof(nulls));
-	memset(replace, false, sizeof(replace));
-
 	replace[Anum_pg_shdepend_dbid - 1] = true;
 	values[Anum_pg_shdepend_dbid - 1] = ObjectIdGetDatum(newDbId);
 
@@ -934,7 +928,7 @@ shdepAddDependency(Relation sdepRel,
 {
 	HeapTuple	tup;
 	Datum		values[Natts_pg_shdepend];
-	bool		nulls[Natts_pg_shdepend];
+	bool		nulls[Natts_pg_shdepend] = INIT_ALL_ELEMS_FALSE;
 
 	/*
 	 * Make sure the object doesn't go away while we record the dependency on
@@ -943,8 +937,6 @@ shdepAddDependency(Relation sdepRel,
 	 */
 	shdepLockAndCheckObject(refclassId, refobjId);
 
-	memset(nulls, false, sizeof(nulls));
-
 	/*
 	 * Form the new tuple and record the dependency.
 	 */
diff --git a/src/backend/catalog/pg_subscription.c b/src/backend/catalog/pg_subscription.c
index afee283..4a1bc80 100644
--- a/src/backend/catalog/pg_subscription.c
+++ b/src/backend/catalog/pg_subscription.c
@@ -243,8 +243,8 @@ AddSubscriptionRelState(Oid subid, Oid relid, char state,
 {
 	Relation	rel;
 	HeapTuple	tup;
-	bool		nulls[Natts_pg_subscription_rel];
-	Datum		values[Natts_pg_subscription_rel];
+	bool		nulls[Natts_pg_subscription_rel] = INIT_ALL_ELEMS_FALSE;
+	Datum		values[Natts_pg_subscription_rel] = INIT_ALL_ELEMS_ZERO;
 
 	LockSharedObject(SubscriptionRelationId, subid, 0, AccessShareLock);
 
@@ -259,8 +259,6 @@ AddSubscriptionRelState(Oid subid, Oid relid, char state,
 			 relid, subid);
 
 	/* Form the tuple. */
-	memset(values, 0, sizeof(values));
-	memset(nulls, false, sizeof(nulls));
 	values[Anum_pg_subscription_rel_srsubid - 1] = ObjectIdGetDatum(subid);
 	values[Anum_pg_subscription_rel_srrelid - 1] = ObjectIdGetDatum(relid);
 	values[Anum_pg_subscription_rel_srsubstate - 1] = CharGetDatum(state);
@@ -289,9 +287,9 @@ UpdateSubscriptionRelState(Oid subid, Oid relid, char state,
 {
 	Relation	rel;
 	HeapTuple	tup;
-	bool		nulls[Natts_pg_subscription_rel];
-	Datum		values[Natts_pg_subscription_rel];
-	bool		replaces[Natts_pg_subscription_rel];
+	bool		nulls[Natts_pg_subscription_rel] = INIT_ALL_ELEMS_FALSE;
+	Datum		values[Natts_pg_subscription_rel] = INIT_ALL_ELEMS_ZERO;
+	bool		replaces[Natts_pg_subscription_rel] = INIT_ALL_ELEMS_FALSE;
 
 	LockSharedObject(SubscriptionRelationId, subid, 0, AccessShareLock);
 
@@ -306,10 +304,6 @@ UpdateSubscriptionRelState(Oid subid, Oid relid, char state,
 			 relid, subid);
 
 	/* Update the tuple. */
-	memset(values, 0, sizeof(values));
-	memset(nulls, false, sizeof(nulls));
-	memset(replaces, false, sizeof(replaces));
-
 	replaces[Anum_pg_subscription_rel_srsubstate - 1] = true;
 	values[Anum_pg_subscription_rel_srsubstate - 1] = CharGetDatum(state);
 
diff --git a/src/backend/commands/amcmds.c b/src/backend/commands/amcmds.c
index c0e4098..d053183 100644
--- a/src/backend/commands/amcmds.c
+++ b/src/backend/commands/amcmds.c
@@ -46,8 +46,8 @@ CreateAccessMethod(CreateAmStmt *stmt)
 	ObjectAddress referenced;
 	Oid			amoid;
 	Oid			amhandler;
-	bool		nulls[Natts_pg_am];
-	Datum		values[Natts_pg_am];
+	bool		nulls[Natts_pg_am] = INIT_ALL_ELEMS_FALSE;
+	Datum		values[Natts_pg_am] = INIT_ALL_ELEMS_ZERO;
 	HeapTuple	tup;
 
 	rel = table_open(AccessMethodRelationId, RowExclusiveLock);
@@ -79,9 +79,6 @@ CreateAccessMethod(CreateAmStmt *stmt)
 	/*
 	 * Insert tuple into pg_am.
 	 */
-	memset(values, 0, sizeof(values));
-	memset(nulls, false, sizeof(nulls));
-
 	amoid = GetNewOidWithIndex(rel, AmOidIndexId, Anum_pg_am_oid);
 	values[Anum_pg_am_oid - 1] = ObjectIdGetDatum(amoid);
 	values[Anum_pg_am_amname - 1] =
diff --git a/src/backend/commands/collationcmds.c b/src/backend/commands/collationcmds.c
index 919e092..4bfa313 100644
--- a/src/backend/commands/collationcmds.c
+++ b/src/backend/commands/collationcmds.c
@@ -315,18 +315,14 @@ AlterCollation(AlterCollationStmt *stmt)
 		elog(ERROR, "invalid collation version change");
 	else if (oldversion && newversion && strcmp(newversion, oldversion) != 0)
 	{
-		bool		nulls[Natts_pg_collation];
-		bool		replaces[Natts_pg_collation];
-		Datum		values[Natts_pg_collation];
+		bool		nulls[Natts_pg_collation] = INIT_ALL_ELEMS_FALSE;
+		bool		replaces[Natts_pg_collation] = INIT_ALL_ELEMS_FALSE;
+		Datum		values[Natts_pg_collation] = INIT_ALL_ELEMS_ZERO;
 
 		ereport(NOTICE,
 				(errmsg("changing version from %s to %s",
 						oldversion, newversion)));
 
-		memset(values, 0, sizeof(values));
-		memset(nulls, false, sizeof(nulls));
-		memset(replaces, false, sizeof(replaces));
-
 		values[Anum_pg_collation_collversion - 1] = CStringGetTextDatum(newversion);
 		replaces[Anum_pg_collation_collversion - 1] = true;
 
diff --git a/src/backend/commands/event_trigger.c b/src/backend/commands/event_trigger.c
index f7ee983..2790439 100644
--- a/src/backend/commands/event_trigger.c
+++ b/src/backend/commands/event_trigger.c
@@ -381,7 +381,7 @@ insert_event_trigger_tuple(const char *trigname, const char *eventname, Oid evtO
 	Oid			trigoid;
 	HeapTuple	tuple;
 	Datum		values[Natts_pg_trigger];
-	bool		nulls[Natts_pg_trigger];
+	bool		nulls[Natts_pg_trigger] = INIT_ALL_ELEMS_FALSE;
 	NameData	evtnamedata,
 				evteventdata;
 	ObjectAddress myself,
@@ -394,7 +394,6 @@ insert_event_trigger_tuple(const char *trigname, const char *eventname, Oid evtO
 	trigoid = GetNewOidWithIndex(tgrel, EventTriggerOidIndexId,
 								 Anum_pg_event_trigger_oid);
 	values[Anum_pg_event_trigger_oid - 1] = ObjectIdGetDatum(trigoid);
-	memset(nulls, false, sizeof(nulls));
 	namestrcpy(&evtnamedata, trigname);
 	values[Anum_pg_event_trigger_evtname - 1] = NameGetDatum(&evtnamedata);
 	namestrcpy(&evteventdata, eventname);
@@ -1494,14 +1493,11 @@ pg_event_trigger_dropped_objects(PG_FUNCTION_ARGS)
 	{
 		SQLDropObject *obj;
 		int			i = 0;
-		Datum		values[12];
-		bool		nulls[12];
+		Datum		values[12] = INIT_ALL_ELEMS_ZERO;
+		bool		nulls[12] = INIT_ALL_ELEMS_FALSE;
 
 		obj = slist_container(SQLDropObject, next, iter.cur);
 
-		MemSet(values, 0, sizeof(values));
-		MemSet(nulls, 0, sizeof(nulls));
-
 		/* classid */
 		values[i++] = ObjectIdGetDatum(obj->address.classId);
 
@@ -2046,7 +2042,7 @@ pg_event_trigger_ddl_commands(PG_FUNCTION_ARGS)
 	{
 		CollectedCommand *cmd = lfirst(lc);
 		Datum		values[9];
-		bool		nulls[9];
+		bool		nulls[9] = INIT_ALL_ELEMS_FALSE;
 		ObjectAddress addr;
 		int			i = 0;
 
@@ -2064,8 +2060,6 @@ pg_event_trigger_ddl_commands(PG_FUNCTION_ARGS)
 			!OidIsValid(cmd->d.simple.address.objectId))
 			continue;
 
-		MemSet(nulls, 0, sizeof(nulls));
-
 		switch (cmd->type)
 		{
 			case SCT_Simple:
diff --git a/src/backend/commands/extension.c b/src/backend/commands/extension.c
index f7202cc..32f02f7 100644
--- a/src/backend/commands/extension.c
+++ b/src/backend/commands/extension.c
@@ -1771,8 +1771,8 @@ InsertExtensionTuple(const char *extName, Oid extOwner,
 {
 	Oid			extensionOid;
 	Relation	rel;
-	Datum		values[Natts_pg_extension];
-	bool		nulls[Natts_pg_extension];
+	Datum		values[Natts_pg_extension] = INIT_ALL_ELEMS_ZERO;
+	bool		nulls[Natts_pg_extension] = INIT_ALL_ELEMS_FALSE;
 	HeapTuple	tuple;
 	ObjectAddress myself;
 	ObjectAddress nsp;
@@ -1783,9 +1783,6 @@ InsertExtensionTuple(const char *extName, Oid extOwner,
 	 */
 	rel = table_open(ExtensionRelationId, RowExclusiveLock);
 
-	memset(values, 0, sizeof(values));
-	memset(nulls, 0, sizeof(nulls));
-
 	extensionOid = GetNewOidWithIndex(rel, ExtensionOidIndexId,
 									  Anum_pg_extension_oid);
 	values[Anum_pg_extension_oid - 1] = ObjectIdGetDatum(extensionOid);
@@ -1960,8 +1957,8 @@ pg_available_extensions(PG_FUNCTION_ARGS)
 		{
 			ExtensionControlFile *control;
 			char	   *extname;
-			Datum		values[3];
-			bool		nulls[3];
+			Datum		values[3] = INIT_ALL_ELEMS_ZERO;
+			bool		nulls[3] = INIT_ALL_ELEMS_FALSE;
 
 			if (!is_extension_control_filename(de->d_name))
 				continue;
@@ -1976,9 +1973,6 @@ pg_available_extensions(PG_FUNCTION_ARGS)
 
 			control = read_extension_control_file(extname);
 
-			memset(values, 0, sizeof(values));
-			memset(nulls, 0, sizeof(nulls));
-
 			/* name */
 			values[0] = DirectFunctionCall1(namein,
 											CStringGetDatum(control->name));
@@ -2117,8 +2111,8 @@ get_available_versions_for_extension(ExtensionControlFile *pcontrol,
 	{
 		ExtensionVersionInfo *evi = (ExtensionVersionInfo *) lfirst(lc);
 		ExtensionControlFile *control;
-		Datum		values[7];
-		bool		nulls[7];
+		Datum		values[7] = INIT_ALL_ELEMS_ZERO;
+		bool		nulls[7] = INIT_ALL_ELEMS_FALSE;
 		ListCell   *lc2;
 
 		if (!evi->installable)
@@ -2129,9 +2123,6 @@ get_available_versions_for_extension(ExtensionControlFile *pcontrol,
 		 */
 		control = read_extension_aux_control_file(pcontrol, evi->name);
 
-		memset(values, 0, sizeof(values));
-		memset(nulls, 0, sizeof(nulls));
-
 		/* name */
 		values[0] = DirectFunctionCall1(namein,
 										CStringGetDatum(control->name));
@@ -2292,8 +2283,8 @@ pg_extension_update_paths(PG_FUNCTION_ARGS)
 		{
 			ExtensionVersionInfo *evi2 = (ExtensionVersionInfo *) lfirst(lc2);
 			List	   *path;
-			Datum		values[3];
-			bool		nulls[3];
+			Datum		values[3] = INIT_ALL_ELEMS_ZERO;
+			bool		nulls[3] = INIT_ALL_ELEMS_FALSE;
 
 			if (evi1 == evi2)
 				continue;
@@ -2302,8 +2293,6 @@ pg_extension_update_paths(PG_FUNCTION_ARGS)
 			path = find_update_path(evi_list, evi1, evi2, false, true);
 
 			/* Emit result row */
-			memset(values, 0, sizeof(values));
-			memset(nulls, 0, sizeof(nulls));
 
 			/* source */
 			values[0] = CStringGetTextDatum(evi1->name);
@@ -3061,9 +3050,9 @@ ApplyExtensionUpdates(Oid extensionOid,
 		SysScanDesc extScan;
 		HeapTuple	extTup;
 		Form_pg_extension extForm;
-		Datum		values[Natts_pg_extension];
-		bool		nulls[Natts_pg_extension];
-		bool		repl[Natts_pg_extension];
+		Datum		values[Natts_pg_extension] = INIT_ALL_ELEMS_ZERO;
+		bool		nulls[Natts_pg_extension] = INIT_ALL_ELEMS_FALSE;
+		bool		repl[Natts_pg_extension] = INIT_ALL_ELEMS_FALSE;
 		ObjectAddress myself;
 		ListCell   *lc;
 
@@ -3100,10 +3089,6 @@ ApplyExtensionUpdates(Oid extensionOid,
 		/*
 		 * Modify extrelocatable and extversion in the pg_extension tuple
 		 */
-		memset(values, 0, sizeof(values));
-		memset(nulls, 0, sizeof(nulls));
-		memset(repl, 0, sizeof(repl));
-
 		values[Anum_pg_extension_extrelocatable - 1] =
 			BoolGetDatum(control->relocatable);
 		repl[Anum_pg_extension_extrelocatable - 1] = true;
diff --git a/src/backend/commands/foreigncmds.c b/src/backend/commands/foreigncmds.c
index f96c278..f320d04 100644
--- a/src/backend/commands/foreigncmds.c
+++ b/src/backend/commands/foreigncmds.c
@@ -563,8 +563,8 @@ ObjectAddress
 CreateForeignDataWrapper(CreateFdwStmt *stmt)
 {
 	Relation	rel;
-	Datum		values[Natts_pg_foreign_data_wrapper];
-	bool		nulls[Natts_pg_foreign_data_wrapper];
+	Datum		values[Natts_pg_foreign_data_wrapper] = INIT_ALL_ELEMS_ZERO;
+	bool		nulls[Natts_pg_foreign_data_wrapper] = INIT_ALL_ELEMS_FALSE;
 	HeapTuple	tuple;
 	Oid			fdwId;
 	bool		handler_given;
@@ -601,9 +601,6 @@ CreateForeignDataWrapper(CreateFdwStmt *stmt)
 	/*
 	 * Insert tuple into pg_foreign_data_wrapper.
 	 */
-	memset(values, 0, sizeof(values));
-	memset(nulls, false, sizeof(nulls));
-
 	fdwId = GetNewOidWithIndex(rel, ForeignDataWrapperOidIndexId,
 							   Anum_pg_foreign_data_wrapper_oid);
 	values[Anum_pg_foreign_data_wrapper_oid - 1] = ObjectIdGetDatum(fdwId);
@@ -868,8 +865,8 @@ CreateForeignServer(CreateForeignServerStmt *stmt)
 {
 	Relation	rel;
 	Datum		srvoptions;
-	Datum		values[Natts_pg_foreign_server];
-	bool		nulls[Natts_pg_foreign_server];
+	Datum		values[Natts_pg_foreign_server] = INIT_ALL_ELEMS_ZERO;
+	bool		nulls[Natts_pg_foreign_server] = INIT_ALL_ELEMS_FALSE;
 	HeapTuple	tuple;
 	Oid			srvId;
 	Oid			ownerId;
@@ -918,9 +915,6 @@ CreateForeignServer(CreateForeignServerStmt *stmt)
 	/*
 	 * Insert tuple into pg_foreign_server.
 	 */
-	memset(values, 0, sizeof(values));
-	memset(nulls, false, sizeof(nulls));
-
 	srvId = GetNewOidWithIndex(rel, ForeignServerOidIndexId,
 							   Anum_pg_foreign_server_oid);
 	values[Anum_pg_foreign_server_oid - 1] = ObjectIdGetDatum(srvId);
@@ -1145,8 +1139,8 @@ CreateUserMapping(CreateUserMappingStmt *stmt)
 {
 	Relation	rel;
 	Datum		useoptions;
-	Datum		values[Natts_pg_user_mapping];
-	bool		nulls[Natts_pg_user_mapping];
+	Datum		values[Natts_pg_user_mapping] = INIT_ALL_ELEMS_ZERO;
+	bool		nulls[Natts_pg_user_mapping] = INIT_ALL_ELEMS_FALSE;
 	HeapTuple	tuple;
 	Oid			useId;
 	Oid			umId;
@@ -1201,9 +1195,6 @@ CreateUserMapping(CreateUserMappingStmt *stmt)
 	/*
 	 * Insert tuple into pg_user_mapping.
 	 */
-	memset(values, 0, sizeof(values));
-	memset(nulls, false, sizeof(nulls));
-
 	umId = GetNewOidWithIndex(rel, UserMappingOidIndexId,
 							  Anum_pg_user_mapping_oid);
 	values[Anum_pg_user_mapping_oid - 1] = ObjectIdGetDatum(umId);
@@ -1465,8 +1456,8 @@ CreateForeignTable(CreateForeignTableStmt *stmt, Oid relid)
 {
 	Relation	ftrel;
 	Datum		ftoptions;
-	Datum		values[Natts_pg_foreign_table];
-	bool		nulls[Natts_pg_foreign_table];
+	Datum		values[Natts_pg_foreign_table] = INIT_ALL_ELEMS_ZERO;
+	bool		nulls[Natts_pg_foreign_table] = INIT_ALL_ELEMS_FALSE;
 	HeapTuple	tuple;
 	AclResult	aclresult;
 	ObjectAddress myself;
@@ -1502,9 +1493,6 @@ CreateForeignTable(CreateForeignTableStmt *stmt, Oid relid)
 	/*
 	 * Insert tuple into pg_foreign_table.
 	 */
-	memset(values, 0, sizeof(values));
-	memset(nulls, false, sizeof(nulls));
-
 	values[Anum_pg_foreign_table_ftrelid - 1] = ObjectIdGetDatum(relid);
 	values[Anum_pg_foreign_table_ftserver - 1] = ObjectIdGetDatum(server->serverid);
 	/* Add table generic options */
diff --git a/src/backend/commands/functioncmds.c b/src/backend/commands/functioncmds.c
index 40f1f9a..325d1f3 100644
--- a/src/backend/commands/functioncmds.c
+++ b/src/backend/commands/functioncmds.c
@@ -1504,7 +1504,7 @@ CreateCast(CreateCastStmt *stmt)
 	Relation	relation;
 	HeapTuple	tuple;
 	Datum		values[Natts_pg_cast];
-	bool		nulls[Natts_pg_cast];
+	bool		nulls[Natts_pg_cast] = INIT_ALL_ELEMS_FALSE;
 	ObjectAddress myself,
 				referenced;
 	AclResult	aclresult;
@@ -1757,8 +1757,6 @@ CreateCast(CreateCastStmt *stmt)
 	values[Anum_pg_cast_castcontext - 1] = CharGetDatum(castcontext);
 	values[Anum_pg_cast_castmethod - 1] = CharGetDatum(castmethod);
 
-	MemSet(nulls, false, sizeof(nulls));
-
 	tuple = heap_form_tuple(RelationGetDescr(relation), values, nulls);
 
 	CatalogTupleInsert(relation, tuple);
@@ -1893,8 +1891,8 @@ CreateTransform(CreateTransformStmt *stmt)
 	AclResult	aclresult;
 	Form_pg_proc procstruct;
 	Datum		values[Natts_pg_transform];
-	bool		nulls[Natts_pg_transform];
-	bool		replaces[Natts_pg_transform];
+	bool		nulls[Natts_pg_transform] = INIT_ALL_ELEMS_FALSE;
+	bool		replaces[Natts_pg_transform] = INIT_ALL_ELEMS_FALSE;
 	Oid			transformid;
 	HeapTuple	tuple;
 	HeapTuple	newtuple;
@@ -1999,8 +1997,6 @@ CreateTransform(CreateTransformStmt *stmt)
 	values[Anum_pg_transform_trffromsql - 1] = ObjectIdGetDatum(fromsqlfuncid);
 	values[Anum_pg_transform_trftosql - 1] = ObjectIdGetDatum(tosqlfuncid);
 
-	MemSet(nulls, false, sizeof(nulls));
-
 	relation = table_open(TransformRelationId, RowExclusiveLock);
 
 	tuple = SearchSysCache2(TRFTYPELANG,
@@ -2017,7 +2013,6 @@ CreateTransform(CreateTransformStmt *stmt)
 							format_type_be(typeid),
 							stmt->lang)));
 
-		MemSet(replaces, false, sizeof(replaces));
 		replaces[Anum_pg_transform_trffromsql - 1] = true;
 		replaces[Anum_pg_transform_trftosql - 1] = true;
 
diff --git a/src/backend/commands/opclasscmds.c b/src/backend/commands/opclasscmds.c
index 6a1ccde..a159770 100644
--- a/src/backend/commands/opclasscmds.c
+++ b/src/backend/commands/opclasscmds.c
@@ -248,8 +248,8 @@ CreateOpFamily(const char *amname, const char *opfname, Oid namespaceoid, Oid am
 	Oid			opfamilyoid;
 	Relation	rel;
 	HeapTuple	tup;
-	Datum		values[Natts_pg_opfamily];
-	bool		nulls[Natts_pg_opfamily];
+	Datum		values[Natts_pg_opfamily] = INIT_ALL_ELEMS_ZERO;
+	bool		nulls[Natts_pg_opfamily] = INIT_ALL_ELEMS_FALSE;
 	NameData	opfName;
 	ObjectAddress myself,
 				referenced;
@@ -272,9 +272,6 @@ CreateOpFamily(const char *amname, const char *opfname, Oid namespaceoid, Oid am
 	/*
 	 * Okay, let's create the pg_opfamily entry.
 	 */
-	memset(values, 0, sizeof(values));
-	memset(nulls, false, sizeof(nulls));
-
 	opfamilyoid = GetNewOidWithIndex(rel, OpfamilyOidIndexId,
 									 Anum_pg_opfamily_oid);
 	values[Anum_pg_opfamily_oid - 1] = ObjectIdGetDatum(opfamilyoid);
@@ -347,8 +344,8 @@ DefineOpClass(CreateOpClassStmt *stmt)
 	HeapTuple	tup;
 	Form_pg_am	amform;
 	IndexAmRoutine *amroutine;
-	Datum		values[Natts_pg_opclass];
-	bool		nulls[Natts_pg_opclass];
+	Datum		values[Natts_pg_opclass] = INIT_ALL_ELEMS_ZERO;
+	bool		nulls[Natts_pg_opclass] = INIT_ALL_ELEMS_FALSE;
 	AclResult	aclresult;
 	NameData	opcName;
 	ObjectAddress myself,
@@ -639,9 +636,6 @@ DefineOpClass(CreateOpClassStmt *stmt)
 	/*
 	 * Okay, let's create the pg_opclass entry.
 	 */
-	memset(values, 0, sizeof(values));
-	memset(nulls, false, sizeof(nulls));
-
 	opclassoid = GetNewOidWithIndex(rel, OpclassOidIndexId,
 									Anum_pg_opclass_oid);
 	values[Anum_pg_opclass_oid - 1] = ObjectIdGetDatum(opclassoid);
@@ -1308,8 +1302,8 @@ storeOperators(List *opfamilyname, Oid amoid,
 			   List *operators, bool isAdd)
 {
 	Relation	rel;
-	Datum		values[Natts_pg_amop];
-	bool		nulls[Natts_pg_amop];
+	Datum		values[Natts_pg_amop] = INIT_ALL_ELEMS_ZERO;
+	bool		nulls[Natts_pg_amop] = INIT_ALL_ELEMS_FALSE;
 	HeapTuple	tup;
 	Oid			entryoid;
 	ObjectAddress myself,
@@ -1344,8 +1338,6 @@ storeOperators(List *opfamilyname, Oid amoid,
 		oppurpose = OidIsValid(op->sortfamily) ? AMOP_ORDER : AMOP_SEARCH;
 
 		/* Create the pg_amop entry */
-		memset(values, 0, sizeof(values));
-		memset(nulls, false, sizeof(nulls));
 
 		entryoid = GetNewOidWithIndex(rel, AccessMethodOperatorOidIndexId,
 									  Anum_pg_amop_oid);
@@ -1426,8 +1418,8 @@ storeProcedures(List *opfamilyname, Oid amoid,
 				List *procedures, bool isAdd)
 {
 	Relation	rel;
-	Datum		values[Natts_pg_amproc];
-	bool		nulls[Natts_pg_amproc];
+	Datum		values[Natts_pg_amproc] = INIT_ALL_ELEMS_ZERO;
+	bool		nulls[Natts_pg_amproc] = INIT_ALL_ELEMS_FALSE;
 	HeapTuple	tup;
 	Oid			entryoid;
 	ObjectAddress myself,
@@ -1459,9 +1451,6 @@ storeProcedures(List *opfamilyname, Oid amoid,
 							NameListToString(opfamilyname))));
 
 		/* Create the pg_amproc entry */
-		memset(values, 0, sizeof(values));
-		memset(nulls, false, sizeof(nulls));
-
 		entryoid = GetNewOidWithIndex(rel, AccessMethodProcedureOidIndexId,
 									  Anum_pg_amproc_oid);
 		values[Anum_pg_amproc_oid - 1] = ObjectIdGetDatum(entryoid);
diff --git a/src/backend/commands/prepare.c b/src/backend/commands/prepare.c
index 7e0a041..c86c409a 100644
--- a/src/backend/commands/prepare.c
+++ b/src/backend/commands/prepare.c
@@ -757,9 +757,7 @@ pg_prepared_statement(PG_FUNCTION_ARGS)
 		while ((prep_stmt = hash_seq_search(&hash_seq)) != NULL)
 		{
 			Datum		values[5];
-			bool		nulls[5];
-
-			MemSet(nulls, 0, sizeof(nulls));
+			bool		nulls[5] = INIT_ALL_ELEMS_FALSE;
 
 			values[0] = CStringGetTextDatum(prep_stmt->stmt_name);
 			values[1] = CStringGetTextDatum(prep_stmt->plansource->query_string);
diff --git a/src/backend/commands/proclang.c b/src/backend/commands/proclang.c
index 343cd1d..ffaf0c0 100644
--- a/src/backend/commands/proclang.c
+++ b/src/backend/commands/proclang.c
@@ -325,8 +325,8 @@ create_proc_lang(const char *languageName, bool replace,
 {
 	Relation	rel;
 	TupleDesc	tupDesc;
-	Datum		values[Natts_pg_language];
-	bool		nulls[Natts_pg_language];
+	Datum		values[Natts_pg_language] = INIT_ALL_ELEMS_ZERO;
+	bool		nulls[Natts_pg_language] = INIT_ALL_ELEMS_FALSE;
 	bool		replaces[Natts_pg_language];
 	NameData	langname;
 	HeapTuple	oldtup;
@@ -340,8 +340,6 @@ create_proc_lang(const char *languageName, bool replace,
 	tupDesc = RelationGetDescr(rel);
 
 	/* Prepare data to be inserted */
-	memset(values, 0, sizeof(values));
-	memset(nulls, false, sizeof(nulls));
 	memset(replaces, true, sizeof(replaces));
 
 	namestrcpy(&langname, languageName);
diff --git a/src/backend/commands/publicationcmds.c b/src/backend/commands/publicationcmds.c
index f115d4b..3d8c9ee 100644
--- a/src/backend/commands/publicationcmds.c
+++ b/src/backend/commands/publicationcmds.c
@@ -142,8 +142,8 @@ CreatePublication(CreatePublicationStmt *stmt)
 	Relation	rel;
 	ObjectAddress myself;
 	Oid			puboid;
-	bool		nulls[Natts_pg_publication];
-	Datum		values[Natts_pg_publication];
+	bool		nulls[Natts_pg_publication] = INIT_ALL_ELEMS_FALSE;
+	Datum		values[Natts_pg_publication] = INIT_ALL_ELEMS_ZERO;
 	HeapTuple	tup;
 	bool		publish_given;
 	bool		publish_insert;
@@ -178,9 +178,6 @@ CreatePublication(CreatePublicationStmt *stmt)
 	}
 
 	/* Form a tuple. */
-	memset(values, 0, sizeof(values));
-	memset(nulls, false, sizeof(nulls));
-
 	values[Anum_pg_publication_pubname - 1] =
 		DirectFunctionCall1(namein, CStringGetDatum(stmt->pubname));
 	values[Anum_pg_publication_pubowner - 1] = ObjectIdGetDatum(GetUserId());
@@ -250,9 +247,9 @@ static void
 AlterPublicationOptions(AlterPublicationStmt *stmt, Relation rel,
 						HeapTuple tup)
 {
-	bool		nulls[Natts_pg_publication];
-	bool		replaces[Natts_pg_publication];
-	Datum		values[Natts_pg_publication];
+	bool		nulls[Natts_pg_publication] = INIT_ALL_ELEMS_FALSE;
+	bool		replaces[Natts_pg_publication] = INIT_ALL_ELEMS_FALSE;
+	Datum		values[Natts_pg_publication] = INIT_ALL_ELEMS_ZERO;
 	bool		publish_given;
 	bool		publish_insert;
 	bool		publish_update;
@@ -267,10 +264,6 @@ AlterPublicationOptions(AlterPublicationStmt *stmt, Relation rel,
 							  &publish_truncate);
 
 	/* Everything ok, form a new tuple. */
-	memset(values, 0, sizeof(values));
-	memset(nulls, false, sizeof(nulls));
-	memset(replaces, false, sizeof(replaces));
-
 	if (publish_given)
 	{
 		values[Anum_pg_publication_pubinsert - 1] = BoolGetDatum(publish_insert);
diff --git a/src/backend/commands/seclabel.c b/src/backend/commands/seclabel.c
index 63219ad..2dfa2d3 100644
--- a/src/backend/commands/seclabel.c
+++ b/src/backend/commands/seclabel.c
@@ -258,12 +258,10 @@ SetSharedSecurityLabel(const ObjectAddress *object,
 	HeapTuple	oldtup;
 	HeapTuple	newtup = NULL;
 	Datum		values[Natts_pg_shseclabel];
-	bool		nulls[Natts_pg_shseclabel];
-	bool		replaces[Natts_pg_shseclabel];
+	bool		nulls[Natts_pg_shseclabel] = INIT_ALL_ELEMS_FALSE;
+	bool		replaces[Natts_pg_shseclabel] = INIT_ALL_ELEMS_FALSE;
 
 	/* Prepare to form or update a tuple, if necessary. */
-	memset(nulls, false, sizeof(nulls));
-	memset(replaces, false, sizeof(replaces));
 	values[Anum_pg_shseclabel_objoid - 1] = ObjectIdGetDatum(object->objectId);
 	values[Anum_pg_shseclabel_classoid - 1] = ObjectIdGetDatum(object->classId);
 	values[Anum_pg_shseclabel_provider - 1] = CStringGetTextDatum(provider);
@@ -333,8 +331,8 @@ SetSecurityLabel(const ObjectAddress *object,
 	HeapTuple	oldtup;
 	HeapTuple	newtup = NULL;
 	Datum		values[Natts_pg_seclabel];
-	bool		nulls[Natts_pg_seclabel];
-	bool		replaces[Natts_pg_seclabel];
+	bool		nulls[Natts_pg_seclabel] = INIT_ALL_ELEMS_FALSE;
+	bool		replaces[Natts_pg_seclabel] = INIT_ALL_ELEMS_FALSE;
 
 	/* Shared objects have their own security label catalog. */
 	if (IsSharedRelation(object->classId))
@@ -344,8 +342,6 @@ SetSecurityLabel(const ObjectAddress *object,
 	}
 
 	/* Prepare to form or update a tuple, if necessary. */
-	memset(nulls, false, sizeof(nulls));
-	memset(replaces, false, sizeof(replaces));
 	values[Anum_pg_seclabel_objoid - 1] = ObjectIdGetDatum(object->objectId);
 	values[Anum_pg_seclabel_classoid - 1] = ObjectIdGetDatum(object->classId);
 	values[Anum_pg_seclabel_objsubid - 1] = Int32GetDatum(object->objectSubId);
diff --git a/src/backend/commands/statscmds.c b/src/backend/commands/statscmds.c
index f51eb7b..c0579ab 100644
--- a/src/backend/commands/statscmds.c
+++ b/src/backend/commands/statscmds.c
@@ -69,10 +69,10 @@ CreateStatistics(CreateStatsStmt *stmt)
 	Oid			namespaceId;
 	Oid			stxowner = GetUserId();
 	HeapTuple	htup;
-	Datum		values[Natts_pg_statistic_ext];
-	bool		nulls[Natts_pg_statistic_ext];
-	Datum		datavalues[Natts_pg_statistic_ext_data];
-	bool		datanulls[Natts_pg_statistic_ext_data];
+	Datum		values[Natts_pg_statistic_ext] = INIT_ALL_ELEMS_ZERO;
+	bool		nulls[Natts_pg_statistic_ext] = INIT_ALL_ELEMS_FALSE;
+	Datum		datavalues[Natts_pg_statistic_ext_data] = INIT_ALL_ELEMS_ZERO;
+	bool		datanulls[Natts_pg_statistic_ext_data] = INIT_ALL_ELEMS_FALSE;
 	int2vector *stxkeys;
 	Relation	statrel;
 	Relation	datarel;
@@ -330,9 +330,6 @@ CreateStatistics(CreateStatsStmt *stmt)
 	/*
 	 * Everything seems fine, so let's build the pg_statistic_ext tuple.
 	 */
-	memset(values, 0, sizeof(values));
-	memset(nulls, false, sizeof(nulls));
-
 	statoid = GetNewOidWithIndex(statrel, StatisticExtOidIndexId,
 								 Anum_pg_statistic_ext_oid);
 	values[Anum_pg_statistic_ext_oid - 1] = ObjectIdGetDatum(statoid);
@@ -357,9 +354,6 @@ CreateStatistics(CreateStatsStmt *stmt)
 	 */
 	datarel = table_open(StatisticExtDataRelationId, RowExclusiveLock);
 
-	memset(datavalues, 0, sizeof(datavalues));
-	memset(datanulls, false, sizeof(datanulls));
-
 	datavalues[Anum_pg_statistic_ext_data_stxoid - 1] = ObjectIdGetDatum(statoid);
 
 	/* no statistics built yet */
@@ -607,9 +601,9 @@ UpdateStatisticsForTypeChange(Oid statsOid, Oid relationOid, int attnum,
 
 	Relation	rel;
 
-	Datum		values[Natts_pg_statistic_ext_data];
-	bool		nulls[Natts_pg_statistic_ext_data];
-	bool		replaces[Natts_pg_statistic_ext_data];
+	Datum		values[Natts_pg_statistic_ext_data] = INIT_ALL_ELEMS_ZERO;
+	bool		nulls[Natts_pg_statistic_ext_data] = INIT_ALL_ELEMS_FALSE;
+	bool		replaces[Natts_pg_statistic_ext_data] = INIT_ALL_ELEMS_FALSE;
 
 	oldtup = SearchSysCache1(STATEXTDATASTXOID, ObjectIdGetDatum(statsOid));
 	if (!HeapTupleIsValid(oldtup))
@@ -630,10 +624,6 @@ UpdateStatisticsForTypeChange(Oid statsOid, Oid relationOid, int attnum,
 	 * OK, we need to reset some statistics. So let's build the new tuple,
 	 * replacing the affected statistics types with NULL.
 	 */
-	memset(nulls, 0, Natts_pg_statistic_ext_data * sizeof(bool));
-	memset(replaces, 0, Natts_pg_statistic_ext_data * sizeof(bool));
-	memset(values, 0, Natts_pg_statistic_ext_data * sizeof(Datum));
-
 	replaces[Anum_pg_statistic_ext_data_stxdmcv - 1] = true;
 	nulls[Anum_pg_statistic_ext_data_stxdmcv - 1] = true;
 
diff --git a/src/backend/commands/subscriptioncmds.c b/src/backend/commands/subscriptioncmds.c
index 2e67a58..07c3e31 100644
--- a/src/backend/commands/subscriptioncmds.c
+++ b/src/backend/commands/subscriptioncmds.c
@@ -317,8 +317,8 @@ CreateSubscription(CreateSubscriptionStmt *stmt, bool isTopLevel)
 	Relation	rel;
 	ObjectAddress myself;
 	Oid			subid;
-	bool		nulls[Natts_pg_subscription];
-	Datum		values[Natts_pg_subscription];
+	bool		nulls[Natts_pg_subscription] = INIT_ALL_ELEMS_FALSE;
+	Datum		values[Natts_pg_subscription] = INIT_ALL_ELEMS_ZERO;
 	Oid			owner = GetUserId();
 	HeapTuple	tup;
 	bool		connect;
@@ -396,9 +396,6 @@ CreateSubscription(CreateSubscriptionStmt *stmt, bool isTopLevel)
 	walrcv_check_conninfo(conninfo);
 
 	/* Everything ok, form a new tuple. */
-	memset(values, 0, sizeof(values));
-	memset(nulls, false, sizeof(nulls));
-
 	subid = GetNewOidWithIndex(rel, SubscriptionObjectIndexId,
 							   Anum_pg_subscription_oid);
 	values[Anum_pg_subscription_oid - 1] = ObjectIdGetDatum(subid);
@@ -636,9 +633,9 @@ AlterSubscription(AlterSubscriptionStmt *stmt)
 {
 	Relation	rel;
 	ObjectAddress myself;
-	bool		nulls[Natts_pg_subscription];
-	bool		replaces[Natts_pg_subscription];
-	Datum		values[Natts_pg_subscription];
+	bool		nulls[Natts_pg_subscription] = INIT_ALL_ELEMS_FALSE;
+	bool		replaces[Natts_pg_subscription] = INIT_ALL_ELEMS_FALSE;
+	Datum		values[Natts_pg_subscription] = INIT_ALL_ELEMS_ZERO;
 	HeapTuple	tup;
 	Oid			subid;
 	bool		update_tuple = false;
@@ -671,9 +668,6 @@ AlterSubscription(AlterSubscriptionStmt *stmt)
 	LockSharedObject(SubscriptionRelationId, subid, 0, AccessExclusiveLock);
 
 	/* Form a new tuple. */
-	memset(values, 0, sizeof(values));
-	memset(nulls, false, sizeof(nulls));
-	memset(replaces, false, sizeof(replaces));
 
 	switch (stmt->kind)
 	{
diff --git a/src/backend/commands/tablespace.c b/src/backend/commands/tablespace.c
index 84efb41..e4ee847 100644
--- a/src/backend/commands/tablespace.c
+++ b/src/backend/commands/tablespace.c
@@ -236,7 +236,7 @@ CreateTableSpace(CreateTableSpaceStmt *stmt)
 #ifdef HAVE_SYMLINK
 	Relation	rel;
 	Datum		values[Natts_pg_tablespace];
-	bool		nulls[Natts_pg_tablespace];
+	bool		nulls[Natts_pg_tablespace] = INIT_ALL_ELEMS_FALSE;
 	HeapTuple	tuple;
 	Oid			tablespaceoid;
 	char	   *location;
@@ -334,8 +334,6 @@ CreateTableSpace(CreateTableSpaceStmt *stmt)
 	 */
 	rel = table_open(TableSpaceRelationId, RowExclusiveLock);
 
-	MemSet(nulls, false, sizeof(nulls));
-
 	tablespaceoid = GetNewOidWithIndex(rel, TablespaceOidIndexId,
 									   Anum_pg_tablespace_oid);
 	values[Anum_pg_tablespace_oid - 1] = ObjectIdGetDatum(tablespaceoid);
diff --git a/src/backend/commands/trigger.c b/src/backend/commands/trigger.c
index cdb1105..d506b2e 100644
--- a/src/backend/commands/trigger.c
+++ b/src/backend/commands/trigger.c
@@ -171,7 +171,7 @@ CreateTrigger(CreateTrigStmt *stmt, const char *queryString,
 	List	   *whenRtable;
 	char	   *qual;
 	Datum		values[Natts_pg_trigger];
-	bool		nulls[Natts_pg_trigger];
+	bool		nulls[Natts_pg_trigger] = INIT_ALL_ELEMS_FALSE;
 	Relation	rel;
 	AclResult	aclresult;
 	Relation	tgrel;
@@ -844,8 +844,6 @@ CreateTrigger(CreateTrigStmt *stmt, const char *queryString,
 	 * makes the triggers in partitions identical to the ones in the
 	 * partitioned tables, except that they are marked internal.
 	 */
-	memset(nulls, false, sizeof(nulls));
-
 	values[Anum_pg_trigger_oid - 1] = ObjectIdGetDatum(trigoid);
 	values[Anum_pg_trigger_tgrelid - 1] = ObjectIdGetDatum(RelationGetRelid(rel));
 	values[Anum_pg_trigger_tgname - 1] = DirectFunctionCall1(namein,
diff --git a/src/backend/commands/tsearchcmds.c b/src/backend/commands/tsearchcmds.c
index 5d6528f..99f66bc 100644
--- a/src/backend/commands/tsearchcmds.c
+++ b/src/backend/commands/tsearchcmds.c
@@ -179,8 +179,8 @@ DefineTSParser(List *names, List *parameters)
 	ListCell   *pl;
 	Relation	prsRel;
 	HeapTuple	tup;
-	Datum		values[Natts_pg_ts_parser];
-	bool		nulls[Natts_pg_ts_parser];
+	Datum		values[Natts_pg_ts_parser] = INIT_ALL_ELEMS_ZERO;
+	bool		nulls[Natts_pg_ts_parser] = INIT_ALL_ELEMS_FALSE;
 	NameData	pname;
 	Oid			prsOid;
 	Oid			namespaceoid;
@@ -197,9 +197,6 @@ DefineTSParser(List *names, List *parameters)
 	namespaceoid = QualifiedNameGetCreationNamespace(names, &prsname);
 
 	/* initialize tuple fields with name/namespace */
-	memset(values, 0, sizeof(values));
-	memset(nulls, false, sizeof(nulls));
-
 	prsOid = GetNewOidWithIndex(prsRel, TSParserOidIndexId,
 								Anum_pg_ts_parser_oid);
 	values[Anum_pg_ts_parser_oid - 1] = ObjectIdGetDatum(prsOid);
@@ -414,8 +411,8 @@ DefineTSDictionary(List *names, List *parameters)
 	ListCell   *pl;
 	Relation	dictRel;
 	HeapTuple	tup;
-	Datum		values[Natts_pg_ts_dict];
-	bool		nulls[Natts_pg_ts_dict];
+	Datum		values[Natts_pg_ts_dict] = INIT_ALL_ELEMS_ZERO;
+	bool		nulls[Natts_pg_ts_dict] = INIT_ALL_ELEMS_FALSE;
 	NameData	dname;
 	Oid			templId = InvalidOid;
 	List	   *dictoptions = NIL;
@@ -468,9 +465,6 @@ DefineTSDictionary(List *names, List *parameters)
 	/*
 	 * Looks good, insert
 	 */
-	memset(values, 0, sizeof(values));
-	memset(nulls, false, sizeof(nulls));
-
 	dictOid = GetNewOidWithIndex(dictRel, TSDictionaryOidIndexId,
 								 Anum_pg_ts_dict_oid);
 	values[Anum_pg_ts_dict_oid - 1] = ObjectIdGetDatum(dictOid);
@@ -733,7 +727,7 @@ DefineTSTemplate(List *names, List *parameters)
 	Relation	tmplRel;
 	HeapTuple	tup;
 	Datum		values[Natts_pg_ts_template];
-	bool		nulls[Natts_pg_ts_template];
+	bool		nulls[Natts_pg_ts_template] = INIT_ALL_ELEMS_FALSE;
 	NameData	dname;
 	int			i;
 	Oid			tmplOid;
@@ -753,7 +747,6 @@ DefineTSTemplate(List *names, List *parameters)
 
 	for (i = 0; i < Natts_pg_ts_template; i++)
 	{
-		nulls[i] = false;
 		values[i] = ObjectIdGetDatum(InvalidOid);
 	}
 
@@ -965,8 +958,8 @@ DefineTSConfiguration(List *names, List *parameters, ObjectAddress *copied)
 	Relation	cfgRel;
 	Relation	mapRel = NULL;
 	HeapTuple	tup;
-	Datum		values[Natts_pg_ts_config];
-	bool		nulls[Natts_pg_ts_config];
+	Datum		values[Natts_pg_ts_config] = INIT_ALL_ELEMS_ZERO;
+	bool		nulls[Natts_pg_ts_config] = INIT_ALL_ELEMS_FALSE;
 	AclResult	aclresult;
 	Oid			namespaceoid;
 	char	   *cfgname;
@@ -1050,9 +1043,6 @@ DefineTSConfiguration(List *names, List *parameters, ObjectAddress *copied)
 	/*
 	 * Looks good, build tuple and insert
 	 */
-	memset(values, 0, sizeof(values));
-	memset(nulls, false, sizeof(nulls));
-
 	cfgOid = GetNewOidWithIndex(cfgRel, TSConfigOidIndexId,
 								Anum_pg_ts_config_oid);
 	values[Anum_pg_ts_config_oid - 1] = ObjectIdGetDatum(cfgOid);
@@ -1089,11 +1079,8 @@ DefineTSConfiguration(List *names, List *parameters, ObjectAddress *copied)
 		{
 			Form_pg_ts_config_map cfgmap = (Form_pg_ts_config_map) GETSTRUCT(maptup);
 			HeapTuple	newmaptup;
-			Datum		mapvalues[Natts_pg_ts_config_map];
-			bool		mapnulls[Natts_pg_ts_config_map];
-
-			memset(mapvalues, 0, sizeof(mapvalues));
-			memset(mapnulls, false, sizeof(mapnulls));
+			Datum		mapvalues[Natts_pg_ts_config_map] = INIT_ALL_ELEMS_ZERO;
+			bool		mapnulls[Natts_pg_ts_config_map] = INIT_ALL_ELEMS_FALSE;
 
 			mapvalues[Anum_pg_ts_config_map_mapcfg - 1] = cfgOid;
 			mapvalues[Anum_pg_ts_config_map_maptokentype - 1] = cfgmap->maptokentype;
@@ -1420,9 +1407,8 @@ MakeConfigurationMapping(AlterTSConfigurationStmt *stmt,
 			for (j = 0; j < ndict; j++)
 			{
 				Datum		values[Natts_pg_ts_config_map];
-				bool		nulls[Natts_pg_ts_config_map];
+				bool		nulls[Natts_pg_ts_config_map] = INIT_ALL_ELEMS_FALSE;
 
-				memset(nulls, false, sizeof(nulls));
 				values[Anum_pg_ts_config_map_mapcfg - 1] = ObjectIdGetDatum(cfgId);
 				values[Anum_pg_ts_config_map_maptokentype - 1] = Int32GetDatum(tokens[i]);
 				values[Anum_pg_ts_config_map_mapseqno - 1] = Int32GetDatum(j + 1);
diff --git a/src/backend/libpq/hba.c b/src/backend/libpq/hba.c
index 2221c04..1e59c49 100644
--- a/src/backend/libpq/hba.c
+++ b/src/backend/libpq/hba.c
@@ -2414,8 +2414,8 @@ static void
 fill_hba_line(Tuplestorestate *tuple_store, TupleDesc tupdesc,
 			  int lineno, HbaLine *hba, const char *err_msg)
 {
-	Datum		values[NUM_PG_HBA_FILE_RULES_ATTS];
-	bool		nulls[NUM_PG_HBA_FILE_RULES_ATTS];
+	Datum		values[NUM_PG_HBA_FILE_RULES_ATTS] = INIT_ALL_ELEMS_ZERO;
+	bool		nulls[NUM_PG_HBA_FILE_RULES_ATTS] = INIT_ALL_ELEMS_FALSE;
 	char		buffer[NI_MAXHOST];
 	HeapTuple	tuple;
 	int			index;
@@ -2427,8 +2427,6 @@ fill_hba_line(Tuplestorestate *tuple_store, TupleDesc tupdesc,
 
 	Assert(tupdesc->natts == NUM_PG_HBA_FILE_RULES_ATTS);
 
-	memset(values, 0, sizeof(values));
-	memset(nulls, 0, sizeof(nulls));
 	index = 0;
 
 	/* line_number */
diff --git a/src/backend/replication/logical/launcher.c b/src/backend/replication/logical/launcher.c
index 186057b..c247dbd 100644
--- a/src/backend/replication/logical/launcher.c
+++ b/src/backend/replication/logical/launcher.c
@@ -1136,8 +1136,8 @@ pg_stat_get_subscription(PG_FUNCTION_ARGS)
 	for (i = 0; i <= max_logical_replication_workers; i++)
 	{
 		/* for each row */
-		Datum		values[PG_STAT_GET_SUBSCRIPTION_COLS];
-		bool		nulls[PG_STAT_GET_SUBSCRIPTION_COLS];
+		Datum		values[PG_STAT_GET_SUBSCRIPTION_COLS] = INIT_ALL_ELEMS_ZERO;
+		bool		nulls[PG_STAT_GET_SUBSCRIPTION_COLS] = INIT_ALL_ELEMS_FALSE;
 		int			worker_pid;
 		LogicalRepWorker worker;
 
@@ -1151,9 +1151,6 @@ pg_stat_get_subscription(PG_FUNCTION_ARGS)
 
 		worker_pid = worker.proc->pid;
 
-		MemSet(values, 0, sizeof(values));
-		MemSet(nulls, 0, sizeof(nulls));
-
 		values[0] = ObjectIdGetDatum(worker.subid);
 		if (OidIsValid(worker.relid))
 			values[1] = ObjectIdGetDatum(worker.relid);
diff --git a/src/backend/replication/logical/logicalfuncs.c b/src/backend/replication/logical/logicalfuncs.c
index d1cf80d..b0294f2 100644
--- a/src/backend/replication/logical/logicalfuncs.c
+++ b/src/backend/replication/logical/logicalfuncs.c
@@ -75,7 +75,7 @@ LogicalOutputWrite(LogicalDecodingContext *ctx, XLogRecPtr lsn, TransactionId xi
 				   bool last_write)
 {
 	Datum		values[3];
-	bool		nulls[3];
+	bool		nulls[3] = INIT_ALL_ELEMS_FALSE;
 	DecodingOutputState *p;
 
 	/* SQL Datums can only be of a limited length... */
@@ -84,7 +84,6 @@ LogicalOutputWrite(LogicalDecodingContext *ctx, XLogRecPtr lsn, TransactionId xi
 
 	p = (DecodingOutputState *) ctx->output_writer_private;
 
-	memset(nulls, 0, sizeof(nulls));
 	values[0] = LSNGetDatum(lsn);
 	values[1] = TransactionIdGetDatum(xid);
 
diff --git a/src/backend/replication/logical/origin.c b/src/backend/replication/logical/origin.c
index 07ae613..6d05dd4 100644
--- a/src/backend/replication/logical/origin.c
+++ b/src/backend/replication/logical/origin.c
@@ -275,7 +275,7 @@ replorigin_create(char *roname)
 
 	for (roident = InvalidOid + 1; roident < PG_UINT16_MAX; roident++)
 	{
-		bool		nulls[Natts_pg_replication_origin];
+		bool		nulls[Natts_pg_replication_origin] = INIT_ALL_ELEMS_FALSE;
 		Datum		values[Natts_pg_replication_origin];
 		bool		collides;
 
@@ -301,8 +301,6 @@ replorigin_create(char *roname)
 			 * Ok, found an unused roident, insert the new row and do a CCI,
 			 * so our callers can look it up if they want to.
 			 */
-			memset(&nulls, 0, sizeof(nulls));
-
 			values[Anum_pg_replication_origin_roident - 1] = ObjectIdGetDatum(roident);
 			values[Anum_pg_replication_origin_roname - 1] = roname_d;
 
@@ -1517,7 +1515,7 @@ pg_show_replication_origin_status(PG_FUNCTION_ARGS)
 	for (i = 0; i < max_replication_slots; i++)
 	{
 		ReplicationState *state;
-		Datum		values[REPLICATION_ORIGIN_PROGRESS_COLS];
+		Datum		values[REPLICATION_ORIGIN_PROGRESS_COLS] = INIT_ALL_ELEMS_ZERO;
 		bool		nulls[REPLICATION_ORIGIN_PROGRESS_COLS];
 		char	   *roname;
 
@@ -1527,7 +1525,6 @@ pg_show_replication_origin_status(PG_FUNCTION_ARGS)
 		if (state->roident == InvalidRepOriginId)
 			continue;
 
-		memset(values, 0, sizeof(values));
 		memset(nulls, 1, sizeof(nulls));
 
 		values[0] = ObjectIdGetDatum(state->roident);
diff --git a/src/backend/replication/slotfuncs.c b/src/backend/replication/slotfuncs.c
index 42da631..f8cfb40 100644
--- a/src/backend/replication/slotfuncs.c
+++ b/src/backend/replication/slotfuncs.c
@@ -77,7 +77,7 @@ pg_create_physical_replication_slot(PG_FUNCTION_ARGS)
 	bool		immediately_reserve = PG_GETARG_BOOL(1);
 	bool		temporary = PG_GETARG_BOOL(2);
 	Datum		values[2];
-	bool		nulls[2];
+	bool		nulls[2] = INIT_ALL_ELEMS_FALSE;
 	TupleDesc	tupdesc;
 	HeapTuple	tuple;
 	Datum		result;
@@ -95,12 +95,10 @@ pg_create_physical_replication_slot(PG_FUNCTION_ARGS)
 									 InvalidXLogRecPtr);
 
 	values[0] = NameGetDatum(&MyReplicationSlot->data.name);
-	nulls[0] = false;
 
 	if (immediately_reserve)
 	{
 		values[1] = LSNGetDatum(MyReplicationSlot->data.restart_lsn);
-		nulls[1] = false;
 	}
 	else
 		nulls[1] = true;
@@ -167,7 +165,7 @@ pg_create_logical_replication_slot(PG_FUNCTION_ARGS)
 	TupleDesc	tupdesc;
 	HeapTuple	tuple;
 	Datum		values[2];
-	bool		nulls[2];
+	bool		nulls[2] = INIT_ALL_ELEMS_FALSE;
 
 	if (get_call_result_type(fcinfo, NULL, &tupdesc) != TYPEFUNC_COMPOSITE)
 		elog(ERROR, "return type must be a row type");
@@ -184,8 +182,6 @@ pg_create_logical_replication_slot(PG_FUNCTION_ARGS)
 	values[0] = NameGetDatum(&MyReplicationSlot->data.name);
 	values[1] = LSNGetDatum(MyReplicationSlot->data.confirmed_flush);
 
-	memset(nulls, 0, sizeof(nulls));
-
 	tuple = heap_form_tuple(tupdesc, values, nulls);
 	result = HeapTupleGetDatum(tuple);
 
@@ -265,7 +261,7 @@ pg_get_replication_slots(PG_FUNCTION_ARGS)
 	{
 		ReplicationSlot *slot = &ReplicationSlotCtl->replication_slots[slotno];
 		Datum		values[PG_GET_REPLICATION_SLOTS_COLS];
-		bool		nulls[PG_GET_REPLICATION_SLOTS_COLS];
+		bool		nulls[PG_GET_REPLICATION_SLOTS_COLS] = INIT_ALL_ELEMS_FALSE;
 
 		ReplicationSlotPersistency persistency;
 		TransactionId xmin;
@@ -295,8 +291,6 @@ pg_get_replication_slots(PG_FUNCTION_ARGS)
 
 		SpinLockRelease(&slot->mutex);
 
-		memset(nulls, 0, sizeof(nulls));
-
 		i = 0;
 		values[i++] = NameGetDatum(&slot_name);
 
@@ -513,7 +507,7 @@ pg_replication_slot_advance(PG_FUNCTION_ARGS)
 	XLogRecPtr	minlsn;
 	TupleDesc	tupdesc;
 	Datum		values[2];
-	bool		nulls[2];
+	bool		nulls[2] = INIT_ALL_ELEMS_FALSE;
 	HeapTuple	tuple;
 	Datum		result;
 
@@ -572,7 +566,6 @@ pg_replication_slot_advance(PG_FUNCTION_ARGS)
 		endlsn = pg_physical_replication_slot_advance(moveto);
 
 	values[0] = NameGetDatum(&MyReplicationSlot->data.name);
-	nulls[0] = false;
 
 	/* Update the on disk state when lsn was updated. */
 	if (XLogRecPtrIsInvalid(endlsn))
@@ -587,7 +580,6 @@ pg_replication_slot_advance(PG_FUNCTION_ARGS)
 
 	/* Return the reached position. */
 	values[1] = LSNGetDatum(endlsn);
-	nulls[1] = false;
 
 	tuple = heap_form_tuple(tupdesc, values, nulls);
 	result = HeapTupleGetDatum(tuple);
@@ -609,7 +601,7 @@ copy_replication_slot(FunctionCallInfo fcinfo, bool logical_slot)
 	bool		temporary;
 	char	   *plugin;
 	Datum		values[2];
-	bool		nulls[2];
+	bool		nulls[2] = INIT_ALL_ELEMS_FALSE;
 	Datum		result;
 	TupleDesc	tupdesc;
 	HeapTuple	tuple;
@@ -779,11 +771,9 @@ copy_replication_slot(FunctionCallInfo fcinfo, bool logical_slot)
 
 	/* All done.  Set up the return values */
 	values[0] = NameGetDatum(dst_name);
-	nulls[0] = false;
 	if (!XLogRecPtrIsInvalid(MyReplicationSlot->data.confirmed_flush))
 	{
 		values[1] = LSNGetDatum(MyReplicationSlot->data.confirmed_flush);
-		nulls[1] = false;
 	}
 	else
 		nulls[1] = true;
diff --git a/src/backend/replication/walsender.c b/src/backend/replication/walsender.c
index eb4a98c..40e1a76 100644
--- a/src/backend/replication/walsender.c
+++ b/src/backend/replication/walsender.c
@@ -351,7 +351,7 @@ IdentifySystem(void)
 	TupOutputState *tstate;
 	TupleDesc	tupdesc;
 	Datum		values[4];
-	bool		nulls[4];
+	bool		nulls[4] = INIT_ALL_ELEMS_FALSE;
 
 	/*
 	 * Reply with a result set with one row, four columns. First col is system
@@ -388,7 +388,6 @@ IdentifySystem(void)
 	}
 
 	dest = CreateDestReceiver(DestRemoteSimple);
-	MemSet(nulls, false, sizeof(nulls));
 
 	/* need a tuple descriptor representing four columns */
 	tupdesc = CreateTemplateTupleDesc(4);
@@ -717,14 +716,13 @@ StartReplication(StartReplicationCmd *cmd)
 		TupOutputState *tstate;
 		TupleDesc	tupdesc;
 		Datum		values[2];
-		bool		nulls[2];
+		bool		nulls[2] = INIT_ALL_ELEMS_FALSE;
 
 		snprintf(startpos_str, sizeof(startpos_str), "%X/%X",
 				 (uint32) (sendTimeLineValidUpto >> 32),
 				 (uint32) sendTimeLineValidUpto);
 
 		dest = CreateDestReceiver(DestRemoteSimple);
-		MemSet(nulls, false, sizeof(nulls));
 
 		/*
 		 * Need a tuple descriptor representing two columns. int8 may seem
@@ -859,7 +857,7 @@ CreateReplicationSlot(CreateReplicationSlotCmd *cmd)
 	TupOutputState *tstate;
 	TupleDesc	tupdesc;
 	Datum		values[4];
-	bool		nulls[4];
+	bool		nulls[4] = INIT_ALL_ELEMS_FALSE;
 
 	Assert(!MyReplicationSlot);
 
@@ -995,7 +993,6 @@ CreateReplicationSlot(CreateReplicationSlotCmd *cmd)
 			 (uint32) MyReplicationSlot->data.confirmed_flush);
 
 	dest = CreateDestReceiver(DestRemoteSimple);
-	MemSet(nulls, false, sizeof(nulls));
 
 	/*----------
 	 * Need a tuple descriptor representing four columns:
@@ -3286,7 +3283,7 @@ pg_stat_get_wal_senders(PG_FUNCTION_ARGS)
 		WalSndState state;
 		TimestampTz replyTime;
 		Datum		values[PG_STAT_GET_WAL_SENDERS_COLS];
-		bool		nulls[PG_STAT_GET_WAL_SENDERS_COLS];
+		bool		nulls[PG_STAT_GET_WAL_SENDERS_COLS] = INIT_ALL_ELEMS_FALSE;
 
 		SpinLockAcquire(&walsnd->mutex);
 		if (walsnd->pid == 0)
@@ -3307,7 +3304,6 @@ pg_stat_get_wal_senders(PG_FUNCTION_ARGS)
 		replyTime = walsnd->replyTime;
 		SpinLockRelease(&walsnd->mutex);
 
-		memset(nulls, 0, sizeof(nulls));
 		values[0] = Int32GetDatum(pid);
 
 		if (!is_member_of_role(GetUserId(), DEFAULT_ROLE_READ_ALL_STATS))
diff --git a/src/backend/rewrite/rewriteDefine.c b/src/backend/rewrite/rewriteDefine.c
index 7df2b61..5df4173 100644
--- a/src/backend/rewrite/rewriteDefine.c
+++ b/src/backend/rewrite/rewriteDefine.c
@@ -67,8 +67,8 @@ InsertRule(const char *rulname,
 	char	   *evqual = nodeToString(event_qual);
 	char	   *actiontree = nodeToString((Node *) action);
 	Datum		values[Natts_pg_rewrite];
-	bool		nulls[Natts_pg_rewrite];
-	bool		replaces[Natts_pg_rewrite];
+	bool		nulls[Natts_pg_rewrite] = INIT_ALL_ELEMS_FALSE;
+	bool		replaces[Natts_pg_rewrite] = INIT_ALL_ELEMS_FALSE;
 	NameData	rname;
 	Relation	pg_rewrite_desc;
 	HeapTuple	tup,
@@ -79,10 +79,8 @@ InsertRule(const char *rulname,
 	bool		is_update = false;
 
 	/*
-	 * Set up *nulls and *values arrays
+	 * Set up *values array
 	 */
-	MemSet(nulls, false, sizeof(nulls));
-
 	namestrcpy(&rname, rulname);
 	values[Anum_pg_rewrite_rulename - 1] = NameGetDatum(&rname);
 	values[Anum_pg_rewrite_ev_class - 1] = ObjectIdGetDatum(eventrel_oid);
@@ -115,7 +113,6 @@ InsertRule(const char *rulname,
 		/*
 		 * When replacing, we don't need to replace every attribute
 		 */
-		MemSet(replaces, false, sizeof(replaces));
 		replaces[Anum_pg_rewrite_ev_type - 1] = true;
 		replaces[Anum_pg_rewrite_is_instead - 1] = true;
 		replaces[Anum_pg_rewrite_ev_qual - 1] = true;
diff --git a/src/backend/statistics/extended_stats.c b/src/backend/statistics/extended_stats.c
index 207ee31..c8f02d9 100644
--- a/src/backend/statistics/extended_stats.c
+++ b/src/backend/statistics/extended_stats.c
@@ -471,14 +471,12 @@ statext_store(Oid statOid,
 {
 	HeapTuple	stup,
 				oldtup;
-	Datum		values[Natts_pg_statistic_ext_data];
+	Datum		values[Natts_pg_statistic_ext_data] = INIT_ALL_ELEMS_ZERO;
 	bool		nulls[Natts_pg_statistic_ext_data];
-	bool		replaces[Natts_pg_statistic_ext_data];
+	bool		replaces[Natts_pg_statistic_ext_data] = INIT_ALL_ELEMS_FALSE;
 	Relation	pg_stextdata;
 
 	memset(nulls, true, sizeof(nulls));
-	memset(replaces, false, sizeof(replaces));
-	memset(values, 0, sizeof(values));
 
 	/*
 	 * Construct a new pg_statistic_ext_data tuple, replacing the calculated
diff --git a/src/backend/storage/large_object/inv_api.c b/src/backend/storage/large_object/inv_api.c
index e591236..d6f5eb6 100644
--- a/src/backend/storage/large_object/inv_api.c
+++ b/src/backend/storage/large_object/inv_api.c
@@ -608,9 +608,6 @@ inv_write(LargeObjectDesc *obj_desc, const char *buf, int nbytes)
 	}			workbuf;
 	char	   *workb = VARDATA(&workbuf.hdr);
 	HeapTuple	newtup;
-	Datum		values[Natts_pg_largeobject];
-	bool		nulls[Natts_pg_largeobject];
-	bool		replace[Natts_pg_largeobject];
 	CatalogIndexState indstate;
 
 	Assert(PointerIsValid(obj_desc));
@@ -656,6 +653,10 @@ inv_write(LargeObjectDesc *obj_desc, const char *buf, int nbytes)
 
 	while (nwritten < nbytes)
 	{
+		Datum           values[Natts_pg_largeobject] = INIT_ALL_ELEMS_ZERO;
+		bool            nulls[Natts_pg_largeobject] = INIT_ALL_ELEMS_FALSE;
+		bool            replace[Natts_pg_largeobject] = INIT_ALL_ELEMS_FALSE;
+
 		/*
 		 * If possible, get next pre-existing page of the LO.  We expect the
 		 * indexscan will deliver these in order --- but there may be holes.
@@ -711,9 +712,6 @@ inv_write(LargeObjectDesc *obj_desc, const char *buf, int nbytes)
 			/*
 			 * Form and insert updated tuple
 			 */
-			memset(values, 0, sizeof(values));
-			memset(nulls, false, sizeof(nulls));
-			memset(replace, false, sizeof(replace));
 			values[Anum_pg_largeobject_data - 1] = PointerGetDatum(&workbuf);
 			replace[Anum_pg_largeobject_data - 1] = true;
 			newtup = heap_modify_tuple(oldtuple, RelationGetDescr(lo_heap_r),
@@ -755,8 +753,6 @@ inv_write(LargeObjectDesc *obj_desc, const char *buf, int nbytes)
 			/*
 			 * Form and insert updated tuple
 			 */
-			memset(values, 0, sizeof(values));
-			memset(nulls, false, sizeof(nulls));
 			values[Anum_pg_largeobject_loid - 1] = ObjectIdGetDatum(obj_desc->id);
 			values[Anum_pg_largeobject_pageno - 1] = Int32GetDatum(pageno);
 			values[Anum_pg_largeobject_data - 1] = PointerGetDatum(&workbuf);
@@ -799,9 +795,9 @@ inv_truncate(LargeObjectDesc *obj_desc, int64 len)
 	}			workbuf;
 	char	   *workb = VARDATA(&workbuf.hdr);
 	HeapTuple	newtup;
-	Datum		values[Natts_pg_largeobject];
-	bool		nulls[Natts_pg_largeobject];
-	bool		replace[Natts_pg_largeobject];
+	Datum		values[Natts_pg_largeobject] = INIT_ALL_ELEMS_ZERO;
+	bool		nulls[Natts_pg_largeobject] = INIT_ALL_ELEMS_FALSE;
+	bool		replace[Natts_pg_largeobject] = INIT_ALL_ELEMS_FALSE;
 	CatalogIndexState indstate;
 
 	Assert(PointerIsValid(obj_desc));
@@ -886,9 +882,6 @@ inv_truncate(LargeObjectDesc *obj_desc, int64 len)
 		/*
 		 * Form and insert updated tuple
 		 */
-		memset(values, 0, sizeof(values));
-		memset(nulls, false, sizeof(nulls));
-		memset(replace, false, sizeof(replace));
 		values[Anum_pg_largeobject_data - 1] = PointerGetDatum(&workbuf);
 		replace[Anum_pg_largeobject_data - 1] = true;
 		newtup = heap_modify_tuple(oldtuple, RelationGetDescr(lo_heap_r),
@@ -925,8 +918,6 @@ inv_truncate(LargeObjectDesc *obj_desc, int64 len)
 		/*
 		 * Form and insert new tuple
 		 */
-		memset(values, 0, sizeof(values));
-		memset(nulls, false, sizeof(nulls));
 		values[Anum_pg_largeobject_loid - 1] = ObjectIdGetDatum(obj_desc->id);
 		values[Anum_pg_largeobject_pageno - 1] = Int32GetDatum(pageno);
 		values[Anum_pg_largeobject_data - 1] = PointerGetDatum(&workbuf);
diff --git a/src/backend/utils/adt/acl.c b/src/backend/utils/adt/acl.c
index d7e6100..36130e0 100644
--- a/src/backend/utils/adt/acl.c
+++ b/src/backend/utils/adt/acl.c
@@ -1810,7 +1810,7 @@ aclexplode(PG_FUNCTION_ARGS)
 		{
 			Datum		result;
 			Datum		values[4];
-			bool		nulls[4];
+			bool		nulls[4] = INIT_ALL_ELEMS_FALSE;
 			HeapTuple	tuple;
 
 			values[0] = ObjectIdGetDatum(aidata->ai_grantor);
@@ -1818,8 +1818,6 @@ aclexplode(PG_FUNCTION_ARGS)
 			values[2] = CStringGetTextDatum(convert_aclright_to_string(priv_bit));
 			values[3] = BoolGetDatum((ACLITEM_GET_GOPTIONS(*aidata) & priv_bit) != 0);
 
-			MemSet(nulls, 0, sizeof(nulls));
-
 			tuple = heap_form_tuple(funcctx->tuple_desc, values, nulls);
 			result = HeapTupleGetDatum(tuple);
 
diff --git a/src/backend/utils/adt/arrayfuncs.c b/src/backend/utils/adt/arrayfuncs.c
index 8079b13..96f5219 100644
--- a/src/backend/utils/adt/arrayfuncs.c
+++ b/src/backend/utils/adt/arrayfuncs.c
@@ -738,11 +738,10 @@ ReadArrayStr(char *arrayStr,
 	bool		eoArray = false;
 	bool		hasnull;
 	int32		totbytes;
-	int			indx[MAXDIM],
+	int			indx[MAXDIM] = INIT_ALL_ELEMS_ZERO,
 				prod[MAXDIM];
 
 	mda_get_prod(ndim, dim, prod);
-	MemSet(indx, 0, sizeof(indx));
 
 	/* Initialize is-null markers to true */
 	memset(nulls, true, nitems * sizeof(bool));
diff --git a/src/backend/utils/adt/datetime.c b/src/backend/utils/adt/datetime.c
index e38bd93..88dd838 100644
--- a/src/backend/utils/adt/datetime.c
+++ b/src/backend/utils/adt/datetime.c
@@ -4635,7 +4635,7 @@ pg_timezone_abbrevs(PG_FUNCTION_ARGS)
 	Datum		result;
 	HeapTuple	tuple;
 	Datum		values[3];
-	bool		nulls[3];
+	bool		nulls[3] = INIT_ALL_ELEMS_FALSE;
 	const datetkn *tp;
 	char		buffer[TOKMAXLEN + 1];
 	int			gmtoffset;
@@ -4722,8 +4722,6 @@ pg_timezone_abbrevs(PG_FUNCTION_ARGS)
 			break;
 	}
 
-	MemSet(nulls, 0, sizeof(nulls));
-
 	/*
 	 * Convert name to text, using upcasing conversion that is the inverse of
 	 * what ParseDateTime() uses.
@@ -4765,7 +4763,7 @@ pg_timezone_names(PG_FUNCTION_ARGS)
 	Datum		result;
 	HeapTuple	tuple;
 	Datum		values[4];
-	bool		nulls[4];
+	bool		nulls[4] = INIT_ALL_ELEMS_FALSE;
 	int			tzoff;
 	struct pg_tm tm;
 	fsec_t		fsec;
@@ -4847,8 +4845,6 @@ pg_timezone_names(PG_FUNCTION_ARGS)
 		break;
 	}
 
-	MemSet(nulls, 0, sizeof(nulls));
-
 	values[0] = CStringGetTextDatum(pg_get_timezone_name(tz));
 	values[1] = CStringGetTextDatum(tzn ? tzn : "");
 
diff --git a/src/backend/utils/adt/genfile.c b/src/backend/utils/adt/genfile.c
index 5d4f26a..056fef1 100644
--- a/src/backend/utils/adt/genfile.c
+++ b/src/backend/utils/adt/genfile.c
@@ -576,7 +576,7 @@ pg_ls_dir_files(FunctionCallInfo fcinfo, const char *dir, bool missing_ok)
 	while ((de = ReadDir(fctx->dirdesc, fctx->location)) != NULL)
 	{
 		Datum		values[3];
-		bool		nulls[3];
+		bool		nulls[3] = INIT_ALL_ELEMS_FALSE;
 		char		path[MAXPGPATH * 2];
 		struct stat attrib;
 		HeapTuple	tuple;
@@ -599,7 +599,6 @@ pg_ls_dir_files(FunctionCallInfo fcinfo, const char *dir, bool missing_ok)
 		values[0] = CStringGetTextDatum(de->d_name);
 		values[1] = Int64GetDatum((int64) attrib.st_size);
 		values[2] = TimestampTzGetDatum(time_t_to_timestamptz(attrib.st_mtime));
-		memset(nulls, 0, sizeof(nulls));
 
 		tuple = heap_form_tuple(funcctx->tuple_desc, values, nulls);
 		SRF_RETURN_NEXT(funcctx, HeapTupleGetDatum(tuple));
diff --git a/src/backend/utils/adt/lockfuncs.c b/src/backend/utils/adt/lockfuncs.c
index bc62c6e..992a96f 100644
--- a/src/backend/utils/adt/lockfuncs.c
+++ b/src/backend/utils/adt/lockfuncs.c
@@ -160,8 +160,8 @@ pg_lock_status(PG_FUNCTION_ARGS)
 		LOCKMODE	mode = 0;
 		const char *locktypename;
 		char		tnbuf[32];
-		Datum		values[NUM_LOCK_STATUS_COLUMNS];
-		bool		nulls[NUM_LOCK_STATUS_COLUMNS];
+		Datum		values[NUM_LOCK_STATUS_COLUMNS] = INIT_ALL_ELEMS_ZERO;
+		bool		nulls[NUM_LOCK_STATUS_COLUMNS] = INIT_ALL_ELEMS_FALSE;
 		HeapTuple	tuple;
 		Datum		result;
 		LockInstanceData *instance;
@@ -218,9 +218,6 @@ pg_lock_status(PG_FUNCTION_ARGS)
 		/*
 		 * Form tuple with appropriate data.
 		 */
-		MemSet(values, 0, sizeof(values));
-		MemSet(nulls, false, sizeof(nulls));
-
 		if (instance->locktag.locktag_type <= LOCKTAG_LAST_TYPE)
 			locktypename = LockTagTypeNames[instance->locktag.locktag_type];
 		else
@@ -332,8 +329,8 @@ pg_lock_status(PG_FUNCTION_ARGS)
 
 		PREDICATELOCKTARGETTAG *predTag = &(predLockData->locktags[mystatus->predLockIdx]);
 		SERIALIZABLEXACT *xact = &(predLockData->xacts[mystatus->predLockIdx]);
-		Datum		values[NUM_LOCK_STATUS_COLUMNS];
-		bool		nulls[NUM_LOCK_STATUS_COLUMNS];
+		Datum		values[NUM_LOCK_STATUS_COLUMNS] = INIT_ALL_ELEMS_ZERO;
+		bool		nulls[NUM_LOCK_STATUS_COLUMNS] = INIT_ALL_ELEMS_FALSE;
 		HeapTuple	tuple;
 		Datum		result;
 
@@ -342,8 +339,6 @@ pg_lock_status(PG_FUNCTION_ARGS)
 		/*
 		 * Form tuple with appropriate data.
 		 */
-		MemSet(values, 0, sizeof(values));
-		MemSet(nulls, false, sizeof(nulls));
 
 		/* lock type */
 		lockType = GET_PREDICATELOCKTARGETTAG_TYPE(*predTag);
diff --git a/src/backend/utils/adt/pgstatfuncs.c b/src/backend/utils/adt/pgstatfuncs.c
index 05240bf..5567bdb 100644
--- a/src/backend/utils/adt/pgstatfuncs.c
+++ b/src/backend/utils/adt/pgstatfuncs.c
@@ -492,13 +492,10 @@ pg_stat_get_progress_info(PG_FUNCTION_ARGS)
 	{
 		LocalPgBackendStatus *local_beentry;
 		PgBackendStatus *beentry;
-		Datum		values[PG_STAT_GET_PROGRESS_COLS];
-		bool		nulls[PG_STAT_GET_PROGRESS_COLS];
+		Datum		values[PG_STAT_GET_PROGRESS_COLS] = INIT_ALL_ELEMS_ZERO;
+		bool		nulls[PG_STAT_GET_PROGRESS_COLS] = INIT_ALL_ELEMS_FALSE;
 		int			i;
 
-		MemSet(values, 0, sizeof(values));
-		MemSet(nulls, 0, sizeof(nulls));
-
 		local_beentry = pgstat_fetch_stat_local_beentry(curr_backend);
 
 		if (!local_beentry)
@@ -585,17 +582,14 @@ pg_stat_get_activity(PG_FUNCTION_ARGS)
 	for (curr_backend = 1; curr_backend <= num_backends; curr_backend++)
 	{
 		/* for each row */
-		Datum		values[PG_STAT_GET_ACTIVITY_COLS];
-		bool		nulls[PG_STAT_GET_ACTIVITY_COLS];
+		Datum		values[PG_STAT_GET_ACTIVITY_COLS] = INIT_ALL_ELEMS_ZERO;
+		bool		nulls[PG_STAT_GET_ACTIVITY_COLS] = INIT_ALL_ELEMS_FALSE;
 		LocalPgBackendStatus *local_beentry;
 		PgBackendStatus *beentry;
 		PGPROC	   *proc;
 		const char *wait_event_type = NULL;
 		const char *wait_event = NULL;
 
-		MemSet(values, 0, sizeof(values));
-		MemSet(nulls, 0, sizeof(nulls));
-
 		/* Get the next one in the list */
 		local_beentry = pgstat_fetch_stat_local_beentry(curr_backend);
 		if (!local_beentry)
@@ -1908,14 +1902,10 @@ Datum
 pg_stat_get_archiver(PG_FUNCTION_ARGS)
 {
 	TupleDesc	tupdesc;
-	Datum		values[7];
-	bool		nulls[7];
+	Datum		values[7] = INIT_ALL_ELEMS_ZERO;
+	bool		nulls[7] = INIT_ALL_ELEMS_FALSE;
 	PgStat_ArchiverStats *archiver_stats;
 
-	/* Initialise values and NULL flags arrays */
-	MemSet(values, 0, sizeof(values));
-	MemSet(nulls, 0, sizeof(nulls));
-
 	/* Initialise attributes information in the tuple descriptor */
 	tupdesc = CreateTemplateTupleDesc(7);
 	TupleDescInitEntry(tupdesc, (AttrNumber) 1, "archived_count",
diff --git a/src/backend/utils/misc/guc.c b/src/backend/utils/misc/guc.c
index 2178e1c..9acd6d3 100644
--- a/src/backend/utils/misc/guc.c
+++ b/src/backend/utils/misc/guc.c
@@ -9483,11 +9483,8 @@ show_all_file_settings(PG_FUNCTION_ARGS)
 	/* Process the results and create a tuplestore */
 	for (seqno = 1; conf != NULL; conf = conf->next, seqno++)
 	{
-		Datum		values[NUM_PG_FILE_SETTINGS_ATTS];
-		bool		nulls[NUM_PG_FILE_SETTINGS_ATTS];
-
-		memset(values, 0, sizeof(values));
-		memset(nulls, 0, sizeof(nulls));
+		Datum		values[NUM_PG_FILE_SETTINGS_ATTS] = INIT_ALL_ELEMS_ZERO;
+		bool		nulls[NUM_PG_FILE_SETTINGS_ATTS] = INIT_ALL_ELEMS_FALSE;
 
 		/* sourcefile */
 		if (conf->filename)
diff --git a/src/backend/utils/mmgr/portalmem.c b/src/backend/utils/mmgr/portalmem.c
index 334e35b..4b66687 100644
--- a/src/backend/utils/mmgr/portalmem.c
+++ b/src/backend/utils/mmgr/portalmem.c
@@ -1176,14 +1176,12 @@ pg_cursor(PG_FUNCTION_ARGS)
 	{
 		Portal		portal = hentry->portal;
 		Datum		values[6];
-		bool		nulls[6];
+		bool		nulls[6] = INIT_ALL_ELEMS_FALSE;
 
 		/* report only "visible" entries */
 		if (!portal->visible)
 			continue;
 
-		MemSet(nulls, 0, sizeof(nulls));
-
 		values[0] = CStringGetTextDatum(portal->name);
 		values[1] = CStringGetTextDatum(portal->sourceText);
 		values[2] = BoolGetDatum(portal->cursorOptions & CURSOR_OPT_HOLD);
diff --git a/src/include/c.h b/src/include/c.h
index f461628..a5db6fe 100644
--- a/src/include/c.h
+++ b/src/include/c.h
@@ -1166,6 +1166,24 @@ typedef union PGAlignedXLogBlock
 	((underlying_type) (expr))
 #endif
 
+/*
+ * Macros for C99 designated-initialiser syntax to set all array elements to 0/false.
+ *
+ * Use these macros in preference to explicit {0} syntax to avoid giving a misleading
+ * impression that the same value is always used for all elements.
+ * e.g.
+ * bool foo[2] = {false}; // sets both elements false
+ * bool foo[2] = {true}; // does NOT set both elements true
+ *
+ * Reference: C99 [$6.7.8/21] If there are fewer initializers in a brace-enclosed list than there
+ * are elements or members of an aggregate, or fewer characters in a string literal used to
+ * initialize an array of known size than there are elements in the array, the remainder of the
+ * aggregate shall be initialized implicitly the same as objects that have static storage duration
+ */
+#define INIT_ALL_ELEMS_ZERO	{0}
+#define INIT_ALL_ELEMS_FALSE	{false}
+
+
 /* ----------------------------------------------------------------
  *				Section 9: system-specific hacks
  *
#23Amit Kapila
amit.kapila16@gmail.com
In reply to: Tom Lane (#14)
Re: Proposal: Make use of C99 designated initialisers for nulls/values arrays

On Wed, Oct 2, 2019 at 9:16 PM Tom Lane <tgl@sss.pgh.pa.us> wrote:

Joe Nelson <joe@begriffs.com> writes:

Isaac Morland wrote:

I hope you'll forgive a noob question. Why does the "After"
initialization for the boolean array have {0} rather than {false}?

I think using a value other than {0} potentially gives the incorrect
impression that the value is used for *all* elements of the
array/structure, whereas it is only used for the first element.

There's been something vaguely bothering me about this proposal,
and I think you just crystallized it.

Using {false} may encourage the unwary to try
bool foo[2] = {true};
which will not set all elements to true.

Right. I think that in general it's bad practice for an initializer
to not specify all fields/elements of the target. It is okay in the
specific case that we're substituting for a memset(..., 0, ...).
Perhaps we could make this explicit by using a coding style like

/* in c.h or some such place: */
#define INIT_ALL_ZEROES {0}

/* in code: */
Datum values[N] = INIT_ALL_ZEROES;

This is a good idea, but by reading the thread it is not completely clear
if we want to pursue this or want to explore something else or leave the
current code as it is. Also, if we want to pursue, do we want to
use INIT_ALL_ZEROES for bool arrays as well?

--
With Regards,
Amit Kapila.
EnterpriseDB: http://www.enterprisedb.com

#24Smith, Peter
peters@fast.au.fujitsu.com
In reply to: Amit Kapila (#23)
RE: Proposal: Make use of C99 designated initialisers for nulls/values arrays

From: Amit Kapila <amit.kapila16@gmail.com> Sent: Friday, 4 October 2019 1:32 PM

  Also, if we want to pursue, do we want to use INIT_ALL_ZEROES for bool arrays as well?

FYI - In case it went unnoticed - my last patch addresses this by defining 2 macros:

#define INIT_ALL_ELEMS_ZERO {0}
#define INIT_ALL_ELEMS_FALSE {false}

Kind Regards
--
Peter Smith
Fujitsu Australia

#25Tom Lane
tgl@sss.pgh.pa.us
In reply to: Smith, Peter (#24)
Re: Proposal: Make use of C99 designated initialisers for nulls/values arrays

"Smith, Peter" <peters@fast.au.fujitsu.com> writes:

From: Amit Kapila <amit.kapila16@gmail.com> Sent: Friday, 4 October 2019 1:32 PM

  Also, if we want to pursue, do we want to use INIT_ALL_ZEROES for bool arrays as well?

FYI - In case it went unnoticed - my last patch addresses this by defining 2 macros:

#define INIT_ALL_ELEMS_ZERO {0}
#define INIT_ALL_ELEMS_FALSE {false}

I would say that's 100% wrong. The entire point here is that it's
memset-equivalent, and therefore writes zeroes, regardless of what
the datatype is. As a counterexample, the coding you have above
looks a lot like it would work to add

#define INIT_ALL_ELEMS_TRUE {true}

which as previously noted will *not* work. So I think the
one-size-fits-all approach is what to use.

regards, tom lane

#26Smith, Peter
peters@fast.au.fujitsu.com
In reply to: Tom Lane (#25)
RE: Proposal: Make use of C99 designated initialisers for nulls/values arrays

From: Tom Lane <tgl@sss.pgh.pa.us> Sent: Friday, 4 October 2019 2:08 PM

#define INIT_ALL_ELEMS_ZERO {0}
#define INIT_ALL_ELEMS_FALSE {false}

I would say that's 100% wrong. The entire point here is that it's memset-equivalent, and therefore writes zeroes, regardless of what the datatype is.

I agree it is memset-equivalent.

All examples of the memset code that INIT_ALL_ELEMS_ZERO replaces looked like this:
memset(values, 0, sizeof(values));

Most examples of the memset code that INIT_ALL_ELEMS_FALSE replaces looked like this:
memset(nulls, false, sizeof(nulls));

~

I made the 2nd macro because I anticipate the same folk that don't like setting 0 to a bool will also not like setting something called INIT_ALL_ELEMS_ZERO to a bool array.

How about I just define them both the same?
#define INIT_ALL_ELEMS_ZERO {0}
#define INIT_ALL_ELEMS_FALSE {0}

As a counterexample, the coding you have above looks a lot like it would work to add

#define INIT_ALL_ELEMS_TRUE {true}
which as previously noted will *not* work. So I think the one-size-fits-all approach is what to use.

I agree it looks that way; in my previous email I should have provided more context to the code.
Below is the full fragment of the last shared patch, which included a note to prevent anybody from doing such a thing.

~~

/*
* Macros for C99 designated-initialiser syntax to set all array elements to 0/false.
*
* Use these macros in preference to explicit {0} syntax to avoid giving a misleading
* impression that the same value is always used for all elements.
* e.g.
* bool foo[2] = {false}; // sets both elements false
* bool foo[2] = {true}; // does NOT set both elements true
*
* Reference: C99 [$6.7.8/21] If there are fewer initializers in a brace-enclosed list than there
* are elements or members of an aggregate, or fewer characters in a string literal used to
* initialize an array of known size than there are elements in the array, the remainder of the
* aggregate shall be initialized implicitly the same as objects that have static storage duration
*/
#define INIT_ALL_ELEMS_ZERO {0}
#define INIT_ALL_ELEMS_FALSE {false}

~~

Kind Regards,
--
Peter Smith
Fujitsu Australia

#27Amit Kapila
amit.kapila16@gmail.com
In reply to: Smith, Peter (#26)
Re: Proposal: Make use of C99 designated initialisers for nulls/values arrays

On Fri, Oct 4, 2019 at 12:10 PM Smith, Peter <peters@fast.au.fujitsu.com>
wrote:

From: Tom Lane <tgl@sss.pgh.pa.us> Sent: Friday, 4 October 2019 2:08 PM

#define INIT_ALL_ELEMS_ZERO {0}
#define INIT_ALL_ELEMS_FALSE {false}

I would say that's 100% wrong. The entire point here is that it's

memset-equivalent, and therefore writes zeroes, regardless of what the
datatype is.

I agree it is memset-equivalent.

All examples of the memset code that INIT_ALL_ELEMS_ZERO replaces looked
like this:
memset(values, 0, sizeof(values));

Most examples of the memset code that INIT_ALL_ELEMS_FALSE replaces looked
like this:
memset(nulls, false, sizeof(nulls));

~

I made the 2nd macro because I anticipate the same folk that don't like
setting 0 to a bool will also not like setting something called
INIT_ALL_ELEMS_ZERO to a bool array.

How about I just define them both the same?
#define INIT_ALL_ELEMS_ZERO {0}
#define INIT_ALL_ELEMS_FALSE {0}

I think using one define would be preferred, but you can wait and see if
others prefer defining different macros for the same thing.

--
With Regards,
Amit Kapila.
EnterpriseDB: http://www.enterprisedb.com

#28Joe Nelson
joe@begriffs.com
In reply to: Amit Kapila (#27)
Re: Proposal: Make use of C99 designated initialisers for nulls/values arrays

Amit Kapila wrote:

How about I just define them both the same?
#define INIT_ALL_ELEMS_ZERO {0}
#define INIT_ALL_ELEMS_FALSE {0}

I think using one define would be preferred, but you can wait and see
if others prefer defining different macros for the same thing.

+1 on using INIT_ALL_ELEMS_ZERO everywhere, even for bool[]. You may
worry, "Should we really be assigning 0 to something of type bool? Is
that the wrong type or a detail that varies by implementation?" It's
safe though, the behavior is guaranteed to be correct by section 7.16 of
the C99 spec, which says that bool, true, and false are always macros
for _Bool, 1, and 0 respectively.

One might argue that INIT_ALL_ELEMS_FALSE as a synonym for
INIT_ALL_ELEMS_ZERO is good for readability in the same way that "false"
is for 0. However I want to avoid creating the impression that there is,
or can be, a collection of INIT_ALL_ELEMS_xxx macros invoking different
initializer behavior.

#29Tom Lane
tgl@sss.pgh.pa.us
In reply to: Joe Nelson (#28)
Re: Proposal: Make use of C99 designated initialisers for nulls/values arrays

Joe Nelson <joe@begriffs.com> writes:

One might argue that INIT_ALL_ELEMS_FALSE as a synonym for
INIT_ALL_ELEMS_ZERO is good for readability in the same way that "false"
is for 0. However I want to avoid creating the impression that there is,
or can be, a collection of INIT_ALL_ELEMS_xxx macros invoking different
initializer behavior.

I concur with Joe here. The reason why some of the existing
memset's use "false" is for symmetry with other places where we use
"memset(p, true, n)" to set an array of bools to all-true. That
coding is unfortunately a bit dubious --- it would sort-of fail if
bool weren't of width 1, in that the bools would still test as true
but they wouldn't contain the standard bit pattern for true.
I don't want to change those places, but we shouldn't make the
mechanism proposed by this patch look like it can do anything but
initialize to zeroes.

regards, tom lane

#30Jacob Champion
pchampion@pivotal.io
In reply to: Tom Lane (#29)
Re: Proposal: Make use of C99 designated initialisers for nulls/values arrays

On Fri, Oct 4, 2019 at 7:51 AM Tom Lane <tgl@sss.pgh.pa.us> wrote:

I concur with Joe here. The reason why some of the existing
memset's use "false" is for symmetry with other places where we use
"memset(p, true, n)" to set an array of bools to all-true. That
coding is unfortunately a bit dubious --- it would sort-of fail if
bool weren't of width 1, in that the bools would still test as true
but they wouldn't contain the standard bit pattern for true.
I don't want to change those places, but we shouldn't make the
mechanism proposed by this patch look like it can do anything but
initialize to zeroes.

regards, tom lane

Why introduce a macro at all for the universal zero initializer, if it
seems to encourage the construction of other (incorrect) macros? IMO
the use of {0} as an initializer is well understood in the C developer
community, and I'm used to it showing up verbatim in code. Similar to
{}'s role as the C++ universal initializer.

--Jacob

#31Tom Lane
tgl@sss.pgh.pa.us
In reply to: Jacob Champion (#30)
Re: Proposal: Make use of C99 designated initialisers for nulls/values arrays

Jacob Champion <pchampion@pivotal.io> writes:

On Fri, Oct 4, 2019 at 7:51 AM Tom Lane <tgl@sss.pgh.pa.us> wrote:

I concur with Joe here. The reason why some of the existing
memset's use "false" is for symmetry with other places where we use
"memset(p, true, n)" to set an array of bools to all-true.

Why introduce a macro at all for the universal zero initializer, if it
seems to encourage the construction of other (incorrect) macros?

Well, the argument is that some people might think that if {0} is enough
to set all array elements to 0, then maybe {1} sets them all to ones
(as, indeed, one could argue would be a far better specification than
what the C committee actually wrote). Using a separate macro and then
discouraging direct use of the incomplete-initializer syntax should help
to avoid that error.

IMO
the use of {0} as an initializer is well understood in the C developer
community, and I'm used to it showing up verbatim in code.

Yeah, if we were all 100% familiar with every sentence in the C standard,
we could argue like that. But we get lots of submissions from people
for whom C is not their main language. The fewer gotchas there are in
our agreed-on subset of C, the better.

regards, tom lane

#32Ashwin Agrawal
aagrawal@pivotal.io
In reply to: Tom Lane (#31)
Re: Proposal: Make use of C99 designated initialisers for nulls/values arrays

On Fri, Oct 4, 2019 at 8:49 AM Tom Lane <tgl@sss.pgh.pa.us> wrote:

Jacob Champion <pchampion@pivotal.io> writes:

On Fri, Oct 4, 2019 at 7:51 AM Tom Lane <tgl@sss.pgh.pa.us> wrote:

I concur with Joe here. The reason why some of the existing
memset's use "false" is for symmetry with other places where we use
"memset(p, true, n)" to set an array of bools to all-true.

Why introduce a macro at all for the universal zero initializer, if it
seems to encourage the construction of other (incorrect) macros?

Well, the argument is that some people might think that if {0} is enough
to set all array elements to 0, then maybe {1} sets them all to ones
(as, indeed, one could argue would be a far better specification than
what the C committee actually wrote). Using a separate macro and then
discouraging direct use of the incomplete-initializer syntax should help
to avoid that error.

Seems avoidable overhead to remind folks on macro existence. Plus, for such
a thing macro exist in first place will be hard to remember. So,
irrespective in long run, {0} might get used in code and hence seems better
to just use {0} from start itself instead of macro/wrapper on top.

Plus, even if someone starts out with thought {1} sets them all to ones, I
feel will soon realize by exercising the code isn't the reality. If such
code is written and nothing fails, that itself seems bigger issue.

#33Chapman Flack
chap@anastigmatix.net
In reply to: Ashwin Agrawal (#32)
Re: Proposal: Make use of C99 designated initialisers for nulls/values arrays

On 10/4/19 1:44 PM, Ashwin Agrawal wrote:

macro exist in first place will be hard to remember. So, irrespective
in long run, {0} might get used in code and hence seems better
to just use {0} from start itself instead of macro/wrapper on top.

Plus, even if someone starts out with thought {1} sets them all to ones,
I feel will soon realize by exercising the code isn't the reality.

I wish ISO C had gone the same place gcc (and C++ ?) went, and allowed
the initializer {}, which would eliminate any chance of it misleading
a casual reader.

If that were the case, I would be +1 on just using the {} syntax.

But given that the standard is stuck on requiring a first element,
I am +1 on using the macro, just to avoid giving any wrong impressions,
even fleeting ones.

Regards,
-Chap

#34Bruce Momjian
bruce@momjian.us
In reply to: Chapman Flack (#33)
Re: Proposal: Make use of C99 designated initialisers for nulls/values arrays

On Fri, Oct 4, 2019 at 02:05:41PM -0400, Chapman Flack wrote:

On 10/4/19 1:44 PM, Ashwin Agrawal wrote:

macro exist in first place will be hard to remember. So, irrespective
in long run, {0} might get used in code and hence seems better
to just use {0} from start itself instead of macro/wrapper on top.

Plus, even if someone starts out with thought {1} sets them all to ones,
I feel will soon realize by exercising the code isn't the reality.

I wish ISO C had gone the same place gcc (and C++ ?) went, and allowed
the initializer {}, which would eliminate any chance of it misleading
a casual reader.

If that were the case, I would be +1 on just using the {} syntax.

But given that the standard is stuck on requiring a first element,
I am +1 on using the macro, just to avoid giving any wrong impressions,
even fleeting ones.

Yeah, it is certainly weird that you have to assign the first array
element to get the rest to be zeros. By using a macro, we can document
this behavior in one place.

--
Bruce Momjian <bruce@momjian.us> http://momjian.us
EnterpriseDB http://enterprisedb.com

+ As you are, so once was I.  As I am, so you will be. +
+                      Ancient Roman grave inscription +
#35Andres Freund
andres@anarazel.de
In reply to: Bruce Momjian (#34)
Re: Proposal: Make use of C99 designated initialisers for nulls/values arrays

Hi,

On 2019-10-04 16:31:29 -0400, Bruce Momjian wrote:

On Fri, Oct 4, 2019 at 02:05:41PM -0400, Chapman Flack wrote:

On 10/4/19 1:44 PM, Ashwin Agrawal wrote:

macro exist in first place will be hard to remember. So, irrespective
in long run, {0} might get used in code and hence seems better
to just use {0} from start itself instead of macro/wrapper on top.

It already is in somewhat frequent use, fwiw.

Plus, even if someone starts out with thought {1} sets them all to ones,
I feel will soon realize by exercising the code isn't the reality.

I wish ISO C had gone the same place gcc (and C++ ?) went, and allowed
the initializer {}, which would eliminate any chance of it misleading
a casual reader.

If that were the case, I would be +1 on just using the {} syntax.

But given that the standard is stuck on requiring a first element,
I am +1 on using the macro, just to avoid giving any wrong impressions,
even fleeting ones.

Yeah, it is certainly weird that you have to assign the first array
element to get the rest to be zeros. By using a macro, we can document
this behavior in one place.

IDK, to me this seems like something one just has to learn about C, with
the macro just obfuscating that already required knowledge. It's not
like this only applies to stack variables initializes with {0}. It's
also true of global variables, or function-local static ones, for
example.

Greetings,

Andres Freund

#36Tom Lane
tgl@sss.pgh.pa.us
In reply to: Andres Freund (#35)
Re: Proposal: Make use of C99 designated initialisers for nulls/values arrays

Andres Freund <andres@anarazel.de> writes:

On 2019-10-04 16:31:29 -0400, Bruce Momjian wrote:

Yeah, it is certainly weird that you have to assign the first array
element to get the rest to be zeros. By using a macro, we can document
this behavior in one place.

IDK, to me this seems like something one just has to learn about C, with
the macro just obfuscating that already required knowledge. It's not
like this only applies to stack variables initializes with {0}. It's
also true of global variables, or function-local static ones, for
example.

Huh? For both those cases, the *default* behavior, going back to K&R C,
is that the variable initializes to all-bits-zero. There's no need to
write anything extra. If some people are writing {0} there, I think
we should discourage that on the grounds that it results in inconsistent
coding style.

Note that I'm not proposing a rule against, say,

static MyNodeType *my_variable = NULL;

That's perfectly sensible and adds no cognitive load that I can see.
But in cases where you have to indulge in type punning or reliance on
obscure language features to get the result that would happen if you'd
just not written anything, I think you should just not write anything.

regards, tom lane

#37Andres Freund
andres@anarazel.de
In reply to: Tom Lane (#36)
Re: Proposal: Make use of C99 designated initialisers for nulls/values arrays

Hi,

On 2019-10-04 17:08:29 -0400, Tom Lane wrote:

Andres Freund <andres@anarazel.de> writes:

On 2019-10-04 16:31:29 -0400, Bruce Momjian wrote:

Yeah, it is certainly weird that you have to assign the first array
element to get the rest to be zeros. By using a macro, we can document
this behavior in one place.

IDK, to me this seems like something one just has to learn about C, with
the macro just obfuscating that already required knowledge. It's not
like this only applies to stack variables initializes with {0}. It's
also true of global variables, or function-local static ones, for
example.

Huh? For both those cases, the *default* behavior, going back to K&R C,
is that the variable initializes to all-bits-zero. There's no need to
write anything extra.

What I mean is that if there's any initialization, it's to all zeroes,
except for the parts explicitly initialized explicitly. And all that the
{0} does, is that the rest of the fields are initialized the way other
such initialization happens.

There's plenty places where we don't initialize every part, e.g. a
struct member, of global variables (and for stack allocated data as
well, increasingly so). To be able to make sense of things like
somevar = {.foo = bar /* field blub is not initialized */};
or things like guc.c - where we rely on zero initialize most fields of
config_generic.

If some people are writing {0} there, I think
we should discourage that on the grounds that it results in inconsistent
coding style.

Yea, I'm not advocating that.

Greetings,

Andres Freund

#38Smith, Peter
peters@fast.au.fujitsu.com
In reply to: Amit Kapila (#27)
1 attachment(s)
RE: Proposal: Make use of C99 designated initialisers for nulls/values arrays

From: Amit Kapila <amit.kapila16@gmail.com> Sent: Friday, 4 October 2019 4:50 PM

How about I just define them both the same?
#define INIT_ALL_ELEMS_ZERO     {0}
#define INIT_ALL_ELEMS_FALSE    {0}

I think using one define would be preferred, but you can wait and see if others prefer defining different macros for the same thing.

While nowhere near unanimous, it seems majority favour using a macro (if only to protect the unwary and document the behaviour).
And of those in favour of macros, using INIT_ALL_ELEMS_ZERO even for bool array is a clear preference.

So, please find attached the updated patch, which now has just 1 macro.

Kind Regards
--
Peter Smith
Fujitsu Australia

Attachments:

c99_init_nulls_4.patchapplication/octet-stream; name=c99_init_nulls_4.patchDownload
diff --git a/src/backend/access/transam/commit_ts.c b/src/backend/access/transam/commit_ts.c
index 3316734..6715fe0 100644
--- a/src/backend/access/transam/commit_ts.c
+++ b/src/backend/access/transam/commit_ts.c
@@ -422,8 +422,8 @@ pg_last_committed_xact(PG_FUNCTION_ARGS)
 {
 	TransactionId xid;
 	TimestampTz ts;
-	Datum		values[2];
-	bool		nulls[2];
+	Datum		values[2] = INIT_ALL_ELEMS_ZERO;
+	bool		nulls[2] = INIT_ALL_ELEMS_ZERO;
 	TupleDesc	tupdesc;
 	HeapTuple	htup;
 
@@ -448,10 +448,7 @@ pg_last_committed_xact(PG_FUNCTION_ARGS)
 	else
 	{
 		values[0] = TransactionIdGetDatum(xid);
-		nulls[0] = false;
-
 		values[1] = TimestampTzGetDatum(ts);
-		nulls[1] = false;
 	}
 
 	htup = heap_form_tuple(tupdesc, values, nulls);
diff --git a/src/backend/access/transam/twophase.c b/src/backend/access/transam/twophase.c
index 546bd43..aefaa89 100644
--- a/src/backend/access/transam/twophase.c
+++ b/src/backend/access/transam/twophase.c
@@ -770,8 +770,8 @@ pg_prepared_xact(PG_FUNCTION_ARGS)
 		GlobalTransaction gxact = &status->array[status->currIdx++];
 		PGPROC	   *proc = &ProcGlobal->allProcs[gxact->pgprocno];
 		PGXACT	   *pgxact = &ProcGlobal->allPgXact[gxact->pgprocno];
-		Datum		values[5];
-		bool		nulls[5];
+		Datum		values[5] = INIT_ALL_ELEMS_ZERO;
+		bool		nulls[5] = INIT_ALL_ELEMS_ZERO;
 		HeapTuple	tuple;
 		Datum		result;
 
@@ -781,9 +781,6 @@ pg_prepared_xact(PG_FUNCTION_ARGS)
 		/*
 		 * Form tuple with appropriate data.
 		 */
-		MemSet(values, 0, sizeof(values));
-		MemSet(nulls, 0, sizeof(nulls));
-
 		values[0] = TransactionIdGetDatum(pgxact->xid);
 		values[1] = CStringGetTextDatum(gxact->gid);
 		values[2] = TimestampTzGetDatum(gxact->prepared_at);
diff --git a/src/backend/access/transam/xlogfuncs.c b/src/backend/access/transam/xlogfuncs.c
index 8f17988..fda4ac3 100644
--- a/src/backend/access/transam/xlogfuncs.c
+++ b/src/backend/access/transam/xlogfuncs.c
@@ -183,8 +183,8 @@ pg_stop_backup_v2(PG_FUNCTION_ARGS)
 	Tuplestorestate *tupstore;
 	MemoryContext per_query_ctx;
 	MemoryContext oldcontext;
-	Datum		values[3];
-	bool		nulls[3];
+	Datum		values[3] = INIT_ALL_ELEMS_ZERO;
+	bool		nulls[3] = INIT_ALL_ELEMS_ZERO;
 
 	bool		exclusive = PG_GETARG_BOOL(0);
 	bool		waitforarchive = PG_GETARG_BOOL(1);
@@ -216,9 +216,6 @@ pg_stop_backup_v2(PG_FUNCTION_ARGS)
 
 	MemoryContextSwitchTo(oldcontext);
 
-	MemSet(values, 0, sizeof(values));
-	MemSet(nulls, 0, sizeof(nulls));
-
 	if (exclusive)
 	{
 		if (status == SESSION_BACKUP_NON_EXCLUSIVE)
diff --git a/src/backend/catalog/aclchk.c b/src/backend/catalog/aclchk.c
index 88ce37c..40d39ca 100644
--- a/src/backend/catalog/aclchk.c
+++ b/src/backend/catalog/aclchk.c
@@ -1158,9 +1158,9 @@ SetDefaultACL(InternalDefaultACL *iacls)
 	Acl		   *old_acl;
 	Acl		   *new_acl;
 	HeapTuple	newtuple;
-	Datum		values[Natts_pg_default_acl];
-	bool		nulls[Natts_pg_default_acl];
-	bool		replaces[Natts_pg_default_acl];
+	Datum		values[Natts_pg_default_acl] = INIT_ALL_ELEMS_ZERO;
+	bool		nulls[Natts_pg_default_acl] = INIT_ALL_ELEMS_ZERO;
+	bool		replaces[Natts_pg_default_acl] = INIT_ALL_ELEMS_ZERO;
 	int			noldmembers;
 	int			nnewmembers;
 	Oid		   *oldmembers;
@@ -1314,9 +1314,6 @@ SetDefaultACL(InternalDefaultACL *iacls)
 		Oid			defAclOid;
 
 		/* Prepare to insert or update pg_default_acl entry */
-		MemSet(values, 0, sizeof(values));
-		MemSet(nulls, false, sizeof(nulls));
-		MemSet(replaces, false, sizeof(replaces));
 
 		if (isNew)
 		{
@@ -1659,9 +1656,9 @@ ExecGrant_Attribute(InternalGrant *istmt, Oid relOid, const char *relname,
 	AclMode		avail_goptions;
 	bool		need_update;
 	HeapTuple	newtuple;
-	Datum		values[Natts_pg_attribute];
-	bool		nulls[Natts_pg_attribute];
-	bool		replaces[Natts_pg_attribute];
+	Datum		values[Natts_pg_attribute] = INIT_ALL_ELEMS_ZERO;
+	bool		nulls[Natts_pg_attribute] = INIT_ALL_ELEMS_ZERO;
+	bool		replaces[Natts_pg_attribute] = INIT_ALL_ELEMS_ZERO;
 	int			noldmembers;
 	int			nnewmembers;
 	Oid		   *oldmembers;
@@ -1742,9 +1739,6 @@ ExecGrant_Attribute(InternalGrant *istmt, Oid relOid, const char *relname,
 	nnewmembers = aclmembers(new_acl, &newmembers);
 
 	/* finished building new ACL value, now insert it */
-	MemSet(values, 0, sizeof(values));
-	MemSet(nulls, false, sizeof(nulls));
-	MemSet(replaces, false, sizeof(replaces));
 
 	/*
 	 * If the updated ACL is empty, we can set attacl to null, and maybe even
@@ -1972,9 +1966,9 @@ ExecGrant_Relation(InternalGrant *istmt)
 			Acl		   *new_acl;
 			Oid			grantorId;
 			HeapTuple	newtuple;
-			Datum		values[Natts_pg_class];
-			bool		nulls[Natts_pg_class];
-			bool		replaces[Natts_pg_class];
+			Datum		values[Natts_pg_class] = INIT_ALL_ELEMS_ZERO;
+			bool		nulls[Natts_pg_class] = INIT_ALL_ELEMS_ZERO;
+			bool		replaces[Natts_pg_class] = INIT_ALL_ELEMS_ZERO;
 			int			nnewmembers;
 			Oid		   *newmembers;
 			ObjectType	objtype;
@@ -2024,9 +2018,6 @@ ExecGrant_Relation(InternalGrant *istmt)
 			nnewmembers = aclmembers(new_acl, &newmembers);
 
 			/* finished building new ACL value, now insert it */
-			MemSet(values, 0, sizeof(values));
-			MemSet(nulls, false, sizeof(nulls));
-			MemSet(replaces, false, sizeof(replaces));
 
 			replaces[Anum_pg_class_relacl - 1] = true;
 			values[Anum_pg_class_relacl - 1] = PointerGetDatum(new_acl);
@@ -2147,9 +2138,9 @@ ExecGrant_Database(InternalGrant *istmt)
 		Oid			grantorId;
 		Oid			ownerId;
 		HeapTuple	newtuple;
-		Datum		values[Natts_pg_database];
-		bool		nulls[Natts_pg_database];
-		bool		replaces[Natts_pg_database];
+		Datum		values[Natts_pg_database] = INIT_ALL_ELEMS_ZERO;
+		bool		nulls[Natts_pg_database] = INIT_ALL_ELEMS_ZERO;
+		bool		replaces[Natts_pg_database] = INIT_ALL_ELEMS_ZERO;
 		int			noldmembers;
 		int			nnewmembers;
 		Oid		   *oldmembers;
@@ -2214,9 +2205,6 @@ ExecGrant_Database(InternalGrant *istmt)
 		nnewmembers = aclmembers(new_acl, &newmembers);
 
 		/* finished building new ACL value, now insert it */
-		MemSet(values, 0, sizeof(values));
-		MemSet(nulls, false, sizeof(nulls));
-		MemSet(replaces, false, sizeof(replaces));
 
 		replaces[Anum_pg_database_datacl - 1] = true;
 		values[Anum_pg_database_datacl - 1] = PointerGetDatum(new_acl);
@@ -2268,9 +2256,9 @@ ExecGrant_Fdw(InternalGrant *istmt)
 		Oid			ownerId;
 		HeapTuple	tuple;
 		HeapTuple	newtuple;
-		Datum		values[Natts_pg_foreign_data_wrapper];
-		bool		nulls[Natts_pg_foreign_data_wrapper];
-		bool		replaces[Natts_pg_foreign_data_wrapper];
+		Datum		values[Natts_pg_foreign_data_wrapper] = INIT_ALL_ELEMS_ZERO;
+		bool		nulls[Natts_pg_foreign_data_wrapper] = INIT_ALL_ELEMS_ZERO;
+		bool		replaces[Natts_pg_foreign_data_wrapper] = INIT_ALL_ELEMS_ZERO;
 		int			noldmembers;
 		int			nnewmembers;
 		Oid		   *oldmembers;
@@ -2336,9 +2324,6 @@ ExecGrant_Fdw(InternalGrant *istmt)
 		nnewmembers = aclmembers(new_acl, &newmembers);
 
 		/* finished building new ACL value, now insert it */
-		MemSet(values, 0, sizeof(values));
-		MemSet(nulls, false, sizeof(nulls));
-		MemSet(replaces, false, sizeof(replaces));
 
 		replaces[Anum_pg_foreign_data_wrapper_fdwacl - 1] = true;
 		values[Anum_pg_foreign_data_wrapper_fdwacl - 1] = PointerGetDatum(new_acl);
@@ -2395,9 +2380,9 @@ ExecGrant_ForeignServer(InternalGrant *istmt)
 		Oid			ownerId;
 		HeapTuple	tuple;
 		HeapTuple	newtuple;
-		Datum		values[Natts_pg_foreign_server];
-		bool		nulls[Natts_pg_foreign_server];
-		bool		replaces[Natts_pg_foreign_server];
+		Datum		values[Natts_pg_foreign_server] = INIT_ALL_ELEMS_ZERO;
+		bool		nulls[Natts_pg_foreign_server] = INIT_ALL_ELEMS_ZERO;
+		bool		replaces[Natts_pg_foreign_server] = INIT_ALL_ELEMS_ZERO;
 		int			noldmembers;
 		int			nnewmembers;
 		Oid		   *oldmembers;
@@ -2462,9 +2447,6 @@ ExecGrant_ForeignServer(InternalGrant *istmt)
 		nnewmembers = aclmembers(new_acl, &newmembers);
 
 		/* finished building new ACL value, now insert it */
-		MemSet(values, 0, sizeof(values));
-		MemSet(nulls, false, sizeof(nulls));
-		MemSet(replaces, false, sizeof(replaces));
 
 		replaces[Anum_pg_foreign_server_srvacl - 1] = true;
 		values[Anum_pg_foreign_server_srvacl - 1] = PointerGetDatum(new_acl);
@@ -2520,9 +2502,9 @@ ExecGrant_Function(InternalGrant *istmt)
 		Oid			ownerId;
 		HeapTuple	tuple;
 		HeapTuple	newtuple;
-		Datum		values[Natts_pg_proc];
-		bool		nulls[Natts_pg_proc];
-		bool		replaces[Natts_pg_proc];
+		Datum		values[Natts_pg_proc] = INIT_ALL_ELEMS_ZERO;
+		bool		nulls[Natts_pg_proc] = INIT_ALL_ELEMS_ZERO;
+		bool		replaces[Natts_pg_proc] = INIT_ALL_ELEMS_ZERO;
 		int			noldmembers;
 		int			nnewmembers;
 		Oid		   *oldmembers;
@@ -2586,9 +2568,6 @@ ExecGrant_Function(InternalGrant *istmt)
 		nnewmembers = aclmembers(new_acl, &newmembers);
 
 		/* finished building new ACL value, now insert it */
-		MemSet(values, 0, sizeof(values));
-		MemSet(nulls, false, sizeof(nulls));
-		MemSet(replaces, false, sizeof(replaces));
 
 		replaces[Anum_pg_proc_proacl - 1] = true;
 		values[Anum_pg_proc_proacl - 1] = PointerGetDatum(new_acl);
@@ -2643,9 +2622,9 @@ ExecGrant_Language(InternalGrant *istmt)
 		Oid			ownerId;
 		HeapTuple	tuple;
 		HeapTuple	newtuple;
-		Datum		values[Natts_pg_language];
-		bool		nulls[Natts_pg_language];
-		bool		replaces[Natts_pg_language];
+		Datum		values[Natts_pg_language] = INIT_ALL_ELEMS_ZERO;
+		bool		nulls[Natts_pg_language] = INIT_ALL_ELEMS_ZERO;
+		bool		replaces[Natts_pg_language] = INIT_ALL_ELEMS_ZERO;
 		int			noldmembers;
 		int			nnewmembers;
 		Oid		   *oldmembers;
@@ -2717,9 +2696,6 @@ ExecGrant_Language(InternalGrant *istmt)
 		nnewmembers = aclmembers(new_acl, &newmembers);
 
 		/* finished building new ACL value, now insert it */
-		MemSet(values, 0, sizeof(values));
-		MemSet(nulls, false, sizeof(nulls));
-		MemSet(replaces, false, sizeof(replaces));
 
 		replaces[Anum_pg_language_lanacl - 1] = true;
 		values[Anum_pg_language_lanacl - 1] = PointerGetDatum(new_acl);
@@ -2775,9 +2751,9 @@ ExecGrant_Largeobject(InternalGrant *istmt)
 		Oid			grantorId;
 		Oid			ownerId;
 		HeapTuple	newtuple;
-		Datum		values[Natts_pg_largeobject_metadata];
-		bool		nulls[Natts_pg_largeobject_metadata];
-		bool		replaces[Natts_pg_largeobject_metadata];
+		Datum		values[Natts_pg_largeobject_metadata] = INIT_ALL_ELEMS_ZERO;
+		bool		nulls[Natts_pg_largeobject_metadata] = INIT_ALL_ELEMS_ZERO;
+		bool		replaces[Natts_pg_largeobject_metadata] = INIT_ALL_ELEMS_ZERO;
 		int			noldmembers;
 		int			nnewmembers;
 		Oid		   *oldmembers;
@@ -2855,9 +2831,6 @@ ExecGrant_Largeobject(InternalGrant *istmt)
 		nnewmembers = aclmembers(new_acl, &newmembers);
 
 		/* finished building new ACL value, now insert it */
-		MemSet(values, 0, sizeof(values));
-		MemSet(nulls, false, sizeof(nulls));
-		MemSet(replaces, false, sizeof(replaces));
 
 		replaces[Anum_pg_largeobject_metadata_lomacl - 1] = true;
 		values[Anum_pg_largeobject_metadata_lomacl - 1]
@@ -2914,9 +2887,9 @@ ExecGrant_Namespace(InternalGrant *istmt)
 		Oid			ownerId;
 		HeapTuple	tuple;
 		HeapTuple	newtuple;
-		Datum		values[Natts_pg_namespace];
-		bool		nulls[Natts_pg_namespace];
-		bool		replaces[Natts_pg_namespace];
+		Datum		values[Natts_pg_namespace] = INIT_ALL_ELEMS_ZERO;
+		bool		nulls[Natts_pg_namespace] = INIT_ALL_ELEMS_ZERO;
+		bool		replaces[Natts_pg_namespace] = INIT_ALL_ELEMS_ZERO;
 		int			noldmembers;
 		int			nnewmembers;
 		Oid		   *oldmembers;
@@ -2981,9 +2954,6 @@ ExecGrant_Namespace(InternalGrant *istmt)
 		nnewmembers = aclmembers(new_acl, &newmembers);
 
 		/* finished building new ACL value, now insert it */
-		MemSet(values, 0, sizeof(values));
-		MemSet(nulls, false, sizeof(nulls));
-		MemSet(replaces, false, sizeof(replaces));
 
 		replaces[Anum_pg_namespace_nspacl - 1] = true;
 		values[Anum_pg_namespace_nspacl - 1] = PointerGetDatum(new_acl);
@@ -3037,9 +3007,9 @@ ExecGrant_Tablespace(InternalGrant *istmt)
 		Oid			grantorId;
 		Oid			ownerId;
 		HeapTuple	newtuple;
-		Datum		values[Natts_pg_tablespace];
-		bool		nulls[Natts_pg_tablespace];
-		bool		replaces[Natts_pg_tablespace];
+		Datum		values[Natts_pg_tablespace] = INIT_ALL_ELEMS_ZERO;
+		bool		nulls[Natts_pg_tablespace] = INIT_ALL_ELEMS_ZERO;
+		bool		replaces[Natts_pg_tablespace] = INIT_ALL_ELEMS_ZERO;
 		int			noldmembers;
 		int			nnewmembers;
 		Oid		   *oldmembers;
@@ -3105,9 +3075,6 @@ ExecGrant_Tablespace(InternalGrant *istmt)
 		nnewmembers = aclmembers(new_acl, &newmembers);
 
 		/* finished building new ACL value, now insert it */
-		MemSet(values, 0, sizeof(values));
-		MemSet(nulls, false, sizeof(nulls));
-		MemSet(replaces, false, sizeof(replaces));
 
 		replaces[Anum_pg_tablespace_spcacl - 1] = true;
 		values[Anum_pg_tablespace_spcacl - 1] = PointerGetDatum(new_acl);
@@ -3157,9 +3124,9 @@ ExecGrant_Type(InternalGrant *istmt)
 		Oid			grantorId;
 		Oid			ownerId;
 		HeapTuple	newtuple;
-		Datum		values[Natts_pg_type];
-		bool		nulls[Natts_pg_type];
-		bool		replaces[Natts_pg_type];
+		Datum		values[Natts_pg_type] = INIT_ALL_ELEMS_ZERO;
+		bool		nulls[Natts_pg_type] = INIT_ALL_ELEMS_ZERO;
+		bool		replaces[Natts_pg_type] = INIT_ALL_ELEMS_ZERO;
 		int			noldmembers;
 		int			nnewmembers;
 		Oid		   *oldmembers;
@@ -3239,9 +3206,6 @@ ExecGrant_Type(InternalGrant *istmt)
 		nnewmembers = aclmembers(new_acl, &newmembers);
 
 		/* finished building new ACL value, now insert it */
-		MemSet(values, 0, sizeof(values));
-		MemSet(nulls, false, sizeof(nulls));
-		MemSet(replaces, false, sizeof(replaces));
 
 		replaces[Anum_pg_type_typacl - 1] = true;
 		values[Anum_pg_type_typacl - 1] = PointerGetDatum(new_acl);
@@ -5992,17 +5956,13 @@ recordExtensionInitPrivWorker(Oid objoid, Oid classoid, int objsubid, Acl *new_a
 	/* If we find an entry, update it with the latest ACL. */
 	if (HeapTupleIsValid(oldtuple))
 	{
-		Datum		values[Natts_pg_init_privs];
-		bool		nulls[Natts_pg_init_privs];
-		bool		replace[Natts_pg_init_privs];
+		Datum		values[Natts_pg_init_privs] = INIT_ALL_ELEMS_ZERO;
+		bool		nulls[Natts_pg_init_privs] = INIT_ALL_ELEMS_ZERO;
+		bool		replace[Natts_pg_init_privs] = INIT_ALL_ELEMS_ZERO;
 
 		/* If we have a new ACL to set, then update the row with it. */
 		if (new_acl)
 		{
-			MemSet(values, 0, sizeof(values));
-			MemSet(nulls, false, sizeof(nulls));
-			MemSet(replace, false, sizeof(replace));
-
 			values[Anum_pg_init_privs_initprivs - 1] = PointerGetDatum(new_acl);
 			replace[Anum_pg_init_privs_initprivs - 1] = true;
 
@@ -6020,7 +5980,7 @@ recordExtensionInitPrivWorker(Oid objoid, Oid classoid, int objsubid, Acl *new_a
 	else
 	{
 		Datum		values[Natts_pg_init_privs];
-		bool		nulls[Natts_pg_init_privs];
+		bool		nulls[Natts_pg_init_privs] = INIT_ALL_ELEMS_ZERO;
 
 		/*
 		 * Only add a new entry if the new ACL is non-NULL.
@@ -6031,8 +5991,6 @@ recordExtensionInitPrivWorker(Oid objoid, Oid classoid, int objsubid, Acl *new_a
 		if (new_acl)
 		{
 			/* No entry found, so add it. */
-			MemSet(nulls, false, sizeof(nulls));
-
 			values[Anum_pg_init_privs_objoid - 1] = ObjectIdGetDatum(objoid);
 			values[Anum_pg_init_privs_classoid - 1] = ObjectIdGetDatum(classoid);
 			values[Anum_pg_init_privs_objsubid - 1] = Int32GetDatum(objsubid);
diff --git a/src/backend/catalog/heap.c b/src/backend/catalog/heap.c
index b7bcdd9..a0cb3a6 100644
--- a/src/backend/catalog/heap.c
+++ b/src/backend/catalog/heap.c
@@ -695,14 +695,10 @@ InsertPgAttributeTuple(Relation pg_attribute_rel,
 					   Form_pg_attribute new_attribute,
 					   CatalogIndexState indstate)
 {
-	Datum		values[Natts_pg_attribute];
-	bool		nulls[Natts_pg_attribute];
+	Datum		values[Natts_pg_attribute] = INIT_ALL_ELEMS_ZERO;
+	bool		nulls[Natts_pg_attribute] = INIT_ALL_ELEMS_ZERO;
 	HeapTuple	tup;
 
-	/* This is a tad tedious, but way cleaner than what we used to do... */
-	memset(values, 0, sizeof(values));
-	memset(nulls, false, sizeof(nulls));
-
 	values[Anum_pg_attribute_attrelid - 1] = ObjectIdGetDatum(new_attribute->attrelid);
 	values[Anum_pg_attribute_attname - 1] = NameGetDatum(&new_attribute->attname);
 	values[Anum_pg_attribute_atttypid - 1] = ObjectIdGetDatum(new_attribute->atttypid);
@@ -852,14 +848,10 @@ InsertPgClassTuple(Relation pg_class_desc,
 				   Datum reloptions)
 {
 	Form_pg_class rd_rel = new_rel_desc->rd_rel;
-	Datum		values[Natts_pg_class];
-	bool		nulls[Natts_pg_class];
+	Datum		values[Natts_pg_class] = INIT_ALL_ELEMS_ZERO;
+	bool		nulls[Natts_pg_class] = INIT_ALL_ELEMS_ZERO;
 	HeapTuple	tup;
 
-	/* This is a tad tedious, but way cleaner than what we used to do... */
-	memset(values, 0, sizeof(values));
-	memset(nulls, false, sizeof(nulls));
-
 	values[Anum_pg_class_oid - 1] = ObjectIdGetDatum(new_rel_oid);
 	values[Anum_pg_class_relname - 1] = NameGetDatum(&rd_rel->relname);
 	values[Anum_pg_class_relnamespace - 1] = ObjectIdGetDatum(rd_rel->relnamespace);
@@ -1645,14 +1637,11 @@ RemoveAttributeById(Oid relid, AttrNumber attnum)
 		/* clear the missing value if any */
 		if (attStruct->atthasmissing)
 		{
-			Datum		valuesAtt[Natts_pg_attribute];
-			bool		nullsAtt[Natts_pg_attribute];
-			bool		replacesAtt[Natts_pg_attribute];
+			Datum		valuesAtt[Natts_pg_attribute] = INIT_ALL_ELEMS_ZERO;
+			bool		nullsAtt[Natts_pg_attribute] = INIT_ALL_ELEMS_ZERO;
+			bool		replacesAtt[Natts_pg_attribute] = INIT_ALL_ELEMS_ZERO;
 
 			/* update the tuple - set atthasmissing and attmissingval */
-			MemSet(valuesAtt, 0, sizeof(valuesAtt));
-			MemSet(nullsAtt, false, sizeof(nullsAtt));
-			MemSet(replacesAtt, false, sizeof(replacesAtt));
 
 			valuesAtt[Anum_pg_attribute_atthasmissing - 1] =
 				BoolGetDatum(false);
@@ -2064,9 +2053,9 @@ RelationClearMissing(Relation rel)
 void
 SetAttrMissing(Oid relid, char *attname, char *value)
 {
-	Datum		valuesAtt[Natts_pg_attribute];
-	bool		nullsAtt[Natts_pg_attribute];
-	bool		replacesAtt[Natts_pg_attribute];
+	Datum		valuesAtt[Natts_pg_attribute] = INIT_ALL_ELEMS_ZERO;
+	bool		nullsAtt[Natts_pg_attribute] = INIT_ALL_ELEMS_ZERO;
+	bool		replacesAtt[Natts_pg_attribute] = INIT_ALL_ELEMS_ZERO;
 	Datum		missingval;
 	Form_pg_attribute attStruct;
 	Relation	attrrel,
@@ -2092,9 +2081,6 @@ SetAttrMissing(Oid relid, char *attname, char *value)
 								  Int32GetDatum(attStruct->atttypmod));
 
 	/* update the tuple - set atthasmissing and attmissingval */
-	MemSet(valuesAtt, 0, sizeof(valuesAtt));
-	MemSet(nullsAtt, false, sizeof(nullsAtt));
-	MemSet(replacesAtt, false, sizeof(replacesAtt));
 
 	valuesAtt[Anum_pg_attribute_atthasmissing - 1] = BoolGetDatum(true);
 	replacesAtt[Anum_pg_attribute_atthasmissing - 1] = true;
@@ -2191,15 +2177,12 @@ StoreAttrDefault(Relation rel, AttrNumber attnum,
 		Expr	   *expr2 = (Expr *) expr;
 		EState	   *estate = NULL;
 		ExprContext *econtext;
-		Datum		valuesAtt[Natts_pg_attribute];
-		bool		nullsAtt[Natts_pg_attribute];
-		bool		replacesAtt[Natts_pg_attribute];
+		Datum		valuesAtt[Natts_pg_attribute] = INIT_ALL_ELEMS_ZERO;
+		bool		nullsAtt[Natts_pg_attribute] = INIT_ALL_ELEMS_ZERO;
+		bool		replacesAtt[Natts_pg_attribute] = INIT_ALL_ELEMS_ZERO;
 		Datum		missingval = (Datum) 0;
 		bool		missingIsNull = true;
 
-		MemSet(valuesAtt, 0, sizeof(valuesAtt));
-		MemSet(nullsAtt, false, sizeof(nullsAtt));
-		MemSet(replacesAtt, false, sizeof(replacesAtt));
 		valuesAtt[Anum_pg_attribute_atthasdef - 1] = true;
 		replacesAtt[Anum_pg_attribute_atthasdef - 1] = true;
 
@@ -3419,7 +3402,7 @@ StorePartitionKey(Relation rel,
 	Relation	pg_partitioned_table;
 	HeapTuple	tuple;
 	Datum		values[Natts_pg_partitioned_table];
-	bool		nulls[Natts_pg_partitioned_table];
+	bool		nulls[Natts_pg_partitioned_table] = INIT_ALL_ELEMS_ZERO;
 	ObjectAddress myself;
 	ObjectAddress referenced;
 
@@ -3444,8 +3427,6 @@ StorePartitionKey(Relation rel,
 
 	pg_partitioned_table = table_open(PartitionedRelationId, RowExclusiveLock);
 
-	MemSet(nulls, false, sizeof(nulls));
-
 	/* Only this can ever be NULL */
 	if (!partexprDatum)
 		nulls[Anum_pg_partitioned_table_partexprs - 1] = true;
diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c
index 098732c..2298856 100644
--- a/src/backend/catalog/index.c
+++ b/src/backend/catalog/index.c
@@ -546,7 +546,7 @@ UpdateIndexRelation(Oid indexoid,
 	Datum		exprsDatum;
 	Datum		predDatum;
 	Datum		values[Natts_pg_index];
-	bool		nulls[Natts_pg_index];
+	bool		nulls[Natts_pg_index] = INIT_ALL_ELEMS_ZERO;
 	Relation	pg_index;
 	HeapTuple	tuple;
 	int			i;
@@ -599,7 +599,6 @@ UpdateIndexRelation(Oid indexoid,
 	/*
 	 * Build a pg_index tuple
 	 */
-	MemSet(nulls, false, sizeof(nulls));
 
 	values[Anum_pg_index_indexrelid - 1] = ObjectIdGetDatum(indexoid);
 	values[Anum_pg_index_indrelid - 1] = ObjectIdGetDatum(heapoid);
diff --git a/src/backend/catalog/pg_collation.c b/src/backend/catalog/pg_collation.c
index dd99d53..e216dd6 100644
--- a/src/backend/catalog/pg_collation.c
+++ b/src/backend/catalog/pg_collation.c
@@ -57,7 +57,7 @@ CollationCreate(const char *collname, Oid collnamespace,
 	TupleDesc	tupDesc;
 	HeapTuple	tup;
 	Datum		values[Natts_pg_collation];
-	bool		nulls[Natts_pg_collation];
+	bool		nulls[Natts_pg_collation] = INIT_ALL_ELEMS_ZERO;
 	NameData	name_name,
 				name_collate,
 				name_ctype;
@@ -151,7 +151,6 @@ CollationCreate(const char *collname, Oid collnamespace,
 	tupDesc = RelationGetDescr(rel);
 
 	/* form a tuple */
-	memset(nulls, 0, sizeof(nulls));
 
 	namestrcpy(&name_name, collname);
 	oid = GetNewOidWithIndex(rel, CollationOidIndexId,
diff --git a/src/backend/catalog/pg_db_role_setting.c b/src/backend/catalog/pg_db_role_setting.c
index 20acac2..d71328a 100644
--- a/src/backend/catalog/pg_db_role_setting.c
+++ b/src/backend/catalog/pg_db_role_setting.c
@@ -136,11 +136,9 @@ AlterSetting(Oid databaseid, Oid roleid, VariableSetStmt *setstmt)
 		/* non-null valuestr means it's not RESET, so insert a new tuple */
 		HeapTuple	newtuple;
 		Datum		values[Natts_pg_db_role_setting];
-		bool		nulls[Natts_pg_db_role_setting];
+		bool		nulls[Natts_pg_db_role_setting] = INIT_ALL_ELEMS_ZERO;
 		ArrayType  *a;
 
-		memset(nulls, false, sizeof(nulls));
-
 		a = GUCArrayAdd(NULL, setstmt->name, valuestr);
 
 		values[Anum_pg_db_role_setting_setdatabase - 1] =
diff --git a/src/backend/catalog/pg_depend.c b/src/backend/catalog/pg_depend.c
index a060c25..e80b8a7 100644
--- a/src/backend/catalog/pg_depend.c
+++ b/src/backend/catalog/pg_depend.c
@@ -61,7 +61,7 @@ recordMultipleDependencies(const ObjectAddress *depender,
 	CatalogIndexState indstate;
 	HeapTuple	tup;
 	int			i;
-	bool		nulls[Natts_pg_depend];
+	bool		nulls[Natts_pg_depend] = INIT_ALL_ELEMS_ZERO;
 	Datum		values[Natts_pg_depend];
 
 	if (nreferenced <= 0)
@@ -79,8 +79,6 @@ recordMultipleDependencies(const ObjectAddress *depender,
 	/* Don't open indexes unless we need to make an update */
 	indstate = NULL;
 
-	memset(nulls, false, sizeof(nulls));
-
 	for (i = 0; i < nreferenced; i++, referenced++)
 	{
 		/*
diff --git a/src/backend/catalog/pg_enum.c b/src/backend/catalog/pg_enum.c
index d0ff802..b174e12 100644
--- a/src/backend/catalog/pg_enum.c
+++ b/src/backend/catalog/pg_enum.c
@@ -66,7 +66,7 @@ EnumValuesCreate(Oid enumTypeOid, List *vals)
 	int			elemno,
 				num_elems;
 	Datum		values[Natts_pg_enum];
-	bool		nulls[Natts_pg_enum];
+	bool		nulls[Natts_pg_enum] = INIT_ALL_ELEMS_ZERO;
 	ListCell   *lc;
 	HeapTuple	tup;
 
@@ -111,8 +111,6 @@ EnumValuesCreate(Oid enumTypeOid, List *vals)
 	qsort(oids, num_elems, sizeof(Oid), oid_cmp);
 
 	/* and make the entries */
-	memset(nulls, false, sizeof(nulls));
-
 	elemno = 0;
 	foreach(lc, vals)
 	{
@@ -215,7 +213,7 @@ AddEnumLabel(Oid enumTypeOid,
 	Relation	pg_enum;
 	Oid			newOid;
 	Datum		values[Natts_pg_enum];
-	bool		nulls[Natts_pg_enum];
+	bool		nulls[Natts_pg_enum] = INIT_ALL_ELEMS_ZERO;
 	NameData	enumlabel;
 	HeapTuple	enum_tup;
 	float4		newelemorder;
@@ -480,7 +478,6 @@ restart:
 	ReleaseCatCacheList(list);
 
 	/* Create the new pg_enum entry */
-	memset(nulls, false, sizeof(nulls));
 	values[Anum_pg_enum_oid - 1] = ObjectIdGetDatum(newOid);
 	values[Anum_pg_enum_enumtypid - 1] = ObjectIdGetDatum(enumTypeOid);
 	values[Anum_pg_enum_enumsortorder - 1] = Float4GetDatum(newelemorder);
diff --git a/src/backend/catalog/pg_inherits.c b/src/backend/catalog/pg_inherits.c
index 59af162..27d709d 100644
--- a/src/backend/catalog/pg_inherits.c
+++ b/src/backend/catalog/pg_inherits.c
@@ -417,7 +417,7 @@ void
 StoreSingleInheritance(Oid relationId, Oid parentOid, int32 seqNumber)
 {
 	Datum		values[Natts_pg_inherits];
-	bool		nulls[Natts_pg_inherits];
+	bool		nulls[Natts_pg_inherits] = INIT_ALL_ELEMS_ZERO;
 	HeapTuple	tuple;
 	Relation	inhRelation;
 
@@ -430,8 +430,6 @@ StoreSingleInheritance(Oid relationId, Oid parentOid, int32 seqNumber)
 	values[Anum_pg_inherits_inhparent - 1] = ObjectIdGetDatum(parentOid);
 	values[Anum_pg_inherits_inhseqno - 1] = Int32GetDatum(seqNumber);
 
-	memset(nulls, 0, sizeof(nulls));
-
 	tuple = heap_form_tuple(RelationGetDescr(inhRelation), values, nulls);
 
 	CatalogTupleInsert(inhRelation, tuple);
diff --git a/src/backend/catalog/pg_largeobject.c b/src/backend/catalog/pg_largeobject.c
index 1a68702..3489ec5 100644
--- a/src/backend/catalog/pg_largeobject.c
+++ b/src/backend/catalog/pg_largeobject.c
@@ -42,8 +42,8 @@ LargeObjectCreate(Oid loid)
 	Relation	pg_lo_meta;
 	HeapTuple	ntup;
 	Oid			loid_new;
-	Datum		values[Natts_pg_largeobject_metadata];
-	bool		nulls[Natts_pg_largeobject_metadata];
+	Datum		values[Natts_pg_largeobject_metadata] = INIT_ALL_ELEMS_ZERO;
+	bool		nulls[Natts_pg_largeobject_metadata] = INIT_ALL_ELEMS_ZERO;
 
 	pg_lo_meta = table_open(LargeObjectMetadataRelationId,
 							RowExclusiveLock);
@@ -51,8 +51,6 @@ LargeObjectCreate(Oid loid)
 	/*
 	 * Insert metadata of the largeobject
 	 */
-	memset(values, 0, sizeof(values));
-	memset(nulls, false, sizeof(nulls));
 
 	if (OidIsValid(loid))
 		loid_new = loid;
diff --git a/src/backend/catalog/pg_publication.c b/src/backend/catalog/pg_publication.c
index fd5da7d..6c62771 100644
--- a/src/backend/catalog/pg_publication.c
+++ b/src/backend/catalog/pg_publication.c
@@ -154,8 +154,8 @@ publication_add_relation(Oid pubid, Relation targetrel,
 {
 	Relation	rel;
 	HeapTuple	tup;
-	Datum		values[Natts_pg_publication_rel];
-	bool		nulls[Natts_pg_publication_rel];
+	Datum		values[Natts_pg_publication_rel] = INIT_ALL_ELEMS_ZERO;
+	bool		nulls[Natts_pg_publication_rel] = INIT_ALL_ELEMS_ZERO;
 	Oid			relid = RelationGetRelid(targetrel);
 	Oid			prrelid;
 	Publication *pub = GetPublication(pubid);
@@ -186,8 +186,6 @@ publication_add_relation(Oid pubid, Relation targetrel,
 	check_publication_add_relation(targetrel);
 
 	/* Form a tuple. */
-	memset(values, 0, sizeof(values));
-	memset(nulls, false, sizeof(nulls));
 
 	prrelid = GetNewOidWithIndex(rel, PublicationRelObjectIndexId,
 								 Anum_pg_publication_rel_oid);
diff --git a/src/backend/catalog/pg_range.c b/src/backend/catalog/pg_range.c
index e6e138b..3796cda 100644
--- a/src/backend/catalog/pg_range.c
+++ b/src/backend/catalog/pg_range.c
@@ -39,15 +39,13 @@ RangeCreate(Oid rangeTypeOid, Oid rangeSubType, Oid rangeCollation,
 {
 	Relation	pg_range;
 	Datum		values[Natts_pg_range];
-	bool		nulls[Natts_pg_range];
+	bool		nulls[Natts_pg_range] = INIT_ALL_ELEMS_ZERO;
 	HeapTuple	tup;
 	ObjectAddress myself;
 	ObjectAddress referenced;
 
 	pg_range = table_open(RangeRelationId, RowExclusiveLock);
 
-	memset(nulls, 0, sizeof(nulls));
-
 	values[Anum_pg_range_rngtypid - 1] = ObjectIdGetDatum(rangeTypeOid);
 	values[Anum_pg_range_rngsubtype - 1] = ObjectIdGetDatum(rangeSubType);
 	values[Anum_pg_range_rngcollation - 1] = ObjectIdGetDatum(rangeCollation);
diff --git a/src/backend/catalog/pg_shdepend.c b/src/backend/catalog/pg_shdepend.c
index fb7f8dd..66bac64 100644
--- a/src/backend/catalog/pg_shdepend.c
+++ b/src/backend/catalog/pg_shdepend.c
@@ -273,9 +273,7 @@ shdepChangeDep(Relation sdepRel,
 	{
 		/* Need to insert new entry */
 		Datum		values[Natts_pg_shdepend];
-		bool		nulls[Natts_pg_shdepend];
-
-		memset(nulls, false, sizeof(nulls));
+		bool		nulls[Natts_pg_shdepend] = INIT_ALL_ELEMS_ZERO;
 
 		values[Anum_pg_shdepend_dbid - 1] = ObjectIdGetDatum(dbid);
 		values[Anum_pg_shdepend_classid - 1] = ObjectIdGetDatum(classid);
@@ -801,9 +799,9 @@ copyTemplateDependencies(Oid templateDbId, Oid newDbId)
 	SysScanDesc scan;
 	HeapTuple	tup;
 	CatalogIndexState indstate;
-	Datum		values[Natts_pg_shdepend];
-	bool		nulls[Natts_pg_shdepend];
-	bool		replace[Natts_pg_shdepend];
+	Datum		values[Natts_pg_shdepend] = INIT_ALL_ELEMS_ZERO;
+	bool		nulls[Natts_pg_shdepend] = INIT_ALL_ELEMS_ZERO;
+	bool		replace[Natts_pg_shdepend] = INIT_ALL_ELEMS_ZERO;
 
 	sdepRel = table_open(SharedDependRelationId, RowExclusiveLock);
 	sdepDesc = RelationGetDescr(sdepRel);
@@ -820,10 +818,6 @@ copyTemplateDependencies(Oid templateDbId, Oid newDbId)
 							  NULL, 1, key);
 
 	/* Set up to copy the tuples except for inserting newDbId */
-	memset(values, 0, sizeof(values));
-	memset(nulls, false, sizeof(nulls));
-	memset(replace, false, sizeof(replace));
-
 	replace[Anum_pg_shdepend_dbid - 1] = true;
 	values[Anum_pg_shdepend_dbid - 1] = ObjectIdGetDatum(newDbId);
 
@@ -934,7 +928,7 @@ shdepAddDependency(Relation sdepRel,
 {
 	HeapTuple	tup;
 	Datum		values[Natts_pg_shdepend];
-	bool		nulls[Natts_pg_shdepend];
+	bool		nulls[Natts_pg_shdepend] = INIT_ALL_ELEMS_ZERO;
 
 	/*
 	 * Make sure the object doesn't go away while we record the dependency on
@@ -943,8 +937,6 @@ shdepAddDependency(Relation sdepRel,
 	 */
 	shdepLockAndCheckObject(refclassId, refobjId);
 
-	memset(nulls, false, sizeof(nulls));
-
 	/*
 	 * Form the new tuple and record the dependency.
 	 */
diff --git a/src/backend/catalog/pg_subscription.c b/src/backend/catalog/pg_subscription.c
index afee283..4a1bc80 100644
--- a/src/backend/catalog/pg_subscription.c
+++ b/src/backend/catalog/pg_subscription.c
@@ -243,8 +243,8 @@ AddSubscriptionRelState(Oid subid, Oid relid, char state,
 {
 	Relation	rel;
 	HeapTuple	tup;
-	bool		nulls[Natts_pg_subscription_rel];
-	Datum		values[Natts_pg_subscription_rel];
+	bool		nulls[Natts_pg_subscription_rel] = INIT_ALL_ELEMS_ZERO;
+	Datum		values[Natts_pg_subscription_rel] = INIT_ALL_ELEMS_ZERO;
 
 	LockSharedObject(SubscriptionRelationId, subid, 0, AccessShareLock);
 
@@ -259,8 +259,6 @@ AddSubscriptionRelState(Oid subid, Oid relid, char state,
 			 relid, subid);
 
 	/* Form the tuple. */
-	memset(values, 0, sizeof(values));
-	memset(nulls, false, sizeof(nulls));
 	values[Anum_pg_subscription_rel_srsubid - 1] = ObjectIdGetDatum(subid);
 	values[Anum_pg_subscription_rel_srrelid - 1] = ObjectIdGetDatum(relid);
 	values[Anum_pg_subscription_rel_srsubstate - 1] = CharGetDatum(state);
@@ -289,9 +287,9 @@ UpdateSubscriptionRelState(Oid subid, Oid relid, char state,
 {
 	Relation	rel;
 	HeapTuple	tup;
-	bool		nulls[Natts_pg_subscription_rel];
-	Datum		values[Natts_pg_subscription_rel];
-	bool		replaces[Natts_pg_subscription_rel];
+	bool		nulls[Natts_pg_subscription_rel] = INIT_ALL_ELEMS_ZERO;
+	Datum		values[Natts_pg_subscription_rel] = INIT_ALL_ELEMS_ZERO;
+	bool		replaces[Natts_pg_subscription_rel] = INIT_ALL_ELEMS_ZERO;
 
 	LockSharedObject(SubscriptionRelationId, subid, 0, AccessShareLock);
 
@@ -306,10 +304,6 @@ UpdateSubscriptionRelState(Oid subid, Oid relid, char state,
 			 relid, subid);
 
 	/* Update the tuple. */
-	memset(values, 0, sizeof(values));
-	memset(nulls, false, sizeof(nulls));
-	memset(replaces, false, sizeof(replaces));
-
 	replaces[Anum_pg_subscription_rel_srsubstate - 1] = true;
 	values[Anum_pg_subscription_rel_srsubstate - 1] = CharGetDatum(state);
 
diff --git a/src/backend/commands/amcmds.c b/src/backend/commands/amcmds.c
index c0e4098..d053183 100644
--- a/src/backend/commands/amcmds.c
+++ b/src/backend/commands/amcmds.c
@@ -46,8 +46,8 @@ CreateAccessMethod(CreateAmStmt *stmt)
 	ObjectAddress referenced;
 	Oid			amoid;
 	Oid			amhandler;
-	bool		nulls[Natts_pg_am];
-	Datum		values[Natts_pg_am];
+	bool		nulls[Natts_pg_am] = INIT_ALL_ELEMS_ZERO;
+	Datum		values[Natts_pg_am] = INIT_ALL_ELEMS_ZERO;
 	HeapTuple	tup;
 
 	rel = table_open(AccessMethodRelationId, RowExclusiveLock);
@@ -79,9 +79,6 @@ CreateAccessMethod(CreateAmStmt *stmt)
 	/*
 	 * Insert tuple into pg_am.
 	 */
-	memset(values, 0, sizeof(values));
-	memset(nulls, false, sizeof(nulls));
-
 	amoid = GetNewOidWithIndex(rel, AmOidIndexId, Anum_pg_am_oid);
 	values[Anum_pg_am_oid - 1] = ObjectIdGetDatum(amoid);
 	values[Anum_pg_am_amname - 1] =
diff --git a/src/backend/commands/collationcmds.c b/src/backend/commands/collationcmds.c
index 919e092..4bfa313 100644
--- a/src/backend/commands/collationcmds.c
+++ b/src/backend/commands/collationcmds.c
@@ -315,18 +315,14 @@ AlterCollation(AlterCollationStmt *stmt)
 		elog(ERROR, "invalid collation version change");
 	else if (oldversion && newversion && strcmp(newversion, oldversion) != 0)
 	{
-		bool		nulls[Natts_pg_collation];
-		bool		replaces[Natts_pg_collation];
-		Datum		values[Natts_pg_collation];
+		bool		nulls[Natts_pg_collation] = INIT_ALL_ELEMS_ZERO;
+		bool		replaces[Natts_pg_collation] = INIT_ALL_ELEMS_ZERO;
+		Datum		values[Natts_pg_collation] = INIT_ALL_ELEMS_ZERO;
 
 		ereport(NOTICE,
 				(errmsg("changing version from %s to %s",
 						oldversion, newversion)));
 
-		memset(values, 0, sizeof(values));
-		memset(nulls, false, sizeof(nulls));
-		memset(replaces, false, sizeof(replaces));
-
 		values[Anum_pg_collation_collversion - 1] = CStringGetTextDatum(newversion);
 		replaces[Anum_pg_collation_collversion - 1] = true;
 
diff --git a/src/backend/commands/event_trigger.c b/src/backend/commands/event_trigger.c
index f7ee983..2790439 100644
--- a/src/backend/commands/event_trigger.c
+++ b/src/backend/commands/event_trigger.c
@@ -381,7 +381,7 @@ insert_event_trigger_tuple(const char *trigname, const char *eventname, Oid evtO
 	Oid			trigoid;
 	HeapTuple	tuple;
 	Datum		values[Natts_pg_trigger];
-	bool		nulls[Natts_pg_trigger];
+	bool		nulls[Natts_pg_trigger] = INIT_ALL_ELEMS_ZERO;
 	NameData	evtnamedata,
 				evteventdata;
 	ObjectAddress myself,
@@ -394,7 +394,6 @@ insert_event_trigger_tuple(const char *trigname, const char *eventname, Oid evtO
 	trigoid = GetNewOidWithIndex(tgrel, EventTriggerOidIndexId,
 								 Anum_pg_event_trigger_oid);
 	values[Anum_pg_event_trigger_oid - 1] = ObjectIdGetDatum(trigoid);
-	memset(nulls, false, sizeof(nulls));
 	namestrcpy(&evtnamedata, trigname);
 	values[Anum_pg_event_trigger_evtname - 1] = NameGetDatum(&evtnamedata);
 	namestrcpy(&evteventdata, eventname);
@@ -1494,14 +1493,11 @@ pg_event_trigger_dropped_objects(PG_FUNCTION_ARGS)
 	{
 		SQLDropObject *obj;
 		int			i = 0;
-		Datum		values[12];
-		bool		nulls[12];
+		Datum		values[12] = INIT_ALL_ELEMS_ZERO;
+		bool		nulls[12] = INIT_ALL_ELEMS_ZERO;
 
 		obj = slist_container(SQLDropObject, next, iter.cur);
 
-		MemSet(values, 0, sizeof(values));
-		MemSet(nulls, 0, sizeof(nulls));
-
 		/* classid */
 		values[i++] = ObjectIdGetDatum(obj->address.classId);
 
@@ -2046,7 +2042,7 @@ pg_event_trigger_ddl_commands(PG_FUNCTION_ARGS)
 	{
 		CollectedCommand *cmd = lfirst(lc);
 		Datum		values[9];
-		bool		nulls[9];
+		bool		nulls[9] = INIT_ALL_ELEMS_ZERO;
 		ObjectAddress addr;
 		int			i = 0;
 
@@ -2064,8 +2060,6 @@ pg_event_trigger_ddl_commands(PG_FUNCTION_ARGS)
 			!OidIsValid(cmd->d.simple.address.objectId))
 			continue;
 
-		MemSet(nulls, 0, sizeof(nulls));
-
 		switch (cmd->type)
 		{
 			case SCT_Simple:
diff --git a/src/backend/commands/extension.c b/src/backend/commands/extension.c
index f7202cc..32f02f7 100644
--- a/src/backend/commands/extension.c
+++ b/src/backend/commands/extension.c
@@ -1771,8 +1771,8 @@ InsertExtensionTuple(const char *extName, Oid extOwner,
 {
 	Oid			extensionOid;
 	Relation	rel;
-	Datum		values[Natts_pg_extension];
-	bool		nulls[Natts_pg_extension];
+	Datum		values[Natts_pg_extension] = INIT_ALL_ELEMS_ZERO;
+	bool		nulls[Natts_pg_extension] = INIT_ALL_ELEMS_ZERO;
 	HeapTuple	tuple;
 	ObjectAddress myself;
 	ObjectAddress nsp;
@@ -1783,9 +1783,6 @@ InsertExtensionTuple(const char *extName, Oid extOwner,
 	 */
 	rel = table_open(ExtensionRelationId, RowExclusiveLock);
 
-	memset(values, 0, sizeof(values));
-	memset(nulls, 0, sizeof(nulls));
-
 	extensionOid = GetNewOidWithIndex(rel, ExtensionOidIndexId,
 									  Anum_pg_extension_oid);
 	values[Anum_pg_extension_oid - 1] = ObjectIdGetDatum(extensionOid);
@@ -1960,8 +1957,8 @@ pg_available_extensions(PG_FUNCTION_ARGS)
 		{
 			ExtensionControlFile *control;
 			char	   *extname;
-			Datum		values[3];
-			bool		nulls[3];
+			Datum		values[3] = INIT_ALL_ELEMS_ZERO;
+			bool		nulls[3] = INIT_ALL_ELEMS_ZERO;
 
 			if (!is_extension_control_filename(de->d_name))
 				continue;
@@ -1976,9 +1973,6 @@ pg_available_extensions(PG_FUNCTION_ARGS)
 
 			control = read_extension_control_file(extname);
 
-			memset(values, 0, sizeof(values));
-			memset(nulls, 0, sizeof(nulls));
-
 			/* name */
 			values[0] = DirectFunctionCall1(namein,
 											CStringGetDatum(control->name));
@@ -2117,8 +2111,8 @@ get_available_versions_for_extension(ExtensionControlFile *pcontrol,
 	{
 		ExtensionVersionInfo *evi = (ExtensionVersionInfo *) lfirst(lc);
 		ExtensionControlFile *control;
-		Datum		values[7];
-		bool		nulls[7];
+		Datum		values[7] = INIT_ALL_ELEMS_ZERO;
+		bool		nulls[7] = INIT_ALL_ELEMS_ZERO;
 		ListCell   *lc2;
 
 		if (!evi->installable)
@@ -2129,9 +2123,6 @@ get_available_versions_for_extension(ExtensionControlFile *pcontrol,
 		 */
 		control = read_extension_aux_control_file(pcontrol, evi->name);
 
-		memset(values, 0, sizeof(values));
-		memset(nulls, 0, sizeof(nulls));
-
 		/* name */
 		values[0] = DirectFunctionCall1(namein,
 										CStringGetDatum(control->name));
@@ -2292,8 +2283,8 @@ pg_extension_update_paths(PG_FUNCTION_ARGS)
 		{
 			ExtensionVersionInfo *evi2 = (ExtensionVersionInfo *) lfirst(lc2);
 			List	   *path;
-			Datum		values[3];
-			bool		nulls[3];
+			Datum		values[3] = INIT_ALL_ELEMS_ZERO;
+			bool		nulls[3] = INIT_ALL_ELEMS_ZERO;
 
 			if (evi1 == evi2)
 				continue;
@@ -2302,8 +2293,6 @@ pg_extension_update_paths(PG_FUNCTION_ARGS)
 			path = find_update_path(evi_list, evi1, evi2, false, true);
 
 			/* Emit result row */
-			memset(values, 0, sizeof(values));
-			memset(nulls, 0, sizeof(nulls));
 
 			/* source */
 			values[0] = CStringGetTextDatum(evi1->name);
@@ -3061,9 +3050,9 @@ ApplyExtensionUpdates(Oid extensionOid,
 		SysScanDesc extScan;
 		HeapTuple	extTup;
 		Form_pg_extension extForm;
-		Datum		values[Natts_pg_extension];
-		bool		nulls[Natts_pg_extension];
-		bool		repl[Natts_pg_extension];
+		Datum		values[Natts_pg_extension] = INIT_ALL_ELEMS_ZERO;
+		bool		nulls[Natts_pg_extension] = INIT_ALL_ELEMS_ZERO;
+		bool		repl[Natts_pg_extension] = INIT_ALL_ELEMS_ZERO;
 		ObjectAddress myself;
 		ListCell   *lc;
 
@@ -3100,10 +3089,6 @@ ApplyExtensionUpdates(Oid extensionOid,
 		/*
 		 * Modify extrelocatable and extversion in the pg_extension tuple
 		 */
-		memset(values, 0, sizeof(values));
-		memset(nulls, 0, sizeof(nulls));
-		memset(repl, 0, sizeof(repl));
-
 		values[Anum_pg_extension_extrelocatable - 1] =
 			BoolGetDatum(control->relocatable);
 		repl[Anum_pg_extension_extrelocatable - 1] = true;
diff --git a/src/backend/commands/foreigncmds.c b/src/backend/commands/foreigncmds.c
index f96c278..f320d04 100644
--- a/src/backend/commands/foreigncmds.c
+++ b/src/backend/commands/foreigncmds.c
@@ -563,8 +563,8 @@ ObjectAddress
 CreateForeignDataWrapper(CreateFdwStmt *stmt)
 {
 	Relation	rel;
-	Datum		values[Natts_pg_foreign_data_wrapper];
-	bool		nulls[Natts_pg_foreign_data_wrapper];
+	Datum		values[Natts_pg_foreign_data_wrapper] = INIT_ALL_ELEMS_ZERO;
+	bool		nulls[Natts_pg_foreign_data_wrapper] = INIT_ALL_ELEMS_ZERO;
 	HeapTuple	tuple;
 	Oid			fdwId;
 	bool		handler_given;
@@ -601,9 +601,6 @@ CreateForeignDataWrapper(CreateFdwStmt *stmt)
 	/*
 	 * Insert tuple into pg_foreign_data_wrapper.
 	 */
-	memset(values, 0, sizeof(values));
-	memset(nulls, false, sizeof(nulls));
-
 	fdwId = GetNewOidWithIndex(rel, ForeignDataWrapperOidIndexId,
 							   Anum_pg_foreign_data_wrapper_oid);
 	values[Anum_pg_foreign_data_wrapper_oid - 1] = ObjectIdGetDatum(fdwId);
@@ -868,8 +865,8 @@ CreateForeignServer(CreateForeignServerStmt *stmt)
 {
 	Relation	rel;
 	Datum		srvoptions;
-	Datum		values[Natts_pg_foreign_server];
-	bool		nulls[Natts_pg_foreign_server];
+	Datum		values[Natts_pg_foreign_server] = INIT_ALL_ELEMS_ZERO;
+	bool		nulls[Natts_pg_foreign_server] = INIT_ALL_ELEMS_ZERO;
 	HeapTuple	tuple;
 	Oid			srvId;
 	Oid			ownerId;
@@ -918,9 +915,6 @@ CreateForeignServer(CreateForeignServerStmt *stmt)
 	/*
 	 * Insert tuple into pg_foreign_server.
 	 */
-	memset(values, 0, sizeof(values));
-	memset(nulls, false, sizeof(nulls));
-
 	srvId = GetNewOidWithIndex(rel, ForeignServerOidIndexId,
 							   Anum_pg_foreign_server_oid);
 	values[Anum_pg_foreign_server_oid - 1] = ObjectIdGetDatum(srvId);
@@ -1145,8 +1139,8 @@ CreateUserMapping(CreateUserMappingStmt *stmt)
 {
 	Relation	rel;
 	Datum		useoptions;
-	Datum		values[Natts_pg_user_mapping];
-	bool		nulls[Natts_pg_user_mapping];
+	Datum		values[Natts_pg_user_mapping] = INIT_ALL_ELEMS_ZERO;
+	bool		nulls[Natts_pg_user_mapping] = INIT_ALL_ELEMS_ZERO;
 	HeapTuple	tuple;
 	Oid			useId;
 	Oid			umId;
@@ -1201,9 +1195,6 @@ CreateUserMapping(CreateUserMappingStmt *stmt)
 	/*
 	 * Insert tuple into pg_user_mapping.
 	 */
-	memset(values, 0, sizeof(values));
-	memset(nulls, false, sizeof(nulls));
-
 	umId = GetNewOidWithIndex(rel, UserMappingOidIndexId,
 							  Anum_pg_user_mapping_oid);
 	values[Anum_pg_user_mapping_oid - 1] = ObjectIdGetDatum(umId);
@@ -1465,8 +1456,8 @@ CreateForeignTable(CreateForeignTableStmt *stmt, Oid relid)
 {
 	Relation	ftrel;
 	Datum		ftoptions;
-	Datum		values[Natts_pg_foreign_table];
-	bool		nulls[Natts_pg_foreign_table];
+	Datum		values[Natts_pg_foreign_table] = INIT_ALL_ELEMS_ZERO;
+	bool		nulls[Natts_pg_foreign_table] = INIT_ALL_ELEMS_ZERO;
 	HeapTuple	tuple;
 	AclResult	aclresult;
 	ObjectAddress myself;
@@ -1502,9 +1493,6 @@ CreateForeignTable(CreateForeignTableStmt *stmt, Oid relid)
 	/*
 	 * Insert tuple into pg_foreign_table.
 	 */
-	memset(values, 0, sizeof(values));
-	memset(nulls, false, sizeof(nulls));
-
 	values[Anum_pg_foreign_table_ftrelid - 1] = ObjectIdGetDatum(relid);
 	values[Anum_pg_foreign_table_ftserver - 1] = ObjectIdGetDatum(server->serverid);
 	/* Add table generic options */
diff --git a/src/backend/commands/functioncmds.c b/src/backend/commands/functioncmds.c
index 40f1f9a..325d1f3 100644
--- a/src/backend/commands/functioncmds.c
+++ b/src/backend/commands/functioncmds.c
@@ -1504,7 +1504,7 @@ CreateCast(CreateCastStmt *stmt)
 	Relation	relation;
 	HeapTuple	tuple;
 	Datum		values[Natts_pg_cast];
-	bool		nulls[Natts_pg_cast];
+	bool		nulls[Natts_pg_cast] = INIT_ALL_ELEMS_ZERO;
 	ObjectAddress myself,
 				referenced;
 	AclResult	aclresult;
@@ -1757,8 +1757,6 @@ CreateCast(CreateCastStmt *stmt)
 	values[Anum_pg_cast_castcontext - 1] = CharGetDatum(castcontext);
 	values[Anum_pg_cast_castmethod - 1] = CharGetDatum(castmethod);
 
-	MemSet(nulls, false, sizeof(nulls));
-
 	tuple = heap_form_tuple(RelationGetDescr(relation), values, nulls);
 
 	CatalogTupleInsert(relation, tuple);
@@ -1893,8 +1891,8 @@ CreateTransform(CreateTransformStmt *stmt)
 	AclResult	aclresult;
 	Form_pg_proc procstruct;
 	Datum		values[Natts_pg_transform];
-	bool		nulls[Natts_pg_transform];
-	bool		replaces[Natts_pg_transform];
+	bool		nulls[Natts_pg_transform] = INIT_ALL_ELEMS_ZERO;
+	bool		replaces[Natts_pg_transform] = INIT_ALL_ELEMS_ZERO;
 	Oid			transformid;
 	HeapTuple	tuple;
 	HeapTuple	newtuple;
@@ -1999,8 +1997,6 @@ CreateTransform(CreateTransformStmt *stmt)
 	values[Anum_pg_transform_trffromsql - 1] = ObjectIdGetDatum(fromsqlfuncid);
 	values[Anum_pg_transform_trftosql - 1] = ObjectIdGetDatum(tosqlfuncid);
 
-	MemSet(nulls, false, sizeof(nulls));
-
 	relation = table_open(TransformRelationId, RowExclusiveLock);
 
 	tuple = SearchSysCache2(TRFTYPELANG,
@@ -2017,7 +2013,6 @@ CreateTransform(CreateTransformStmt *stmt)
 							format_type_be(typeid),
 							stmt->lang)));
 
-		MemSet(replaces, false, sizeof(replaces));
 		replaces[Anum_pg_transform_trffromsql - 1] = true;
 		replaces[Anum_pg_transform_trftosql - 1] = true;
 
diff --git a/src/backend/commands/opclasscmds.c b/src/backend/commands/opclasscmds.c
index 6a1ccde..a159770 100644
--- a/src/backend/commands/opclasscmds.c
+++ b/src/backend/commands/opclasscmds.c
@@ -248,8 +248,8 @@ CreateOpFamily(const char *amname, const char *opfname, Oid namespaceoid, Oid am
 	Oid			opfamilyoid;
 	Relation	rel;
 	HeapTuple	tup;
-	Datum		values[Natts_pg_opfamily];
-	bool		nulls[Natts_pg_opfamily];
+	Datum		values[Natts_pg_opfamily] = INIT_ALL_ELEMS_ZERO;
+	bool		nulls[Natts_pg_opfamily] = INIT_ALL_ELEMS_ZERO;
 	NameData	opfName;
 	ObjectAddress myself,
 				referenced;
@@ -272,9 +272,6 @@ CreateOpFamily(const char *amname, const char *opfname, Oid namespaceoid, Oid am
 	/*
 	 * Okay, let's create the pg_opfamily entry.
 	 */
-	memset(values, 0, sizeof(values));
-	memset(nulls, false, sizeof(nulls));
-
 	opfamilyoid = GetNewOidWithIndex(rel, OpfamilyOidIndexId,
 									 Anum_pg_opfamily_oid);
 	values[Anum_pg_opfamily_oid - 1] = ObjectIdGetDatum(opfamilyoid);
@@ -347,8 +344,8 @@ DefineOpClass(CreateOpClassStmt *stmt)
 	HeapTuple	tup;
 	Form_pg_am	amform;
 	IndexAmRoutine *amroutine;
-	Datum		values[Natts_pg_opclass];
-	bool		nulls[Natts_pg_opclass];
+	Datum		values[Natts_pg_opclass] = INIT_ALL_ELEMS_ZERO;
+	bool		nulls[Natts_pg_opclass] = INIT_ALL_ELEMS_ZERO;
 	AclResult	aclresult;
 	NameData	opcName;
 	ObjectAddress myself,
@@ -639,9 +636,6 @@ DefineOpClass(CreateOpClassStmt *stmt)
 	/*
 	 * Okay, let's create the pg_opclass entry.
 	 */
-	memset(values, 0, sizeof(values));
-	memset(nulls, false, sizeof(nulls));
-
 	opclassoid = GetNewOidWithIndex(rel, OpclassOidIndexId,
 									Anum_pg_opclass_oid);
 	values[Anum_pg_opclass_oid - 1] = ObjectIdGetDatum(opclassoid);
@@ -1308,8 +1302,8 @@ storeOperators(List *opfamilyname, Oid amoid,
 			   List *operators, bool isAdd)
 {
 	Relation	rel;
-	Datum		values[Natts_pg_amop];
-	bool		nulls[Natts_pg_amop];
+	Datum		values[Natts_pg_amop] = INIT_ALL_ELEMS_ZERO;
+	bool		nulls[Natts_pg_amop] = INIT_ALL_ELEMS_ZERO;
 	HeapTuple	tup;
 	Oid			entryoid;
 	ObjectAddress myself,
@@ -1344,8 +1338,6 @@ storeOperators(List *opfamilyname, Oid amoid,
 		oppurpose = OidIsValid(op->sortfamily) ? AMOP_ORDER : AMOP_SEARCH;
 
 		/* Create the pg_amop entry */
-		memset(values, 0, sizeof(values));
-		memset(nulls, false, sizeof(nulls));
 
 		entryoid = GetNewOidWithIndex(rel, AccessMethodOperatorOidIndexId,
 									  Anum_pg_amop_oid);
@@ -1426,8 +1418,8 @@ storeProcedures(List *opfamilyname, Oid amoid,
 				List *procedures, bool isAdd)
 {
 	Relation	rel;
-	Datum		values[Natts_pg_amproc];
-	bool		nulls[Natts_pg_amproc];
+	Datum		values[Natts_pg_amproc] = INIT_ALL_ELEMS_ZERO;
+	bool		nulls[Natts_pg_amproc] = INIT_ALL_ELEMS_ZERO;
 	HeapTuple	tup;
 	Oid			entryoid;
 	ObjectAddress myself,
@@ -1459,9 +1451,6 @@ storeProcedures(List *opfamilyname, Oid amoid,
 							NameListToString(opfamilyname))));
 
 		/* Create the pg_amproc entry */
-		memset(values, 0, sizeof(values));
-		memset(nulls, false, sizeof(nulls));
-
 		entryoid = GetNewOidWithIndex(rel, AccessMethodProcedureOidIndexId,
 									  Anum_pg_amproc_oid);
 		values[Anum_pg_amproc_oid - 1] = ObjectIdGetDatum(entryoid);
diff --git a/src/backend/commands/prepare.c b/src/backend/commands/prepare.c
index 7e0a041..c86c409a 100644
--- a/src/backend/commands/prepare.c
+++ b/src/backend/commands/prepare.c
@@ -757,9 +757,7 @@ pg_prepared_statement(PG_FUNCTION_ARGS)
 		while ((prep_stmt = hash_seq_search(&hash_seq)) != NULL)
 		{
 			Datum		values[5];
-			bool		nulls[5];
-
-			MemSet(nulls, 0, sizeof(nulls));
+			bool		nulls[5] = INIT_ALL_ELEMS_ZERO;
 
 			values[0] = CStringGetTextDatum(prep_stmt->stmt_name);
 			values[1] = CStringGetTextDatum(prep_stmt->plansource->query_string);
diff --git a/src/backend/commands/proclang.c b/src/backend/commands/proclang.c
index 343cd1d..ffaf0c0 100644
--- a/src/backend/commands/proclang.c
+++ b/src/backend/commands/proclang.c
@@ -325,8 +325,8 @@ create_proc_lang(const char *languageName, bool replace,
 {
 	Relation	rel;
 	TupleDesc	tupDesc;
-	Datum		values[Natts_pg_language];
-	bool		nulls[Natts_pg_language];
+	Datum		values[Natts_pg_language] = INIT_ALL_ELEMS_ZERO;
+	bool		nulls[Natts_pg_language] = INIT_ALL_ELEMS_ZERO;
 	bool		replaces[Natts_pg_language];
 	NameData	langname;
 	HeapTuple	oldtup;
@@ -340,8 +340,6 @@ create_proc_lang(const char *languageName, bool replace,
 	tupDesc = RelationGetDescr(rel);
 
 	/* Prepare data to be inserted */
-	memset(values, 0, sizeof(values));
-	memset(nulls, false, sizeof(nulls));
 	memset(replaces, true, sizeof(replaces));
 
 	namestrcpy(&langname, languageName);
diff --git a/src/backend/commands/publicationcmds.c b/src/backend/commands/publicationcmds.c
index f115d4b..3d8c9ee 100644
--- a/src/backend/commands/publicationcmds.c
+++ b/src/backend/commands/publicationcmds.c
@@ -142,8 +142,8 @@ CreatePublication(CreatePublicationStmt *stmt)
 	Relation	rel;
 	ObjectAddress myself;
 	Oid			puboid;
-	bool		nulls[Natts_pg_publication];
-	Datum		values[Natts_pg_publication];
+	bool		nulls[Natts_pg_publication] = INIT_ALL_ELEMS_ZERO;
+	Datum		values[Natts_pg_publication] = INIT_ALL_ELEMS_ZERO;
 	HeapTuple	tup;
 	bool		publish_given;
 	bool		publish_insert;
@@ -178,9 +178,6 @@ CreatePublication(CreatePublicationStmt *stmt)
 	}
 
 	/* Form a tuple. */
-	memset(values, 0, sizeof(values));
-	memset(nulls, false, sizeof(nulls));
-
 	values[Anum_pg_publication_pubname - 1] =
 		DirectFunctionCall1(namein, CStringGetDatum(stmt->pubname));
 	values[Anum_pg_publication_pubowner - 1] = ObjectIdGetDatum(GetUserId());
@@ -250,9 +247,9 @@ static void
 AlterPublicationOptions(AlterPublicationStmt *stmt, Relation rel,
 						HeapTuple tup)
 {
-	bool		nulls[Natts_pg_publication];
-	bool		replaces[Natts_pg_publication];
-	Datum		values[Natts_pg_publication];
+	bool		nulls[Natts_pg_publication] = INIT_ALL_ELEMS_ZERO;
+	bool		replaces[Natts_pg_publication] = INIT_ALL_ELEMS_ZERO;
+	Datum		values[Natts_pg_publication] = INIT_ALL_ELEMS_ZERO;
 	bool		publish_given;
 	bool		publish_insert;
 	bool		publish_update;
@@ -267,10 +264,6 @@ AlterPublicationOptions(AlterPublicationStmt *stmt, Relation rel,
 							  &publish_truncate);
 
 	/* Everything ok, form a new tuple. */
-	memset(values, 0, sizeof(values));
-	memset(nulls, false, sizeof(nulls));
-	memset(replaces, false, sizeof(replaces));
-
 	if (publish_given)
 	{
 		values[Anum_pg_publication_pubinsert - 1] = BoolGetDatum(publish_insert);
diff --git a/src/backend/commands/seclabel.c b/src/backend/commands/seclabel.c
index 63219ad..2dfa2d3 100644
--- a/src/backend/commands/seclabel.c
+++ b/src/backend/commands/seclabel.c
@@ -258,12 +258,10 @@ SetSharedSecurityLabel(const ObjectAddress *object,
 	HeapTuple	oldtup;
 	HeapTuple	newtup = NULL;
 	Datum		values[Natts_pg_shseclabel];
-	bool		nulls[Natts_pg_shseclabel];
-	bool		replaces[Natts_pg_shseclabel];
+	bool		nulls[Natts_pg_shseclabel] = INIT_ALL_ELEMS_ZERO;
+	bool		replaces[Natts_pg_shseclabel] = INIT_ALL_ELEMS_ZERO;
 
 	/* Prepare to form or update a tuple, if necessary. */
-	memset(nulls, false, sizeof(nulls));
-	memset(replaces, false, sizeof(replaces));
 	values[Anum_pg_shseclabel_objoid - 1] = ObjectIdGetDatum(object->objectId);
 	values[Anum_pg_shseclabel_classoid - 1] = ObjectIdGetDatum(object->classId);
 	values[Anum_pg_shseclabel_provider - 1] = CStringGetTextDatum(provider);
@@ -333,8 +331,8 @@ SetSecurityLabel(const ObjectAddress *object,
 	HeapTuple	oldtup;
 	HeapTuple	newtup = NULL;
 	Datum		values[Natts_pg_seclabel];
-	bool		nulls[Natts_pg_seclabel];
-	bool		replaces[Natts_pg_seclabel];
+	bool		nulls[Natts_pg_seclabel] = INIT_ALL_ELEMS_ZERO;
+	bool		replaces[Natts_pg_seclabel] = INIT_ALL_ELEMS_ZERO;
 
 	/* Shared objects have their own security label catalog. */
 	if (IsSharedRelation(object->classId))
@@ -344,8 +342,6 @@ SetSecurityLabel(const ObjectAddress *object,
 	}
 
 	/* Prepare to form or update a tuple, if necessary. */
-	memset(nulls, false, sizeof(nulls));
-	memset(replaces, false, sizeof(replaces));
 	values[Anum_pg_seclabel_objoid - 1] = ObjectIdGetDatum(object->objectId);
 	values[Anum_pg_seclabel_classoid - 1] = ObjectIdGetDatum(object->classId);
 	values[Anum_pg_seclabel_objsubid - 1] = Int32GetDatum(object->objectSubId);
diff --git a/src/backend/commands/statscmds.c b/src/backend/commands/statscmds.c
index f51eb7b..c0579ab 100644
--- a/src/backend/commands/statscmds.c
+++ b/src/backend/commands/statscmds.c
@@ -69,10 +69,10 @@ CreateStatistics(CreateStatsStmt *stmt)
 	Oid			namespaceId;
 	Oid			stxowner = GetUserId();
 	HeapTuple	htup;
-	Datum		values[Natts_pg_statistic_ext];
-	bool		nulls[Natts_pg_statistic_ext];
-	Datum		datavalues[Natts_pg_statistic_ext_data];
-	bool		datanulls[Natts_pg_statistic_ext_data];
+	Datum		values[Natts_pg_statistic_ext] = INIT_ALL_ELEMS_ZERO;
+	bool		nulls[Natts_pg_statistic_ext] = INIT_ALL_ELEMS_ZERO;
+	Datum		datavalues[Natts_pg_statistic_ext_data] = INIT_ALL_ELEMS_ZERO;
+	bool		datanulls[Natts_pg_statistic_ext_data] = INIT_ALL_ELEMS_ZERO;
 	int2vector *stxkeys;
 	Relation	statrel;
 	Relation	datarel;
@@ -330,9 +330,6 @@ CreateStatistics(CreateStatsStmt *stmt)
 	/*
 	 * Everything seems fine, so let's build the pg_statistic_ext tuple.
 	 */
-	memset(values, 0, sizeof(values));
-	memset(nulls, false, sizeof(nulls));
-
 	statoid = GetNewOidWithIndex(statrel, StatisticExtOidIndexId,
 								 Anum_pg_statistic_ext_oid);
 	values[Anum_pg_statistic_ext_oid - 1] = ObjectIdGetDatum(statoid);
@@ -357,9 +354,6 @@ CreateStatistics(CreateStatsStmt *stmt)
 	 */
 	datarel = table_open(StatisticExtDataRelationId, RowExclusiveLock);
 
-	memset(datavalues, 0, sizeof(datavalues));
-	memset(datanulls, false, sizeof(datanulls));
-
 	datavalues[Anum_pg_statistic_ext_data_stxoid - 1] = ObjectIdGetDatum(statoid);
 
 	/* no statistics built yet */
@@ -607,9 +601,9 @@ UpdateStatisticsForTypeChange(Oid statsOid, Oid relationOid, int attnum,
 
 	Relation	rel;
 
-	Datum		values[Natts_pg_statistic_ext_data];
-	bool		nulls[Natts_pg_statistic_ext_data];
-	bool		replaces[Natts_pg_statistic_ext_data];
+	Datum		values[Natts_pg_statistic_ext_data] = INIT_ALL_ELEMS_ZERO;
+	bool		nulls[Natts_pg_statistic_ext_data] = INIT_ALL_ELEMS_ZERO;
+	bool		replaces[Natts_pg_statistic_ext_data] = INIT_ALL_ELEMS_ZERO;
 
 	oldtup = SearchSysCache1(STATEXTDATASTXOID, ObjectIdGetDatum(statsOid));
 	if (!HeapTupleIsValid(oldtup))
@@ -630,10 +624,6 @@ UpdateStatisticsForTypeChange(Oid statsOid, Oid relationOid, int attnum,
 	 * OK, we need to reset some statistics. So let's build the new tuple,
 	 * replacing the affected statistics types with NULL.
 	 */
-	memset(nulls, 0, Natts_pg_statistic_ext_data * sizeof(bool));
-	memset(replaces, 0, Natts_pg_statistic_ext_data * sizeof(bool));
-	memset(values, 0, Natts_pg_statistic_ext_data * sizeof(Datum));
-
 	replaces[Anum_pg_statistic_ext_data_stxdmcv - 1] = true;
 	nulls[Anum_pg_statistic_ext_data_stxdmcv - 1] = true;
 
diff --git a/src/backend/commands/subscriptioncmds.c b/src/backend/commands/subscriptioncmds.c
index 2e67a58..07c3e31 100644
--- a/src/backend/commands/subscriptioncmds.c
+++ b/src/backend/commands/subscriptioncmds.c
@@ -317,8 +317,8 @@ CreateSubscription(CreateSubscriptionStmt *stmt, bool isTopLevel)
 	Relation	rel;
 	ObjectAddress myself;
 	Oid			subid;
-	bool		nulls[Natts_pg_subscription];
-	Datum		values[Natts_pg_subscription];
+	bool		nulls[Natts_pg_subscription] = INIT_ALL_ELEMS_ZERO;
+	Datum		values[Natts_pg_subscription] = INIT_ALL_ELEMS_ZERO;
 	Oid			owner = GetUserId();
 	HeapTuple	tup;
 	bool		connect;
@@ -396,9 +396,6 @@ CreateSubscription(CreateSubscriptionStmt *stmt, bool isTopLevel)
 	walrcv_check_conninfo(conninfo);
 
 	/* Everything ok, form a new tuple. */
-	memset(values, 0, sizeof(values));
-	memset(nulls, false, sizeof(nulls));
-
 	subid = GetNewOidWithIndex(rel, SubscriptionObjectIndexId,
 							   Anum_pg_subscription_oid);
 	values[Anum_pg_subscription_oid - 1] = ObjectIdGetDatum(subid);
@@ -636,9 +633,9 @@ AlterSubscription(AlterSubscriptionStmt *stmt)
 {
 	Relation	rel;
 	ObjectAddress myself;
-	bool		nulls[Natts_pg_subscription];
-	bool		replaces[Natts_pg_subscription];
-	Datum		values[Natts_pg_subscription];
+	bool		nulls[Natts_pg_subscription] = INIT_ALL_ELEMS_ZERO;
+	bool		replaces[Natts_pg_subscription] = INIT_ALL_ELEMS_ZERO;
+	Datum		values[Natts_pg_subscription] = INIT_ALL_ELEMS_ZERO;
 	HeapTuple	tup;
 	Oid			subid;
 	bool		update_tuple = false;
@@ -671,9 +668,6 @@ AlterSubscription(AlterSubscriptionStmt *stmt)
 	LockSharedObject(SubscriptionRelationId, subid, 0, AccessExclusiveLock);
 
 	/* Form a new tuple. */
-	memset(values, 0, sizeof(values));
-	memset(nulls, false, sizeof(nulls));
-	memset(replaces, false, sizeof(replaces));
 
 	switch (stmt->kind)
 	{
diff --git a/src/backend/commands/tablespace.c b/src/backend/commands/tablespace.c
index 84efb41..e4ee847 100644
--- a/src/backend/commands/tablespace.c
+++ b/src/backend/commands/tablespace.c
@@ -236,7 +236,7 @@ CreateTableSpace(CreateTableSpaceStmt *stmt)
 #ifdef HAVE_SYMLINK
 	Relation	rel;
 	Datum		values[Natts_pg_tablespace];
-	bool		nulls[Natts_pg_tablespace];
+	bool		nulls[Natts_pg_tablespace] = INIT_ALL_ELEMS_ZERO;
 	HeapTuple	tuple;
 	Oid			tablespaceoid;
 	char	   *location;
@@ -334,8 +334,6 @@ CreateTableSpace(CreateTableSpaceStmt *stmt)
 	 */
 	rel = table_open(TableSpaceRelationId, RowExclusiveLock);
 
-	MemSet(nulls, false, sizeof(nulls));
-
 	tablespaceoid = GetNewOidWithIndex(rel, TablespaceOidIndexId,
 									   Anum_pg_tablespace_oid);
 	values[Anum_pg_tablespace_oid - 1] = ObjectIdGetDatum(tablespaceoid);
diff --git a/src/backend/commands/trigger.c b/src/backend/commands/trigger.c
index 7ba859d..79b1a8d 100644
--- a/src/backend/commands/trigger.c
+++ b/src/backend/commands/trigger.c
@@ -171,7 +171,7 @@ CreateTrigger(CreateTrigStmt *stmt, const char *queryString,
 	List	   *whenRtable;
 	char	   *qual;
 	Datum		values[Natts_pg_trigger];
-	bool		nulls[Natts_pg_trigger];
+	bool		nulls[Natts_pg_trigger] = INIT_ALL_ELEMS_ZERO;
 	Relation	rel;
 	AclResult	aclresult;
 	Relation	tgrel;
@@ -844,8 +844,6 @@ CreateTrigger(CreateTrigStmt *stmt, const char *queryString,
 	 * makes the triggers in partitions identical to the ones in the
 	 * partitioned tables, except that they are marked internal.
 	 */
-	memset(nulls, false, sizeof(nulls));
-
 	values[Anum_pg_trigger_oid - 1] = ObjectIdGetDatum(trigoid);
 	values[Anum_pg_trigger_tgrelid - 1] = ObjectIdGetDatum(RelationGetRelid(rel));
 	values[Anum_pg_trigger_tgname - 1] = DirectFunctionCall1(namein,
diff --git a/src/backend/commands/tsearchcmds.c b/src/backend/commands/tsearchcmds.c
index 5d6528f..99f66bc 100644
--- a/src/backend/commands/tsearchcmds.c
+++ b/src/backend/commands/tsearchcmds.c
@@ -179,8 +179,8 @@ DefineTSParser(List *names, List *parameters)
 	ListCell   *pl;
 	Relation	prsRel;
 	HeapTuple	tup;
-	Datum		values[Natts_pg_ts_parser];
-	bool		nulls[Natts_pg_ts_parser];
+	Datum		values[Natts_pg_ts_parser] = INIT_ALL_ELEMS_ZERO;
+	bool		nulls[Natts_pg_ts_parser] = INIT_ALL_ELEMS_ZERO;
 	NameData	pname;
 	Oid			prsOid;
 	Oid			namespaceoid;
@@ -197,9 +197,6 @@ DefineTSParser(List *names, List *parameters)
 	namespaceoid = QualifiedNameGetCreationNamespace(names, &prsname);
 
 	/* initialize tuple fields with name/namespace */
-	memset(values, 0, sizeof(values));
-	memset(nulls, false, sizeof(nulls));
-
 	prsOid = GetNewOidWithIndex(prsRel, TSParserOidIndexId,
 								Anum_pg_ts_parser_oid);
 	values[Anum_pg_ts_parser_oid - 1] = ObjectIdGetDatum(prsOid);
@@ -414,8 +411,8 @@ DefineTSDictionary(List *names, List *parameters)
 	ListCell   *pl;
 	Relation	dictRel;
 	HeapTuple	tup;
-	Datum		values[Natts_pg_ts_dict];
-	bool		nulls[Natts_pg_ts_dict];
+	Datum		values[Natts_pg_ts_dict] = INIT_ALL_ELEMS_ZERO;
+	bool		nulls[Natts_pg_ts_dict] = INIT_ALL_ELEMS_ZERO;
 	NameData	dname;
 	Oid			templId = InvalidOid;
 	List	   *dictoptions = NIL;
@@ -468,9 +465,6 @@ DefineTSDictionary(List *names, List *parameters)
 	/*
 	 * Looks good, insert
 	 */
-	memset(values, 0, sizeof(values));
-	memset(nulls, false, sizeof(nulls));
-
 	dictOid = GetNewOidWithIndex(dictRel, TSDictionaryOidIndexId,
 								 Anum_pg_ts_dict_oid);
 	values[Anum_pg_ts_dict_oid - 1] = ObjectIdGetDatum(dictOid);
@@ -733,7 +727,7 @@ DefineTSTemplate(List *names, List *parameters)
 	Relation	tmplRel;
 	HeapTuple	tup;
 	Datum		values[Natts_pg_ts_template];
-	bool		nulls[Natts_pg_ts_template];
+	bool		nulls[Natts_pg_ts_template] = INIT_ALL_ELEMS_ZERO;
 	NameData	dname;
 	int			i;
 	Oid			tmplOid;
@@ -753,7 +747,6 @@ DefineTSTemplate(List *names, List *parameters)
 
 	for (i = 0; i < Natts_pg_ts_template; i++)
 	{
-		nulls[i] = false;
 		values[i] = ObjectIdGetDatum(InvalidOid);
 	}
 
@@ -965,8 +958,8 @@ DefineTSConfiguration(List *names, List *parameters, ObjectAddress *copied)
 	Relation	cfgRel;
 	Relation	mapRel = NULL;
 	HeapTuple	tup;
-	Datum		values[Natts_pg_ts_config];
-	bool		nulls[Natts_pg_ts_config];
+	Datum		values[Natts_pg_ts_config] = INIT_ALL_ELEMS_ZERO;
+	bool		nulls[Natts_pg_ts_config] = INIT_ALL_ELEMS_ZERO;
 	AclResult	aclresult;
 	Oid			namespaceoid;
 	char	   *cfgname;
@@ -1050,9 +1043,6 @@ DefineTSConfiguration(List *names, List *parameters, ObjectAddress *copied)
 	/*
 	 * Looks good, build tuple and insert
 	 */
-	memset(values, 0, sizeof(values));
-	memset(nulls, false, sizeof(nulls));
-
 	cfgOid = GetNewOidWithIndex(cfgRel, TSConfigOidIndexId,
 								Anum_pg_ts_config_oid);
 	values[Anum_pg_ts_config_oid - 1] = ObjectIdGetDatum(cfgOid);
@@ -1089,11 +1079,8 @@ DefineTSConfiguration(List *names, List *parameters, ObjectAddress *copied)
 		{
 			Form_pg_ts_config_map cfgmap = (Form_pg_ts_config_map) GETSTRUCT(maptup);
 			HeapTuple	newmaptup;
-			Datum		mapvalues[Natts_pg_ts_config_map];
-			bool		mapnulls[Natts_pg_ts_config_map];
-
-			memset(mapvalues, 0, sizeof(mapvalues));
-			memset(mapnulls, false, sizeof(mapnulls));
+			Datum		mapvalues[Natts_pg_ts_config_map] = INIT_ALL_ELEMS_ZERO;
+			bool		mapnulls[Natts_pg_ts_config_map] = INIT_ALL_ELEMS_ZERO;
 
 			mapvalues[Anum_pg_ts_config_map_mapcfg - 1] = cfgOid;
 			mapvalues[Anum_pg_ts_config_map_maptokentype - 1] = cfgmap->maptokentype;
@@ -1420,9 +1407,8 @@ MakeConfigurationMapping(AlterTSConfigurationStmt *stmt,
 			for (j = 0; j < ndict; j++)
 			{
 				Datum		values[Natts_pg_ts_config_map];
-				bool		nulls[Natts_pg_ts_config_map];
+				bool		nulls[Natts_pg_ts_config_map] = INIT_ALL_ELEMS_ZERO;
 
-				memset(nulls, false, sizeof(nulls));
 				values[Anum_pg_ts_config_map_mapcfg - 1] = ObjectIdGetDatum(cfgId);
 				values[Anum_pg_ts_config_map_maptokentype - 1] = Int32GetDatum(tokens[i]);
 				values[Anum_pg_ts_config_map_mapseqno - 1] = Int32GetDatum(j + 1);
diff --git a/src/backend/libpq/hba.c b/src/backend/libpq/hba.c
index 2221c04..1e59c49 100644
--- a/src/backend/libpq/hba.c
+++ b/src/backend/libpq/hba.c
@@ -2414,8 +2414,8 @@ static void
 fill_hba_line(Tuplestorestate *tuple_store, TupleDesc tupdesc,
 			  int lineno, HbaLine *hba, const char *err_msg)
 {
-	Datum		values[NUM_PG_HBA_FILE_RULES_ATTS];
-	bool		nulls[NUM_PG_HBA_FILE_RULES_ATTS];
+	Datum		values[NUM_PG_HBA_FILE_RULES_ATTS] = INIT_ALL_ELEMS_ZERO;
+	bool		nulls[NUM_PG_HBA_FILE_RULES_ATTS] = INIT_ALL_ELEMS_ZERO;
 	char		buffer[NI_MAXHOST];
 	HeapTuple	tuple;
 	int			index;
@@ -2427,8 +2427,6 @@ fill_hba_line(Tuplestorestate *tuple_store, TupleDesc tupdesc,
 
 	Assert(tupdesc->natts == NUM_PG_HBA_FILE_RULES_ATTS);
 
-	memset(values, 0, sizeof(values));
-	memset(nulls, 0, sizeof(nulls));
 	index = 0;
 
 	/* line_number */
diff --git a/src/backend/replication/logical/launcher.c b/src/backend/replication/logical/launcher.c
index 186057b..c247dbd 100644
--- a/src/backend/replication/logical/launcher.c
+++ b/src/backend/replication/logical/launcher.c
@@ -1136,8 +1136,8 @@ pg_stat_get_subscription(PG_FUNCTION_ARGS)
 	for (i = 0; i <= max_logical_replication_workers; i++)
 	{
 		/* for each row */
-		Datum		values[PG_STAT_GET_SUBSCRIPTION_COLS];
-		bool		nulls[PG_STAT_GET_SUBSCRIPTION_COLS];
+		Datum		values[PG_STAT_GET_SUBSCRIPTION_COLS] = INIT_ALL_ELEMS_ZERO;
+		bool		nulls[PG_STAT_GET_SUBSCRIPTION_COLS] = INIT_ALL_ELEMS_ZERO;
 		int			worker_pid;
 		LogicalRepWorker worker;
 
@@ -1151,9 +1151,6 @@ pg_stat_get_subscription(PG_FUNCTION_ARGS)
 
 		worker_pid = worker.proc->pid;
 
-		MemSet(values, 0, sizeof(values));
-		MemSet(nulls, 0, sizeof(nulls));
-
 		values[0] = ObjectIdGetDatum(worker.subid);
 		if (OidIsValid(worker.relid))
 			values[1] = ObjectIdGetDatum(worker.relid);
diff --git a/src/backend/replication/logical/logicalfuncs.c b/src/backend/replication/logical/logicalfuncs.c
index d1cf80d..b0294f2 100644
--- a/src/backend/replication/logical/logicalfuncs.c
+++ b/src/backend/replication/logical/logicalfuncs.c
@@ -75,7 +75,7 @@ LogicalOutputWrite(LogicalDecodingContext *ctx, XLogRecPtr lsn, TransactionId xi
 				   bool last_write)
 {
 	Datum		values[3];
-	bool		nulls[3];
+	bool		nulls[3] = INIT_ALL_ELEMS_ZERO;
 	DecodingOutputState *p;
 
 	/* SQL Datums can only be of a limited length... */
@@ -84,7 +84,6 @@ LogicalOutputWrite(LogicalDecodingContext *ctx, XLogRecPtr lsn, TransactionId xi
 
 	p = (DecodingOutputState *) ctx->output_writer_private;
 
-	memset(nulls, 0, sizeof(nulls));
 	values[0] = LSNGetDatum(lsn);
 	values[1] = TransactionIdGetDatum(xid);
 
diff --git a/src/backend/replication/logical/origin.c b/src/backend/replication/logical/origin.c
index 07ae613..6d05dd4 100644
--- a/src/backend/replication/logical/origin.c
+++ b/src/backend/replication/logical/origin.c
@@ -275,7 +275,7 @@ replorigin_create(char *roname)
 
 	for (roident = InvalidOid + 1; roident < PG_UINT16_MAX; roident++)
 	{
-		bool		nulls[Natts_pg_replication_origin];
+		bool		nulls[Natts_pg_replication_origin] = INIT_ALL_ELEMS_ZERO;
 		Datum		values[Natts_pg_replication_origin];
 		bool		collides;
 
@@ -301,8 +301,6 @@ replorigin_create(char *roname)
 			 * Ok, found an unused roident, insert the new row and do a CCI,
 			 * so our callers can look it up if they want to.
 			 */
-			memset(&nulls, 0, sizeof(nulls));
-
 			values[Anum_pg_replication_origin_roident - 1] = ObjectIdGetDatum(roident);
 			values[Anum_pg_replication_origin_roname - 1] = roname_d;
 
@@ -1517,7 +1515,7 @@ pg_show_replication_origin_status(PG_FUNCTION_ARGS)
 	for (i = 0; i < max_replication_slots; i++)
 	{
 		ReplicationState *state;
-		Datum		values[REPLICATION_ORIGIN_PROGRESS_COLS];
+		Datum		values[REPLICATION_ORIGIN_PROGRESS_COLS] = INIT_ALL_ELEMS_ZERO;
 		bool		nulls[REPLICATION_ORIGIN_PROGRESS_COLS];
 		char	   *roname;
 
@@ -1527,7 +1525,6 @@ pg_show_replication_origin_status(PG_FUNCTION_ARGS)
 		if (state->roident == InvalidRepOriginId)
 			continue;
 
-		memset(values, 0, sizeof(values));
 		memset(nulls, 1, sizeof(nulls));
 
 		values[0] = ObjectIdGetDatum(state->roident);
diff --git a/src/backend/replication/slotfuncs.c b/src/backend/replication/slotfuncs.c
index 42da631..f8cfb40 100644
--- a/src/backend/replication/slotfuncs.c
+++ b/src/backend/replication/slotfuncs.c
@@ -77,7 +77,7 @@ pg_create_physical_replication_slot(PG_FUNCTION_ARGS)
 	bool		immediately_reserve = PG_GETARG_BOOL(1);
 	bool		temporary = PG_GETARG_BOOL(2);
 	Datum		values[2];
-	bool		nulls[2];
+	bool		nulls[2] = INIT_ALL_ELEMS_ZERO;
 	TupleDesc	tupdesc;
 	HeapTuple	tuple;
 	Datum		result;
@@ -95,12 +95,10 @@ pg_create_physical_replication_slot(PG_FUNCTION_ARGS)
 									 InvalidXLogRecPtr);
 
 	values[0] = NameGetDatum(&MyReplicationSlot->data.name);
-	nulls[0] = false;
 
 	if (immediately_reserve)
 	{
 		values[1] = LSNGetDatum(MyReplicationSlot->data.restart_lsn);
-		nulls[1] = false;
 	}
 	else
 		nulls[1] = true;
@@ -167,7 +165,7 @@ pg_create_logical_replication_slot(PG_FUNCTION_ARGS)
 	TupleDesc	tupdesc;
 	HeapTuple	tuple;
 	Datum		values[2];
-	bool		nulls[2];
+	bool		nulls[2] = INIT_ALL_ELEMS_ZERO;
 
 	if (get_call_result_type(fcinfo, NULL, &tupdesc) != TYPEFUNC_COMPOSITE)
 		elog(ERROR, "return type must be a row type");
@@ -184,8 +182,6 @@ pg_create_logical_replication_slot(PG_FUNCTION_ARGS)
 	values[0] = NameGetDatum(&MyReplicationSlot->data.name);
 	values[1] = LSNGetDatum(MyReplicationSlot->data.confirmed_flush);
 
-	memset(nulls, 0, sizeof(nulls));
-
 	tuple = heap_form_tuple(tupdesc, values, nulls);
 	result = HeapTupleGetDatum(tuple);
 
@@ -265,7 +261,7 @@ pg_get_replication_slots(PG_FUNCTION_ARGS)
 	{
 		ReplicationSlot *slot = &ReplicationSlotCtl->replication_slots[slotno];
 		Datum		values[PG_GET_REPLICATION_SLOTS_COLS];
-		bool		nulls[PG_GET_REPLICATION_SLOTS_COLS];
+		bool		nulls[PG_GET_REPLICATION_SLOTS_COLS] = INIT_ALL_ELEMS_ZERO;
 
 		ReplicationSlotPersistency persistency;
 		TransactionId xmin;
@@ -295,8 +291,6 @@ pg_get_replication_slots(PG_FUNCTION_ARGS)
 
 		SpinLockRelease(&slot->mutex);
 
-		memset(nulls, 0, sizeof(nulls));
-
 		i = 0;
 		values[i++] = NameGetDatum(&slot_name);
 
@@ -513,7 +507,7 @@ pg_replication_slot_advance(PG_FUNCTION_ARGS)
 	XLogRecPtr	minlsn;
 	TupleDesc	tupdesc;
 	Datum		values[2];
-	bool		nulls[2];
+	bool		nulls[2] = INIT_ALL_ELEMS_ZERO;
 	HeapTuple	tuple;
 	Datum		result;
 
@@ -572,7 +566,6 @@ pg_replication_slot_advance(PG_FUNCTION_ARGS)
 		endlsn = pg_physical_replication_slot_advance(moveto);
 
 	values[0] = NameGetDatum(&MyReplicationSlot->data.name);
-	nulls[0] = false;
 
 	/* Update the on disk state when lsn was updated. */
 	if (XLogRecPtrIsInvalid(endlsn))
@@ -587,7 +580,6 @@ pg_replication_slot_advance(PG_FUNCTION_ARGS)
 
 	/* Return the reached position. */
 	values[1] = LSNGetDatum(endlsn);
-	nulls[1] = false;
 
 	tuple = heap_form_tuple(tupdesc, values, nulls);
 	result = HeapTupleGetDatum(tuple);
@@ -609,7 +601,7 @@ copy_replication_slot(FunctionCallInfo fcinfo, bool logical_slot)
 	bool		temporary;
 	char	   *plugin;
 	Datum		values[2];
-	bool		nulls[2];
+	bool		nulls[2] = INIT_ALL_ELEMS_ZERO;
 	Datum		result;
 	TupleDesc	tupdesc;
 	HeapTuple	tuple;
@@ -779,11 +771,9 @@ copy_replication_slot(FunctionCallInfo fcinfo, bool logical_slot)
 
 	/* All done.  Set up the return values */
 	values[0] = NameGetDatum(dst_name);
-	nulls[0] = false;
 	if (!XLogRecPtrIsInvalid(MyReplicationSlot->data.confirmed_flush))
 	{
 		values[1] = LSNGetDatum(MyReplicationSlot->data.confirmed_flush);
-		nulls[1] = false;
 	}
 	else
 		nulls[1] = true;
diff --git a/src/backend/replication/walsender.c b/src/backend/replication/walsender.c
index eb4a98c..40e1a76 100644
--- a/src/backend/replication/walsender.c
+++ b/src/backend/replication/walsender.c
@@ -351,7 +351,7 @@ IdentifySystem(void)
 	TupOutputState *tstate;
 	TupleDesc	tupdesc;
 	Datum		values[4];
-	bool		nulls[4];
+	bool		nulls[4] = INIT_ALL_ELEMS_ZERO;
 
 	/*
 	 * Reply with a result set with one row, four columns. First col is system
@@ -388,7 +388,6 @@ IdentifySystem(void)
 	}
 
 	dest = CreateDestReceiver(DestRemoteSimple);
-	MemSet(nulls, false, sizeof(nulls));
 
 	/* need a tuple descriptor representing four columns */
 	tupdesc = CreateTemplateTupleDesc(4);
@@ -717,14 +716,13 @@ StartReplication(StartReplicationCmd *cmd)
 		TupOutputState *tstate;
 		TupleDesc	tupdesc;
 		Datum		values[2];
-		bool		nulls[2];
+		bool		nulls[2] = INIT_ALL_ELEMS_ZERO;
 
 		snprintf(startpos_str, sizeof(startpos_str), "%X/%X",
 				 (uint32) (sendTimeLineValidUpto >> 32),
 				 (uint32) sendTimeLineValidUpto);
 
 		dest = CreateDestReceiver(DestRemoteSimple);
-		MemSet(nulls, false, sizeof(nulls));
 
 		/*
 		 * Need a tuple descriptor representing two columns. int8 may seem
@@ -859,7 +857,7 @@ CreateReplicationSlot(CreateReplicationSlotCmd *cmd)
 	TupOutputState *tstate;
 	TupleDesc	tupdesc;
 	Datum		values[4];
-	bool		nulls[4];
+	bool		nulls[4] = INIT_ALL_ELEMS_ZERO;
 
 	Assert(!MyReplicationSlot);
 
@@ -995,7 +993,6 @@ CreateReplicationSlot(CreateReplicationSlotCmd *cmd)
 			 (uint32) MyReplicationSlot->data.confirmed_flush);
 
 	dest = CreateDestReceiver(DestRemoteSimple);
-	MemSet(nulls, false, sizeof(nulls));
 
 	/*----------
 	 * Need a tuple descriptor representing four columns:
@@ -3286,7 +3283,7 @@ pg_stat_get_wal_senders(PG_FUNCTION_ARGS)
 		WalSndState state;
 		TimestampTz replyTime;
 		Datum		values[PG_STAT_GET_WAL_SENDERS_COLS];
-		bool		nulls[PG_STAT_GET_WAL_SENDERS_COLS];
+		bool		nulls[PG_STAT_GET_WAL_SENDERS_COLS] = INIT_ALL_ELEMS_ZERO;
 
 		SpinLockAcquire(&walsnd->mutex);
 		if (walsnd->pid == 0)
@@ -3307,7 +3304,6 @@ pg_stat_get_wal_senders(PG_FUNCTION_ARGS)
 		replyTime = walsnd->replyTime;
 		SpinLockRelease(&walsnd->mutex);
 
-		memset(nulls, 0, sizeof(nulls));
 		values[0] = Int32GetDatum(pid);
 
 		if (!is_member_of_role(GetUserId(), DEFAULT_ROLE_READ_ALL_STATS))
diff --git a/src/backend/rewrite/rewriteDefine.c b/src/backend/rewrite/rewriteDefine.c
index 7df2b61..5df4173 100644
--- a/src/backend/rewrite/rewriteDefine.c
+++ b/src/backend/rewrite/rewriteDefine.c
@@ -67,8 +67,8 @@ InsertRule(const char *rulname,
 	char	   *evqual = nodeToString(event_qual);
 	char	   *actiontree = nodeToString((Node *) action);
 	Datum		values[Natts_pg_rewrite];
-	bool		nulls[Natts_pg_rewrite];
-	bool		replaces[Natts_pg_rewrite];
+	bool		nulls[Natts_pg_rewrite] = INIT_ALL_ELEMS_ZERO;
+	bool		replaces[Natts_pg_rewrite] = INIT_ALL_ELEMS_ZERO;
 	NameData	rname;
 	Relation	pg_rewrite_desc;
 	HeapTuple	tup,
@@ -79,10 +79,8 @@ InsertRule(const char *rulname,
 	bool		is_update = false;
 
 	/*
-	 * Set up *nulls and *values arrays
+	 * Set up *values array
 	 */
-	MemSet(nulls, false, sizeof(nulls));
-
 	namestrcpy(&rname, rulname);
 	values[Anum_pg_rewrite_rulename - 1] = NameGetDatum(&rname);
 	values[Anum_pg_rewrite_ev_class - 1] = ObjectIdGetDatum(eventrel_oid);
@@ -115,7 +113,6 @@ InsertRule(const char *rulname,
 		/*
 		 * When replacing, we don't need to replace every attribute
 		 */
-		MemSet(replaces, false, sizeof(replaces));
 		replaces[Anum_pg_rewrite_ev_type - 1] = true;
 		replaces[Anum_pg_rewrite_is_instead - 1] = true;
 		replaces[Anum_pg_rewrite_ev_qual - 1] = true;
diff --git a/src/backend/statistics/extended_stats.c b/src/backend/statistics/extended_stats.c
index 207ee31..c8f02d9 100644
--- a/src/backend/statistics/extended_stats.c
+++ b/src/backend/statistics/extended_stats.c
@@ -471,14 +471,12 @@ statext_store(Oid statOid,
 {
 	HeapTuple	stup,
 				oldtup;
-	Datum		values[Natts_pg_statistic_ext_data];
+	Datum		values[Natts_pg_statistic_ext_data] = INIT_ALL_ELEMS_ZERO;
 	bool		nulls[Natts_pg_statistic_ext_data];
-	bool		replaces[Natts_pg_statistic_ext_data];
+	bool		replaces[Natts_pg_statistic_ext_data] = INIT_ALL_ELEMS_ZERO;
 	Relation	pg_stextdata;
 
 	memset(nulls, true, sizeof(nulls));
-	memset(replaces, false, sizeof(replaces));
-	memset(values, 0, sizeof(values));
 
 	/*
 	 * Construct a new pg_statistic_ext_data tuple, replacing the calculated
diff --git a/src/backend/storage/large_object/inv_api.c b/src/backend/storage/large_object/inv_api.c
index 263d5be..338edf9 100644
--- a/src/backend/storage/large_object/inv_api.c
+++ b/src/backend/storage/large_object/inv_api.c
@@ -608,9 +608,6 @@ inv_write(LargeObjectDesc *obj_desc, const char *buf, int nbytes)
 	}			workbuf;
 	char	   *workb = VARDATA(&workbuf.hdr);
 	HeapTuple	newtup;
-	Datum		values[Natts_pg_largeobject];
-	bool		nulls[Natts_pg_largeobject];
-	bool		replace[Natts_pg_largeobject];
 	CatalogIndexState indstate;
 
 	Assert(PointerIsValid(obj_desc));
@@ -656,6 +653,10 @@ inv_write(LargeObjectDesc *obj_desc, const char *buf, int nbytes)
 
 	while (nwritten < nbytes)
 	{
+		Datum           values[Natts_pg_largeobject] = INIT_ALL_ELEMS_ZERO;
+		bool            nulls[Natts_pg_largeobject] = INIT_ALL_ELEMS_ZERO;
+		bool            replace[Natts_pg_largeobject] = INIT_ALL_ELEMS_ZERO;
+
 		/*
 		 * If possible, get next pre-existing page of the LO.  We expect the
 		 * indexscan will deliver these in order --- but there may be holes.
@@ -711,9 +712,6 @@ inv_write(LargeObjectDesc *obj_desc, const char *buf, int nbytes)
 			/*
 			 * Form and insert updated tuple
 			 */
-			memset(values, 0, sizeof(values));
-			memset(nulls, false, sizeof(nulls));
-			memset(replace, false, sizeof(replace));
 			values[Anum_pg_largeobject_data - 1] = PointerGetDatum(&workbuf);
 			replace[Anum_pg_largeobject_data - 1] = true;
 			newtup = heap_modify_tuple(oldtuple, RelationGetDescr(lo_heap_r),
@@ -755,8 +753,6 @@ inv_write(LargeObjectDesc *obj_desc, const char *buf, int nbytes)
 			/*
 			 * Form and insert updated tuple
 			 */
-			memset(values, 0, sizeof(values));
-			memset(nulls, false, sizeof(nulls));
 			values[Anum_pg_largeobject_loid - 1] = ObjectIdGetDatum(obj_desc->id);
 			values[Anum_pg_largeobject_pageno - 1] = Int32GetDatum(pageno);
 			values[Anum_pg_largeobject_data - 1] = PointerGetDatum(&workbuf);
@@ -799,9 +795,9 @@ inv_truncate(LargeObjectDesc *obj_desc, int64 len)
 	}			workbuf;
 	char	   *workb = VARDATA(&workbuf.hdr);
 	HeapTuple	newtup;
-	Datum		values[Natts_pg_largeobject];
-	bool		nulls[Natts_pg_largeobject];
-	bool		replace[Natts_pg_largeobject];
+	Datum		values[Natts_pg_largeobject] = INIT_ALL_ELEMS_ZERO;
+	bool		nulls[Natts_pg_largeobject] = INIT_ALL_ELEMS_ZERO;
+	bool		replace[Natts_pg_largeobject] = INIT_ALL_ELEMS_ZERO;
 	CatalogIndexState indstate;
 
 	Assert(PointerIsValid(obj_desc));
@@ -886,9 +882,6 @@ inv_truncate(LargeObjectDesc *obj_desc, int64 len)
 		/*
 		 * Form and insert updated tuple
 		 */
-		memset(values, 0, sizeof(values));
-		memset(nulls, false, sizeof(nulls));
-		memset(replace, false, sizeof(replace));
 		values[Anum_pg_largeobject_data - 1] = PointerGetDatum(&workbuf);
 		replace[Anum_pg_largeobject_data - 1] = true;
 		newtup = heap_modify_tuple(oldtuple, RelationGetDescr(lo_heap_r),
@@ -925,8 +918,6 @@ inv_truncate(LargeObjectDesc *obj_desc, int64 len)
 		/*
 		 * Form and insert new tuple
 		 */
-		memset(values, 0, sizeof(values));
-		memset(nulls, false, sizeof(nulls));
 		values[Anum_pg_largeobject_loid - 1] = ObjectIdGetDatum(obj_desc->id);
 		values[Anum_pg_largeobject_pageno - 1] = Int32GetDatum(pageno);
 		values[Anum_pg_largeobject_data - 1] = PointerGetDatum(&workbuf);
diff --git a/src/backend/utils/adt/acl.c b/src/backend/utils/adt/acl.c
index d7e6100..36130e0 100644
--- a/src/backend/utils/adt/acl.c
+++ b/src/backend/utils/adt/acl.c
@@ -1810,7 +1810,7 @@ aclexplode(PG_FUNCTION_ARGS)
 		{
 			Datum		result;
 			Datum		values[4];
-			bool		nulls[4];
+			bool		nulls[4] = INIT_ALL_ELEMS_ZERO;
 			HeapTuple	tuple;
 
 			values[0] = ObjectIdGetDatum(aidata->ai_grantor);
@@ -1818,8 +1818,6 @@ aclexplode(PG_FUNCTION_ARGS)
 			values[2] = CStringGetTextDatum(convert_aclright_to_string(priv_bit));
 			values[3] = BoolGetDatum((ACLITEM_GET_GOPTIONS(*aidata) & priv_bit) != 0);
 
-			MemSet(nulls, 0, sizeof(nulls));
-
 			tuple = heap_form_tuple(funcctx->tuple_desc, values, nulls);
 			result = HeapTupleGetDatum(tuple);
 
diff --git a/src/backend/utils/adt/arrayfuncs.c b/src/backend/utils/adt/arrayfuncs.c
index 8079b13..96f5219 100644
--- a/src/backend/utils/adt/arrayfuncs.c
+++ b/src/backend/utils/adt/arrayfuncs.c
@@ -738,11 +738,10 @@ ReadArrayStr(char *arrayStr,
 	bool		eoArray = false;
 	bool		hasnull;
 	int32		totbytes;
-	int			indx[MAXDIM],
+	int			indx[MAXDIM] = INIT_ALL_ELEMS_ZERO,
 				prod[MAXDIM];
 
 	mda_get_prod(ndim, dim, prod);
-	MemSet(indx, 0, sizeof(indx));
 
 	/* Initialize is-null markers to true */
 	memset(nulls, true, nitems * sizeof(bool));
diff --git a/src/backend/utils/adt/datetime.c b/src/backend/utils/adt/datetime.c
index e38bd93..88dd838 100644
--- a/src/backend/utils/adt/datetime.c
+++ b/src/backend/utils/adt/datetime.c
@@ -4635,7 +4635,7 @@ pg_timezone_abbrevs(PG_FUNCTION_ARGS)
 	Datum		result;
 	HeapTuple	tuple;
 	Datum		values[3];
-	bool		nulls[3];
+	bool		nulls[3] = INIT_ALL_ELEMS_ZERO;
 	const datetkn *tp;
 	char		buffer[TOKMAXLEN + 1];
 	int			gmtoffset;
@@ -4722,8 +4722,6 @@ pg_timezone_abbrevs(PG_FUNCTION_ARGS)
 			break;
 	}
 
-	MemSet(nulls, 0, sizeof(nulls));
-
 	/*
 	 * Convert name to text, using upcasing conversion that is the inverse of
 	 * what ParseDateTime() uses.
@@ -4765,7 +4763,7 @@ pg_timezone_names(PG_FUNCTION_ARGS)
 	Datum		result;
 	HeapTuple	tuple;
 	Datum		values[4];
-	bool		nulls[4];
+	bool		nulls[4] = INIT_ALL_ELEMS_ZERO;
 	int			tzoff;
 	struct pg_tm tm;
 	fsec_t		fsec;
@@ -4847,8 +4845,6 @@ pg_timezone_names(PG_FUNCTION_ARGS)
 		break;
 	}
 
-	MemSet(nulls, 0, sizeof(nulls));
-
 	values[0] = CStringGetTextDatum(pg_get_timezone_name(tz));
 	values[1] = CStringGetTextDatum(tzn ? tzn : "");
 
diff --git a/src/backend/utils/adt/genfile.c b/src/backend/utils/adt/genfile.c
index 5d4f26a..056fef1 100644
--- a/src/backend/utils/adt/genfile.c
+++ b/src/backend/utils/adt/genfile.c
@@ -576,7 +576,7 @@ pg_ls_dir_files(FunctionCallInfo fcinfo, const char *dir, bool missing_ok)
 	while ((de = ReadDir(fctx->dirdesc, fctx->location)) != NULL)
 	{
 		Datum		values[3];
-		bool		nulls[3];
+		bool		nulls[3] = INIT_ALL_ELEMS_ZERO;
 		char		path[MAXPGPATH * 2];
 		struct stat attrib;
 		HeapTuple	tuple;
@@ -599,7 +599,6 @@ pg_ls_dir_files(FunctionCallInfo fcinfo, const char *dir, bool missing_ok)
 		values[0] = CStringGetTextDatum(de->d_name);
 		values[1] = Int64GetDatum((int64) attrib.st_size);
 		values[2] = TimestampTzGetDatum(time_t_to_timestamptz(attrib.st_mtime));
-		memset(nulls, 0, sizeof(nulls));
 
 		tuple = heap_form_tuple(funcctx->tuple_desc, values, nulls);
 		SRF_RETURN_NEXT(funcctx, HeapTupleGetDatum(tuple));
diff --git a/src/backend/utils/adt/lockfuncs.c b/src/backend/utils/adt/lockfuncs.c
index bc62c6e..992a96f 100644
--- a/src/backend/utils/adt/lockfuncs.c
+++ b/src/backend/utils/adt/lockfuncs.c
@@ -160,8 +160,8 @@ pg_lock_status(PG_FUNCTION_ARGS)
 		LOCKMODE	mode = 0;
 		const char *locktypename;
 		char		tnbuf[32];
-		Datum		values[NUM_LOCK_STATUS_COLUMNS];
-		bool		nulls[NUM_LOCK_STATUS_COLUMNS];
+		Datum		values[NUM_LOCK_STATUS_COLUMNS] = INIT_ALL_ELEMS_ZERO;
+		bool		nulls[NUM_LOCK_STATUS_COLUMNS] = INIT_ALL_ELEMS_ZERO;
 		HeapTuple	tuple;
 		Datum		result;
 		LockInstanceData *instance;
@@ -218,9 +218,6 @@ pg_lock_status(PG_FUNCTION_ARGS)
 		/*
 		 * Form tuple with appropriate data.
 		 */
-		MemSet(values, 0, sizeof(values));
-		MemSet(nulls, false, sizeof(nulls));
-
 		if (instance->locktag.locktag_type <= LOCKTAG_LAST_TYPE)
 			locktypename = LockTagTypeNames[instance->locktag.locktag_type];
 		else
@@ -332,8 +329,8 @@ pg_lock_status(PG_FUNCTION_ARGS)
 
 		PREDICATELOCKTARGETTAG *predTag = &(predLockData->locktags[mystatus->predLockIdx]);
 		SERIALIZABLEXACT *xact = &(predLockData->xacts[mystatus->predLockIdx]);
-		Datum		values[NUM_LOCK_STATUS_COLUMNS];
-		bool		nulls[NUM_LOCK_STATUS_COLUMNS];
+		Datum		values[NUM_LOCK_STATUS_COLUMNS] = INIT_ALL_ELEMS_ZERO;
+		bool		nulls[NUM_LOCK_STATUS_COLUMNS] = INIT_ALL_ELEMS_ZERO;
 		HeapTuple	tuple;
 		Datum		result;
 
@@ -342,8 +339,6 @@ pg_lock_status(PG_FUNCTION_ARGS)
 		/*
 		 * Form tuple with appropriate data.
 		 */
-		MemSet(values, 0, sizeof(values));
-		MemSet(nulls, false, sizeof(nulls));
 
 		/* lock type */
 		lockType = GET_PREDICATELOCKTARGETTAG_TYPE(*predTag);
diff --git a/src/backend/utils/adt/pgstatfuncs.c b/src/backend/utils/adt/pgstatfuncs.c
index 05240bf..5567bdb 100644
--- a/src/backend/utils/adt/pgstatfuncs.c
+++ b/src/backend/utils/adt/pgstatfuncs.c
@@ -492,13 +492,10 @@ pg_stat_get_progress_info(PG_FUNCTION_ARGS)
 	{
 		LocalPgBackendStatus *local_beentry;
 		PgBackendStatus *beentry;
-		Datum		values[PG_STAT_GET_PROGRESS_COLS];
-		bool		nulls[PG_STAT_GET_PROGRESS_COLS];
+		Datum		values[PG_STAT_GET_PROGRESS_COLS] = INIT_ALL_ELEMS_ZERO;
+		bool		nulls[PG_STAT_GET_PROGRESS_COLS] = INIT_ALL_ELEMS_ZERO;
 		int			i;
 
-		MemSet(values, 0, sizeof(values));
-		MemSet(nulls, 0, sizeof(nulls));
-
 		local_beentry = pgstat_fetch_stat_local_beentry(curr_backend);
 
 		if (!local_beentry)
@@ -585,17 +582,14 @@ pg_stat_get_activity(PG_FUNCTION_ARGS)
 	for (curr_backend = 1; curr_backend <= num_backends; curr_backend++)
 	{
 		/* for each row */
-		Datum		values[PG_STAT_GET_ACTIVITY_COLS];
-		bool		nulls[PG_STAT_GET_ACTIVITY_COLS];
+		Datum		values[PG_STAT_GET_ACTIVITY_COLS] = INIT_ALL_ELEMS_ZERO;
+		bool		nulls[PG_STAT_GET_ACTIVITY_COLS] = INIT_ALL_ELEMS_ZERO;
 		LocalPgBackendStatus *local_beentry;
 		PgBackendStatus *beentry;
 		PGPROC	   *proc;
 		const char *wait_event_type = NULL;
 		const char *wait_event = NULL;
 
-		MemSet(values, 0, sizeof(values));
-		MemSet(nulls, 0, sizeof(nulls));
-
 		/* Get the next one in the list */
 		local_beentry = pgstat_fetch_stat_local_beentry(curr_backend);
 		if (!local_beentry)
@@ -1908,14 +1902,10 @@ Datum
 pg_stat_get_archiver(PG_FUNCTION_ARGS)
 {
 	TupleDesc	tupdesc;
-	Datum		values[7];
-	bool		nulls[7];
+	Datum		values[7] = INIT_ALL_ELEMS_ZERO;
+	bool		nulls[7] = INIT_ALL_ELEMS_ZERO;
 	PgStat_ArchiverStats *archiver_stats;
 
-	/* Initialise values and NULL flags arrays */
-	MemSet(values, 0, sizeof(values));
-	MemSet(nulls, 0, sizeof(nulls));
-
 	/* Initialise attributes information in the tuple descriptor */
 	tupdesc = CreateTemplateTupleDesc(7);
 	TupleDescInitEntry(tupdesc, (AttrNumber) 1, "archived_count",
diff --git a/src/backend/utils/misc/guc.c b/src/backend/utils/misc/guc.c
index 2178e1c..9acd6d3 100644
--- a/src/backend/utils/misc/guc.c
+++ b/src/backend/utils/misc/guc.c
@@ -9483,11 +9483,8 @@ show_all_file_settings(PG_FUNCTION_ARGS)
 	/* Process the results and create a tuplestore */
 	for (seqno = 1; conf != NULL; conf = conf->next, seqno++)
 	{
-		Datum		values[NUM_PG_FILE_SETTINGS_ATTS];
-		bool		nulls[NUM_PG_FILE_SETTINGS_ATTS];
-
-		memset(values, 0, sizeof(values));
-		memset(nulls, 0, sizeof(nulls));
+		Datum		values[NUM_PG_FILE_SETTINGS_ATTS] = INIT_ALL_ELEMS_ZERO;
+		bool		nulls[NUM_PG_FILE_SETTINGS_ATTS] = INIT_ALL_ELEMS_ZERO;
 
 		/* sourcefile */
 		if (conf->filename)
diff --git a/src/backend/utils/mmgr/portalmem.c b/src/backend/utils/mmgr/portalmem.c
index 334e35b..4b66687 100644
--- a/src/backend/utils/mmgr/portalmem.c
+++ b/src/backend/utils/mmgr/portalmem.c
@@ -1176,14 +1176,12 @@ pg_cursor(PG_FUNCTION_ARGS)
 	{
 		Portal		portal = hentry->portal;
 		Datum		values[6];
-		bool		nulls[6];
+		bool		nulls[6] = INIT_ALL_ELEMS_ZERO;
 
 		/* report only "visible" entries */
 		if (!portal->visible)
 			continue;
 
-		MemSet(nulls, 0, sizeof(nulls));
-
 		values[0] = CStringGetTextDatum(portal->name);
 		values[1] = CStringGetTextDatum(portal->sourceText);
 		values[2] = BoolGetDatum(portal->cursorOptions & CURSOR_OPT_HOLD);
diff --git a/src/include/c.h b/src/include/c.h
index f461628..a5db6fe 100644
--- a/src/include/c.h
+++ b/src/include/c.h
@@ -1166,6 +1166,23 @@ typedef union PGAlignedXLogBlock
 	((underlying_type) (expr))
 #endif
 
+/*
+ * C99 designated-initialiser syntax to set all array elements to 0/false.
+ *
+ * Use the macro in preference to explicit {0} syntax to avoid giving a misleading
+ * impression that the same value is always used for all elements.
+ * e.g.
+ * bool foo[2] = {false}; // sets both elements false
+ * bool foo[2] = {true}; // does NOT set both elements true
+ *
+ * Reference: C99 [$6.7.8/21] If there are fewer initializers in a brace-enclosed list than there
+ * are elements or members of an aggregate, or fewer characters in a string literal used to
+ * initialize an array of known size than there are elements in the array, the remainder of the
+ * aggregate shall be initialized implicitly the same as objects that have static storage duration
+ */
+#define INIT_ALL_ELEMS_ZERO {0}
+
+
 /* ----------------------------------------------------------------
  *				Section 9: system-specific hacks
  *
#39Amit Kapila
amit.kapila16@gmail.com
In reply to: Andres Freund (#37)
Re: Proposal: Make use of C99 designated initialisers for nulls/values arrays

On Sat, Oct 5, 2019 at 3:10 AM Andres Freund <andres@anarazel.de> wrote:

On 2019-10-04 17:08:29 -0400, Tom Lane wrote:

Andres Freund <andres@anarazel.de> writes:

On 2019-10-04 16:31:29 -0400, Bruce Momjian wrote:

Yeah, it is certainly weird that you have to assign the first array
element to get the rest to be zeros. By using a macro, we can document
this behavior in one place.

IDK, to me this seems like something one just has to learn about C, with
the macro just obfuscating that already required knowledge. It's not
like this only applies to stack variables initializes with {0}. It's
also true of global variables, or function-local static ones, for
example.

Huh? For both those cases, the *default* behavior, going back to K&R C,
is that the variable initializes to all-bits-zero. There's no need to
write anything extra.

What I mean is that if there's any initialization, it's to all zeroes,
except for the parts explicitly initialized explicitly. And all that the
{0} does, is that the rest of the fields are initialized the way other
such initialization happens.

You have a point and I think over time everyone will know this.
However, so many people advocating for having a macro with a comment
to be more explicit about this behavior shows that this is not equally
obvious to everyone or at least they think that it will help future
patch authors.

Now, I think as the usage ({0}) already exists in the code, so I think
if we decide to use a macro, then ideally those places should also be
changed. I am not telling that it must be done in the same patch, we
can even do it as a separate patch.

I am personally still in the camp of people advocating the use of
macro for this purpose. It is quite possible after reading your
points, some people might change their opinion or some others also
share their opinion against using a macro in which case we can drop
the idea of using a macro.

--
With Regards,
Amit Kapila.
EnterpriseDB: http://www.enterprisedb.com

#40vignesh C
vignesh21@gmail.com
In reply to: Smith, Peter (#38)
Re: Proposal: Make use of C99 designated initialisers for nulls/values arrays

On Tue, Oct 8, 2019 at 4:43 AM Smith, Peter <peters@fast.au.fujitsu.com> wrote:

From: Amit Kapila <amit.kapila16@gmail.com> Sent: Friday, 4 October 2019 4:50 PM

How about I just define them both the same?
#define INIT_ALL_ELEMS_ZERO {0}
#define INIT_ALL_ELEMS_FALSE {0}

I think using one define would be preferred, but you can wait and see if others prefer defining different macros for the same thing.

While nowhere near unanimous, it seems majority favour using a macro (if only to protect the unwary and document the behaviour).
And of those in favour of macros, using INIT_ALL_ELEMS_ZERO even for bool array is a clear preference.

So, please find attached the updated patch, which now has just 1 macro.

Few thoughts on the patch:
--- a/src/backend/access/transam/twophase.c
+++ b/src/backend/access/transam/twophase.c
@@ -770,8 +770,8 @@ pg_prepared_xact(PG_FUNCTION_ARGS)
  GlobalTransaction gxact = &status->array[status->currIdx++];
  PGPROC   *proc = &ProcGlobal->allProcs[gxact->pgprocno];
  PGXACT   *pgxact = &ProcGlobal->allPgXact[gxact->pgprocno];
- Datum values[5];
- bool nulls[5];
+ Datum values[5] = INIT_ALL_ELEMS_ZERO;
+ bool nulls[5] = INIT_ALL_ELEMS_ZERO;
  HeapTuple tuple;
  Datum result;
Initialisation may not be required here as all the members are getting
populated immediately

@@ -1314,9 +1314,6 @@ SetDefaultACL(InternalDefaultACL *iacls)
Oid defAclOid;

/* Prepare to insert or update pg_default_acl entry */
- MemSet(values, 0, sizeof(values));
- MemSet(nulls, false, sizeof(nulls));
- MemSet(replaces, false, sizeof(replaces));

if (isNew)
We can place the comment just before the next block of code for
better readability like you have done in other places.

@@ -2024,9 +2018,6 @@ ExecGrant_Relation(InternalGrant *istmt)
nnewmembers = aclmembers(new_acl, &newmembers);

/* finished building new ACL value, now insert it */
- MemSet(values, 0, sizeof(values));
- MemSet(nulls, false, sizeof(nulls));
- MemSet(replaces, false, sizeof(replaces));

replaces[Anum_pg_class_relacl - 1] = true;
We can place the comment just before the next block of code for
better readability like you have done in other places.
There are few more instances like this in the same file, we can
handle that too.

-- a/src/backend/replication/slotfuncs.c
+++ b/src/backend/replication/slotfuncs.c
@@ -77,7 +77,7 @@ pg_create_physical_replication_slot(PG_FUNCTION_ARGS)
  bool immediately_reserve = PG_GETARG_BOOL(1);
  bool temporary = PG_GETARG_BOOL(2);
  Datum values[2];
- bool nulls[2];
+ bool nulls[2] = INIT_ALL_ELEMS_ZERO;
  TupleDesc tupdesc;
  HeapTuple tuple;
  Datum result;
@@ -95,12 +95,10 @@ pg_create_physical_replication_slot(PG_FUNCTION_ARGS)
  InvalidXLogRecPtr);

values[0] = NameGetDatum(&MyReplicationSlot->data.name);
- nulls[0] = false;

if (immediately_reserve)
{
values[1] = LSNGetDatum(MyReplicationSlot->data.restart_lsn);
- nulls[1] = false;
}
else
nulls[1] = true;
We might not gain much here, may be this change is not required.

Regards,
Vignesh
EnterpriseDB: http://www.enterprisedb.com

#41Thomas Munro
thomas.munro@gmail.com
In reply to: Amit Kapila (#39)
Re: Proposal: Make use of C99 designated initialisers for nulls/values arrays

On Tue, Oct 8, 2019 at 11:09 PM Amit Kapila <amit.kapila16@gmail.com> wrote:

On Sat, Oct 5, 2019 at 3:10 AM Andres Freund <andres@anarazel.de> wrote:

On 2019-10-04 17:08:29 -0400, Tom Lane wrote:

Andres Freund <andres@anarazel.de> writes:

On 2019-10-04 16:31:29 -0400, Bruce Momjian wrote:

Yeah, it is certainly weird that you have to assign the first array
element to get the rest to be zeros. By using a macro, we can document
this behavior in one place.

IDK, to me this seems like something one just has to learn about C, with
the macro just obfuscating that already required knowledge. It's not
like this only applies to stack variables initializes with {0}. It's
also true of global variables, or function-local static ones, for
example.

Huh? For both those cases, the *default* behavior, going back to K&R C,
is that the variable initializes to all-bits-zero. There's no need to
write anything extra.

What I mean is that if there's any initialization, it's to all zeroes,
except for the parts explicitly initialized explicitly. And all that the
{0} does, is that the rest of the fields are initialized the way other
such initialization happens.

You have a point and I think over time everyone will know this.
However, so many people advocating for having a macro with a comment
to be more explicit about this behavior shows that this is not equally
obvious to everyone or at least they think that it will help future
patch authors.

Now, I think as the usage ({0}) already exists in the code, so I think
if we decide to use a macro, then ideally those places should also be
changed. I am not telling that it must be done in the same patch, we
can even do it as a separate patch.

I am personally still in the camp of people advocating the use of
macro for this purpose. It is quite possible after reading your
points, some people might change their opinion or some others also
share their opinion against using a macro in which case we can drop
the idea of using a macro.

-1 for these macros.

These are basic facts about the C language. I hope C eventually
supports {} like C++, so that you don't have to think hard about
whether the first member is another struct, and recursively so … but
since the macros can't help with that problem, what is the point?

I am reminded of an (apocryphal?) complaint from an old C FAQ about
people using #define BEGIN {.

#42Michael Paquier
michael@paquier.xyz
In reply to: Thomas Munro (#41)
Re: Proposal: Make use of C99 designated initialisers for nulls/values arrays

On Thu, Oct 17, 2019 at 06:37:11PM +1300, Thomas Munro wrote:

-1 for these macros.

These are basic facts about the C language. I hope C eventually
supports {} like C++, so that you don't have to think hard about
whether the first member is another struct, and recursively so … but
since the macros can't help with that problem, what is the point?

FWIW, I am not convinced that those macros are an improvement either.

I am reminded of an (apocryphal?) complaint from an old C FAQ about
people using #define BEGIN {.

This one? Wow.
http://c-faq.com/cpp/slm.html
--
Michael

#43Kyotaro Horiguchi
horikyota.ntt@gmail.com
In reply to: Michael Paquier (#42)
Re: Proposal: Make use of C99 designated initialisers for nulls/values arrays

At Thu, 17 Oct 2019 16:30:02 +0900, Michael Paquier <michael@paquier.xyz> wrote in

On Thu, Oct 17, 2019 at 06:37:11PM +1300, Thomas Munro wrote:

-1 for these macros.

These are basic facts about the C language. I hope C eventually
supports {} like C++, so that you don't have to think hard about
whether the first member is another struct, and recursively so … but
since the macros can't help with that problem, what is the point?

FWIW, I am not convinced that those macros are an improvement either.

FWIW agreed. I might have put +1 if it had multpile definitions
according to platforms, though.

I am reminded of an (apocryphal?) complaint from an old C FAQ about
people using #define BEGIN {.

This one? Wow.
http://c-faq.com/cpp/slm.html

I remember this.

Though the new macro proposed here doesn't completely seems to be a
so-called nonsyntactic macro, but the syntax using the macro looks
somewhat broken since it lacks {}, which should be there.

bool nulls[Natts_pg_collection] = INIT_ALL_ELEMS_ZERO;

We could abuse the macro for structs.

pgstattuple_type stat = INIT_ALL_ELEMS_ZERO;

This is correct in syntax, but seems completely broken.

regards.

--
Kyotaro Horiguchi
NTT Open Source Software Center

#44Amit Kapila
amit.kapila16@gmail.com
In reply to: Kyotaro Horiguchi (#43)
Re: Proposal: Make use of C99 designated initialisers for nulls/values arrays

On Thu, Oct 17, 2019 at 4:58 PM Kyotaro Horiguchi
<horikyota.ntt@gmail.com> wrote:

At Thu, 17 Oct 2019 16:30:02 +0900, Michael Paquier <michael@paquier.xyz> wrote in

On Thu, Oct 17, 2019 at 06:37:11PM +1300, Thomas Munro wrote:

-1 for these macros.

These are basic facts about the C language. I hope C eventually
supports {} like C++, so that you don't have to think hard about
whether the first member is another struct, and recursively so … but
since the macros can't help with that problem, what is the point?

FWIW, I am not convinced that those macros are an improvement either.

FWIW agreed. I might have put +1 if it had multpile definitions
according to platforms, though.

Thanks, Thomas, Michael, and Horiguchi-San. I think there are enough
votes on not using a macro that we can proceed with that approach.
This takes us back to what Smith, Peter has initially proposed [1]/messages/by-id/201DD0641B056142AC8C6645EC1B5F62014B919631@SYD1217.
I shall wait for a couple of days to see if someone would like to
argue otherwise and then review the proposed patch.

[1]: /messages/by-id/201DD0641B056142AC8C6645EC1B5F62014B919631@SYD1217

--
With Regards,
Amit Kapila.
EnterpriseDB: http://www.enterprisedb.com

#45Stephen Frost
sfrost@snowman.net
In reply to: Thomas Munro (#41)
Re: Proposal: Make use of C99 designated initialisers for nulls/values arrays

Greetings,

* Thomas Munro (thomas.munro@gmail.com) wrote:

On Tue, Oct 8, 2019 at 11:09 PM Amit Kapila <amit.kapila16@gmail.com> wrote:

I am personally still in the camp of people advocating the use of
macro for this purpose. It is quite possible after reading your
points, some people might change their opinion or some others also
share their opinion against using a macro in which case we can drop
the idea of using a macro.

-1 for these macros.

Agreed.

These are basic facts about the C language. I hope C eventually
supports {} like C++, so that you don't have to think hard about
whether the first member is another struct, and recursively so … but
since the macros can't help with that problem, what is the point?

I realize that I need to don some fireproof gear for suggesting this,
but I really wonder how much fallout we'd have from just allowing {} to
be used.. It's about a billion[1] times cleaner and more sensible than
using {0} and doesn't create a dependency on what the first element of
the struct is..

Thanks,

Stephen

1: Detailed justification not included intentionally and is left as an
exercise to the reader.

#46Chapman Flack
chap@anastigmatix.net
In reply to: Stephen Frost (#45)
Re: Proposal: Make use of C99 designated initialisers for nulls/values arrays

On 10/18/19 08:18, Stephen Frost wrote:

I realize that I need to don some fireproof gear for suggesting this,
but I really wonder how much fallout we'd have from just allowing {} to
be used.. It's about a billion[1] times cleaner and more sensible than
using {0} and doesn't create a dependency on what the first element of
the struct is..

I guess the non-flamey empirical question would be, if it's not ISO C,
are we supporting any compiler that doesn't understand it?

-Chap

#47Stephen Frost
sfrost@snowman.net
In reply to: Chapman Flack (#46)
Re: Proposal: Make use of C99 designated initialisers for nulls/values arrays

Greetings,

* Chapman Flack (chap@anastigmatix.net) wrote:

On 10/18/19 08:18, Stephen Frost wrote:

I realize that I need to don some fireproof gear for suggesting this,
but I really wonder how much fallout we'd have from just allowing {} to
be used.. It's about a billion[1] times cleaner and more sensible than
using {0} and doesn't create a dependency on what the first element of
the struct is..

I guess the non-flamey empirical question would be, if it's not ISO C,
are we supporting any compiler that doesn't understand it?

Right, that's basically what I was trying to ask. :)

Thanks,

Stephen

#48Andres Freund
andres@anarazel.de
In reply to: Stephen Frost (#47)
Re: Proposal: Make use of C99 designated initialisers for nulls/values arrays

Hi,

On 2019-10-18 09:03:31 -0400, Stephen Frost wrote:

* Chapman Flack (chap@anastigmatix.net) wrote:

On 10/18/19 08:18, Stephen Frost wrote:

I realize that I need to don some fireproof gear for suggesting this,
but I really wonder how much fallout we'd have from just allowing {} to
be used.. It's about a billion[1] times cleaner and more sensible than
using {0} and doesn't create a dependency on what the first element of
the struct is..

I guess the non-flamey empirical question would be, if it's not ISO C,
are we supporting any compiler that doesn't understand it?

Right, that's basically what I was trying to ask. :)

I don't understand why this is an issue worth deviating from the
standard for. Especially not when the person suggesting to do so isn't
even doing the leg work to estimate the portability issues.

I feel we've spent more than enough time on this topic.

- Andres

#49Stephen Frost
sfrost@snowman.net
In reply to: Andres Freund (#48)
Re: Proposal: Make use of C99 designated initialisers for nulls/values arrays

Greetings,

* Andres Freund (andres@anarazel.de) wrote:

On 2019-10-18 09:03:31 -0400, Stephen Frost wrote:

* Chapman Flack (chap@anastigmatix.net) wrote:

On 10/18/19 08:18, Stephen Frost wrote:

I realize that I need to don some fireproof gear for suggesting this,
but I really wonder how much fallout we'd have from just allowing {} to
be used.. It's about a billion[1] times cleaner and more sensible than
using {0} and doesn't create a dependency on what the first element of
the struct is..

I guess the non-flamey empirical question would be, if it's not ISO C,
are we supporting any compiler that doesn't understand it?

Right, that's basically what I was trying to ask. :)

I don't understand why this is an issue worth deviating from the
standard for.

Because this use and the way the standard is defined in this case is
confusing and could lead later hackers to misunderstand what's going on
and end up creating bugs- which is what a good chunk of this discussion
was about. The {} construct is much clearer in this regard and while
it's not in the C standard it's in C++ and it's accepted by the commonly
used compilers (clang and and pretty far back it seems for gcc), without
warning unless you enable -pedantic or similar.

Especially not when the person suggesting to do so isn't
even doing the leg work to estimate the portability issues.

I figured it was common knowledge that gcc/clang supported it just fine,
which covers something like 90% of the buildfarm. I haven't got easy
access to check others.

Thanks,

Stephen

#50Amit Kapila
amit.kapila16@gmail.com
In reply to: Stephen Frost (#49)
Re: Proposal: Make use of C99 designated initialisers for nulls/values arrays

On Sat, Oct 19, 2019 at 9:14 PM Stephen Frost <sfrost@snowman.net> wrote:

* Andres Freund (andres@anarazel.de) wrote:

Especially not when the person suggesting to do so isn't
even doing the leg work to estimate the portability issues.

I figured it was common knowledge that gcc/clang supported it just fine,
which covers something like 90% of the buildfarm. I haven't got easy
access to check others.

I have tried {} on Windows (MSVC-2017) and it is giving compilation error:

\src\backend\access\transam\commit_ts.c(425): error C2059: syntax error: '}'

1>\src\backend\access\transam\commit_ts.c(426): error C2059: syntax error: '}'

The changed code looks like below:
Datum
pg_last_committed_xact(PG_FUNCTION_ARGS)
{
..
Datum values[2] = {};
bool nulls[2] = {};
..
}

Does this put an end to the option of using {} or do we want to
investigate something more?

--
With Regards,
Amit Kapila.
EnterpriseDB: http://www.enterprisedb.com

#51Joe Nelson
joe@begriffs.com
In reply to: Stephen Frost (#49)
Re: Proposal: Make use of C99 designated initialisers for nulls/values arrays

I don't understand why this is an issue worth deviating from the
standard for.

Because this use and the way the standard is defined in this case is
confusing and could lead later hackers to misunderstand what's going on
and end up creating bugs-

The two possible misunderstandings seem to be:

1. how 0 is interpreted in various contexts such as bool
2. that the x in {x} applies to only the first element

IMHO we should expect people to be familiar with (1), and we have the
INIT_ALL_ELEMS_ZERO macro to avoid (2). However the more I look at the
code using that macro the less I like it. The {0} initializer is more
idiomatic.

My vote would be to use {0} everywhere and avoid constructions like
{false} which might exacerbate misunderstanding (2).

I figured it was common knowledge that gcc/clang supported it just fine,
which covers something like 90% of the buildfarm. I haven't got easy
access to check others.

As Amit pointed out, {} doesn't work with MSVC-2017, nor is there any
reason it should, given that it isn't part of the C standard.

#52Chapman Flack
chap@anastigmatix.net
In reply to: Joe Nelson (#51)
Re: Proposal: Make use of C99 designated initialisers for nulls/values arrays

On 10/21/19 11:25 AM, Joe Nelson wrote:

we have the
INIT_ALL_ELEMS_ZERO macro to avoid (2). However the more I look at the
code using that macro the less I like it. The {0} initializer is more
idiomatic.

If faced with the two questions:

1. which of a or b is more "clear" ?
2. which of a or b is more "idiomatic" ?

I think I would feel on more solid ground opining on (1),
where wrt (2) I would feel a little muzzier trying to say
what the question means.

It seems to me that idioms are common bits of usage that take off
because they're widely recognized as saying a specific thing
efficiently and clearly.

On that score, I'm not sure {0} really makes a good idiom ... indeed,
it seems this conversation is largely about whether it /looks/ too
much like an idiom, and to some readers could appear to be saying
something efficiently and clearly but that isn't quite what it means.

I would favor {} in a heartbeat if it were standard, because that
sucker is an idiom.

Failing that, though, I think I still favor the macro, because
question (1) seems less fuzzy than question (2), and on "clear",
the macro wins.

Regards,
-Chap

#53Isaac Morland
isaac.morland@gmail.com
In reply to: Chapman Flack (#52)
Re: Proposal: Make use of C99 designated initialisers for nulls/values arrays

On Mon, 21 Oct 2019 at 11:46, Chapman Flack <chap@anastigmatix.net> wrote:

I would favor {} in a heartbeat if it were standard, because that
sucker is an idiom.

Failing that, though, I think I still favor the macro, because
question (1) seems less fuzzy than question (2), and on "clear",
the macro wins.

Is it possible to define the macro to be {} where supported and {0} where
needed? Something like:

#if ...
#define INIT_ALL_ELEMS_ZERO {}
#else
#define INIT_ALL_ELEMS_ZERO {0}
#endif

Then it's clear the 0 is just there to make certain compilers happy and
doesn't have any actual meaning.

#54Joe Nelson
joe@begriffs.com
In reply to: Isaac Morland (#53)
Re: Proposal: Make use of C99 designated initialisers for nulls/values arrays

Is it possible to define the macro to be {} where supported and {0}
where needed? Something like:

If it's being put behind a macro then *stylistically* it shouldn't
matter whether {} or {0} is chosen, right? In which case {0} would
be a better choice because it's supported everywhere.

#55Stephen Frost
sfrost@snowman.net
In reply to: Joe Nelson (#54)
Re: Proposal: Make use of C99 designated initialisers for nulls/values arrays

Greetings,

* Joe Nelson (joe@begriffs.com) wrote:

Is it possible to define the macro to be {} where supported and {0}
where needed? Something like:

If it's being put behind a macro then *stylistically* it shouldn't
matter whether {} or {0} is chosen, right? In which case {0} would
be a better choice because it's supported everywhere.

The problem with {0} in the first place is that it doesn't actually work
in all cases... Simple cases, yes, but not more complex ones. It's
unfortunate that there isn't a general solution here that works across
platforms (even if it involved macros..), but that seems to be the case.

Thanks,

Stephen

#56Tom Lane
tgl@sss.pgh.pa.us
In reply to: Stephen Frost (#55)
Re: Proposal: Make use of C99 designated initialisers for nulls/values arrays

Stephen Frost <sfrost@snowman.net> writes:

* Joe Nelson (joe@begriffs.com) wrote:

If it's being put behind a macro then *stylistically* it shouldn't
matter whether {} or {0} is chosen, right? In which case {0} would
be a better choice because it's supported everywhere.

The problem with {0} in the first place is that it doesn't actually work
in all cases... Simple cases, yes, but not more complex ones. It's
unfortunate that there isn't a general solution here that works across
platforms (even if it involved macros..), but that seems to be the case.

There is a general solution that works across platforms; it's called
memset() and it's what we're using today. I'm beginning to think that
we should just reject this patch. It's certainly not enough of an
improvement to justify the amount of discussion that's gone into it.

regards, tom lane

#57Andres Freund
andres@anarazel.de
In reply to: Tom Lane (#56)
Re: Proposal: Make use of C99 designated initialisers for nulls/values arrays

On 2019-10-21 15:04:36 -0400, Tom Lane wrote:

There is a general solution that works across platforms; it's called
memset() and it's what we're using today. I'm beginning to think that
we should just reject this patch. It's certainly not enough of an
improvement to justify the amount of discussion that's gone into it.

bikeshedding vs reality of programming & efficiency: 1 : 0.

#58Amit Kapila
amit.kapila16@gmail.com
In reply to: Tom Lane (#56)
Re: Proposal: Make use of C99 designated initialisers for nulls/values arrays

On Tue, Oct 22, 2019 at 12:35 AM Tom Lane <tgl@sss.pgh.pa.us> wrote:

Stephen Frost <sfrost@snowman.net> writes:

* Joe Nelson (joe@begriffs.com) wrote:

If it's being put behind a macro then *stylistically* it shouldn't
matter whether {} or {0} is chosen, right? In which case {0} would
be a better choice because it's supported everywhere.

The problem with {0} in the first place is that it doesn't actually work
in all cases... Simple cases, yes, but not more complex ones. It's
unfortunate that there isn't a general solution here that works across
platforms (even if it involved macros..), but that seems to be the case.

There is a general solution that works across platforms; it's called
memset() and it's what we're using today. I'm beginning to think that
we should just reject this patch.

Hmm, but then what is your suggestion for existing code that uses {0}.
If we reject this patch and leave the current code as it is, there is
always a risk of some people using {0} and others using memset which
will lead to further deviation in the code. Now, maybe if we change
the existing code to always use memset where we use {0}, then we can
kind of enforce such a rule for future patch authors.

--
With Regards,
Amit Kapila.
EnterpriseDB: http://www.enterprisedb.com

#59Michael Paquier
michael@paquier.xyz
In reply to: Amit Kapila (#58)
Re: Proposal: Make use of C99 designated initialisers for nulls/values arrays

On Tue, Oct 22, 2019 at 04:13:03PM +0530, Amit Kapila wrote:

Hmm, but then what is your suggestion for existing code that uses {0}.
If we reject this patch and leave the current code as it is, there is
always a risk of some people using {0} and others using memset which
will lead to further deviation in the code. Now, maybe if we change
the existing code to always use memset where we use {0}, then we can
kind of enforce such a rule for future patch authors.

Well, we could have a shot at reducing the footprint of {0} then where
we can. I am seeing less than a dozen in contrib/, and a bit more
than thirty in src/backend/. Or we could just do as we do with such
business: let's update them when we see that's adapted and when
modifying the surrounding area.

At least I see one conclusion coming out of this thread: the patch is
in the direction of getting rejected. My recommendation would be to
do that, and focus on other patches which could get merged: we have a
total of 220 entries in this CF.
--
Michael

#60Andres Freund
andres@anarazel.de
In reply to: Michael Paquier (#59)
Re: Proposal: Make use of C99 designated initialisers for nulls/values arrays

Hi,

On 2019-11-12 14:17:42 +0900, Michael Paquier wrote:

On Tue, Oct 22, 2019 at 04:13:03PM +0530, Amit Kapila wrote:

Hmm, but then what is your suggestion for existing code that uses {0}.
If we reject this patch and leave the current code as it is, there is
always a risk of some people using {0} and others using memset which
will lead to further deviation in the code. Now, maybe if we change
the existing code to always use memset where we use {0}, then we can
kind of enforce such a rule for future patch authors.

Well, we could have a shot at reducing the footprint of {0} then where
we can. I am seeing less than a dozen in contrib/, and a bit more
than thirty in src/backend/.

-many. I think this serves zero positive purpose, except to make it
harder to analyze code-flow.

I think it's not worth going around to convert code to use {0} style
initializers in most cases, but when authors write it, we shouldn't
remove it either.

Greetings,

Andres Freund

#61Smith, Peter
peters@fast.au.fujitsu.com
In reply to: Andres Freund (#60)
RE: Proposal: Make use of C99 designated initialisers for nulls/values arrays

Hi Hackers.

This submission seems to have stalled.

Please forgive this post - I am unsure if the submission process expects me to come to defence of my own patch for one last gasp, or if I am supposed to just sit back and watch it die a slow death of a thousand cuts.

I thought this submission actually started out very popular, but then support slowly eroded, and currently seems headed towards a likely rejection.

~

Anyway, here are my arguments:

(a) I recognise that on first glance, the {0} syntax might evoke a momentary "double-take" by the someone reading the code. IMO this would only be experienced by somebody encountering {0} syntax for the very first time. This is not an really uncommon "pattern" (it's already elsewhere in PostreSQL code), and once you've seen it two or three times there is no confusion what it is doing.

(b) Because of (a) I don't really agree with the notion that it should be replaced by a macro to hide the C syntax. I did try adding various macros as suggested, but all that achieved was to was spin off another 20 emails debating the macro format. I thought any code committer/reviewer should have no trouble at all to understand standard C syntax.

(c) It was never a goal of this submission that *all* memsets should be replaced by {0}. Sometimes {0} is more concise and better IMO, but sometimes memset is a way more appropriate choice. This patch only replaces simple examples of primitive types like the values[] and nulls[] arrays (which was a repeated pattern for many tuple operations). I think any concern that {0} may not work for all other complex cases is a red-herring. When memset is better, then use memset.

(d) Wishing for C99 syntax to be same as the simpler {} style of C++ is another red-herring. I can only use what is officially supported. It is what it is.

(e) The PostgreSQL miscellaneous coding conventions - https://www.postgresql.org/docs/current/source-conventions.html - says to avoid " intermingled declarations and code". This leads to some code where the variable declaration and the initialization (e.g. memset 0 or memset false) code can be widely separated. It can be an easy source of mistakes to assume a variable was already initialized when maybe it wasn't. This patch puts the initialization at the point of declaration, and so eliminates this risk. Isn't that best practice?

(f) I'm still a bit perplexed how can it be that removing 200 lines of unnecessary function calls is not considered a good thing to do? Are patches that only tidy up code generally not accepted? I don't know.

~

That's all I have to say in support of my patch; it will live or it will die according to the community wish.

If nothing else, at least I've learned a new term - "bike shedding" :-)

Kind Regards.
---
Peter Smith
Fujitsu Australia

#62Michael Paquier
michael@paquier.xyz
In reply to: Smith, Peter (#61)
Re: Proposal: Make use of C99 designated initialisers for nulls/values arrays

On Thu, Nov 21, 2019 at 04:50:22AM +0000, Smith, Peter wrote:

I thought this submission actually started out very popular, but
then support slowly eroded, and currently seems headed towards a
likely rejection.

Yeah, it seems to me that this tends to be a rejection, and the thread
has actually died. As we are close to the end of the CF, I am just
updating the patch as such.
--
Michael