{
MemoryContext oldcontext2;
- /*
- * Save tuple descriptor for later use by result set metadata
- * functions. Save it in TopMemoryContext so that it survives
- * outside of an SPI context. We trust that PLy_result_dealloc()
- * will clean it up when the time is right.
- */
- oldcontext2 = MemoryContextSwitchTo(TopMemoryContext);
- result->tupdesc = CreateTupleDescCopy(tuptable->tupdesc);
- MemoryContextSwitchTo(oldcontext2);
-
if (rows)
{
Py_DECREF(result->rows);
PLy_input_tuple_funcs(&args, tuptable->tupdesc);
for (i = 0; i < rows; i++)
{
- PyObject *row = PLyDict_FromTuple(&args, tuptable->vals[i],
+ PyObject *row = PLyDict_FromTuple(&args,
+ tuptable->vals[i],
tuptable->tupdesc);
PyList_SetItem(result->rows, i, row);
}
}
+
+ /*
+ * Save tuple descriptor for later use by result set metadata
+ * functions. Save it in TopMemoryContext so that it survives
+ * outside of an SPI context. We trust that PLy_result_dealloc()
+ * will clean it up when the time is right. (Do this as late as
+ * possible, to minimize the number of ways the tupdesc could get
+ * leaked due to errors.)
+ */
+ oldcontext2 = MemoryContextSwitchTo(TopMemoryContext);
+ result->tupdesc = CreateTupleDescCopy(tuptable->tupdesc);
+ MemoryContextSwitchTo(oldcontext2);
}
PG_CATCH();
{
MemoryContextSwitchTo(oldcontext);
- if (!PyErr_Occurred())
- PLy_exception_set(PLy_exc_error,
- "unrecognized error in PLy_spi_execute_fetch_result");
PLy_typeinfo_dealloc(&args);
SPI_freetuptable(tuptable);
Py_DECREF(result);
- return NULL;
+ PG_RE_THROW();
}
PG_END_TRY();