PostgreSQL Source Code: contrib/jsonb_plpython/jsonb_plpython.c Source File (original) (raw)

2

6#include "utils/fmgrprotos.h"

9

11 .name = "jsonb_plpython",

12 .version = PG_VERSION

13);

14

15

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

18

21

22

23

24

25

27

31

32typedef PyObject *(*PLyUnicode_FromStringAndSize_t)

33 (const char *s, Py_ssize_t size);

35

36

37

38

39void

41{

42

46 true, NULL);

50 true, NULL);

54 true, NULL);

55}

56

57

58#define PLyObject_AsString (PLyObject_AsString_p)

59#define PLyUnicode_FromStringAndSize (PLyUnicode_FromStringAndSize_p)

60#undef PLy_elog

61#define PLy_elog (PLy_elog_impl_p)

62

63

64

65

66

67

68static PyObject *

70{

72

74}

75

76

77

78

79

80

81static void

83{

86 jbvElem->val.string.len = strlen(jbvElem->val.string.val);

87}

88

89

90

91

92

93

94static PyObject *

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}

130

131

132

133

134

135

136static PyObject *

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}

258

259

260

261

262

263

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}

314

315

316

317

318

319

320

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}

353

354

355

356

357

358

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}

403

404

405

406

407

408

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}

451

452

453

454

455

456

460{

461 PyObject *obj;

464

468}

469

470

471

472

473

474

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}

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)

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)

Assert(PointerIsAligned(start, uint64))

#define PG_GETARG_JSONB_P(x)

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

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

#define PLyUnicode_FromStringAndSize

PG_MODULE_MAGIC_EXT(.name="jsonb_plpython",.version=PG_VERSION)

static PLy_elog_impl_t PLy_elog_impl_p

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

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,...)

static PyObject * PLyObject_FromJsonbValue(JsonbValue *jsonbValue)

PG_FUNCTION_INFO_V1(plpython_to_jsonb)

static PLyObject_AsString_t PLyObject_AsString_p

char *(* PLyObject_AsString_t)(PyObject *plrv)

static PyObject * decimal_constructor

Datum jsonb_to_plpython(PG_FUNCTION_ARGS)

static PLyUnicode_FromStringAndSize_t PLyUnicode_FromStringAndSize_p

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

static PyObject * PLyObject_FromJsonbContainer(JsonbContainer *jsonb)

#define PLyObject_AsString

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

static PyObject * PLyUnicode_FromJsonbValue(JsonbValue *jbv)

JsonbValue * pushJsonbValue(JsonbParseState **pstate, JsonbIteratorToken seq, JsonbValue *jbval)

JsonbIterator * JsonbIteratorInit(JsonbContainer *container)

JsonbIteratorToken JsonbIteratorNext(JsonbIterator **it, JsonbValue *val, bool skipNested)

Jsonb * JsonbValueToJsonb(JsonbValue *val)

void pfree(void *pointer)

static Numeric DatumGetNumeric(Datum X)

static Datum NumericGetDatum(Numeric X)

void PLy_elog_impl(int elevel, const char *fmt,...)

static Datum PointerGetDatum(const void *X)

static Datum ObjectIdGetDatum(Oid X)

static char * DatumGetCString(Datum X)

static Datum CStringGetDatum(const char *X)

static Datum Int32GetDatum(int32 X)