From 52713d02c73926898629e349a9804cd0cae0470b Mon Sep 17 00:00:00 2001
From: Peter Eisentraut <peter_e@gmx.net>
Date: Mon, 24 Jan 2011 22:12:01 +0200
Subject: [PATCH] Refactor PLy_spi_prepare to save two levels of indentation
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Instead of checking whether the arglist is NULL and then if its length
is 0, do it in one step, and outside of the try/catch block.

Jan Urbański
---
 src/pl/plpython/plpython.c | 132 ++++++++++++++++++-------------------
 1 file changed, 66 insertions(+), 66 deletions(-)

diff --git a/src/pl/plpython/plpython.c b/src/pl/plpython/plpython.c
index 947d3e63f92..cb04f12382e 100644
--- a/src/pl/plpython/plpython.c
+++ b/src/pl/plpython/plpython.c
@@ -2817,6 +2817,7 @@ PLy_spi_prepare(PyObject *self, PyObject *args)
 	char	   *query;
 	void	   *tmpplan;
 	volatile MemoryContext oldcontext;
+	int			nargs;
 
 	if (!PyArg_ParseTuple(args, "s|O", &query, &list))
 	{
@@ -2835,80 +2836,78 @@ PLy_spi_prepare(PyObject *self, PyObject *args)
 	if ((plan = (PLyPlanObject *) PLy_plan_new()) == NULL)
 		return NULL;
 
+	nargs = list ? PySequence_Length(list) : 0;
+
+	plan->nargs = nargs;
+	plan->types = nargs ? PLy_malloc(sizeof(Oid) * nargs) : NULL;
+	plan->values = nargs ? PLy_malloc(sizeof(Datum) * nargs) : NULL;
+	plan->args = nargs ? PLy_malloc(sizeof(PLyTypeInfo) * nargs) : NULL;
+
 	oldcontext = CurrentMemoryContext;
 	PG_TRY();
 	{
-		if (list != NULL)
+		int	i;
+
+		/*
+		 * the other loop might throw an exception, if PLyTypeInfo
+		 * member isn't properly initialized the Py_DECREF(plan) will
+		 * go boom
+		 */
+		for (i = 0; i < nargs; i++)
 		{
-			int			nargs,
-						i;
+			PLy_typeinfo_init(&plan->args[i]);
+			plan->values[i] = PointerGetDatum(NULL);
+		}
 
-			nargs = PySequence_Length(list);
-			if (nargs > 0)
+		for (i = 0; i < nargs; i++)
+		{
+			char	   *sptr;
+			HeapTuple	typeTup;
+			Oid			typeId;
+			int32		typmod;
+			Form_pg_type typeStruct;
+
+			optr = PySequence_GetItem(list, i);
+			if (PyString_Check(optr))
+				sptr = PyString_AsString(optr);
+			else if (PyUnicode_Check(optr))
+				sptr = PLyUnicode_AsString(optr);
+			else
 			{
-				plan->nargs = nargs;
-				plan->types = PLy_malloc(sizeof(Oid) * nargs);
-				plan->values = PLy_malloc(sizeof(Datum) * nargs);
-				plan->args = PLy_malloc(sizeof(PLyTypeInfo) * nargs);
+				ereport(ERROR,
+						(errmsg("plpy.prepare: type name at ordinal position %d is not a string", i)));
+				sptr = NULL;	/* keep compiler quiet */
+			}
 
-				/*
-				 * the other loop might throw an exception, if PLyTypeInfo
-				 * member isn't properly initialized the Py_DECREF(plan) will
-				 * go boom
-				 */
-				for (i = 0; i < nargs; i++)
-				{
-					PLy_typeinfo_init(&plan->args[i]);
-					plan->values[i] = PointerGetDatum(NULL);
-				}
+			/********************************************************
+			 * Resolve argument type names and then look them up by
+			 * oid in the system cache, and remember the required
+			 *information for input conversion.
+			 ********************************************************/
 
-				for (i = 0; i < nargs; i++)
-				{
-					char	   *sptr;
-					HeapTuple	typeTup;
-					Oid			typeId;
-					int32		typmod;
-					Form_pg_type typeStruct;
-
-					optr = PySequence_GetItem(list, i);
-					if (PyString_Check(optr))
-						sptr = PyString_AsString(optr);
-					else if (PyUnicode_Check(optr))
-						sptr = PLyUnicode_AsString(optr);
-					else
-					{
-						ereport(ERROR,
-								(errmsg("plpy.prepare: type name at ordinal position %d is not a string", i)));
-						sptr = NULL;	/* keep compiler quiet */
-					}
-
-					/********************************************************
-					 * Resolve argument type names and then look them up by
-					 * oid in the system cache, and remember the required
-					 *information for input conversion.
-					 ********************************************************/
-
-					parseTypeString(sptr, &typeId, &typmod);
-
-					typeTup = SearchSysCache1(TYPEOID,
-											  ObjectIdGetDatum(typeId));
-					if (!HeapTupleIsValid(typeTup))
-						elog(ERROR, "cache lookup failed for type %u", typeId);
-
-					Py_DECREF(optr);
-					optr = NULL;	/* this is important */
-
-					plan->types[i] = typeId;
-					typeStruct = (Form_pg_type) GETSTRUCT(typeTup);
-					if (typeStruct->typtype != TYPTYPE_COMPOSITE)
-						PLy_output_datum_func(&plan->args[i], typeTup);
-					else
-						ereport(ERROR,
-								(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
-								 errmsg("plpy.prepare does not support composite types")));
-					ReleaseSysCache(typeTup);
-				}
-			}
+			parseTypeString(sptr, &typeId, &typmod);
+
+			typeTup = SearchSysCache1(TYPEOID,
+									  ObjectIdGetDatum(typeId));
+			if (!HeapTupleIsValid(typeTup))
+				elog(ERROR, "cache lookup failed for type %u", typeId);
+
+			Py_DECREF(optr);
+			/*
+			 * set optr to NULL, so we won't try to unref it again in
+			 * case of an error
+			 */
+			optr = NULL;
+
+			plan->types[i] = typeId;
+			typeStruct = (Form_pg_type) GETSTRUCT(typeTup);
+			if (typeStruct->typtype != TYPTYPE_COMPOSITE)
+				PLy_output_datum_func(&plan->args[i], typeTup);
+			else
+				ereport(ERROR,
+						(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
+						 errmsg("plpy.prepare does not support composite types")));
+			ReleaseSysCache(typeTup);
 		}
 
 		pg_verifymbstr(query, strlen(query), false);
@@ -2943,6 +2942,7 @@ PLy_spi_prepare(PyObject *self, PyObject *args)
 	}
 	PG_END_TRY();
 
+	Assert(plan->plan != NULL);
 	return (PyObject *) plan;
 }
 
-- 
GitLab