@ -164,56 +164,91 @@ PLyObject_FromJsonbContainer(JsonbContainer *jsonb)
}
else
{
/* array in v */
PyObject * volatile elem = NULL ;
result = PyList_New ( 0 ) ;
if ( ! result )
return NULL ;
while ( ( r = JsonbIteratorNext ( & it , & v , true ) ) ! = WJB_DONE )
PG_TRY ( ) ;
{
if ( r = = WJB_ELEM )
while ( ( r = JsonbIteratorNext ( & it , & v , true ) ) ! = WJB_DON E )
{
PyObject * elem = PLyObject_FromJsonbValue ( & v ) ;
if ( r ! = WJB_ELEM )
continue ;
elem = PLyObject_FromJsonbValue ( & v ) ;
PyList_Append ( result , elem ) ;
Py_XDECREF ( elem ) ;
elem = NULL ;
}
}
PG_CATCH ( ) ;
{
Py_XDECREF ( elem ) ;
Py_XDECREF ( result ) ;
PG_RE_THROW ( ) ;
}
PG_END_TRY ( ) ;
}
break ;
case WJB_BEGIN_OBJECT :
result = PyDict_New ( ) ;
if ( ! result )
return NULL ;
while ( ( r = JsonbIteratorNext ( & it , & v , true ) ) ! = WJB_DONE )
{
if ( r = = WJB_KEY )
{
PyObject * key = PLyString_FromJsonbValue ( & v ) ;
PyObject * volatile result_v = PyDict_New ( ) ;
PyObject * volatile key = NULL ;
PyObject * volatile val = NULL ;
if ( ! key )
return NULL ;
r = JsonbIteratorNext ( & it , & v , true ) ;
if ( ! result_v )
return NULL ;
if ( r = = WJB_VALUE )
PG_TRY ( ) ;
{
while ( ( r = JsonbIteratorNext ( & it , & v , true ) ) ! = WJB_DONE )
{
PyObject * value = PLyObject_FromJsonbValue ( & v ) ;
if ( r ! = WJB_KEY )
continue ;
if ( ! value )
key = PLyString_FromJsonbValue ( & v ) ;
if ( ! key )
{
Py_XDECREF ( result_v ) ;
result_v = NULL ;
break ;
}
if ( ( r = JsonbIteratorNext ( & it , & v , true ) ) ! = WJB_VALUE )
elog ( ERROR , " unexpected jsonb token: %d " , r ) ;
val = PLyObject_FromJsonbValue ( & v ) ;
if ( ! val )
{
Py_XDECREF ( key ) ;
return NULL ;
key = NULL ;
Py_XDECREF ( result_v ) ;
result_v = NULL ;
break ;
}
PyDict_SetItem ( result , key , value ) ;
Py_XDECREF ( value ) ;
}
PyDict_SetItem ( result_v , key , val ) ;
Py_XDECREF ( key ) ;
key = NULL ;
Py_XDECREF ( val ) ;
val = NULL ;
}
}
PG_CATCH ( ) ;
{
Py_XDECREF ( result_v ) ;
Py_XDECREF ( key ) ;
Py_XDECREF ( val ) ;
PG_RE_THROW ( ) ;
}
PG_END_TRY ( ) ;
result = result_v ;
}
break ;
@ -234,10 +269,8 @@ static JsonbValue *
PLyMapping_ToJsonbValue ( PyObject * obj , JsonbParseState * * jsonb_state )
{
Py_ssize_t pcount ;
JsonbValue * out = NULL ;
/* We need it volatile, since we use it after longjmp */
PyObject * volatile items = NULL ;
PyObject * volatile items ;
JsonbValue * volatile out ;
pcount = PyMapping_Size ( obj ) ;
items = PyMapping_Items ( obj ) ;
@ -281,6 +314,8 @@ PLyMapping_ToJsonbValue(PyObject *obj, JsonbParseState **jsonb_state)
}
PG_END_TRY ( ) ;
Py_DECREF ( items ) ;
return out ;
}
@ -295,19 +330,30 @@ PLySequence_ToJsonbValue(PyObject *obj, JsonbParseState **jsonb_state)
{
Py_ssize_t i ;
Py_ssize_t pcount ;
PyObject * volatile value = NULL ;
pcount = PySequence_Size ( obj ) ;
pushJsonbValue ( jsonb_state , WJB_BEGIN_ARRAY , NULL ) ;
for ( i = 0 ; i < pcount ; i + + )
PG_TRY ( ) ;
{
PyObject * value = PySequence_GetItem ( obj , i ) ;
( void ) PLyObject_ToJsonbValue ( value , jsonb_state , true ) ;
for ( i = 0 ; i < pcount ; i + + )
{
value = PySequence_GetItem ( obj , i ) ;
Assert ( value ) ;
( void ) PLyObject_ToJsonbValue ( value , jsonb_state , true ) ;
Py_XDECREF ( value ) ;
value = NULL ;
}
}
PG_CATCH ( ) ;
{
Py_XDECREF ( value ) ;
PG_RE_THROW ( ) ;
}
PG_END_TRY ( ) ;
return pushJsonbValue ( jsonb_state , WJB_END_ARRAY , NULL ) ;
}