From 6a5b230f741fb4272770d09750b57fdad225027e Mon Sep 17 00:00:00 2001
From: Alvaro Herrera <alvherre@alvh.no-ip.org>
Date: Thu, 28 Nov 2019 19:08:43 -0300
Subject: [PATCH 1/6] Simplify makeMultirangeConstructors

---
 src/backend/commands/typecmds.c | 134 +++++++++++++++++++-------------
 1 file changed, 80 insertions(+), 54 deletions(-)

diff --git a/src/backend/commands/typecmds.c b/src/backend/commands/typecmds.c
index 38948a049b..1b012c9cad 100644
--- a/src/backend/commands/typecmds.c
+++ b/src/backend/commands/typecmds.c
@@ -1784,70 +1784,96 @@ static void
 makeMultirangeConstructors(const char *name, Oid namespace,
 						   Oid multirangeOid, Oid rangeArrayOid)
 {
-	static const char *const prosrc[2] = {"multirange_constructor0",
-	"multirange_constructor1"};
-	static const int pronargs[2] = {0, 1};
-
-	Oid			constructorArgTypes = rangeArrayOid;
 	ObjectAddress myself,
 				referenced;
-	int			i;
-
-	Datum		allParamTypes[1] = {ObjectIdGetDatum(rangeArrayOid)};
-	ArrayType  *allParameterTypes = construct_array(allParamTypes, 1, OIDOID,
-													sizeof(Oid), true, 'i');
-	Datum		constructorAllParamTypes[2] = {PointerGetDatum(NULL), PointerGetDatum(allParameterTypes)};
-
-	Datum		paramModes[1] = {CharGetDatum(FUNC_PARAM_VARIADIC)};
-	ArrayType  *parameterModes = construct_array(paramModes, 1, CHAROID,
-												 1, true, 'c');
-	Datum		constructorParamModes[2] = {PointerGetDatum(NULL), PointerGetDatum(parameterModes)};
+	oidvector  *argtypes;
+	Datum		allParamTypes;
+	ArrayType  *allParameterTypes;
+	Datum		paramModes;
+	ArrayType  *parameterModes;
 
 	referenced.classId = TypeRelationId;
 	referenced.objectId = multirangeOid;
 	referenced.objectSubId = 0;
 
-	for (i = 0; i < lengthof(prosrc); i++)
-	{
-		oidvector  *constructorArgTypesVector;
+	argtypes = buildoidvector(NULL, 0);
+	myself = ProcedureCreate(name,	/* name: same as multirange type */
+							 namespace,
+							 false, /* replace */
+							 false, /* returns set */
+							 multirangeOid, /* return type */
+							 BOOTSTRAP_SUPERUSERID, /* proowner */
+							 INTERNALlanguageId,	/* language */
+							 F_FMGR_INTERNAL_VALIDATOR,
+							 "multirange_constructor0", /* prosrc */
+							 NULL,	/* probin */
+							 PROKIND_FUNCTION,
+							 false, /* security_definer */
+							 false, /* leakproof */
+							 false, /* isStrict */
+							 PROVOLATILE_IMMUTABLE, /* volatility */
+							 PROPARALLEL_SAFE,	/* parallel safety */
+							 argtypes,	/* parameterTypes */
+							 PointerGetDatum(NULL), /* allParameterTypes */
+							 PointerGetDatum(NULL), /* parameterModes */
+							 PointerGetDatum(NULL), /* parameterNames */
+							 NIL,	/* parameterDefaults */
+							 PointerGetDatum(NULL), /* trftypes */
+							 PointerGetDatum(NULL), /* proconfig */
+							 InvalidOid,	/* prosupport */
+							 1.0,	/* procost */
+							 0.0);	/* prorows */
 
-		constructorArgTypesVector = buildoidvector(&constructorArgTypes,
-												   pronargs[i]);
+	/*
+	 * Make the constructor internally-dependent on the multirange type so
+	 * that they go away silently when the type is dropped.  Note that pg_dump
+	 * depends on this choice to avoid dumping the constructors.
+	 */
+	recordDependencyOn(&myself, &referenced, DEPENDENCY_INTERNAL);
 
-		myself = ProcedureCreate(name,	/* name: same as multirange type */
-								 namespace, /* namespace */
-								 false, /* replace */
-								 false, /* returns set */
-								 multirangeOid, /* return type */
-								 BOOTSTRAP_SUPERUSERID, /* proowner */
-								 INTERNALlanguageId,	/* language */
-								 F_FMGR_INTERNAL_VALIDATOR, /* language validator */
-								 prosrc[i], /* prosrc */
-								 NULL,	/* probin */
-								 PROKIND_FUNCTION,
-								 false, /* security_definer */
-								 false, /* leakproof */
-								 false, /* isStrict */
-								 PROVOLATILE_IMMUTABLE, /* volatility */
-								 PROPARALLEL_SAFE,	/* parallel safety */
-								 constructorArgTypesVector, /* parameterTypes */
-								 constructorAllParamTypes[i],	/* allParameterTypes */
-								 constructorParamModes[i],	/* parameterModes */
-								 PointerGetDatum(NULL), /* parameterNames */
-								 NIL,	/* parameterDefaults */
-								 PointerGetDatum(NULL), /* trftypes */
-								 PointerGetDatum(NULL), /* proconfig */
-								 InvalidOid,	/* prosupport */
-								 1.0,	/* procost */
-								 0.0);	/* prorows */
+	pfree(argtypes);
 
-		/*
-		 * Make the constructors internally-dependent on the multirange type
-		 * so that they go away silently when the type is dropped.  Note that
-		 * pg_dump depends on this choice to avoid dumping the constructors.
-		 */
-		recordDependencyOn(&myself, &referenced, DEPENDENCY_INTERNAL);
-	}
+	argtypes = buildoidvector(&rangeArrayOid, 1);
+	allParamTypes = ObjectIdGetDatum(rangeArrayOid);
+	allParameterTypes = construct_array(&allParamTypes,
+										1, OIDOID,
+										sizeof(Oid), true, 'i');
+	paramModes = CharGetDatum(FUNC_PARAM_VARIADIC);
+	parameterModes = construct_array(&paramModes, 1, CHAROID,
+									 1, true, 'c');
+
+	myself = ProcedureCreate(name,	/* name: same as multirange type */
+							 namespace,
+							 false, /* replace */
+							 false, /* returns set */
+							 multirangeOid, /* return type */
+							 BOOTSTRAP_SUPERUSERID, /* proowner */
+							 INTERNALlanguageId,	/* language */
+							 F_FMGR_INTERNAL_VALIDATOR,
+							 "multirange_constructor1", /* prosrc */
+							 NULL,	/* probin */
+							 PROKIND_FUNCTION,
+							 false, /* security_definer */
+							 false, /* leakproof */
+							 false, /* isStrict */
+							 PROVOLATILE_IMMUTABLE, /* volatility */
+							 PROPARALLEL_SAFE,	/* parallel safety */
+							 argtypes,	/* parameterTypes */
+							 PointerGetDatum(allParameterTypes),	/* allParameterTypes */
+							 PointerGetDatum(parameterModes),	/* parameterModes */
+							 PointerGetDatum(NULL), /* parameterNames */
+							 NIL,	/* parameterDefaults */
+							 PointerGetDatum(NULL), /* trftypes */
+							 PointerGetDatum(NULL), /* proconfig */
+							 InvalidOid,	/* prosupport */
+							 1.0,	/* procost */
+							 0.0);	/* prorows */
+	/* ditto */
+	recordDependencyOn(&myself, &referenced, DEPENDENCY_INTERNAL);
+
+	pfree(argtypes);
+	pfree(allParameterTypes);
+	pfree(parameterModes);
 }
 
 /*
-- 
2.20.1

