55#include "plpy_main.h"
66#include "plpy_typeio.h"
77#include "jsonb_plpython.h"
8+ #include "numeric_plpython.h"
89#include "utils/jsonb.h"
910#include "utils/fmgrprotos.h"
1011#include "utils/numeric.h"
@@ -13,8 +14,11 @@ PG_MODULE_MAGIC;
1314
1415void _PG_init (void );
1516
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
1822
1923PLy_get_global_memory_context_t PLy_get_global_memory_context_p ;
2024PLyObject_AsString_t PLyObject_AsString_p ;
@@ -37,12 +41,6 @@ static JsonbValue *PLyObject_ToJsonbValue(PyObject *obj,
3741 PLyJsonb_FromJsonbContainer(jbc, len)
3842#endif
3943
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-
4644/*
4745 * Module initialize function: fetch function pointers for cross-module calls.
4846 */
@@ -134,6 +132,7 @@ PLyObject_FromJsonbValue(JsonbValue *jsonbValue)
134132#endif
135133 return PyInt_FromLong ((long ) intval );
136134
135+ return PLyObject_FromNumeric (jsonbValue -> val .numeric );
137136 num = NumericGetDatum (jsonbValue -> val .numeric );
138137 str = DatumGetCString (DirectFunctionCall1 (numeric_out , num ));
139138
@@ -415,60 +414,19 @@ PLySequence_ToJsonbValue(PyObject *obj, JsonbParseState **jsonb_state)
415414static JsonbValue *
416415PLyNumber_ToJsonbValue (PyObject * obj , JsonbValue * jbvNum )
417416{
418- Numeric num ;
419- char * str ;
420-
421417 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 );
459419
460420 /*
461421 * jsonb doesn't allow NaN (per JSON specification), so we have to prevent
462422 * it here explicitly. (Infinity is also not allowed in jsonb, but
463423 * numeric_in above already catches that.)
464424 */
465- if (numeric_is_nan (num ))
425+ if (numeric_is_nan (jbvNum -> val . numeric ))
466426 ereport (ERROR ,
467427 (errcode (ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE ),
468428 (errmsg ("cannot convert NaN to jsonb" ))));
469429
470- jbvNum -> val .numeric = num ;
471-
472430 return jbvNum ;
473431}
474432
0 commit comments