PostgreSQL Source Code git master
All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Pages
plpy_cursorobject.h File Reference
#include "plpy_typeio.h"
Include dependency graph for plpy_cursorobject.h:
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Data Structures

struct  PLyCursorObject
 

Typedefs

typedef struct PLyCursorObject PLyCursorObject
 

Functions

void PLy_cursor_init_type (void)
 
PyObject * PLy_cursor (PyObject *self, PyObject *args)
 
PyObject * PLy_cursor_plan (PyObject *ob, PyObject *args)
 

Typedef Documentation

◆ PLyCursorObject

Function Documentation

◆ PLy_cursor()

PyObject * PLy_cursor ( PyObject *  self,
PyObject *  args 
)

Definition at line 77 of file plpy_cursorobject.c.

78{
79 char *query;
80 PyObject *plan;
81 PyObject *planargs = NULL;
82
83 if (PyArg_ParseTuple(args, "s", &query))
84 return PLy_cursor_query(query);
85
86 PyErr_Clear();
87
88 if (PyArg_ParseTuple(args, "O|O", &plan, &planargs))
89 return PLy_cursor_plan(plan, planargs);
90
91 PLy_exception_set(PLy_exc_error, "plpy.cursor expected a query or a plan");
92 return NULL;
93}
#define plan(x)
Definition: pg_regress.c:161
PyObject * PLy_cursor_plan(PyObject *ob, PyObject *args)
static PyObject * PLy_cursor_query(const char *query)
PyObject * PLy_exc_error
Definition: plpy_elog.c:15
void PLy_exception_set(PyObject *exc, const char *fmt,...)
Definition: plpy_elog.c:472

References generate_unaccent_rules::args, plan, PLy_cursor_plan(), PLy_cursor_query(), PLy_exc_error, and PLy_exception_set().

◆ PLy_cursor_init_type()

void PLy_cursor_init_type ( void  )

Definition at line 69 of file plpy_cursorobject.c.

70{
71 PLy_CursorType = (PyTypeObject *) PyType_FromSpec(&PLyCursor_spec);
72 if (!PLy_CursorType)
73 elog(ERROR, "could not initialize PLy_CursorType");
74}
#define ERROR
Definition: elog.h:39
#define elog(elevel,...)
Definition: elog.h:225
static PyType_Spec PLyCursor_spec
static PyTypeObject * PLy_CursorType

References elog, ERROR, PLy_CursorType, and PLyCursor_spec.

Referenced by PLy_init_plpy().

◆ PLy_cursor_plan()

PyObject * PLy_cursor_plan ( PyObject *  ob,
PyObject *  args 
)

Definition at line 164 of file plpy_cursorobject.c.

165{
167 volatile int nargs;
170 volatile MemoryContext oldcontext;
171 volatile ResourceOwner oldowner;
172
173 if (args)
174 {
175 if (!PySequence_Check(args) || PyUnicode_Check(args))
176 {
177 PLy_exception_set(PyExc_TypeError, "plpy.cursor takes a sequence as its second argument");
178 return NULL;
179 }
180 nargs = PySequence_Length(args);
181 }
182 else
183 nargs = 0;
184
185 plan = (PLyPlanObject *) ob;
186
187 if (nargs != plan->nargs)
188 {
189 char *sv;
190 PyObject *so = PyObject_Str(args);
191
192 if (!so)
193 PLy_elog(ERROR, "could not execute plan");
194 sv = PLyUnicode_AsString(so);
195 PLy_exception_set_plural(PyExc_TypeError,
196 "Expected sequence of %d argument, got %d: %s",
197 "Expected sequence of %d arguments, got %d: %s",
198 plan->nargs,
199 plan->nargs, nargs, sv);
200 Py_DECREF(so);
201
202 return NULL;
203 }
204
205 if ((cursor = PyObject_New(PLyCursorObject, PLy_CursorType)) == NULL)
206 return NULL;
207#if PY_VERSION_HEX < 0x03080000
208 /* Workaround for Python issue 35810; no longer necessary in Python 3.8 */
209 Py_INCREF(PLy_CursorType);
210#endif
211 cursor->portalname = NULL;
212 cursor->closed = false;
214 "PL/Python cursor context",
216
217 /* Initialize for converting result tuples to Python */
218 PLy_input_setup_func(&cursor->result, cursor->mcxt,
219 RECORDOID, -1,
220 exec_ctx->curr_proc);
221
222 oldcontext = CurrentMemoryContext;
223 oldowner = CurrentResourceOwner;
224
225 PLy_spi_subtransaction_begin(oldcontext, oldowner);
226
227 PG_TRY();
228 {
229 Portal portal;
230 MemoryContext tmpcontext;
231 Datum *volatile values;
232 char *volatile nulls;
233 volatile int j;
234
235 /*
236 * Converted arguments and associated cruft will be in this context,
237 * which is local to our subtransaction.
238 */
240 "PL/Python temporary context",
242 MemoryContextSwitchTo(tmpcontext);
243
244 if (nargs > 0)
245 {
246 values = (Datum *) palloc(nargs * sizeof(Datum));
247 nulls = (char *) palloc(nargs * sizeof(char));
248 }
249 else
250 {
251 values = NULL;
252 nulls = NULL;
253 }
254
255 for (j = 0; j < nargs; j++)
256 {
257 PLyObToDatum *arg = &plan->args[j];
258 PyObject *elem;
259
260 elem = PySequence_GetItem(args, j);
261 PG_TRY(2);
262 {
263 bool isnull;
264
265 values[j] = PLy_output_convert(arg, elem, &isnull);
266 nulls[j] = isnull ? 'n' : ' ';
267 }
268 PG_FINALLY(2);
269 {
270 Py_DECREF(elem);
271 }
272 PG_END_TRY(2);
273 }
274
275 MemoryContextSwitchTo(oldcontext);
276
277 portal = SPI_cursor_open(NULL, plan->plan, values, nulls,
278 exec_ctx->curr_proc->fn_readonly);
279 if (portal == NULL)
280 elog(ERROR, "SPI_cursor_open() failed: %s",
282
283 cursor->portalname = MemoryContextStrdup(cursor->mcxt, portal->name);
284
285 PinPortal(portal);
286
287 MemoryContextDelete(tmpcontext);
288 PLy_spi_subtransaction_commit(oldcontext, oldowner);
289 }
290 PG_CATCH();
291 {
292 Py_DECREF(cursor);
293 /* Subtransaction abort will remove the tmpcontext */
294 PLy_spi_subtransaction_abort(oldcontext, oldowner);
295 return NULL;
296 }
297 PG_END_TRY();
298
299 Assert(cursor->portalname != NULL);
300 return (PyObject *) cursor;
301}
static Datum values[MAXATTR]
Definition: bootstrap.c:151
#define PG_TRY(...)
Definition: elog.h:371
#define PG_END_TRY(...)
Definition: elog.h:396
#define PG_CATCH(...)
Definition: elog.h:381
#define PG_FINALLY(...)
Definition: elog.h:388
Assert(PointerIsAligned(start, uint64))
int j
Definition: isn.c:78
#define PLy_elog
char * MemoryContextStrdup(MemoryContext context, const char *string)
Definition: mcxt.c:1686
MemoryContext TopMemoryContext
Definition: mcxt.c:149
void * palloc(Size size)
Definition: mcxt.c:1317
MemoryContext CurTransactionContext
Definition: mcxt.c:155
MemoryContext CurrentMemoryContext
Definition: mcxt.c:143
void MemoryContextDelete(MemoryContext context)
Definition: mcxt.c:454
#define AllocSetContextCreate
Definition: memutils.h:129
#define ALLOCSET_DEFAULT_SIZES
Definition: memutils.h:160
#define ALLOCSET_SMALL_SIZES
Definition: memutils.h:170
static MemoryContext MemoryContextSwitchTo(MemoryContext context)
Definition: palloc.h:124
void * arg
void PLy_exception_set_plural(PyObject *exc, const char *fmt_singular, const char *fmt_plural, unsigned long n,...)
Definition: plpy_elog.c:486
PLyExecutionContext * PLy_current_execution_context(void)
Definition: plpy_main.c:368
void PLy_spi_subtransaction_commit(MemoryContext oldcontext, ResourceOwner oldowner)
Definition: plpy_spi.c:573
void PLy_spi_subtransaction_abort(MemoryContext oldcontext, ResourceOwner oldowner)
Definition: plpy_spi.c:582
void PLy_spi_subtransaction_begin(MemoryContext oldcontext, ResourceOwner oldowner)
Definition: plpy_spi.c:565
void PLy_input_setup_func(PLyDatumToOb *arg, MemoryContext arg_mcxt, Oid typeOid, int32 typmod, PLyProcedure *proc)
Definition: plpy_typeio.c:418
Datum PLy_output_convert(PLyObToDatum *arg, PyObject *val, bool *isnull)
Definition: plpy_typeio.c:120
char * PLyUnicode_AsString(PyObject *unicode)
Definition: plpy_util.c:82
void PinPortal(Portal portal)
Definition: portalmem.c:373
uintptr_t Datum
Definition: postgres.h:69
ResourceOwner CurrentResourceOwner
Definition: resowner.c:173
const char * SPI_result_code_string(int code)
Definition: spi.c:1974
int SPI_result
Definition: spi.c:46
Portal SPI_cursor_open(const char *name, SPIPlanPtr plan, Datum *Values, const char *Nulls, bool read_only)
Definition: spi.c:1446
PLyProcedure * curr_proc
Definition: plpy_main.h:20
const char * name
Definition: portal.h:118
Definition: type.h:138

References ALLOCSET_DEFAULT_SIZES, ALLOCSET_SMALL_SIZES, AllocSetContextCreate, arg, generate_unaccent_rules::args, Assert(), PLyExecutionContext::curr_proc, CurrentMemoryContext, CurrentResourceOwner, CurTransactionContext, elog, ERROR, PLyProcedure::fn_readonly, j, MemoryContextDelete(), MemoryContextStrdup(), MemoryContextSwitchTo(), PortalData::name, palloc(), PG_CATCH, PG_END_TRY, PG_FINALLY, PG_TRY, PinPortal(), plan, PLy_current_execution_context(), PLy_CursorType, PLy_elog, PLy_exception_set(), PLy_exception_set_plural(), PLy_input_setup_func(), PLy_output_convert(), PLy_spi_subtransaction_abort(), PLy_spi_subtransaction_begin(), PLy_spi_subtransaction_commit(), PLyUnicode_AsString(), SPI_cursor_open(), SPI_result, SPI_result_code_string(), TopMemoryContext, and values.

Referenced by PLy_cursor(), and PLy_plan_cursor().