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 (key)

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 (val)

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

PLy_elog_impl_p

PLyObject_AsString_p

PLyUnicode_FromStringAndSize_p