42 PyObject *
list = NULL;
43 PyObject *
volatile optr = NULL;
50 if (!PyArg_ParseTuple(args,
"s|O:prepare", &query, &list))
53 if (list && (!PySequence_Check(list)))
56 "second argument of plpy.prepare must be a sequence");
64 "PL/Python plan context",
68 nargs = list ? PySequence_Length(list) : 0;
86 for (i = 0; i < nargs; i++)
92 optr = PySequence_GetItem(list, i);
93 if (PyString_Check(optr))
94 sptr = PyString_AsString(optr);
95 else if (PyUnicode_Check(optr))
100 (
errmsg(
"plpy.prepare: type name at ordinal position %d is not a string", i)));
128 if (plan->
plan == NULL)
149 return (PyObject *) plan;
160 PyObject *
list = NULL;
163 if (PyArg_ParseTuple(args,
"s|l", &query, &limit))
168 if (PyArg_ParseTuple(args,
"O|Ol", &plan, &list, &limit) &&
189 if (!PySequence_Check(list) || PyString_Check(list) || PyUnicode_Check(list))
191 PLy_exception_set(PyExc_TypeError,
"plpy.execute takes a sequence as its second argument");
194 nargs = PySequence_Length(list);
201 if (nargs != plan->
nargs)
204 PyObject *so = PyObject_Str(list);
208 sv = PyString_AsString(so);
210 "Expected sequence of %d argument, got %d: %s",
211 "Expected sequence of %d arguments, got %d: %s",
213 plan->
nargs, nargs, sv);
227 char *
volatile nulls;
231 nulls =
palloc(nargs *
sizeof(
char));
235 for (j = 0; j < nargs; j++)
240 elem = PySequence_GetItem(list, j);
246 nulls[j] = isnull ?
'n' :
' ';
271 for (k = 0; k < nargs; k++)
286 for (i = 0; i < nargs; i++)
299 "SPI_execute_plan failed: %s",
313 PyObject *ret = NULL;
341 "SPI_execute failed: %s",
362 Py_DECREF(result->
status);
363 result->
status = PyInt_FromLong(status);
365 if (status > 0 && tuptable == NULL)
367 Py_DECREF(result->
nrows);
368 result->
nrows = PyLong_FromUnsignedLongLong(rows);
370 else if (status > 0 && tuptable != NULL)
375 Py_DECREF(result->
nrows);
376 result->
nrows = PyLong_FromUnsignedLongLong(rows);
379 "PL/Python temp context",
400 if (rows > (uint64) PY_SSIZE_T_MAX)
402 (
errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
403 errmsg(
"query result has too many rows to fit in a Python list")));
405 Py_DECREF(result->
rows);
406 result->
rows = PyList_New(rows);
412 for (i = 0; i < rows; i++)
419 PyList_SetItem(result->
rows, i, row);
456 return (PyObject *) result;
539 PyObject *
args = NULL;
540 PyObject *spierror = NULL;
541 PyObject *spidata = NULL;
543 args = Py_BuildValue(
"(s)", edata->
message);
548 spierror = PyObject_CallObject(excclass, args);
559 if (PyObject_SetAttrString(spierror,
"spidata", spidata) == -1)
562 PyErr_SetObject(excclass, spierror);
571 Py_XDECREF(spierror);
573 elog(
ERROR,
"could not convert SPI error to Python exception");
static void PLy_spi_exception_set(PyObject *excclass, ErrorData *edata)
TupleDesc CreateTupleDescCopy(TupleDesc tupdesc)
void MemoryContextDelete(MemoryContext context)
void PLy_exception_set_plural(PyObject *exc, const char *fmt_singular, const char *fmt_plural, unsigned long n,...)
#define AllocSetContextCreate
Datum PLy_output_convert(PLyObToDatum *arg, PyObject *val, bool *isnull)
void PLy_spi_subtransaction_abort(MemoryContext oldcontext, ResourceOwner oldowner)
ErrorData * CopyErrorData(void)
#define PointerGetDatum(X)
ResourceOwner CurrentResourceOwner
SPIPlanPtr SPI_prepare(const char *src, int nargs, Oid *argtypes)
void ReleaseCurrentSubTransaction(void)
static MemoryContext MemoryContextSwitchTo(MemoryContext context)
SPITupleTable * SPI_tuptable
int errcode(int sqlerrcode)
void * hash_search(HTAB *hashp, const void *keyPtr, HASHACTION action, bool *foundPtr)
PLyExecutionContext * PLy_current_execution_context(void)
void PLy_exception_set(PyObject *exc, const char *fmt,...)
bool is_PLyPlanObject(PyObject *ob)
void FlushErrorState(void)
char * PLyUnicode_AsString(PyObject *unicode)
void PLy_spi_subtransaction_begin(MemoryContext oldcontext, ResourceOwner oldowner)
void pfree(void *pointer)
void FreeErrorData(ErrorData *edata)
int SPI_execute_plan(SPIPlanPtr plan, Datum *Values, const char *Nulls, bool read_only, long tcount)
const char * SPI_result_code_string(int code)
#define ALLOCSET_DEFAULT_SIZES
int SPI_keepplan(SPIPlanPtr plan)
void RollbackAndReleaseCurrentSubTransaction(void)
void PLy_input_setup_tuple(PLyDatumToOb *arg, TupleDesc desc, PLyProcedure *proc)
void PLy_input_setup_func(PLyDatumToOb *arg, MemoryContext arg_mcxt, Oid typeOid, int32 typmod, PLyProcedure *proc)
PyObject_HEAD SPIPlanPtr plan
MemoryContext CurrentMemoryContext
MemoryContext TopMemoryContext
void SPI_freetuptable(SPITupleTable *tuptable)
static PyObject * PLy_spi_execute_fetch_result(SPITupleTable *tuptable, uint64 rows, int status)
PyObject * PLy_spi_execute_plan(PyObject *ob, PyObject *list, long limit)
void * palloc0(Size size)
PyObject * PLy_plan_new(void)
void parseTypeString(const char *str, Oid *typeid_p, int32 *typmod_p, bool missing_ok)
bool pg_verifymbstr(const char *mbstr, int len, bool noError)
#define ereport(elevel,...)
#define Assert(condition)
PyObject * PLy_spi_execute(PyObject *self, PyObject *args)
void BeginInternalSubTransaction(const char *name)
PyObject * PLy_input_from_tuple(PLyDatumToOb *arg, HeapTuple tuple, TupleDesc desc, bool include_generated)
HTAB * PLy_spi_exceptions
static PyObject * PLy_spi_execute_query(char *query, long limit)
#define DatumGetPointer(X)
void PLy_output_setup_func(PLyObToDatum *arg, MemoryContext arg_mcxt, Oid typeOid, int32 typmod, PLyProcedure *proc)
PyObject * PLy_result_new(void)
void PLy_spi_subtransaction_commit(MemoryContext oldcontext, ResourceOwner oldowner)
int errmsg(const char *fmt,...)
PyObject_HEAD PyObject * nrows
static void static void status(const char *fmt,...) pg_attribute_printf(1
PyObject * PLy_exc_spi_error
PyObject * PLy_spi_prepare(PyObject *self, PyObject *args)
int SPI_execute(const char *src, bool read_only, long tcount)