PostgreSQL Source Code  git master
jsonb_plpython.c File Reference
#include "postgres.h"
#include "plpython.h"
#include "plpy_elog.h"
#include "plpy_typeio.h"
#include "utils/jsonb.h"
#include "utils/fmgrprotos.h"
#include "utils/numeric.h"
Include dependency graph for jsonb_plpython.c:

Go to the source code of this file.

Macros

#define PLyObject_AsString   (PLyObject_AsString_p)
 
#define PLyUnicode_FromStringAndSize   (PLyUnicode_FromStringAndSize_p)
 
#define PLy_elog   (PLy_elog_impl_p)
 

Typedefs

typedef char *(* PLyObject_AsString_t) (PyObject *plrv)
 
typedef void(* PLy_elog_impl_t) (int elevel, const char *fmt,...)
 

Functions

void _PG_init (void)
 
static PyObject * PLyObject_FromJsonbContainer (JsonbContainer *jsonb)
 
static JsonbValuePLyObject_ToJsonbValue (PyObject *obj, JsonbParseState **jsonb_state, bool is_elem)
 
static PyObject * PLyString_FromJsonbValue (JsonbValue *jbv)
 
static void PLyString_ToJsonbValue (PyObject *obj, JsonbValue *jbvElem)
 
static PyObject * PLyObject_FromJsonbValue (JsonbValue *jsonbValue)
 
static JsonbValuePLyMapping_ToJsonbValue (PyObject *obj, JsonbParseState **jsonb_state)
 
static JsonbValuePLySequence_ToJsonbValue (PyObject *obj, JsonbParseState **jsonb_state)
 
static JsonbValuePLyNumber_ToJsonbValue (PyObject *obj, JsonbValue *jbvNum)
 
 PG_FUNCTION_INFO_V1 (plpython_to_jsonb)
 
Datum plpython_to_jsonb (PG_FUNCTION_ARGS)
 
 PG_FUNCTION_INFO_V1 (jsonb_to_plpython)
 
Datum jsonb_to_plpython (PG_FUNCTION_ARGS)
 

Variables

 PG_MODULE_MAGIC
 
static PLyObject_AsString_t PLyObject_AsString_p
 
static PLy_elog_impl_t PLy_elog_impl_p
 
static PyObject * decimal_constructor
 

Macro Definition Documentation

◆ PLy_elog

◆ PLyObject_AsString

#define PLyObject_AsString   (PLyObject_AsString_p)

◆ PLyUnicode_FromStringAndSize

#define PLyUnicode_FromStringAndSize   (PLyUnicode_FromStringAndSize_p)

Definition at line 63 of file jsonb_plpython.c.

Referenced by _PG_init().

Typedef Documentation

◆ PLy_elog_impl_t

typedef void(* PLy_elog_impl_t) (int elevel, const char *fmt,...)

Definition at line 18 of file jsonb_plpython.c.

◆ PLyObject_AsString_t

typedef char*(* PLyObject_AsString_t) (PyObject *plrv)

Definition at line 15 of file jsonb_plpython.c.

Function Documentation

◆ _PG_init()

void _PG_init ( void  )

Definition at line 41 of file jsonb_plpython.c.

References AssertVariableIsOfType, load_external_function(), PLy_elog_impl(), PLy_elog_impl_p, PLyObject_AsString, PLyObject_AsString_p, and PLyUnicode_FromStringAndSize.

42 {
43  /* Asserts verify that typedefs above match original declarations */
46  load_external_function("$libdir/" PLPYTHON_LIBNAME, "PLyObject_AsString",
47  true, NULL);
48 #if PY_MAJOR_VERSION >= 3
49  AssertVariableIsOfType(&PLyUnicode_FromStringAndSize, PLyUnicode_FromStringAndSize_t);
50  PLyUnicode_FromStringAndSize_p = (PLyUnicode_FromStringAndSize_t)
51  load_external_function("$libdir/" PLPYTHON_LIBNAME, "PLyUnicode_FromStringAndSize",
52  true, NULL);
53 #endif
54 
57  load_external_function("$libdir/" PLPYTHON_LIBNAME, "PLy_elog_impl",
58  true, NULL);
59 }
void PLy_elog_impl(int elevel, const char *fmt,...)
Definition: plpy_elog.c:47
#define PLyObject_AsString
void(* PLy_elog_impl_t)(int elevel, const char *fmt,...)
PGFunction load_external_function(const char *filename, const char *funcname, bool signalNotFound, void **filehandle)
Definition: dfmgr.c:107
char *(* PLyObject_AsString_t)(PyObject *plrv)
#define PLyUnicode_FromStringAndSize
static PLy_elog_impl_t PLy_elog_impl_p
static PLyObject_AsString_t PLyObject_AsString_p
#define AssertVariableIsOfType(varname, typename)
Definition: c.h:881

◆ jsonb_to_plpython()

Datum jsonb_to_plpython ( PG_FUNCTION_ARGS  )

Definition at line 486 of file jsonb_plpython.c.

References Assert, decimal_constructor, ERROR, PG_GETARG_JSONB_P, PLy_elog, PLyObject_FromJsonbContainer(), PointerGetDatum, and Jsonb::root.

Referenced by plpython_to_jsonb().

487 {
488  PyObject *result;
489  Jsonb *in = PG_GETARG_JSONB_P(0);
490 
491  /*
492  * Initialize pointer to Decimal constructor. First we try "cdecimal", C
493  * version of decimal library. In case of failure we use slower "decimal"
494  * module.
495  */
496  if (!decimal_constructor)
497  {
498  PyObject *decimal_module = PyImport_ImportModule("cdecimal");
499 
500  if (!decimal_module)
501  {
502  PyErr_Clear();
503  decimal_module = PyImport_ImportModule("decimal");
504  }
505  Assert(decimal_module);
506  decimal_constructor = PyObject_GetAttrString(decimal_module, "Decimal");
507  }
508 
509  result = PLyObject_FromJsonbContainer(&in->root);
510  if (!result)
511  PLy_elog(ERROR, "transformation from jsonb to Python failed");
512 
513  return PointerGetDatum(result);
514 }
Definition: jsonb.h:220
#define PointerGetDatum(X)
Definition: postgres.h:556
#define ERROR
Definition: elog.h:43
static PyObject * decimal_constructor
#define PLy_elog
JsonbContainer root
Definition: jsonb.h:223
static PyObject * PLyObject_FromJsonbContainer(JsonbContainer *jsonb)
#define Assert(condition)
Definition: c.h:732
#define PG_GETARG_JSONB_P(x)
Definition: jsonb.h:74

◆ PG_FUNCTION_INFO_V1() [1/2]

PG_FUNCTION_INFO_V1 ( plpython_to_jsonb  )

◆ PG_FUNCTION_INFO_V1() [2/2]

PG_FUNCTION_INFO_V1 ( jsonb_to_plpython  )

◆ plpython_to_jsonb()

Datum plpython_to_jsonb ( PG_FUNCTION_ARGS  )

Definition at line 468 of file jsonb_plpython.c.

References jsonb_to_plpython(), JsonbValueToJsonb(), PG_FUNCTION_INFO_V1(), PG_GETARG_POINTER, PG_RETURN_POINTER, and PLyObject_ToJsonbValue().

Referenced by PLyObject_ToJsonbValue().

469 {
470  PyObject *obj;
471  JsonbValue *out;
472  JsonbParseState *jsonb_state = NULL;
473 
474  obj = (PyObject *) PG_GETARG_POINTER(0);
475  out = PLyObject_ToJsonbValue(obj, &jsonb_state, true);
477 }
#define PG_RETURN_POINTER(x)
Definition: fmgr.h:351
Jsonb * JsonbValueToJsonb(JsonbValue *val)
Definition: jsonb_util.c:84
#define PG_GETARG_POINTER(n)
Definition: fmgr.h:271
static JsonbValue * PLyObject_ToJsonbValue(PyObject *obj, JsonbParseState **jsonb_state, bool is_elem)

◆ PLyMapping_ToJsonbValue()

static JsonbValue* PLyMapping_ToJsonbValue ( PyObject *  obj,
JsonbParseState **  jsonb_state 
)
static

Definition at line 269 of file jsonb_plpython.c.

References i, jbvString, sort-test::key, PG_CATCH, PG_END_TRY, PG_RE_THROW, PG_TRY, PLyObject_ToJsonbValue(), PLyString_ToJsonbValue(), pushJsonbValue(), JsonbValue::type, JsonbValue::val, value, WJB_BEGIN_OBJECT, WJB_END_OBJECT, and WJB_KEY.

Referenced by PLyObject_ToJsonbValue().

270 {
271  Py_ssize_t pcount;
272  PyObject *volatile items;
273  JsonbValue *volatile out;
274 
275  pcount = PyMapping_Size(obj);
276  items = PyMapping_Items(obj);
277 
278  PG_TRY();
279  {
280  Py_ssize_t i;
281 
282  pushJsonbValue(jsonb_state, WJB_BEGIN_OBJECT, NULL);
283 
284  for (i = 0; i < pcount; i++)
285  {
286  JsonbValue jbvKey;
287  PyObject *item = PyList_GetItem(items, i);
288  PyObject *key = PyTuple_GetItem(item, 0);
289  PyObject *value = PyTuple_GetItem(item, 1);
290 
291  /* Python dictionary can have None as key */
292  if (key == Py_None)
293  {
294  jbvKey.type = jbvString;
295  jbvKey.val.string.len = 0;
296  jbvKey.val.string.val = "";
297  }
298  else
299  {
300  /* All others types of keys we serialize to string */
301  PLyString_ToJsonbValue(key, &jbvKey);
302  }
303 
304  (void) pushJsonbValue(jsonb_state, WJB_KEY, &jbvKey);
305  (void) PLyObject_ToJsonbValue(value, jsonb_state, false);
306  }
307 
308  out = pushJsonbValue(jsonb_state, WJB_END_OBJECT, NULL);
309  }
310  PG_CATCH();
311  {
312  Py_DECREF(items);
313  PG_RE_THROW();
314  }
315  PG_END_TRY();
316 
317  Py_DECREF(items);
318 
319  return out;
320 }
char * val
Definition: jsonb.h:272
static struct @145 value
int Py_ssize_t
Definition: plpython.h:66
JsonbValue * pushJsonbValue(JsonbParseState **pstate, JsonbIteratorToken seq, JsonbValue *jbval)
Definition: jsonb_util.c:558
static void PLyString_ToJsonbValue(PyObject *obj, JsonbValue *jbvElem)
Definition: jsonb.h:23
#define PG_CATCH()
Definition: elog.h:310
static JsonbValue * PLyObject_ToJsonbValue(PyObject *obj, JsonbParseState **jsonb_state, bool is_elem)
#define PG_RE_THROW()
Definition: elog.h:331
enum jbvType type
Definition: jsonb.h:263
int i
#define PG_TRY()
Definition: elog.h:301
#define PG_END_TRY()
Definition: elog.h:317

◆ PLyNumber_ToJsonbValue()

static JsonbValue* PLyNumber_ToJsonbValue ( PyObject *  obj,
JsonbValue jbvNum 
)
static

Definition at line 367 of file jsonb_plpython.c.

References CStringGetDatum, DatumGetNumeric, DirectFunctionCall3, ereport, errcode(), errmsg(), ERROR, Int32GetDatum, InvalidOid, jbvNumeric, numeric_in(), numeric_is_nan(), ObjectIdGetDatum, pfree(), PG_CATCH, PG_END_TRY, PG_TRY, PLyObject_AsString, generate_unaccent_rules::str, JsonbValue::type, and JsonbValue::val.

Referenced by PLyObject_ToJsonbValue().

368 {
369  Numeric num;
370  char *str = PLyObject_AsString(obj);
371 
372  PG_TRY();
373  {
374  Datum numd;
375 
377  CStringGetDatum(str),
379  Int32GetDatum(-1));
380  num = DatumGetNumeric(numd);
381  }
382  PG_CATCH();
383  {
384  ereport(ERROR,
385  (errcode(ERRCODE_DATATYPE_MISMATCH),
386  (errmsg("could not convert value \"%s\" to jsonb", str))));
387  }
388  PG_END_TRY();
389 
390  pfree(str);
391 
392  /*
393  * jsonb doesn't allow NaN (per JSON specification), so we have to prevent
394  * it here explicitly. (Infinity is also not allowed in jsonb, but
395  * numeric_in above already catches that.)
396  */
397  if (numeric_is_nan(num))
398  ereport(ERROR,
399  (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
400  (errmsg("cannot convert NaN to jsonb"))));
401 
402  jbvNum->type = jbvNumeric;
403  jbvNum->val.numeric = num;
404 
405  return jbvNum;
406 }
char * val
Definition: jsonb.h:272
int errcode(int sqlerrcode)
Definition: elog.c:570
void pfree(void *pointer)
Definition: mcxt.c:1056
#define ObjectIdGetDatum(X)
Definition: postgres.h:507
#define ERROR
Definition: elog.h:43
bool numeric_is_nan(Numeric num)
Definition: numeric.c:683
#define PLyObject_AsString
#define CStringGetDatum(X)
Definition: postgres.h:578
Datum numeric_in(PG_FUNCTION_ARGS)
Definition: numeric.c:573
#define ereport(elevel, rest)
Definition: elog.h:141
#define DirectFunctionCall3(func, arg1, arg2, arg3)
Definition: fmgr.h:621
uintptr_t Datum
Definition: postgres.h:367
#define InvalidOid
Definition: postgres_ext.h:36
#define PG_CATCH()
Definition: elog.h:310
#define DatumGetNumeric(X)
Definition: numeric.h:49
enum jbvType type
Definition: jsonb.h:263
#define Int32GetDatum(X)
Definition: postgres.h:479
int errmsg(const char *fmt,...)
Definition: elog.c:784
#define PG_TRY()
Definition: elog.h:301
#define PG_END_TRY()
Definition: elog.h:317

◆ PLyObject_FromJsonbContainer()

static PyObject * PLyObject_FromJsonbContainer ( JsonbContainer jsonb)
static

Definition at line 141 of file jsonb_plpython.c.

References elog, ERROR, JsonbIteratorInit(), JsonbIteratorNext(), sort-test::key, PG_CATCH, PG_END_TRY, PG_RE_THROW, PG_TRY, PLyObject_FromJsonbValue(), PLyString_FromJsonbValue(), JsonbValue::val, val, WJB_BEGIN_ARRAY, WJB_BEGIN_OBJECT, WJB_DONE, WJB_ELEM, WJB_END_ARRAY, WJB_KEY, and WJB_VALUE.

Referenced by jsonb_to_plpython(), and PLyObject_FromJsonbValue().

142 {
144  JsonbValue v;
145  JsonbIterator *it;
146  PyObject *result;
147 
148  it = JsonbIteratorInit(jsonb);
149  r = JsonbIteratorNext(&it, &v, true);
150 
151  switch (r)
152  {
153  case WJB_BEGIN_ARRAY:
154  if (v.val.array.rawScalar)
155  {
156  JsonbValue tmp;
157 
158  if ((r = JsonbIteratorNext(&it, &v, true)) != WJB_ELEM ||
159  (r = JsonbIteratorNext(&it, &tmp, true)) != WJB_END_ARRAY ||
160  (r = JsonbIteratorNext(&it, &tmp, true)) != WJB_DONE)
161  elog(ERROR, "unexpected jsonb token: %d", r);
162 
163  result = PLyObject_FromJsonbValue(&v);
164  }
165  else
166  {
167  PyObject *volatile elem = NULL;
168 
169  result = PyList_New(0);
170  if (!result)
171  return NULL;
172 
173  PG_TRY();
174  {
175  while ((r = JsonbIteratorNext(&it, &v, true)) != WJB_DONE)
176  {
177  if (r != WJB_ELEM)
178  continue;
179 
180  elem = PLyObject_FromJsonbValue(&v);
181 
182  PyList_Append(result, elem);
183  Py_XDECREF(elem);
184  elem = NULL;
185  }
186  }
187  PG_CATCH();
188  {
189  Py_XDECREF(elem);
190  Py_XDECREF(result);
191  PG_RE_THROW();
192  }
193  PG_END_TRY();
194  }
195  break;
196 
197  case WJB_BEGIN_OBJECT:
198  {
199  PyObject *volatile result_v = PyDict_New();
200  PyObject *volatile key = NULL;
201  PyObject *volatile val = NULL;
202 
203  if (!result_v)
204  return NULL;
205 
206  PG_TRY();
207  {
208  while ((r = JsonbIteratorNext(&it, &v, true)) != WJB_DONE)
209  {
210  if (r != WJB_KEY)
211  continue;
212 
213  key = PLyString_FromJsonbValue(&v);
214  if (!key)
215  {
216  Py_XDECREF(result_v);
217  result_v = NULL;
218  break;
219  }
220 
221  if ((r = JsonbIteratorNext(&it, &v, true)) != WJB_VALUE)
222  elog(ERROR, "unexpected jsonb token: %d", r);
223 
224  val = PLyObject_FromJsonbValue(&v);
225  if (!val)
226  {
227  Py_XDECREF(key);
228  key = NULL;
229  Py_XDECREF(result_v);
230  result_v = NULL;
231  break;
232  }
233 
234  PyDict_SetItem(result_v, key, val);
235 
236  Py_XDECREF(key);
237  key = NULL;
238  Py_XDECREF(val);
239  val = NULL;
240  }
241  }
242  PG_CATCH();
243  {
244  Py_XDECREF(result_v);
245  Py_XDECREF(key);
246  Py_XDECREF(val);
247  PG_RE_THROW();
248  }
249  PG_END_TRY();
250 
251  result = result_v;
252  }
253  break;
254 
255  default:
256  elog(ERROR, "unexpected jsonb token: %d", r);
257  return NULL;
258  }
259 
260  return result;
261 }
char * val
Definition: jsonb.h:272
Definition: jsonb.h:22
#define ERROR
Definition: elog.h:43
Definition: jsonb.h:23
JsonbIteratorToken
Definition: jsonb.h:20
static PyObject * PLyString_FromJsonbValue(JsonbValue *jbv)
#define PG_CATCH()
Definition: elog.h:310
JsonbIterator * JsonbIteratorInit(JsonbContainer *container)
Definition: jsonb_util.c:759
#define PG_RE_THROW()
Definition: elog.h:331
#define elog(elevel,...)
Definition: elog.h:226
#define PG_TRY()
Definition: elog.h:301
long val
Definition: informix.c:684
#define PG_END_TRY()
Definition: elog.h:317
JsonbIteratorToken JsonbIteratorNext(JsonbIterator **it, JsonbValue *val, bool skipNested)
Definition: jsonb_util.c:795
Definition: jsonb.h:25
static PyObject * PLyObject_FromJsonbValue(JsonbValue *jsonbValue)

◆ PLyObject_FromJsonbValue()

static PyObject* PLyObject_FromJsonbValue ( JsonbValue jsonbValue)
static

Definition at line 99 of file jsonb_plpython.c.

References DatumGetCString, decimal_constructor, DirectFunctionCall1, elog, ERROR, jbvBinary, jbvBool, jbvNull, jbvNumeric, jbvString, numeric_out(), NumericGetDatum, PLyObject_FromJsonbContainer(), PLyString_FromJsonbValue(), generate_unaccent_rules::str, JsonbValue::type, and JsonbValue::val.

Referenced by PLyObject_FromJsonbContainer().

100 {
101  switch (jsonbValue->type)
102  {
103  case jbvNull:
104  Py_RETURN_NONE;
105 
106  case jbvBinary:
107  return PLyObject_FromJsonbContainer(jsonbValue->val.binary.data);
108 
109  case jbvNumeric:
110  {
111  Datum num;
112  char *str;
113 
114  num = NumericGetDatum(jsonbValue->val.numeric);
116 
117  return PyObject_CallFunction(decimal_constructor, "s", str);
118  }
119 
120  case jbvString:
121  return PLyString_FromJsonbValue(jsonbValue);
122 
123  case jbvBool:
124  if (jsonbValue->val.boolean)
125  Py_RETURN_TRUE;
126  else
127  Py_RETURN_FALSE;
128 
129  default:
130  elog(ERROR, "unexpected jsonb value type: %d", jsonbValue->type);
131  return NULL;
132  }
133 }
char * val
Definition: jsonb.h:272
#define NumericGetDatum(X)
Definition: numeric.h:51
Definition: jsonb.h:239
Datum numeric_out(PG_FUNCTION_ARGS)
Definition: numeric.c:655
Definition: jsonb.h:236
#define DirectFunctionCall1(func, arg1)
Definition: fmgr.h:617
#define ERROR
Definition: elog.h:43
static PyObject * decimal_constructor
#define DatumGetCString(X)
Definition: postgres.h:566
uintptr_t Datum
Definition: postgres.h:367
static PyObject * PLyObject_FromJsonbContainer(JsonbContainer *jsonb)
static PyObject * PLyString_FromJsonbValue(JsonbValue *jbv)
enum jbvType type
Definition: jsonb.h:263
#define elog(elevel,...)
Definition: elog.h:226

◆ PLyObject_ToJsonbValue()

static JsonbValue * PLyObject_ToJsonbValue ( PyObject *  obj,
JsonbParseState **  jsonb_state,
bool  is_elem 
)
static

Definition at line 414 of file jsonb_plpython.c.

References buf, ereport, errcode(), errmsg(), ERROR, jbvBool, jbvNull, palloc(), PG_FUNCTION_INFO_V1(), plpython_to_jsonb(), PLyMapping_ToJsonbValue(), PLyNumber_ToJsonbValue(), PLyObject_AsString, PLySequence_ToJsonbValue(), PLyString_ToJsonbValue(), pushJsonbValue(), JsonbValue::type, JsonbValue::val, WJB_ELEM, and WJB_VALUE.

Referenced by plpython_to_jsonb(), PLyMapping_ToJsonbValue(), and PLySequence_ToJsonbValue().

415 {
416  JsonbValue buf;
417  JsonbValue *out;
418 
419  if (!(PyString_Check(obj) || PyUnicode_Check(obj)))
420  {
421  if (PySequence_Check(obj))
422  return PLySequence_ToJsonbValue(obj, jsonb_state);
423  else if (PyMapping_Check(obj))
424  return PLyMapping_ToJsonbValue(obj, jsonb_state);
425  }
426 
427  /* Allocate JsonbValue in heap only if it is raw scalar value. */
428  if (*jsonb_state)
429  out = &buf;
430  else
431  out = palloc(sizeof(JsonbValue));
432 
433  if (obj == Py_None)
434  out->type = jbvNull;
435  else if (PyString_Check(obj) || PyUnicode_Check(obj))
436  PLyString_ToJsonbValue(obj, out);
437 
438  /*
439  * PyNumber_Check() returns true for booleans, so boolean check should
440  * come first.
441  */
442  else if (PyBool_Check(obj))
443  {
444  out->type = jbvBool;
445  out->val.boolean = (obj == Py_True);
446  }
447  else if (PyNumber_Check(obj))
448  out = PLyNumber_ToJsonbValue(obj, out);
449  else
450  ereport(ERROR,
451  (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
452  (errmsg("Python type \"%s\" cannot be transformed to jsonb",
453  PLyObject_AsString((PyObject *) obj->ob_type)))));
454 
455  /* Push result into 'jsonb_state' unless it is raw scalar value. */
456  return (*jsonb_state ?
457  pushJsonbValue(jsonb_state, is_elem ? WJB_ELEM : WJB_VALUE, out) :
458  out);
459 }
static JsonbValue * PLyMapping_ToJsonbValue(PyObject *obj, JsonbParseState **jsonb_state)
char * val
Definition: jsonb.h:272
Definition: jsonb.h:239
int errcode(int sqlerrcode)
Definition: elog.c:570
Definition: jsonb.h:236
JsonbValue * pushJsonbValue(JsonbParseState **pstate, JsonbIteratorToken seq, JsonbValue *jbval)
Definition: jsonb_util.c:558
static void PLyString_ToJsonbValue(PyObject *obj, JsonbValue *jbvElem)
#define ERROR
Definition: elog.h:43
static char * buf
Definition: pg_test_fsync.c:68
#define PLyObject_AsString
#define ereport(elevel, rest)
Definition: elog.h:141
static JsonbValue * PLyNumber_ToJsonbValue(PyObject *obj, JsonbValue *jbvNum)
enum jbvType type
Definition: jsonb.h:263
void * palloc(Size size)
Definition: mcxt.c:949
int errmsg(const char *fmt,...)
Definition: elog.c:784
static JsonbValue * PLySequence_ToJsonbValue(PyObject *obj, JsonbParseState **jsonb_state)
Definition: jsonb.h:25

◆ PLySequence_ToJsonbValue()

static JsonbValue* PLySequence_ToJsonbValue ( PyObject *  obj,
JsonbParseState **  jsonb_state 
)
static

Definition at line 329 of file jsonb_plpython.c.

References Assert, i, PG_CATCH, PG_END_TRY, PG_RE_THROW, PG_TRY, PLyObject_ToJsonbValue(), pushJsonbValue(), value, WJB_BEGIN_ARRAY, and WJB_END_ARRAY.

Referenced by PLyObject_ToJsonbValue().

330 {
331  Py_ssize_t i;
332  Py_ssize_t pcount;
333  PyObject *volatile value = NULL;
334 
335  pcount = PySequence_Size(obj);
336 
337  pushJsonbValue(jsonb_state, WJB_BEGIN_ARRAY, NULL);
338 
339  PG_TRY();
340  {
341  for (i = 0; i < pcount; i++)
342  {
343  value = PySequence_GetItem(obj, i);
344  Assert(value);
345 
346  (void) PLyObject_ToJsonbValue(value, jsonb_state, true);
347  Py_XDECREF(value);
348  value = NULL;
349  }
350  }
351  PG_CATCH();
352  {
353  Py_XDECREF(value);
354  PG_RE_THROW();
355  }
356  PG_END_TRY();
357 
358  return pushJsonbValue(jsonb_state, WJB_END_ARRAY, NULL);
359 }
static struct @145 value
int Py_ssize_t
Definition: plpython.h:66
JsonbValue * pushJsonbValue(JsonbParseState **pstate, JsonbIteratorToken seq, JsonbValue *jbval)
Definition: jsonb_util.c:558
#define PG_CATCH()
Definition: elog.h:310
#define Assert(condition)
Definition: c.h:732
static JsonbValue * PLyObject_ToJsonbValue(PyObject *obj, JsonbParseState **jsonb_state, bool is_elem)
#define PG_RE_THROW()
Definition: elog.h:331
int i
#define PG_TRY()
Definition: elog.h:301
#define PG_END_TRY()
Definition: elog.h:317

◆ PLyString_FromJsonbValue()

static PyObject* PLyString_FromJsonbValue ( JsonbValue jbv)
static

Definition at line 73 of file jsonb_plpython.c.

References Assert, jbvString, JsonbValue::type, and JsonbValue::val.

Referenced by PLyObject_FromJsonbContainer(), and PLyObject_FromJsonbValue().

74 {
75  Assert(jbv->type == jbvString);
76 
77  return PyString_FromStringAndSize(jbv->val.string.val, jbv->val.string.len);
78 }
char * val
Definition: jsonb.h:272
#define Assert(condition)
Definition: c.h:732
enum jbvType type
Definition: jsonb.h:263

◆ PLyString_ToJsonbValue()

static void PLyString_ToJsonbValue ( PyObject *  obj,
JsonbValue jbvElem 
)
static

Definition at line 86 of file jsonb_plpython.c.

References jbvString, PLyObject_AsString, JsonbValue::type, and JsonbValue::val.

Referenced by PLyMapping_ToJsonbValue(), and PLyObject_ToJsonbValue().

87 {
88  jbvElem->type = jbvString;
89  jbvElem->val.string.val = PLyObject_AsString(obj);
90  jbvElem->val.string.len = strlen(jbvElem->val.string.val);
91 }
char * val
Definition: jsonb.h:272
#define PLyObject_AsString
enum jbvType type
Definition: jsonb.h:263

Variable Documentation

◆ decimal_constructor

PyObject* decimal_constructor
static

◆ PG_MODULE_MAGIC

PG_MODULE_MAGIC

Definition at line 10 of file jsonb_plpython.c.

◆ PLy_elog_impl_p

PLy_elog_impl_t PLy_elog_impl_p
static

Definition at line 19 of file jsonb_plpython.c.

Referenced by _PG_init().

◆ PLyObject_AsString_p

PLyObject_AsString_t PLyObject_AsString_p
static

Definition at line 16 of file jsonb_plpython.c.

Referenced by _PG_init().