PostgreSQL Source Code: contrib/jsonb_plpython/jsonb_plpython.c File Reference (original) (raw)
#include "[postgres.h](postgres%5F8h%5Fsource.html)"
#include "[plpy_elog.h](plpy%5F%5Felog%5F8h%5Fsource.html)"
#include "[plpy_typeio.h](plpy%5F%5Ftypeio%5F8h%5Fsource.html)"
#include "[plpy_util.h](plpy%5F%5Futil%5F8h%5Fsource.html)"
#include "utils/fmgrprotos.h"
#include "[utils/jsonb.h](jsonb%5F8h%5Fsource.html)"
#include "[utils/numeric.h](numeric%5F8h%5Fsource.html)"
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,...) |
typedef PyObject *(* | PLyUnicode_FromStringAndSize_t) (const char *s, Py_ssize_t size) |
Functions | |
---|---|
PG_MODULE_MAGIC_EXT (.name="jsonb_plpython",.version=PG_VERSION) | |
static PyObject * | PLyObject_FromJsonbContainer (JsonbContainer *jsonb) |
static JsonbValue * | PLyObject_ToJsonbValue (PyObject *obj, JsonbParseState **jsonb_state, bool is_elem) |
void | _PG_init (void) |
static PyObject * | PLyUnicode_FromJsonbValue (JsonbValue *jbv) |
static void | PLyUnicode_ToJsonbValue (PyObject *obj, JsonbValue *jbvElem) |
static PyObject * | PLyObject_FromJsonbValue (JsonbValue *jsonbValue) |
static JsonbValue * | PLyMapping_ToJsonbValue (PyObject *obj, JsonbParseState **jsonb_state) |
static JsonbValue * | PLySequence_ToJsonbValue (PyObject *obj, JsonbParseState **jsonb_state) |
static JsonbValue * | PLyNumber_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 | |
---|---|
static PLyObject_AsString_t | PLyObject_AsString_p |
static PLy_elog_impl_t | PLy_elog_impl_p |
static PyObject * | decimal_constructor |
static PLyUnicode_FromStringAndSize_t | PLyUnicode_FromStringAndSize_p |
◆ PLy_elog
◆ PLyObject_AsString
◆ PLyUnicode_FromStringAndSize
◆ PLy_elog_impl_t
typedef void(* PLy_elog_impl_t) (int elevel, const char *fmt,...)
◆ PLyObject_AsString_t
typedef char *(* PLyObject_AsString_t) (PyObject *plrv)
◆ PLyUnicode_FromStringAndSize_t
typedef PyObject *(* PLyUnicode_FromStringAndSize_t) (const char *s, Py_ssize_t size)
◆ _PG_init()
Definition at line 40 of file jsonb_plpython.c.
41{
42
46 true, NULL);
50 true, NULL);
54 true, NULL);
55}
#define AssertVariableIsOfType(varname, typename)
void * load_external_function(const char *filename, const char *funcname, bool signalNotFound, void **filehandle)
#define PLyUnicode_FromStringAndSize
static PLy_elog_impl_t PLy_elog_impl_p
PyObject *(* PLyUnicode_FromStringAndSize_t)(const char *s, Py_ssize_t size)
void(* PLy_elog_impl_t)(int elevel, const char *fmt,...)
static PLyObject_AsString_t PLyObject_AsString_p
char *(* PLyObject_AsString_t)(PyObject *plrv)
static PLyUnicode_FromStringAndSize_t PLyUnicode_FromStringAndSize_p
#define PLyObject_AsString
void PLy_elog_impl(int elevel, const char *fmt,...)
References AssertVariableIsOfType, load_external_function(), PLy_elog_impl(), PLy_elog_impl_p, PLyObject_AsString, PLyObject_AsString_p, PLyUnicode_FromStringAndSize, and PLyUnicode_FromStringAndSize_p.
◆ jsonb_to_plpython()
Definition at line 477 of file jsonb_plpython.c.
478{
479 PyObject *result;
481
482
483
484
485
486
488 {
489 PyObject *decimal_module = PyImport_ImportModule("cdecimal");
490
491 if (!decimal_module)
492 {
493 PyErr_Clear();
494 decimal_module = PyImport_ImportModule("decimal");
495 }
496 Assert(decimal_module);
498 }
499
501 if (!result)
502 PLy_elog(ERROR, "transformation from jsonb to Python failed");
503
505}
Assert(PointerIsAligned(start, uint64))
#define PG_GETARG_JSONB_P(x)
static PyObject * decimal_constructor
static PyObject * PLyObject_FromJsonbContainer(JsonbContainer *jsonb)
static Datum PointerGetDatum(const void *X)
References Assert(), decimal_constructor, ERROR, PG_GETARG_JSONB_P, PLy_elog, PLyObject_FromJsonbContainer(), PointerGetDatum(), and Jsonb::root.
◆ PG_FUNCTION_INFO_V1() [1/2]
◆ PG_FUNCTION_INFO_V1() [2/2]
◆ PG_MODULE_MAGIC_EXT()
PG_MODULE_MAGIC_EXT | ( | . | name = "jsonb_plpython", |
---|---|---|---|
. | version = PG_VERSION | ||
) |
◆ plpython_to_jsonb()
◆ PLyMapping_ToJsonbValue()
Definition at line 265 of file jsonb_plpython.c.
266{
267 Py_ssize_t pcount;
268 PyObject *volatile items;
270
271 pcount = PyMapping_Size(obj);
272 items = PyMapping_Items(obj);
273
275 {
276 Py_ssize_t i;
277
279
280 for (i = 0; i < pcount; i++)
281 {
283 PyObject *item = PyList_GetItem(items, i);
284 PyObject *key = PyTuple_GetItem(item, 0);
285 PyObject *value = PyTuple_GetItem(item, 1);
286
287
288 if (key == Py_None)
289 {
291 jbvKey.val.string.len = 0;
292 jbvKey.val.string.val = "";
293 }
294 else
295 {
296
298 }
299
302 }
303
305 }
307 {
308 Py_DECREF(items);
309 }
311
312 return out;
313}
static void PLyUnicode_ToJsonbValue(PyObject *obj, JsonbValue *jbvElem)
JsonbValue * pushJsonbValue(JsonbParseState **pstate, JsonbIteratorToken seq, JsonbValue *jbval)
References i, items, jbvString, sort-test::key, PG_END_TRY, PG_FINALLY, PG_TRY, PLyObject_ToJsonbValue(), PLyUnicode_ToJsonbValue(), pushJsonbValue(), JsonbValue::type, JsonbValue::val, value, WJB_BEGIN_OBJECT, WJB_END_OBJECT, and WJB_KEY.
Referenced by PLyObject_ToJsonbValue().
◆ PLyNumber_ToJsonbValue()
Definition at line 360 of file jsonb_plpython.c.
361{
364
366 {
368
374 }
376 {
378 (errcode(ERRCODE_DATATYPE_MISMATCH),
379 errmsg("could not convert value \"%s\" to jsonb", str)));
380 }
382
384
385
386
387
388
391 (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
392 errmsg("cannot convert NaN to jsonb")));
395 (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
396 errmsg("cannot convert infinity to jsonb")));
397
399 jbvNum->val.numeric = num;
400
401 return jbvNum;
402}
Datum numeric_in(PG_FUNCTION_ARGS)
bool numeric_is_nan(Numeric num)
bool numeric_is_inf(Numeric num)
int errcode(int sqlerrcode)
int errmsg(const char *fmt,...)
#define ereport(elevel,...)
#define DirectFunctionCall3(func, arg1, arg2, arg3)
void pfree(void *pointer)
static Numeric DatumGetNumeric(Datum X)
static Datum ObjectIdGetDatum(Oid X)
static Datum CStringGetDatum(const char *X)
static Datum Int32GetDatum(int32 X)
References CStringGetDatum(), DatumGetNumeric(), DirectFunctionCall3, ereport, errcode(), errmsg(), ERROR, Int32GetDatum(), InvalidOid, jbvNumeric, numeric_in(), numeric_is_inf(), numeric_is_nan(), ObjectIdGetDatum(), pfree(), PG_CATCH, PG_END_TRY, PG_TRY, PLyObject_AsString, str, JsonbValue::type, and JsonbValue::val.
Referenced by PLyObject_ToJsonbValue().
◆ PLyObject_FromJsonbContainer()
static PyObject * PLyObject_FromJsonbContainer ( JsonbContainer * jsonb) | static |
---|
Definition at line 137 of file jsonb_plpython.c.
138{
142 PyObject *result;
143
146
147 switch (r)
148 {
150 if (v.val.array.rawScalar)
151 {
153
157 elog(ERROR, "unexpected jsonb token: %d", r);
158
160 }
161 else
162 {
163 PyObject *volatile elem = NULL;
164
165 result = PyList_New(0);
166 if (!result)
167 return NULL;
168
170 {
172 {
174 continue;
175
177
178 PyList_Append(result, elem);
179 Py_XDECREF(elem);
180 elem = NULL;
181 }
182 }
184 {
185 Py_XDECREF(elem);
186 Py_XDECREF(result);
188 }
190 }
191 break;
192
194 {
195 PyObject *volatile result_v = PyDict_New();
196 PyObject *volatile key = NULL;
197 PyObject *volatile val = NULL;
198
199 if (!result_v)
200 return NULL;
201
203 {
205 {
207 continue;
208
210 if ()
211 {
212 Py_XDECREF(result_v);
213 result_v = NULL;
214 break;
215 }
216
218 elog(ERROR, "unexpected jsonb token: %d", r);
219
221 if ()
222 {
223 Py_XDECREF(key);
224 key = NULL;
225 Py_XDECREF(result_v);
226 result_v = NULL;
227 break;
228 }
229
230 PyDict_SetItem(result_v, key, val);
231
232 Py_XDECREF(key);
233 key = NULL;
234 Py_XDECREF(val);
235 val = NULL;
236 }
237 }
239 {
240 Py_XDECREF(result_v);
241 Py_XDECREF(key);
242 Py_XDECREF(val);
244 }
246
247 result = result_v;
248 }
249 break;
250
251 default:
252 elog(ERROR, "unexpected jsonb token: %d", r);
253 return NULL;
254 }
255
256 return result;
257}
static PyObject * PLyObject_FromJsonbValue(JsonbValue *jsonbValue)
static PyObject * PLyUnicode_FromJsonbValue(JsonbValue *jbv)
JsonbIterator * JsonbIteratorInit(JsonbContainer *container)
JsonbIteratorToken JsonbIteratorNext(JsonbIterator **it, JsonbValue *val, bool skipNested)
References elog, ERROR, JsonbIteratorInit(), JsonbIteratorNext(), sort-test::key, PG_CATCH, PG_END_TRY, PG_RE_THROW, PG_TRY, PLyObject_FromJsonbValue(), PLyUnicode_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().
◆ PLyObject_FromJsonbValue()
static PyObject * PLyObject_FromJsonbValue ( JsonbValue * jsonbValue) | static |
---|
Definition at line 95 of file jsonb_plpython.c.
96{
97 switch (jsonbValue->type)
98 {
100 Py_RETURN_NONE;
101
104
106 {
108 char *str;
109
112
114 }
115
118
120 if (jsonbValue->val.boolean)
121 Py_RETURN_TRUE;
122 else
123 Py_RETURN_FALSE;
124
125 default:
126 elog(ERROR, "unexpected jsonb value type: %d", jsonbValue->type);
127 return NULL;
128 }
129}
Datum numeric_out(PG_FUNCTION_ARGS)
#define DirectFunctionCall1(func, arg1)
static Datum NumericGetDatum(Numeric X)
static char * DatumGetCString(Datum X)
References DatumGetCString(), decimal_constructor, DirectFunctionCall1, elog, ERROR, jbvBinary, jbvBool, jbvNull, jbvNumeric, jbvString, numeric_out(), NumericGetDatum(), PLyObject_FromJsonbContainer(), PLyUnicode_FromJsonbValue(), str, JsonbValue::type, and JsonbValue::val.
Referenced by PLyObject_FromJsonbContainer().
◆ PLyObject_ToJsonbValue()
Definition at line 410 of file jsonb_plpython.c.
411{
413
414 if (!PyUnicode_Check(obj))
415 {
416 if (PySequence_Check(obj))
418 else if (PyMapping_Check(obj))
420 }
421
423
424 if (obj == Py_None)
426 else if (PyUnicode_Check(obj))
428
429
430
431
432
433 else if (PyBool_Check(obj))
434 {
436 out->val.boolean = (obj == Py_True);
437 }
438 else if (PyNumber_Check(obj))
440 else
442 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
443 errmsg("Python type \"%s\" cannot be transformed to jsonb",
445
446
447 return (*jsonb_state ?
449 out);
450}
static JsonbValue * PLyMapping_ToJsonbValue(PyObject *obj, JsonbParseState **jsonb_state)
static JsonbValue * PLyNumber_ToJsonbValue(PyObject *obj, JsonbValue *jbvNum)
static JsonbValue * PLySequence_ToJsonbValue(PyObject *obj, JsonbParseState **jsonb_state)
References ereport, errcode(), errmsg(), ERROR, jbvBool, jbvNull, palloc(), PLyMapping_ToJsonbValue(), PLyNumber_ToJsonbValue(), PLyObject_AsString, PLySequence_ToJsonbValue(), PLyUnicode_ToJsonbValue(), pushJsonbValue(), JsonbValue::type, JsonbValue::val, WJB_ELEM, and WJB_VALUE.
Referenced by plpython_to_jsonb(), PLyMapping_ToJsonbValue(), and PLySequence_ToJsonbValue().
◆ PLySequence_ToJsonbValue()
Definition at line 322 of file jsonb_plpython.c.
323{
324 Py_ssize_t i;
325 Py_ssize_t pcount;
326 PyObject *volatile value = NULL;
327
328 pcount = PySequence_Size(obj);
329
331
333 {
334 for (i = 0; i < pcount; i++)
335 {
336 value = PySequence_GetItem(obj, i);
338
340 Py_XDECREF(value);
342 }
343 }
345 {
346 Py_XDECREF(value);
348 }
350
352}
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().
◆ PLyUnicode_FromJsonbValue()
static PyObject * PLyUnicode_FromJsonbValue ( JsonbValue * jbv) | static |
---|
◆ PLyUnicode_ToJsonbValue()
static void PLyUnicode_ToJsonbValue ( PyObject * obj, JsonbValue * jbvElem ) | static |
---|
◆ decimal_constructor
PyObject* decimal_constructor | static |
---|