6 #include "utils/fmgrprotos.h"
15 typedef char *(*PLyObject_AsString_t) (PyObject *plrv);
31 typedef PyObject *(*PLyUnicode_FromStringAndSize_t)
32 (
const char *s, Py_ssize_t size);
57 #define PLyObject_AsString (PLyObject_AsString_p)
58 #define PLyUnicode_FromStringAndSize (PLyUnicode_FromStringAndSize_p)
60 #define PLy_elog (PLy_elog_impl_p)
85 jbvElem->
val.string.len = strlen(jbvElem->
val.string.val);
96 switch (jsonbValue->
type)
119 if (jsonbValue->
val.boolean)
125 elog(
ERROR,
"unexpected jsonb value type: %d", jsonbValue->
type);
149 if (v.
val.array.rawScalar)
156 elog(
ERROR,
"unexpected jsonb token: %d", r);
162 PyObject *
volatile elem = NULL;
164 result = PyList_New(0);
177 PyList_Append(result, elem);
194 PyObject *
volatile result_v = PyDict_New();
195 PyObject *
volatile key = NULL;
196 PyObject *
volatile val = NULL;
211 Py_XDECREF(result_v);
217 elog(
ERROR,
"unexpected jsonb token: %d", r);
224 Py_XDECREF(result_v);
229 PyDict_SetItem(result_v,
key,
val);
239 Py_XDECREF(result_v);
251 elog(
ERROR,
"unexpected jsonb token: %d", r);
267 PyObject *
volatile items;
270 pcount = PyMapping_Size(obj);
271 items = PyMapping_Items(obj);
279 for (
i = 0;
i < pcount;
i++)
282 PyObject *item = PyList_GetItem(items,
i);
283 PyObject *
key = PyTuple_GetItem(item, 0);
284 PyObject *
value = PyTuple_GetItem(item, 1);
290 jbvKey.
val.string.len = 0;
291 jbvKey.
val.string.val =
"";
325 PyObject *
volatile value = NULL;
327 pcount = PySequence_Size(obj);
333 for (
i = 0;
i < pcount;
i++)
335 value = PySequence_GetItem(obj,
i);
377 (
errcode(ERRCODE_DATATYPE_MISMATCH),
378 errmsg(
"could not convert value \"%s\" to jsonb",
str)));
390 (
errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
391 errmsg(
"cannot convert NaN to jsonb")));
394 (
errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
395 errmsg(
"cannot convert infinity to jsonb")));
398 jbvNum->
val.numeric = num;
413 if (!PyUnicode_Check(obj))
415 if (PySequence_Check(obj))
417 else if (PyMapping_Check(obj))
425 else if (PyUnicode_Check(obj))
432 else if (PyBool_Check(obj))
435 out->
val.boolean = (obj == Py_True);
437 else if (PyNumber_Check(obj))
441 (
errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
442 errmsg(
"Python type \"%s\" cannot be transformed to jsonb",
446 return (*jsonb_state ?
488 PyObject *decimal_module = PyImport_ImportModule(
"cdecimal");
493 decimal_module = PyImport_ImportModule(
"decimal");
501 PLy_elog(
ERROR,
"transformation from jsonb to Python failed");
Datum numeric_out(PG_FUNCTION_ARGS)
Datum numeric_in(PG_FUNCTION_ARGS)
bool numeric_is_nan(Numeric num)
bool numeric_is_inf(Numeric num)
#define AssertVariableIsOfType(varname, typename)
elog(ERROR, "%s: %s", p2, msg)
void * load_external_function(const char *filename, const char *funcname, bool signalNotFound, void **filehandle)
int errcode(int sqlerrcode)
int errmsg(const char *fmt,...)
#define ereport(elevel,...)
#define PG_GETARG_POINTER(n)
#define DirectFunctionCall1(func, arg1)
#define DirectFunctionCall3(func, arg1, arg2, arg3)
#define PG_RETURN_POINTER(x)
#define PG_GETARG_JSONB_P(x)
static JsonbValue * PLyObject_ToJsonbValue(PyObject *obj, JsonbParseState **jsonb_state, bool is_elem)
#define PLyUnicode_FromStringAndSize
static PLy_elog_impl_t PLy_elog_impl_p
char *(* PLyObject_AsString_t)(PyObject *plrv)
static PyObject * PLyUnicode_FromJsonbValue(JsonbValue *jbv)
PyObject *(* PLyUnicode_FromStringAndSize_t)(const char *s, Py_ssize_t size)
Datum plpython_to_jsonb(PG_FUNCTION_ARGS)
void(* PLy_elog_impl_t)(int elevel, const char *fmt,...)
PG_FUNCTION_INFO_V1(plpython_to_jsonb)
static PLyObject_AsString_t PLyObject_AsString_p
static JsonbValue * PLyMapping_ToJsonbValue(PyObject *obj, JsonbParseState **jsonb_state)
static PyObject * decimal_constructor
Datum jsonb_to_plpython(PG_FUNCTION_ARGS)
static PLyUnicode_FromStringAndSize_t PLyUnicode_FromStringAndSize_p
static PyObject * PLyObject_FromJsonbValue(JsonbValue *jsonbValue)
static void PLyUnicode_ToJsonbValue(PyObject *obj, JsonbValue *jbvElem)
static JsonbValue * PLyNumber_ToJsonbValue(PyObject *obj, JsonbValue *jbvNum)
static PyObject * PLyObject_FromJsonbContainer(JsonbContainer *jsonb)
#define PLyObject_AsString
static JsonbValue * PLySequence_ToJsonbValue(PyObject *obj, JsonbParseState **jsonb_state)
JsonbIterator * JsonbIteratorInit(JsonbContainer *container)
Jsonb * JsonbValueToJsonb(JsonbValue *val)
JsonbIteratorToken JsonbIteratorNext(JsonbIterator **it, JsonbValue *val, bool skipNested)
JsonbValue * pushJsonbValue(JsonbParseState **pstate, JsonbIteratorToken seq, JsonbValue *jbval)
Assert(fmt[strlen(fmt) - 1] !='\n')
static void const char * fmt
void pfree(void *pointer)
#define DatumGetNumeric(X)
#define NumericGetDatum(X)
void PLy_elog_impl(int elevel, const char *fmt,...)
#define CStringGetDatum(X)
#define ObjectIdGetDatum(X)
#define DatumGetCString(X)
#define PointerGetDatum(X)