From 96788cc4dae14e8508eac9cdec90b0feeed99e31 Mon Sep 17 00:00:00 2001
From: postgres <postgre@CentOS7-x64.au.fjanz.com>
Date: Wed, 18 Sep 2019 15:38:06 +1000
Subject: [PATCH] Add compile-time asserts to expose any inconsistencies
 between arrays and enums that depend on each other

---
 src/backend/utils/adt/lockfuncs.c | 13 +++++++++++++
 src/backend/utils/misc/guc.c      | 29 +++++++++++++++++++++++++++++
 src/bin/pg_dump/pg_dump_sort.c    | 12 ++++++++++++
 src/common/relpath.c              | 12 ++++++++++++
 4 files changed, 66 insertions(+)

diff --git a/src/backend/utils/adt/lockfuncs.c b/src/backend/utils/adt/lockfuncs.c
index bc62c6e..0032ccd 100644
--- a/src/backend/utils/adt/lockfuncs.c
+++ b/src/backend/utils/adt/lockfuncs.c
@@ -1039,3 +1039,16 @@ pg_advisory_unlock_all(PG_FUNCTION_ARGS)
 
 	PG_RETURN_VOID();
 }
+
+/*
+ * Compile-time assertions.
+ */
+static inline void 
+ct_asserts(void)
+{
+	/*
+ 	 * When arrays use enum indices check if there are the correct number of elements.
+ 	 */
+	StaticAssertStmt(lengthof(LockTagTypeNames) == LOCKTAG_ADVISORY+1, "LockTagTypeNames array inconsistency");
+	StaticAssertStmt(lengthof(PredicateLockTagTypeNames) == PREDLOCKTAG_TUPLE+1, "PredicateLockTagTypeNames array inconsistency");		
+}
diff --git a/src/backend/utils/misc/guc.c b/src/backend/utils/misc/guc.c
index 90ffd89..550eb75 100644
--- a/src/backend/utils/misc/guc.c
+++ b/src/backend/utils/misc/guc.c
@@ -11715,4 +11715,33 @@ check_default_with_oids(bool *newval, void **extra, GucSource source)
 	return true;
 }
 
+/*
+ * Compile-time assertions.
+ */
+static inline void 
+ct_asserts(void)
+{
+        /*
+ 	 * Ensure arrays which use enum indices have the required number of elements.
+	 */
+        StaticAssertStmt(lengthof(GucContext_Names) == PGC_USERSET+1, "GucContext_Names array inconsistency");
+        StaticAssertStmt(lengthof(GucSource_Names) == PGC_S_SESSION+1, "GucSource_Names array inconsistency");
+        StaticAssertStmt(lengthof(config_group_names) == DEVELOPER_OPTIONS+1+1, "config_group_names array inconsistency");
+        StaticAssertStmt(lengthof(config_type_names) == PGC_ENUM+1, "config_type_names array inconsistency");
+
+	/*
+	 * When option values are 0..N check if the arrays have all values accounted for.
+	 */ 
+	StaticAssertStmt(lengthof(bytea_output_options) == BYTEA_OUTPUT_HEX+1+1, "bytea_output_options array inconsistency");
+	StaticAssertStmt(lengthof(intervalstyle_options) == INTSTYLE_ISO_8601+1+1, "intervalstyle_options array inconsistency");		
+	StaticAssertStmt(lengthof(log_error_verbosity_options) == PGERROR_VERBOSE+1+1, "log_error_verbosity_options array inconsistency");
+	StaticAssertStmt(lengthof(log_statement_options) == LOGSTMT_ALL+1+1, "log_statement_options array inconsistency");
+	StaticAssertStmt(lengthof(session_replication_role_options) == SESSION_REPLICATION_ROLE_LOCAL+1+1, "session_replication_role_options array inconsistency");
+	StaticAssertStmt(lengthof(track_function_options) == TRACK_FUNC_ALL+1+1, "track_function_options array inconsistency");
+	StaticAssertStmt(lengthof(xmlbinary_options) == XMLBINARY_HEX+1+1, "xmlbinary_options array inconsistency");
+	StaticAssertStmt(lengthof(xmloption_options) == XMLOPTION_CONTENT+1+1, "xmloption_options array inconsistency");
+	StaticAssertStmt(lengthof(ssl_protocol_versions_info) == PG_TLS1_3_VERSION+1+1, "ssl_protocol_versions_info array inconsistency");
+}
+
+
 #include "guc-file.c"
diff --git a/src/bin/pg_dump/pg_dump_sort.c b/src/bin/pg_dump/pg_dump_sort.c
index 31fc06a..46d8e39 100644
--- a/src/bin/pg_dump/pg_dump_sort.c
+++ b/src/bin/pg_dump/pg_dump_sort.c
@@ -1410,3 +1410,15 @@ describeDumpableObject(DumpableObject *obj, char *buf, int bufsize)
 			 (int) obj->objType,
 			 obj->dumpId, obj->catId.oid);
 }
+
+/*
+ * Compile-time assertions.
+ */
+static inline void 
+ct_asserts(void)
+{
+	/*
+	 * When arrays use enum indices check if there are the correct number of elements.
+	 */
+	StaticAssertStmt(lengthof(dbObjectTypePriority) == DO_SUBSCRIPTION+1, "dbObjectTypePriority array inconsistency");
+}
diff --git a/src/common/relpath.c b/src/common/relpath.c
index 62b9553..0b0901b 100644
--- a/src/common/relpath.c
+++ b/src/common/relpath.c
@@ -205,3 +205,15 @@ GetRelationPath(Oid dbNode, Oid spcNode, Oid relNode,
 	}
 	return path;
 }
+
+/*
+ * Compile-time assertions.
+ */
+static inline void 
+ct_asserts(void)
+{
+	/*
+	 * When arrays use enum indices check if there are the correct number of elements.
+	 */
+	StaticAssertStmt(lengthof(forkNames) == (MAX_FORKNUM+1), "forkNames array inconsistency");
+}
-- 
1.8.3.1

