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:437
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, tupleDesc::attrs, 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, 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 
156  if (desc->attrs[i]->attisdropped)
157  continue;
158 
159  if (arg->in.r.atts[i].typoid == desc->attrs[i]->atttypid)
160  continue; /* already set up this entry */
161 
162  typeTup = SearchSysCache1(TYPEOID,
163  ObjectIdGetDatum(desc->attrs[i]->atttypid));
164  if (!HeapTupleIsValid(typeTup))
165  elog(ERROR, "cache lookup failed for type %u",
166  desc->attrs[i]->atttypid);
167 
168  PLy_input_datum_func2(&(arg->in.r.atts[i]), arg->mcxt,
169  desc->attrs[i]->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:77
PLyDatumToOb * atts
Definition: plpy_typeio.h:35
Form_pg_attribute * attrs
Definition: tupdesc.h:74
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:534
int natts
Definition: tupdesc.h:73
#define SearchSysCache1(cacheId, key1)
Definition: syscache.h:149
int32 tdtypmod
Definition: tupdesc.h:78
HeapTupleHeader t_data
Definition: htup.h:67
ItemPointerData typrel_tid
Definition: plpy_typeio.h:97
void pfree(void *pointer)
Definition: mcxt.c:992
static void PLy_input_datum_func2(PLyDatumToOb *arg, MemoryContext arg_mcxt, Oid typeOid, HeapTuple typeTup, Oid langid, List *trftypes)
Definition: plpy_typeio.c:437
PLyTypeInput in
Definition: plpy_typeio.h:86
#define ObjectIdGetDatum(X)
Definition: postgres.h:515
#define ERROR
Definition: elog.h:43
ItemPointerData t_self
Definition: htup.h:65
#define RECORDOID
Definition: pg_type.h:668
PLyProcedure * curr_proc
Definition: plpy_main.h:20
void * palloc0(Size size)
Definition: mcxt.c:920
void ReleaseSysCache(HeapTuple tuple)
Definition: syscache.c:1083
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:671
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:365
#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:78
PLyObToDatum d
Definition: plpy_typeio.h:77
TupleDesc BlessTupleDesc(TupleDesc tupdesc)
Definition: execTuples.c:1031
PLyTypeOutput out
Definition: plpy_typeio.h:87
#define Assert(condition)
Definition: c.h:671
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, tupleDesc::attrs, 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, 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 
228  if (desc->attrs[i]->attisdropped)
229  continue;
230 
231  if (arg->out.r.atts[i].typoid == desc->attrs[i]->atttypid)
232  continue; /* already set up this entry */
233 
234  typeTup = SearchSysCache1(TYPEOID,
235  ObjectIdGetDatum(desc->attrs[i]->atttypid));
236  if (!HeapTupleIsValid(typeTup))
237  elog(ERROR, "cache lookup failed for type %u",
238  desc->attrs[i]->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:77
Form_pg_attribute * attrs
Definition: tupdesc.h:74
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:534
int natts
Definition: tupdesc.h:73
#define SearchSysCache1(cacheId, key1)
Definition: syscache.h:149
HeapTupleHeader t_data
Definition: htup.h:67
ItemPointerData typrel_tid
Definition: plpy_typeio.h:97
void pfree(void *pointer)
Definition: mcxt.c:992
#define ObjectIdGetDatum(X)
Definition: postgres.h:515
#define ERROR
Definition: elog.h:43
ItemPointerData t_self
Definition: htup.h:65
PLyTypeOutput out
Definition: plpy_typeio.h:87
#define RECORDOID
Definition: pg_type.h:668
PLyProcedure * curr_proc
Definition: plpy_main.h:20
void * palloc0(Size size)
Definition: mcxt.c:920
void ReleaseSysCache(HeapTuple tuple)
Definition: syscache.c:1083
MemoryContext mcxt
Definition: plpy_typeio.h:100
#define HeapTupleIsValid(tuple)
Definition: htup.h:77
#define Assert(condition)
Definition: c.h:671
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:365
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, NULL, 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
#define NULL
Definition: c.h:226
int is_rowtype
Definition: plpy_typeio.h:93
PLyObToTuple r
Definition: plpy_typeio.h:78
#define ItemPointerSetInvalid(pointer)
Definition: itemptr.h:131
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 tupleDesc::attrs, PLyTupleToOb::atts, CurrentMemoryContext, elog, ERROR, PLyDatumToOb::func, heap_getattr, i, PLyTypeInfo::in, PLyTypeInfo::is_rowtype, MemoryContextReset(), MemoryContextSwitchTo(), NameStr, PLyTupleToOb::natts, NULL, PG_CATCH, PG_END_TRY, PG_RE_THROW, PG_TRY, PLy_current_execution_context(), PLy_elog(), PLy_get_scratch_context(), PLyTypeInput::r, 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 
310  if (desc->attrs[i]->attisdropped)
311  continue;
312 
313  key = NameStr(desc->attrs[i]->attname);
314  vattr = heap_getattr(tuple, (i + 1), desc, &is_null);
315 
316  if (is_null || info->in.r.atts[i].func == NULL)
317  PyDict_SetItemString(dict, key, Py_None);
318  else
319  {
320  value = (info->in.r.atts[i].func) (&info->in.r.atts[i], vattr);
321  PyDict_SetItemString(dict, key, value);
322  Py_DECREF(value);
323  }
324  }
325  MemoryContextSwitchTo(oldcontext);
326  MemoryContextReset(scratch_context);
327  }
328  PG_CATCH();
329  {
330  MemoryContextSwitchTo(oldcontext);
331  Py_DECREF(dict);
332  PG_RE_THROW();
333  }
334  PG_END_TRY();
335 
336  return dict;
337 }
static struct @76 value
PLyDatumToOb * atts
Definition: plpy_typeio.h:35
void PLy_elog(int elevel, const char *fmt,...)
Definition: plpy_elog.c:47
Form_pg_attribute * attrs
Definition: tupdesc.h:74
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
MemoryContext CurrentMemoryContext
Definition: mcxt.c:37
#define heap_getattr(tup, attnum, tupleDesc, isnull)
Definition: htup_details.h:769
uintptr_t Datum
Definition: postgres.h:374
PLyTupleToOb r
Definition: plpy_typeio.h:42
#define PG_CATCH()
Definition: elog.h:293
#define NULL
Definition: c.h:226
int is_rowtype
Definition: plpy_typeio.h:93
#define PG_RE_THROW()
Definition: elog.h:314
int i
#define NameStr(name)
Definition: c.h:495
#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 848 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().

849 {
850  PyObject *plrv_bo;
851  char *plrv_sc;
852  size_t plen;
853  size_t slen;
854 
855  if (PyUnicode_Check(plrv))
856  plrv_bo = PLyUnicode_Bytes(plrv);
857  else if (PyFloat_Check(plrv))
858  {
859  /* use repr() for floats, str() is lossy */
860 #if PY_MAJOR_VERSION >= 3
861  PyObject *s = PyObject_Repr(plrv);
862 
863  plrv_bo = PLyUnicode_Bytes(s);
864  Py_XDECREF(s);
865 #else
866  plrv_bo = PyObject_Repr(plrv);
867 #endif
868  }
869  else
870  {
871 #if PY_MAJOR_VERSION >= 3
872  PyObject *s = PyObject_Str(plrv);
873 
874  plrv_bo = PLyUnicode_Bytes(s);
875  Py_XDECREF(s);
876 #else
877  plrv_bo = PyObject_Str(plrv);
878 #endif
879  }
880  if (!plrv_bo)
881  PLy_elog(ERROR, "could not create string representation of Python object");
882 
883  plrv_sc = pstrdup(PyBytes_AsString(plrv_bo));
884  plen = PyBytes_Size(plrv_bo);
885  slen = strlen(plrv_sc);
886 
887  Py_XDECREF(plrv_bo);
888 
889  if (slen < plen)
890  ereport(ERROR,
891  (errcode(ERRCODE_DATATYPE_MISMATCH),
892  errmsg("could not convert Python object into cstring: Python string representation appears to contain null bytes")));
893  else if (slen > plen)
894  elog(ERROR, "could not convert Python object into cstring: Python string longer than reported length");
895  pg_verifymbstr(plrv_sc, slen, false);
896 
897  return plrv_sc;
898 }
char * pstrdup(const char *in)
Definition: mcxt.c:1165
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 345 of file plpy_typeio.c.

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

Referenced by PLy_exec_function(), and PLyObject_ToComposite().

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