Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Skip to content

Commit 52713d0

Browse files
committed
Refactor PLy_spi_prepare to save two levels of indentation
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
1 parent ea2c264 commit 52713d0

File tree

1 file changed

+66
-66
lines changed

1 file changed

+66
-66
lines changed

src/pl/plpython/plpython.c

+66-66
Original file line numberDiff line numberDiff line change
@@ -2817,6 +2817,7 @@ PLy_spi_prepare(PyObject *self, PyObject *args)
28172817
char *query;
28182818
void *tmpplan;
28192819
volatile MemoryContext oldcontext;
2820+
int nargs;
28202821

28212822
if (!PyArg_ParseTuple(args, "s|O", &query, &list))
28222823
{
@@ -2835,80 +2836,78 @@ PLy_spi_prepare(PyObject *self, PyObject *args)
28352836
if ((plan = (PLyPlanObject *) PLy_plan_new()) == NULL)
28362837
return NULL;
28372838

2839+
nargs = list ? PySequence_Length(list) : 0;
2840+
2841+
plan->nargs = nargs;
2842+
plan->types = nargs ? PLy_malloc(sizeof(Oid) * nargs) : NULL;
2843+
plan->values = nargs ? PLy_malloc(sizeof(Datum) * nargs) : NULL;
2844+
plan->args = nargs ? PLy_malloc(sizeof(PLyTypeInfo) * nargs) : NULL;
2845+
28382846
oldcontext = CurrentMemoryContext;
28392847
PG_TRY();
28402848
{
2841-
if (list != NULL)
2849+
int i;
2850+
2851+
/*
2852+
* the other loop might throw an exception, if PLyTypeInfo
2853+
* member isn't properly initialized the Py_DECREF(plan) will
2854+
* go boom
2855+
*/
2856+
for (i = 0; i < nargs; i++)
28422857
{
2843-
int nargs,
2844-
i;
2858+
PLy_typeinfo_init(&plan->args[i]);
2859+
plan->values[i] = PointerGetDatum(NULL);
2860+
}
28452861

2846-
nargs = PySequence_Length(list);
2847-
if (nargs > 0)
2862+
for (i = 0; i < nargs; i++)
2863+
{
2864+
char *sptr;
2865+
HeapTuple typeTup;
2866+
Oid typeId;
2867+
int32 typmod;
2868+
Form_pg_type typeStruct;
2869+
2870+
optr = PySequence_GetItem(list, i);
2871+
if (PyString_Check(optr))
2872+
sptr = PyString_AsString(optr);
2873+
else if (PyUnicode_Check(optr))
2874+
sptr = PLyUnicode_AsString(optr);
2875+
else
28482876
{
2849-
plan->nargs = nargs;
2850-
plan->types = PLy_malloc(sizeof(Oid) * nargs);
2851-
plan->values = PLy_malloc(sizeof(Datum) * nargs);
2852-
plan->args = PLy_malloc(sizeof(PLyTypeInfo) * nargs);
2877+
ereport(ERROR,
2878+
(errmsg("plpy.prepare: type name at ordinal position %d is not a string", i)));
2879+
sptr = NULL; /* keep compiler quiet */
2880+
}
28532881

2854-
/*
2855-
* the other loop might throw an exception, if PLyTypeInfo
2856-
* member isn't properly initialized the Py_DECREF(plan) will
2857-
* go boom
2858-
*/
2859-
for (i = 0; i < nargs; i++)
2860-
{
2861-
PLy_typeinfo_init(&plan->args[i]);
2862-
plan->values[i] = PointerGetDatum(NULL);
2863-
}
2882+
/********************************************************
2883+
* Resolve argument type names and then look them up by
2884+
* oid in the system cache, and remember the required
2885+
*information for input conversion.
2886+
********************************************************/
28642887

2865-
for (i = 0; i < nargs; i++)
2866-
{
2867-
char *sptr;
2868-
HeapTuple typeTup;
2869-
Oid typeId;
2870-
int32 typmod;
2871-
Form_pg_type typeStruct;
2872-
2873-
optr = PySequence_GetItem(list, i);
2874-
if (PyString_Check(optr))
2875-
sptr = PyString_AsString(optr);
2876-
else if (PyUnicode_Check(optr))
2877-
sptr = PLyUnicode_AsString(optr);
2878-
else
2879-
{
2880-
ereport(ERROR,
2881-
(errmsg("plpy.prepare: type name at ordinal position %d is not a string", i)));
2882-
sptr = NULL; /* keep compiler quiet */
2883-
}
2884-
2885-
/********************************************************
2886-
* Resolve argument type names and then look them up by
2887-
* oid in the system cache, and remember the required
2888-
*information for input conversion.
2889-
********************************************************/
2890-
2891-
parseTypeString(sptr, &typeId, &typmod);
2892-
2893-
typeTup = SearchSysCache1(TYPEOID,
2894-
ObjectIdGetDatum(typeId));
2895-
if (!HeapTupleIsValid(typeTup))
2896-
elog(ERROR, "cache lookup failed for type %u", typeId);
2897-
2898-
Py_DECREF(optr);
2899-
optr = NULL; /* this is important */
2900-
2901-
plan->types[i] = typeId;
2902-
typeStruct = (Form_pg_type) GETSTRUCT(typeTup);
2903-
if (typeStruct->typtype != TYPTYPE_COMPOSITE)
2904-
PLy_output_datum_func(&plan->args[i], typeTup);
2905-
else
2906-
ereport(ERROR,
2907-
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
2908-
errmsg("plpy.prepare does not support composite types")));
2909-
ReleaseSysCache(typeTup);
2910-
}
2911-
}
2888+
parseTypeString(sptr, &typeId, &typmod);
2889+
2890+
typeTup = SearchSysCache1(TYPEOID,
2891+
ObjectIdGetDatum(typeId));
2892+
if (!HeapTupleIsValid(typeTup))
2893+
elog(ERROR, "cache lookup failed for type %u", typeId);
2894+
2895+
Py_DECREF(optr);
2896+
/*
2897+
* set optr to NULL, so we won't try to unref it again in
2898+
* case of an error
2899+
*/
2900+
optr = NULL;
2901+
2902+
plan->types[i] = typeId;
2903+
typeStruct = (Form_pg_type) GETSTRUCT(typeTup);
2904+
if (typeStruct->typtype != TYPTYPE_COMPOSITE)
2905+
PLy_output_datum_func(&plan->args[i], typeTup);
2906+
else
2907+
ereport(ERROR,
2908+
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
2909+
errmsg("plpy.prepare does not support composite types")));
2910+
ReleaseSysCache(typeTup);
29122911
}
29132912

29142913
pg_verifymbstr(query, strlen(query), false);
@@ -2943,6 +2942,7 @@ PLy_spi_prepare(PyObject *self, PyObject *args)
29432942
}
29442943
PG_END_TRY();
29452944

2945+
Assert(plan->plan != NULL);
29462946
return (PyObject *) plan;
29472947
}
29482948

0 commit comments

Comments
 (0)