PostgreSQL Source Code  git master
jsonb_plpython.c File Reference
#include "postgres.h"
#include "plpy_elog.h"
#include "plpy_typeio.h"
#include "plpython.h"
#include "utils/fmgrprotos.h"
#include "utils/jsonb.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:43
#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:888

◆ jsonb_to_plpython()

Datum jsonb_to_plpython ( PG_FUNCTION_ARGS  )

Definition at line 483 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().

484 {
485  PyObject *result;
486  Jsonb *in = PG_GETARG_JSONB_P(0);
487 
488  /*
489  * Initialize pointer to Decimal constructor. First we try "cdecimal", C
490  * version of decimal library. In case of failure we use slower "decimal"
491  * module.
492  */
493  if (!decimal_constructor)
494  {
495  PyObject *decimal_module = PyImport_ImportModule("cdecimal");
496 
497  if (!decimal_module)
498  {
499  PyErr_Clear();
500  decimal_module = PyImport_ImportModule("decimal");
501  }
502  Assert(decimal_module);
503  decimal_constructor = PyObject_GetAttrString(decimal_module, "Decimal");
504  }
505 
506  result = PLyObject_FromJsonbContainer(&in->root);
507  if (!result)
508  PLy_elog(ERROR, "transformation from jsonb to Python failed");
509 
510  return PointerGetDatum(result);
511 }
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:739
#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 465 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().

466 {
467  PyObject *obj;
468  JsonbValue *out;
469  JsonbParseState *jsonb_state = NULL;
470 
471  obj = (PyObject *) PG_GETARG_POINTER(0);
472  out = PLyObject_ToJsonbValue(obj, &jsonb_state, true);
474 }
#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_END_TRY, PG_FINALLY, 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_FINALLY();
311  {
312  Py_DECREF(items);
313  }
314  PG_END_TRY();
315 
316  return out;
317 }
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_FINALLY()
Definition: elog.h:339
static JsonbValue * PLyObject_ToJsonbValue(PyObject *obj, JsonbParseState **jsonb_state, bool is_elem)
enum jbvType type
Definition: jsonb.h:263
int i
#define PG_TRY()
Definition: elog.h:322
#define PG_END_TRY()
Definition: elog.h:347

◆ PLyNumber_ToJsonbValue()

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

Definition at line 364 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().

365 {
366  Numeric num;
367  char *str = PLyObject_AsString(obj);
368 
369  PG_TRY();
370  {
371  Datum numd;
372 
374  CStringGetDatum(str),
376  Int32GetDatum(-1));
377  num = DatumGetNumeric(numd);
378  }
379  PG_CATCH();
380  {
381  ereport(ERROR,
382  (errcode(ERRCODE_DATATYPE_MISMATCH),
383  (errmsg("could not convert value \"%s\" to jsonb", str))));
384  }
385  PG_END_TRY();
386 
387  pfree(str);
388 
389  /*
390  * jsonb doesn't allow NaN (per JSON specification), so we have to prevent
391  * it here explicitly. (Infinity is also not allowed in jsonb, but
392  * numeric_in above already catches that.)
393  */
394  if (numeric_is_nan(num))
395  ereport(ERROR,
396  (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
397  (errmsg("cannot convert NaN to jsonb"))));
398 
399  jbvNum->type = jbvNumeric;
400  jbvNum->val.numeric = num;
401 
402  return jbvNum;
403 }
char * val
Definition: jsonb.h:272
int errcode(int sqlerrcode)
Definition: elog.c:608
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:619
uintptr_t Datum
Definition: postgres.h:367
#define InvalidOid
Definition: postgres_ext.h:36
#define PG_CATCH()
Definition: elog.h:332
#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:822
#define PG_TRY()
Definition: elog.h:322
#define PG_END_TRY()
Definition: elog.h:347

◆ 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:332
JsonbIterator * JsonbIteratorInit(JsonbContainer *container)
Definition: jsonb_util.c:759
#define PG_RE_THROW()
Definition: elog.h:363
#define elog(elevel,...)
Definition: elog.h:228
#define PG_TRY()
Definition: elog.h:322
long val
Definition: informix.c:664
#define PG_END_TRY()
Definition: elog.h:347
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:615
#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:228

◆ PLyObject_ToJsonbValue()

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

Definition at line 411 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().

412 {
413  JsonbValue buf;
414  JsonbValue *out;
415 
416  if (!(PyString_Check(obj) || PyUnicode_Check(obj)))
417  {
418  if (PySequence_Check(obj))
419  return PLySequence_ToJsonbValue(obj, jsonb_state);
420  else if (PyMapping_Check(obj))
421  return PLyMapping_ToJsonbValue(obj, jsonb_state);
422  }
423 
424  /* Allocate JsonbValue in heap only if it is raw scalar value. */
425  if (*jsonb_state)
426  out = &buf;
427  else
428  out = palloc(sizeof(JsonbValue));
429 
430  if (obj == Py_None)
431  out->type = jbvNull;
432  else if (PyString_Check(obj) || PyUnicode_Check(obj))
433  PLyString_ToJsonbValue(obj, out);
434 
435  /*
436  * PyNumber_Check() returns true for booleans, so boolean check should
437  * come first.
438  */
439  else if (PyBool_Check(obj))
440  {
441  out->type = jbvBool;
442  out->val.boolean = (obj == Py_True);
443  }
444  else if (PyNumber_Check(obj))
445  out = PLyNumber_ToJsonbValue(obj, out);
446  else
447  ereport(ERROR,
448  (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
449  (errmsg("Python type \"%s\" cannot be transformed to jsonb",
450  PLyObject_AsString((PyObject *) obj->ob_type)))));
451 
452  /* Push result into 'jsonb_state' unless it is raw scalar value. */
453  return (*jsonb_state ?
454  pushJsonbValue(jsonb_state, is_elem ? WJB_ELEM : WJB_VALUE, out) :
455  out);
456 }
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:608
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:67
#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:822
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 326 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().

327 {
328  Py_ssize_t i;
329  Py_ssize_t pcount;
330  PyObject *volatile value = NULL;
331 
332  pcount = PySequence_Size(obj);
333 
334  pushJsonbValue(jsonb_state, WJB_BEGIN_ARRAY, NULL);
335 
336  PG_TRY();
337  {
338  for (i = 0; i < pcount; i++)
339  {
340  value = PySequence_GetItem(obj, i);
341  Assert(value);
342 
343  (void) PLyObject_ToJsonbValue(value, jsonb_state, true);
344  Py_XDECREF(value);
345  value = NULL;
346  }
347  }
348  PG_CATCH();
349  {
350  Py_XDECREF(value);
351  PG_RE_THROW();
352  }
353  PG_END_TRY();
354 
355  return pushJsonbValue(jsonb_state, WJB_END_ARRAY, NULL);
356 }
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:332
#define Assert(condition)
Definition: c.h:739
static JsonbValue * PLyObject_ToJsonbValue(PyObject *obj, JsonbParseState **jsonb_state, bool is_elem)
#define PG_RE_THROW()
Definition: elog.h:363
int i
#define PG_TRY()
Definition: elog.h:322
#define PG_END_TRY()
Definition: elog.h:347

◆ 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:739
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().