|
|
|
@ -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,21 +2836,17 @@ 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 nargs, |
|
|
|
|
i; |
|
|
|
|
|
|
|
|
|
nargs = PySequence_Length(list); |
|
|
|
|
if (nargs > 0) |
|
|
|
|
{ |
|
|
|
|
plan->nargs = nargs; |
|
|
|
|
plan->types = PLy_malloc(sizeof(Oid) * nargs); |
|
|
|
|
plan->values = PLy_malloc(sizeof(Datum) * nargs); |
|
|
|
|
plan->args = PLy_malloc(sizeof(PLyTypeInfo) * nargs); |
|
|
|
|
int i; |
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* the other loop might throw an exception, if PLyTypeInfo |
|
|
|
@ -2896,7 +2893,11 @@ PLy_spi_prepare(PyObject *self, PyObject *args) |
|
|
|
|
elog(ERROR, "cache lookup failed for type %u", typeId); |
|
|
|
|
|
|
|
|
|
Py_DECREF(optr); |
|
|
|
|
optr = NULL; /* this is important */ |
|
|
|
|
/*
|
|
|
|
|
* 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); |
|
|
|
@ -2908,8 +2909,6 @@ PLy_spi_prepare(PyObject *self, PyObject *args) |
|
|
|
|
errmsg("plpy.prepare does not support composite types"))); |
|
|
|
|
ReleaseSysCache(typeTup); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
pg_verifymbstr(query, strlen(query), false); |
|
|
|
|
plan->plan = SPI_prepare(query, plan->nargs, plan->types); |
|
|
|
@ -2943,6 +2942,7 @@ PLy_spi_prepare(PyObject *self, PyObject *args) |
|
|
|
|
} |
|
|
|
|
PG_END_TRY(); |
|
|
|
|
|
|
|
|
|
Assert(plan->plan != NULL); |
|
|
|
|
return (PyObject *) plan; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|