39 PyObject *
list = NULL;
40 PyObject *
volatile optr = NULL;
47 if (!PyArg_ParseTuple(
args,
"s|O:prepare", &query, &
list))
50 if (
list && (!PySequence_Check(
list)))
53 "second argument of plpy.prepare must be a sequence");
61 "PL/Python plan context",
65 nargs =
list ? PySequence_Length(
list) : 0;
82 for (
i = 0;
i < nargs;
i++)
88 optr = PySequence_GetItem(
list,
i);
89 if (PyUnicode_Check(optr))
94 (
errmsg(
"plpy.prepare: type name at ordinal position %d is not a string",
i)));
114 plan->types[
i] = typeId;
122 if (
plan->plan == NULL)
143 return (PyObject *)
plan;
154 PyObject *
list = NULL;
157 if (PyArg_ParseTuple(
args,
"s|l", &query, &limit))
162 if (PyArg_ParseTuple(
args,
"O|Ol", &
plan, &
list, &limit) &&
182 if (!PySequence_Check(
list) || PyUnicode_Check(
list))
184 PLy_exception_set(PyExc_TypeError,
"plpy.execute takes a sequence as its second argument");
187 nargs = PySequence_Length(
list);
194 if (nargs !=
plan->nargs)
197 PyObject *so = PyObject_Str(
list);
203 "Expected sequence of %d argument, got %d: %s",
204 "Expected sequence of %d arguments, got %d: %s",
206 plan->nargs, nargs, sv);
222 char *
volatile nulls;
230 "PL/Python temporary context",
237 nulls = (
char *)
palloc(nargs *
sizeof(
char));
245 for (
j = 0;
j < nargs;
j++)
250 elem = PySequence_GetItem(
list,
j);
256 nulls[
j] = isnull ?
'n' :
' ';
285 "SPI_execute_plan failed: %s",
299 PyObject *ret = NULL;
327 "SPI_execute failed: %s",
348 Py_DECREF(result->
status);
349 result->
status = PyLong_FromLong(status);
351 if (status > 0 && tuptable == NULL)
353 Py_DECREF(result->
nrows);
354 result->
nrows = PyLong_FromUnsignedLongLong(rows);
356 else if (status > 0 && tuptable != NULL)
361 Py_DECREF(result->
nrows);
362 result->
nrows = PyLong_FromUnsignedLongLong(rows);
365 "PL/Python temp context",
386 if (rows > (
uint64) PY_SSIZE_T_MAX)
388 (
errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
389 errmsg(
"query result has too many rows to fit in a Python list")));
391 Py_DECREF(result->
rows);
392 result->
rows = PyList_New(rows);
398 for (
i = 0;
i < rows;
i++)
405 PyList_SetItem(result->
rows,
i, row);
442 return (PyObject *) result;
619 PyObject *
args = NULL;
620 PyObject *spierror = NULL;
621 PyObject *spidata = NULL;
628 spierror = PyObject_CallObject(excclass,
args);
639 if (PyObject_SetAttrString(spierror,
"spidata", spidata) == -1)
642 PyErr_SetObject(excclass, spierror);
651 Py_XDECREF(spierror);
653 elog(
ERROR,
"could not convert SPI error to Python exception");
static Datum values[MAXATTR]
void * hash_search(HTAB *hashp, const void *keyPtr, HASHACTION action, bool *foundPtr)
void FreeErrorData(ErrorData *edata)
ErrorData * CopyErrorData(void)
void FlushErrorState(void)
int errcode(int sqlerrcode)
int errmsg(const char *fmt,...)
#define ereport(elevel,...)
Assert(PointerIsAligned(start, uint64))
bool pg_verifymbstr(const char *mbstr, int len, bool noError)
void * palloc0(Size size)
MemoryContext TopMemoryContext
MemoryContext CurTransactionContext
MemoryContext CurrentMemoryContext
void MemoryContextDelete(MemoryContext context)
#define AllocSetContextCreate
#define ALLOCSET_DEFAULT_SIZES
#define ALLOCSET_SMALL_SIZES
static MemoryContext MemoryContextSwitchTo(MemoryContext context)
bool parseTypeString(const char *str, Oid *typeid_p, int32 *typmod_p, Node *escontext)
PyObject * PLy_exc_spi_error
void PLy_exception_set(PyObject *exc, const char *fmt,...)
void PLy_exception_set_plural(PyObject *exc, const char *fmt_singular, const char *fmt_plural, unsigned long n,...)
PLyExecutionContext * PLy_current_execution_context(void)
PyObject * PLy_plan_new(void)
bool is_PLyPlanObject(PyObject *ob)
HTAB * PLy_spi_exceptions
PyObject * PLy_result_new(void)
void PLy_spi_subtransaction_commit(MemoryContext oldcontext, ResourceOwner oldowner)
PyObject * PLy_spi_prepare(PyObject *self, PyObject *args)
static PyObject * PLy_spi_execute_fetch_result(SPITupleTable *tuptable, uint64 rows, int status)
PyObject * PLy_spi_execute_plan(PyObject *ob, PyObject *list, long limit)
PyObject * PLy_commit(PyObject *self, PyObject *args)
PyObject * PLy_rollback(PyObject *self, PyObject *args)
static PyObject * PLy_spi_execute_query(char *query, long limit)
PyObject * PLy_spi_execute(PyObject *self, PyObject *args)
void PLy_spi_subtransaction_abort(MemoryContext oldcontext, ResourceOwner oldowner)
static void PLy_spi_exception_set(PyObject *excclass, ErrorData *edata)
void PLy_spi_subtransaction_begin(MemoryContext oldcontext, ResourceOwner oldowner)
void PLy_output_setup_func(PLyObToDatum *arg, MemoryContext arg_mcxt, Oid typeOid, int32 typmod, PLyProcedure *proc)
void PLy_input_setup_func(PLyDatumToOb *arg, MemoryContext arg_mcxt, Oid typeOid, int32 typmod, PLyProcedure *proc)
PyObject * PLy_input_from_tuple(PLyDatumToOb *arg, HeapTuple tuple, TupleDesc desc, bool include_generated)
void PLy_input_setup_tuple(PLyDatumToOb *arg, TupleDesc desc, PLyProcedure *proc)
Datum PLy_output_convert(PLyObToDatum *arg, PyObject *val, bool *isnull)
char * PLyUnicode_AsString(PyObject *unicode)
ResourceOwner CurrentResourceOwner
const char * SPI_result_code_string(int code)
SPITupleTable * SPI_tuptable
int SPI_execute_plan(SPIPlanPtr plan, Datum *Values, const char *Nulls, bool read_only, long tcount)
void SPI_freetuptable(SPITupleTable *tuptable)
SPIPlanPtr SPI_prepare(const char *src, int nargs, Oid *argtypes)
int SPI_keepplan(SPIPlanPtr plan)
int SPI_execute(const char *src, bool read_only, long tcount)
MemoryContext scratch_ctx
PyObject_HEAD PyObject * nrows
TupleDesc CreateTupleDescCopy(TupleDesc tupdesc)
void BeginInternalSubTransaction(const char *name)
void RollbackAndReleaseCurrentSubTransaction(void)
void ReleaseCurrentSubTransaction(void)