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 56 of file plpy_cursorobject.c.

57 {
58  char *query;
59  PyObject *plan;
60  PyObject *planargs = NULL;
61 
62  if (PyArg_ParseTuple(args, "s", &query))
63  return PLy_cursor_query(query);
64 
65  PyErr_Clear();
66 
67  if (PyArg_ParseTuple(args, "O|O", &plan, &planargs))
68  return PLy_cursor_plan(plan, planargs);
69 
70  PLy_exception_set(PLy_exc_error, "plpy.cursor expected a query or a plan");
71  return NULL;
72 }
#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 49 of file plpy_cursorobject.c.

50 {
51  if (PyType_Ready(&PLy_CursorType) < 0)
52  elog(ERROR, "could not initialize PLy_CursorType");
53 }
#define ERROR
Definition: elog.h:39
#define elog(elevel,...)
Definition: elog.h:225
static PyTypeObject PLy_CursorType

References elog, ERROR, and PLy_CursorType.

Referenced by PLy_init_plpy().

◆ PLy_cursor_plan()

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

Definition at line 139 of file plpy_cursorobject.c.

140 {
142  volatile int nargs;
143  int i;
146  volatile MemoryContext oldcontext;
147  volatile ResourceOwner oldowner;
148 
149  if (args)
150  {
151  if (!PySequence_Check(args) || PyUnicode_Check(args))
152  {
153  PLy_exception_set(PyExc_TypeError, "plpy.cursor takes a sequence as its second argument");
154  return NULL;
155  }
156  nargs = PySequence_Length(args);
157  }
158  else
159  nargs = 0;
160 
161  plan = (PLyPlanObject *) ob;
162 
163  if (nargs != plan->nargs)
164  {
165  char *sv;
166  PyObject *so = PyObject_Str(args);
167 
168  if (!so)
169  PLy_elog(ERROR, "could not execute plan");
170  sv = PLyUnicode_AsString(so);
171  PLy_exception_set_plural(PyExc_TypeError,
172  "Expected sequence of %d argument, got %d: %s",
173  "Expected sequence of %d arguments, got %d: %s",
174  plan->nargs,
175  plan->nargs, nargs, sv);
176  Py_DECREF(so);
177 
178  return NULL;
179  }
180 
181  if ((cursor = PyObject_New(PLyCursorObject, &PLy_CursorType)) == NULL)
182  return NULL;
183  cursor->portalname = NULL;
184  cursor->closed = false;
186  "PL/Python cursor context",
188 
189  /* Initialize for converting result tuples to Python */
190  PLy_input_setup_func(&cursor->result, cursor->mcxt,
191  RECORDOID, -1,
192  exec_ctx->curr_proc);
193 
194  oldcontext = CurrentMemoryContext;
195  oldowner = CurrentResourceOwner;
196 
197  PLy_spi_subtransaction_begin(oldcontext, oldowner);
198 
199  PG_TRY();
200  {
201  Portal portal;
202  char *volatile nulls;
203  volatile int j;
204 
205  if (nargs > 0)
206  nulls = palloc(nargs * sizeof(char));
207  else
208  nulls = NULL;
209 
210  for (j = 0; j < nargs; j++)
211  {
212  PLyObToDatum *arg = &plan->args[j];
213  PyObject *elem;
214 
215  elem = PySequence_GetItem(args, j);
216  PG_TRY(2);
217  {
218  bool isnull;
219 
220  plan->values[j] = PLy_output_convert(arg, elem, &isnull);
221  nulls[j] = isnull ? 'n' : ' ';
222  }
223  PG_FINALLY(2);
224  {
225  Py_DECREF(elem);
226  }
227  PG_END_TRY(2);
228  }
229 
230  portal = SPI_cursor_open(NULL, plan->plan, plan->values, nulls,
231  exec_ctx->curr_proc->fn_readonly);
232  if (portal == NULL)
233  elog(ERROR, "SPI_cursor_open() failed: %s",
235 
236  cursor->portalname = MemoryContextStrdup(cursor->mcxt, portal->name);
237 
238  PinPortal(portal);
239 
240  PLy_spi_subtransaction_commit(oldcontext, oldowner);
241  }
242  PG_CATCH();
243  {
244  int k;
245 
246  /* cleanup plan->values array */
247  for (k = 0; k < nargs; k++)
248  {
249  if (!plan->args[k].typbyval &&
250  (plan->values[k] != PointerGetDatum(NULL)))
251  {
252  pfree(DatumGetPointer(plan->values[k]));
253  plan->values[k] = PointerGetDatum(NULL);
254  }
255  }
256 
257  Py_DECREF(cursor);
258 
259  PLy_spi_subtransaction_abort(oldcontext, oldowner);
260  return NULL;
261  }
262  PG_END_TRY();
263 
264  for (i = 0; i < nargs; i++)
265  {
266  if (!plan->args[i].typbyval &&
267  (plan->values[i] != PointerGetDatum(NULL)))
268  {
269  pfree(DatumGetPointer(plan->values[i]));
270  plan->values[i] = PointerGetDatum(NULL);
271  }
272  }
273 
274  Assert(cursor->portalname != NULL);
275  return (PyObject *) cursor;
276 }
#define Assert(condition)
Definition: c.h:837
#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
int j
Definition: isn.c:73
int i
Definition: isn.c:72
#define PLy_elog
void pfree(void *pointer)
Definition: mcxt.c:1521
MemoryContext TopMemoryContext
Definition: mcxt.c:149
MemoryContext CurrentMemoryContext
Definition: mcxt.c:143
char * MemoryContextStrdup(MemoryContext context, const char *string)
Definition: mcxt.c:1683
void * palloc(Size size)
Definition: mcxt.c:1317
#define AllocSetContextCreate
Definition: memutils.h:129
#define ALLOCSET_DEFAULT_SIZES
Definition: memutils.h:160
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:365
void PLy_spi_subtransaction_commit(MemoryContext oldcontext, ResourceOwner oldowner)
Definition: plpy_spi.c:582
void PLy_spi_subtransaction_abort(MemoryContext oldcontext, ResourceOwner oldowner)
Definition: plpy_spi.c:591
void PLy_spi_subtransaction_begin(MemoryContext oldcontext, ResourceOwner oldowner)
Definition: plpy_spi.c:574
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:371
static Datum PointerGetDatum(const void *X)
Definition: postgres.h:322
static Pointer DatumGetPointer(Datum X)
Definition: postgres.h:312
ResourceOwner CurrentResourceOwner
Definition: resowner.c:165
int SPI_result
Definition: spi.c:46
const char * SPI_result_code_string(int code)
Definition: spi.c:1972
Portal SPI_cursor_open(const char *name, SPIPlanPtr plan, Datum *Values, const char *Nulls, bool read_only)
Definition: spi.c:1445
PLyProcedure * curr_proc
Definition: plpy_main.h:20
const char * name
Definition: portal.h:118
Definition: type.h:138

References ALLOCSET_DEFAULT_SIZES, AllocSetContextCreate, arg, generate_unaccent_rules::args, Assert, PLyExecutionContext::curr_proc, CurrentMemoryContext, CurrentResourceOwner, DatumGetPointer(), elog, ERROR, PLyProcedure::fn_readonly, i, j, MemoryContextStrdup(), PortalData::name, palloc(), pfree(), 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(), PointerGetDatum(), SPI_cursor_open(), SPI_result, SPI_result_code_string(), and TopMemoryContext.

Referenced by PLy_cursor(), and PLy_plan_cursor().