5
5
#include "plpy_main.h"
6
6
#include "plpy_typeio.h"
7
7
#include "jsonb_plpython.h"
8
+ #include "numeric_plpython.h"
8
9
#include "utils/jsonb.h"
9
10
#include "utils/fmgrprotos.h"
10
11
#include "utils/numeric.h"
@@ -13,8 +14,11 @@ PG_MODULE_MAGIC;
13
14
14
15
void _PG_init (void );
15
16
16
- typedef void (* PLy_elog_impl_t ) (int elevel , const char * fmt ,...);
17
- static PLy_elog_impl_t PLy_elog_impl_p ;
17
+ PLyObject_AsString_t PLyObject_AsString_p ;
18
+ PLy_elog_impl_t PLy_elog_impl_p ;
19
+ #if PY_MAJOR_VERSION >= 3
20
+ PLyUnicode_FromStringAndSize_t PLyUnicode_FromStringAndSize_p ;
21
+ #endif
18
22
19
23
PLy_get_global_memory_context_t PLy_get_global_memory_context_p ;
20
24
PLyObject_AsString_t PLyObject_AsString_p ;
@@ -37,12 +41,6 @@ static JsonbValue *PLyObject_ToJsonbValue(PyObject *obj,
37
41
PLyJsonb_FromJsonbContainer(jbc, len)
38
42
#endif
39
43
40
- #if PY_MAJOR_VERSION >= 3
41
- typedef PyObject * (* PLyUnicode_FromStringAndSize_t )
42
- (const char * s , Py_ssize_t size );
43
- static PLyUnicode_FromStringAndSize_t PLyUnicode_FromStringAndSize_p ;
44
- #endif
45
-
46
44
/*
47
45
* Module initialize function: fetch function pointers for cross-module calls.
48
46
*/
@@ -134,6 +132,7 @@ PLyObject_FromJsonbValue(JsonbValue *jsonbValue)
134
132
#endif
135
133
return PyInt_FromLong ((long ) intval );
136
134
135
+ return PLyObject_FromNumeric (jsonbValue -> val .numeric );
137
136
num = NumericGetDatum (jsonbValue -> val .numeric );
138
137
str = DatumGetCString (DirectFunctionCall1 (numeric_out , num ));
139
138
@@ -415,60 +414,19 @@ PLySequence_ToJsonbValue(PyObject *obj, JsonbParseState **jsonb_state)
415
414
static JsonbValue *
416
415
PLyNumber_ToJsonbValue (PyObject * obj , JsonbValue * jbvNum )
417
416
{
418
- Numeric num ;
419
- char * str ;
420
-
421
417
jbvNum -> type = jbvNumeric ;
422
-
423
- if (PyInt_Check (obj ))
424
- {
425
- long val = PyInt_AsLong (obj );
426
-
427
- if (val != -1 || !PyErr_Occurred ())
428
- {
429
- jbvNum -> val .numeric =
430
- DatumGetNumeric (DirectFunctionCall1 (int8_numeric ,
431
- Int64GetDatum ((int64 ) val )));
432
- return jbvNum ;
433
- }
434
-
435
- PyErr_Clear ();
436
- }
437
-
438
- str = PLyObject_AsString (obj );
439
-
440
- PG_TRY ();
441
- {
442
- Datum numd ;
443
-
444
- numd = DirectFunctionCall3 (numeric_in ,
445
- CStringGetDatum (str ),
446
- ObjectIdGetDatum (InvalidOid ),
447
- Int32GetDatum (-1 ));
448
- num = DatumGetNumeric (numd );
449
- }
450
- PG_CATCH ();
451
- {
452
- ereport (ERROR ,
453
- (errcode (ERRCODE_DATATYPE_MISMATCH ),
454
- (errmsg ("could not convert value \"%s\" to jsonb" , str ))));
455
- }
456
- PG_END_TRY ();
457
-
458
- pfree (str );
418
+ jbvNum -> val .numeric = PLyNumber_ToNumeric (obj );
459
419
460
420
/*
461
421
* jsonb doesn't allow NaN (per JSON specification), so we have to prevent
462
422
* it here explicitly. (Infinity is also not allowed in jsonb, but
463
423
* numeric_in above already catches that.)
464
424
*/
465
- if (numeric_is_nan (num ))
425
+ if (numeric_is_nan (jbvNum -> val . numeric ))
466
426
ereport (ERROR ,
467
427
(errcode (ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE ),
468
428
(errmsg ("cannot convert NaN to jsonb" ))));
469
429
470
- jbvNum -> val .numeric = num ;
471
-
472
430
return jbvNum ;
473
431
}
474
432
0 commit comments