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

Go to the source code of this file.

Data Structures

struct  PLyDatumToOb
 
struct  PLyTupleToOb
 
union  PLyTypeInput
 
struct  PLyObToDatum
 
struct  PLyObToTuple
 
union  PLyTypeOutput
 
struct  PLyTypeInfo
 

Typedefs

typedef PyObject *(* PLyDatumToObFunc )(struct PLyDatumToOb *arg, Datum val)
 
typedef struct PLyDatumToOb PLyDatumToOb
 
typedef struct PLyTupleToOb PLyTupleToOb
 
typedef union PLyTypeInput PLyTypeInput
 
typedef Datum(* PLyObToDatumFunc )(struct PLyObToDatum *arg, int32 typmod, PyObject *val, bool inarray)
 
typedef struct PLyObToDatum PLyObToDatum
 
typedef struct PLyObToTuple PLyObToTuple
 
typedef union PLyTypeOutput PLyTypeOutput
 
typedef struct PLyTypeInfo PLyTypeInfo
 

Functions

void PLy_typeinfo_init (PLyTypeInfo *arg, MemoryContext mcxt)
 
void PLy_input_datum_func (PLyTypeInfo *arg, Oid typeOid, HeapTuple typeTup, Oid langid, List *trftypes)
 
void PLy_output_datum_func (PLyTypeInfo *arg, HeapTuple typeTup, Oid langid, List *trftypes)
 
void PLy_input_tuple_funcs (PLyTypeInfo *arg, TupleDesc desc)
 
void PLy_output_tuple_funcs (PLyTypeInfo *arg, TupleDesc desc)
 
void PLy_output_record_funcs (PLyTypeInfo *arg, TupleDesc desc)
 
Datum PLyObject_ToCompositeDatum (PLyTypeInfo *info, TupleDesc desc, PyObject *plrv, bool isarray)
 
PyObject * PLyDict_FromTuple (PLyTypeInfo *info, HeapTuple tuple, TupleDesc desc)
 
char * PLyObject_AsString (PyObject *plrv)
 

Typedef Documentation

typedef PyObject*(* PLyDatumToObFunc)(struct PLyDatumToOb *arg, Datum val)

Definition at line 17 of file plpy_typeio.h.

typedef Datum(* PLyObToDatumFunc)(struct PLyObToDatum *arg, int32 typmod, PyObject *val, bool inarray)

Definition at line 53 of file plpy_typeio.h.

Function Documentation

void PLy_input_datum_func ( PLyTypeInfo arg,
Oid  typeOid,
HeapTuple  typeTup,
Oid  langid,
List trftypes 
)

Definition at line 87 of file plpy_typeio.c.

References PLyTypeInput::d, elog, ERROR, PLyTypeInfo::in, PLyTypeInfo::is_rowtype, PLyTypeInfo::mcxt, and PLy_input_datum_func2().

Referenced by PLy_procedure_create().

88 {
89  if (arg->is_rowtype > 0)
90  elog(ERROR, "PLyTypeInfo struct is initialized for Tuple");
91  arg->is_rowtype = 0;
92  PLy_input_datum_func2(&(arg->in.d), arg->mcxt, typeOid, typeTup, langid, trftypes);
93 }
static void PLy_input_datum_func2(PLyDatumToOb *arg, MemoryContext arg_mcxt, Oid typeOid, HeapTuple typeTup, Oid langid, List *trftypes)
Definition: plpy_typeio.c:438
PLyTypeInput in
Definition: plpy_typeio.h:86
#define ERROR
Definition: elog.h:43
MemoryContext mcxt
Definition: plpy_typeio.h:100
int is_rowtype
Definition: plpy_typeio.h:93
#define elog
Definition: elog.h:219
PLyDatumToOb d
Definition: plpy_typeio.h:41
void PLy_input_tuple_funcs ( PLyTypeInfo arg,
TupleDesc  desc 
)

Definition at line 105 of file plpy_typeio.c.

References Assert, PLyTupleToOb::atts, PLyExecutionContext::curr_proc, elog, ERROR, HeapTupleHeaderGetRawXmin, HeapTupleIsValid, i, PLyTypeInfo::in, PLyTypeInfo::is_rowtype, PLyProcedure::langid, PLyTypeInfo::mcxt, MemoryContextSwitchTo(), PLyTupleToOb::natts, tupleDesc::natts, ObjectIdGetDatum, OidIsValid, palloc0(), pfree(), PLy_current_execution_context(), PLy_input_datum_func2(), PLyTypeInput::r, RECORDOID, ReleaseSysCache(), RELOID, SearchSysCache1, HeapTupleData::t_data, HeapTupleData::t_self, tupleDesc::tdtypeid, tupleDesc::tdtypmod, PLyProcedure::trftypes, TupleDescAttr, PLyTypeInfo::typ_relid, typeidTypeRelid(), TYPEOID, PLyDatumToOb::typoid, PLyTypeInfo::typrel_tid, and PLyTypeInfo::typrel_xmin.

Referenced by PLy_cursor_fetch(), PLy_cursor_iternext(), PLy_exec_trigger(), PLy_function_build_args(), and PLy_spi_execute_fetch_result().

106 {
107  int i;
109  MemoryContext oldcxt;
110 
111  oldcxt = MemoryContextSwitchTo(arg->mcxt);
112 
113  if (arg->is_rowtype == 0)
114  elog(ERROR, "PLyTypeInfo struct is initialized for a Datum");
115  arg->is_rowtype = 1;
116 
117  if (arg->in.r.natts != desc->natts)
118  {
119  if (arg->in.r.atts)
120  pfree(arg->in.r.atts);
121  arg->in.r.natts = desc->natts;
122  arg->in.r.atts = palloc0(desc->natts * sizeof(PLyDatumToOb));
123  }
124 
125  /* Can this be an unnamed tuple? If not, then an Assert would be enough */
126  if (desc->tdtypmod != -1)
127  elog(ERROR, "received unnamed record type as input");
128 
129  Assert(OidIsValid(desc->tdtypeid));
130 
131  /*
132  * RECORDOID means we got called to create input functions for a tuple
133  * fetched by plpy.execute or for an anonymous record type
134  */
135  if (desc->tdtypeid != RECORDOID)
136  {
137  HeapTuple relTup;
138 
139  /* Get the pg_class tuple corresponding to the type of the input */
140  arg->typ_relid = typeidTypeRelid(desc->tdtypeid);
142  if (!HeapTupleIsValid(relTup))
143  elog(ERROR, "cache lookup failed for relation %u", arg->typ_relid);
144 
145  /* Remember XMIN and TID for later validation if cache is still OK */
147  arg->typrel_tid = relTup->t_self;
148 
149  ReleaseSysCache(relTup);
150  }
151 
152  for (i = 0; i < desc->natts; i++)
153  {
154  HeapTuple typeTup;
155  Form_pg_attribute attr = TupleDescAttr(desc, i);
156 
157  if (attr->attisdropped)
158  continue;
159 
160  if (arg->in.r.atts[i].typoid == attr->atttypid)
161  continue; /* already set up this entry */
162 
163  typeTup = SearchSysCache1(TYPEOID, ObjectIdGetDatum(attr->atttypid));
164  if (!HeapTupleIsValid(typeTup))
165  elog(ERROR, "cache lookup failed for type %u",
166  attr->atttypid);
167 
168  PLy_input_datum_func2(&(arg->in.r.atts[i]), arg->mcxt,
169  attr->atttypid,
170  typeTup,
171  exec_ctx->curr_proc->langid,
172  exec_ctx->curr_proc->trftypes);
173 
174  ReleaseSysCache(typeTup);
175  }
176 
177  MemoryContextSwitchTo(oldcxt);
178 }
TransactionId typrel_xmin
Definition: plpy_typeio.h:96
Oid tdtypeid
Definition: tupdesc.h:74
PLyDatumToOb * atts
Definition: plpy_typeio.h:35
#define TupleDescAttr(tupdesc, i)
Definition: tupdesc.h:84
static MemoryContext MemoryContextSwitchTo(MemoryContext context)
Definition: palloc.h:109
Oid typeidTypeRelid(Oid type_id)
Definition: parse_type.c:646
PLyExecutionContext * PLy_current_execution_context(void)
Definition: plpy_main.c:398
#define OidIsValid(objectId)
Definition: c.h:532
int natts
Definition: tupdesc.h:73
#define SearchSysCache1(cacheId, key1)
Definition: syscache.h:159
int32 tdtypmod
Definition: tupdesc.h:75
HeapTupleHeader t_data
Definition: htup.h:67
ItemPointerData typrel_tid
Definition: plpy_typeio.h:97
void pfree(void *pointer)
Definition: mcxt.c:949
static void PLy_input_datum_func2(PLyDatumToOb *arg, MemoryContext arg_mcxt, Oid typeOid, HeapTuple typeTup, Oid langid, List *trftypes)
Definition: plpy_typeio.c:438
PLyTypeInput in
Definition: plpy_typeio.h:86
#define ObjectIdGetDatum(X)
Definition: postgres.h:513
#define ERROR
Definition: elog.h:43
ItemPointerData t_self
Definition: htup.h:65
FormData_pg_attribute * Form_pg_attribute
Definition: pg_attribute.h:187
#define RECORDOID
Definition: pg_type.h:680
PLyProcedure * curr_proc
Definition: plpy_main.h:20
void * palloc0(Size size)
Definition: mcxt.c:877
void ReleaseSysCache(HeapTuple tuple)
Definition: syscache.c:1117
PLyTupleToOb r
Definition: plpy_typeio.h:42
MemoryContext mcxt
Definition: plpy_typeio.h:100
#define HeapTupleIsValid(tuple)
Definition: htup.h:77
#define Assert(condition)
Definition: c.h:664
int is_rowtype
Definition: plpy_typeio.h:93
#define HeapTupleHeaderGetRawXmin(tup)
Definition: htup_details.h:302
int i
#define elog
Definition: elog.h:219
void PLy_output_datum_func ( PLyTypeInfo arg,
HeapTuple  typeTup,
Oid  langid,
List trftypes 
)

Definition at line 96 of file plpy_typeio.c.

References PLyTypeOutput::d, elog, ERROR, PLyTypeInfo::is_rowtype, PLyTypeInfo::mcxt, PLyTypeInfo::out, and PLy_output_datum_func2().

Referenced by PLy_procedure_create(), and PLy_spi_prepare().

97 {
98  if (arg->is_rowtype > 0)
99  elog(ERROR, "PLyTypeInfo struct is initialized for a Tuple");
100  arg->is_rowtype = 0;
101  PLy_output_datum_func2(&(arg->out.d), arg->mcxt, typeTup, langid, trftypes);
102 }
#define ERROR
Definition: elog.h:43
PLyObToDatum d
Definition: plpy_typeio.h:77
PLyTypeOutput out
Definition: plpy_typeio.h:87
MemoryContext mcxt
Definition: plpy_typeio.h:100
int is_rowtype
Definition: plpy_typeio.h:93
static void PLy_output_datum_func2(PLyObToDatum *arg, MemoryContext arg_mcxt, HeapTuple typeTup, Oid langid, List *trftypes)
Definition: plpy_typeio.c:366
#define elog
Definition: elog.h:219
void PLy_output_record_funcs ( PLyTypeInfo arg,
TupleDesc  desc 
)

Definition at line 251 of file plpy_typeio.c.

References Assert, BlessTupleDesc(), PLyTypeOutput::d, PLyTypeInfo::is_rowtype, PLyTypeInfo::out, PLy_output_tuple_funcs(), tupleDesc::tdtypmod, and PLyObToDatum::typmod.

Referenced by PLy_function_build_args().

252 {
253  /*
254  * If the output record functions are already set, we just have to check
255  * if the record descriptor has not changed
256  */
257  if ((arg->is_rowtype == 1) &&
258  (arg->out.d.typmod != -1) &&
259  (arg->out.d.typmod == desc->tdtypmod))
260  return;
261 
262  /* bless the record to make it known to the typcache lookup code */
263  BlessTupleDesc(desc);
264  /* save the freshly generated typmod */
265  arg->out.d.typmod = desc->tdtypmod;
266  /* proceed with normal I/O function caching */
267  PLy_output_tuple_funcs(arg, desc);
268 
269  /*
270  * it should change is_rowtype to 1, so we won't go through this again
271  * unless the output record description changes
272  */
273  Assert(arg->is_rowtype == 1);
274 }
void PLy_output_tuple_funcs(PLyTypeInfo *arg, TupleDesc desc)
Definition: plpy_typeio.c:181
int32 typmod
Definition: plpy_typeio.h:61
int32 tdtypmod
Definition: tupdesc.h:75
PLyObToDatum d
Definition: plpy_typeio.h:77
TupleDesc BlessTupleDesc(TupleDesc tupdesc)
Definition: execTuples.c:1032
PLyTypeOutput out
Definition: plpy_typeio.h:87
#define Assert(condition)
Definition: c.h:664
int is_rowtype
Definition: plpy_typeio.h:93
void PLy_output_tuple_funcs ( PLyTypeInfo arg,
TupleDesc  desc 
)

Definition at line 181 of file plpy_typeio.c.

References Assert, PLyObToTuple::atts, PLyExecutionContext::curr_proc, elog, ERROR, HeapTupleHeaderGetRawXmin, HeapTupleIsValid, i, PLyTypeInfo::is_rowtype, PLyProcedure::langid, PLyTypeInfo::mcxt, MemoryContextSwitchTo(), PLyObToTuple::natts, tupleDesc::natts, ObjectIdGetDatum, OidIsValid, PLyTypeInfo::out, palloc0(), pfree(), PLy_current_execution_context(), PLy_output_datum_func2(), PLyTypeOutput::r, RECORDOID, ReleaseSysCache(), RELOID, SearchSysCache1, HeapTupleData::t_data, HeapTupleData::t_self, tupleDesc::tdtypeid, PLyProcedure::trftypes, TupleDescAttr, PLyTypeInfo::typ_relid, typeidTypeRelid(), TYPEOID, PLyObToDatum::typoid, PLyTypeInfo::typrel_tid, and PLyTypeInfo::typrel_xmin.

Referenced by PLy_exec_trigger(), PLy_output_record_funcs(), PLyGenericObject_ToComposite(), PLyMapping_ToComposite(), and PLySequence_ToComposite().

182 {
183  int i;
185  MemoryContext oldcxt;
186 
187  oldcxt = MemoryContextSwitchTo(arg->mcxt);
188 
189  if (arg->is_rowtype == 0)
190  elog(ERROR, "PLyTypeInfo struct is initialized for a Datum");
191  arg->is_rowtype = 1;
192 
193  if (arg->out.r.natts != desc->natts)
194  {
195  if (arg->out.r.atts)
196  pfree(arg->out.r.atts);
197  arg->out.r.natts = desc->natts;
198  arg->out.r.atts = palloc0(desc->natts * sizeof(PLyObToDatum));
199  }
200 
201  Assert(OidIsValid(desc->tdtypeid));
202 
203  /*
204  * RECORDOID means we got called to create output functions for an
205  * anonymous record type
206  */
207  if (desc->tdtypeid != RECORDOID)
208  {
209  HeapTuple relTup;
210 
211  /* Get the pg_class tuple corresponding to the type of the output */
212  arg->typ_relid = typeidTypeRelid(desc->tdtypeid);
214  if (!HeapTupleIsValid(relTup))
215  elog(ERROR, "cache lookup failed for relation %u", arg->typ_relid);
216 
217  /* Remember XMIN and TID for later validation if cache is still OK */
219  arg->typrel_tid = relTup->t_self;
220 
221  ReleaseSysCache(relTup);
222  }
223 
224  for (i = 0; i < desc->natts; i++)
225  {
226  HeapTuple typeTup;
227  Form_pg_attribute attr = TupleDescAttr(desc, i);
228 
229  if (attr->attisdropped)
230  continue;
231 
232  if (arg->out.r.atts[i].typoid == attr->atttypid)
233  continue; /* already set up this entry */
234 
235  typeTup = SearchSysCache1(TYPEOID, ObjectIdGetDatum(attr->atttypid));
236  if (!HeapTupleIsValid(typeTup))
237  elog(ERROR, "cache lookup failed for type %u",
238  attr->atttypid);
239 
240  PLy_output_datum_func2(&(arg->out.r.atts[i]), arg->mcxt, typeTup,
241  exec_ctx->curr_proc->langid,
242  exec_ctx->curr_proc->trftypes);
243 
244  ReleaseSysCache(typeTup);
245  }
246 
247  MemoryContextSwitchTo(oldcxt);
248 }
TransactionId typrel_xmin
Definition: plpy_typeio.h:96
Oid tdtypeid
Definition: tupdesc.h:74
#define TupleDescAttr(tupdesc, i)
Definition: tupdesc.h:84
static MemoryContext MemoryContextSwitchTo(MemoryContext context)
Definition: palloc.h:109
Oid typeidTypeRelid(Oid type_id)
Definition: parse_type.c:646
PLyExecutionContext * PLy_current_execution_context(void)
Definition: plpy_main.c:398
#define OidIsValid(objectId)
Definition: c.h:532
int natts
Definition: tupdesc.h:73
#define SearchSysCache1(cacheId, key1)
Definition: syscache.h:159
HeapTupleHeader t_data
Definition: htup.h:67
ItemPointerData typrel_tid
Definition: plpy_typeio.h:97
void pfree(void *pointer)
Definition: mcxt.c:949
#define ObjectIdGetDatum(X)
Definition: postgres.h:513
#define ERROR
Definition: elog.h:43
ItemPointerData t_self
Definition: htup.h:65
PLyTypeOutput out
Definition: plpy_typeio.h:87
FormData_pg_attribute * Form_pg_attribute
Definition: pg_attribute.h:187
#define RECORDOID
Definition: pg_type.h:680
PLyProcedure * curr_proc
Definition: plpy_main.h:20
void * palloc0(Size size)
Definition: mcxt.c:877
void ReleaseSysCache(HeapTuple tuple)
Definition: syscache.c:1117
MemoryContext mcxt
Definition: plpy_typeio.h:100
#define HeapTupleIsValid(tuple)
Definition: htup.h:77
#define Assert(condition)
Definition: c.h:664
int is_rowtype
Definition: plpy_typeio.h:93
PLyObToTuple r
Definition: plpy_typeio.h:78
#define HeapTupleHeaderGetRawXmin(tup)
Definition: htup_details.h:302
static void PLy_output_datum_func2(PLyObToDatum *arg, MemoryContext arg_mcxt, HeapTuple typeTup, Oid langid, List *trftypes)
Definition: plpy_typeio.c:366
int i
PLyObToDatum * atts
Definition: plpy_typeio.h:71
#define elog
Definition: elog.h:219
void PLy_typeinfo_init ( PLyTypeInfo arg,
MemoryContext  mcxt 
)

Definition at line 70 of file plpy_typeio.c.

References PLyTupleToOb::atts, PLyObToTuple::atts, PLyTypeInfo::in, InvalidOid, InvalidTransactionId, PLyTypeInfo::is_rowtype, ItemPointerSetInvalid, PLyTypeInfo::mcxt, PLyTupleToOb::natts, PLyObToTuple::natts, PLyTypeInfo::out, PLyTypeInput::r, PLyTypeOutput::r, PLyTypeInfo::typ_relid, PLyTypeInfo::typrel_tid, and PLyTypeInfo::typrel_xmin.

Referenced by PLy_cursor_plan(), PLy_cursor_query(), PLy_procedure_create(), PLy_spi_execute_fetch_result(), PLy_spi_prepare(), PLyObject_ToComposite(), and PLyString_ToComposite().

71 {
72  arg->is_rowtype = -1;
73  arg->in.r.natts = arg->out.r.natts = 0;
74  arg->in.r.atts = NULL;
75  arg->out.r.atts = NULL;
76  arg->typ_relid = InvalidOid;
79  arg->mcxt = mcxt;
80 }
TransactionId typrel_xmin
Definition: plpy_typeio.h:96
PLyDatumToOb * atts
Definition: plpy_typeio.h:35
ItemPointerData typrel_tid
Definition: plpy_typeio.h:97
PLyTypeInput in
Definition: plpy_typeio.h:86
PLyTypeOutput out
Definition: plpy_typeio.h:87
#define InvalidTransactionId
Definition: transam.h:31
PLyTupleToOb r
Definition: plpy_typeio.h:42
#define InvalidOid
Definition: postgres_ext.h:36
MemoryContext mcxt
Definition: plpy_typeio.h:100
int is_rowtype
Definition: plpy_typeio.h:93
PLyObToTuple r
Definition: plpy_typeio.h:78
#define ItemPointerSetInvalid(pointer)
Definition: itemptr.h:150
PLyObToDatum * atts
Definition: plpy_typeio.h:71
PyObject* PLyDict_FromTuple ( PLyTypeInfo info,
HeapTuple  tuple,
TupleDesc  desc 
)

Definition at line 280 of file plpy_typeio.c.

References PLyTupleToOb::atts, CurrentMemoryContext, elog, ERROR, PLyDatumToOb::func, heap_getattr, i, PLyTypeInfo::in, PLyTypeInfo::is_rowtype, MemoryContextReset(), MemoryContextSwitchTo(), NameStr, PLyTupleToOb::natts, PG_CATCH, PG_END_TRY, PG_RE_THROW, PG_TRY, PLy_current_execution_context(), PLy_elog(), PLy_get_scratch_context(), PLyTypeInput::r, TupleDescAttr, and value.

Referenced by PLy_cursor_fetch(), PLy_cursor_iternext(), PLy_function_build_args(), PLy_spi_execute_fetch_result(), and PLy_trigger_build_args().

281 {
282  PyObject *volatile dict;
284  MemoryContext scratch_context = PLy_get_scratch_context(exec_ctx);
285  MemoryContext oldcontext = CurrentMemoryContext;
286 
287  if (info->is_rowtype != 1)
288  elog(ERROR, "PLyTypeInfo structure describes a datum");
289 
290  dict = PyDict_New();
291  if (dict == NULL)
292  PLy_elog(ERROR, "could not create new dictionary");
293 
294  PG_TRY();
295  {
296  int i;
297 
298  /*
299  * Do the work in the scratch context to avoid leaking memory from the
300  * datatype output function calls.
301  */
302  MemoryContextSwitchTo(scratch_context);
303  for (i = 0; i < info->in.r.natts; i++)
304  {
305  char *key;
306  Datum vattr;
307  bool is_null;
308  PyObject *value;
309  Form_pg_attribute attr = TupleDescAttr(desc, i);
310 
311  if (attr->attisdropped)
312  continue;
313 
314  key = NameStr(attr->attname);
315  vattr = heap_getattr(tuple, (i + 1), desc, &is_null);
316 
317  if (is_null || info->in.r.atts[i].func == NULL)
318  PyDict_SetItemString(dict, key, Py_None);
319  else
320  {
321  value = (info->in.r.atts[i].func) (&info->in.r.atts[i], vattr);
322  PyDict_SetItemString(dict, key, value);
323  Py_DECREF(value);
324  }
325  }
326  MemoryContextSwitchTo(oldcontext);
327  MemoryContextReset(scratch_context);
328  }
329  PG_CATCH();
330  {
331  MemoryContextSwitchTo(oldcontext);
332  Py_DECREF(dict);
333  PG_RE_THROW();
334  }
335  PG_END_TRY();
336 
337  return dict;
338 }
PLyDatumToOb * atts
Definition: plpy_typeio.h:35
#define TupleDescAttr(tupdesc, i)
Definition: tupdesc.h:84
void PLy_elog(int elevel, const char *fmt,...)
Definition: plpy_elog.c:47
static MemoryContext MemoryContextSwitchTo(MemoryContext context)
Definition: palloc.h:109
void MemoryContextReset(MemoryContext context)
Definition: mcxt.c:135
PLyExecutionContext * PLy_current_execution_context(void)
Definition: plpy_main.c:398
PLyTypeInput in
Definition: plpy_typeio.h:86
#define ERROR
Definition: elog.h:43
PLyDatumToObFunc func
Definition: plpy_typeio.h:21
static struct @121 value
FormData_pg_attribute * Form_pg_attribute
Definition: pg_attribute.h:187
MemoryContext CurrentMemoryContext
Definition: mcxt.c:37
#define heap_getattr(tup, attnum, tupleDesc, isnull)
Definition: htup_details.h:769
uintptr_t Datum
Definition: postgres.h:372
PLyTupleToOb r
Definition: plpy_typeio.h:42
#define PG_CATCH()
Definition: elog.h:293
int is_rowtype
Definition: plpy_typeio.h:93
#define PG_RE_THROW()
Definition: elog.h:314
int i
#define NameStr(name)
Definition: c.h:493
#define elog
Definition: elog.h:219
#define PG_TRY()
Definition: elog.h:284
#define PG_END_TRY()
Definition: elog.h:300
MemoryContext PLy_get_scratch_context(PLyExecutionContext *context)
Definition: plpy_main.c:407
char* PLyObject_AsString ( PyObject *  plrv)

Definition at line 850 of file plpy_typeio.c.

References elog, ereport, errcode(), errmsg(), ERROR, pg_verifymbstr(), PLy_elog(), PLyUnicode_Bytes(), pstrdup(), PyBytes_AsString, and PyBytes_Size.

Referenced by PLyObject_ToDatum().

851 {
852  PyObject *plrv_bo;
853  char *plrv_sc;
854  size_t plen;
855  size_t slen;
856 
857  if (PyUnicode_Check(plrv))
858  plrv_bo = PLyUnicode_Bytes(plrv);
859  else if (PyFloat_Check(plrv))
860  {
861  /* use repr() for floats, str() is lossy */
862 #if PY_MAJOR_VERSION >= 3
863  PyObject *s = PyObject_Repr(plrv);
864 
865  plrv_bo = PLyUnicode_Bytes(s);
866  Py_XDECREF(s);
867 #else
868  plrv_bo = PyObject_Repr(plrv);
869 #endif
870  }
871  else
872  {
873 #if PY_MAJOR_VERSION >= 3
874  PyObject *s = PyObject_Str(plrv);
875 
876  plrv_bo = PLyUnicode_Bytes(s);
877  Py_XDECREF(s);
878 #else
879  plrv_bo = PyObject_Str(plrv);
880 #endif
881  }
882  if (!plrv_bo)
883  PLy_elog(ERROR, "could not create string representation of Python object");
884 
885  plrv_sc = pstrdup(PyBytes_AsString(plrv_bo));
886  plen = PyBytes_Size(plrv_bo);
887  slen = strlen(plrv_sc);
888 
889  Py_XDECREF(plrv_bo);
890 
891  if (slen < plen)
892  ereport(ERROR,
893  (errcode(ERRCODE_DATATYPE_MISMATCH),
894  errmsg("could not convert Python object into cstring: Python string representation appears to contain null bytes")));
895  else if (slen > plen)
896  elog(ERROR, "could not convert Python object into cstring: Python string longer than reported length");
897  pg_verifymbstr(plrv_sc, slen, false);
898 
899  return plrv_sc;
900 }
char * pstrdup(const char *in)
Definition: mcxt.c:1076
void PLy_elog(int elevel, const char *fmt,...)
Definition: plpy_elog.c:47
int errcode(int sqlerrcode)
Definition: elog.c:575
#define PyBytes_AsString
Definition: plpython.h:84
#define ERROR
Definition: elog.h:43
#define ereport(elevel, rest)
Definition: elog.h:122
#define PyBytes_Size
Definition: plpython.h:86
PyObject * PLyUnicode_Bytes(PyObject *unicode)
Definition: plpy_util.c:26
int errmsg(const char *fmt,...)
Definition: elog.c:797
bool pg_verifymbstr(const char *mbstr, int len, bool noError)
Definition: wchar.c:1866
#define elog
Definition: elog.h:219
Datum PLyObject_ToCompositeDatum ( PLyTypeInfo info,
TupleDesc  desc,
PyObject *  plrv,
bool  isarray 
)

Definition at line 346 of file plpy_typeio.c.

References PLyGenericObject_ToComposite(), PLyMapping_ToComposite(), PLySequence_ToComposite(), and PLyString_ToComposite().

Referenced by PLy_exec_function(), and PLyObject_ToComposite().

347 {
348  Datum datum;
349 
350  if (PyString_Check(plrv) || PyUnicode_Check(plrv))
351  datum = PLyString_ToComposite(info, desc, plrv, inarray);
352  else if (PySequence_Check(plrv))
353  /* composite type as sequence (tuple, list etc) */
354  datum = PLySequence_ToComposite(info, desc, plrv);
355  else if (PyMapping_Check(plrv))
356  /* composite type as mapping (currently only dict) */
357  datum = PLyMapping_ToComposite(info, desc, plrv);
358  else
359  /* returned as smth, must provide method __getattr__(name) */
360  datum = PLyGenericObject_ToComposite(info, desc, plrv, inarray);
361 
362  return datum;
363 }
static Datum PLyString_ToComposite(PLyTypeInfo *info, TupleDesc desc, PyObject *string, bool inarray)
Definition: plpy_typeio.c:1131
uintptr_t Datum
Definition: postgres.h:372
static Datum PLyGenericObject_ToComposite(PLyTypeInfo *info, TupleDesc desc, PyObject *object, bool inarray)
Definition: plpy_typeio.c:1331
static Datum PLyMapping_ToComposite(PLyTypeInfo *info, TupleDesc desc, PyObject *mapping)
Definition: plpy_typeio.c:1165
static Datum PLySequence_ToComposite(PLyTypeInfo *info, TupleDesc desc, PyObject *sequence)
Definition: plpy_typeio.c:1242