Как создать вложенный объект в функции jsonb C? - PullRequest
2 голосов
/ 19 июня 2020

Я могу создать и вернуть простой объект jsonb, но я застрял на попытке использовать вложенный объект в качестве значения.

Например, я хотел бы вернуть jsonb объект:

{"one":1.0,"nest":{"a":1.0,"b":2.0}}

Следующий код возвращает ошибку unknown type of jsonb container именно в этой строке:

result.res = pushJsonbValue(&result.parseState, WJB_VALUE, &obj_val);

Вот мой текущий код:

Datum
build_a_nested_object(PG_FUNCTION_ARGS)
{

    Datum num_val;
    JsonbInState result, nested_result;
    JsonbValue key, val, obj_val;

    memset(&result, 0, sizeof(JsonbInState));
    result.res = pushJsonbValue(&result.parseState, WJB_BEGIN_OBJECT, NULL);

    // first key
    key.type = jbvString;
    key.val.string.len = 3;
    key.val.string.val = "one";
    result.res = pushJsonbValue(&result.parseState, WJB_KEY, &key);

    // first value
    val.type = jbvNumeric;
    num_val = DirectFunctionCall3(numeric_in, CStringGetDatum("1.0"), ObjectIdGetDatum(InvalidOid), Int32GetDatum(-1));
    val.val.numeric = DatumGetNumeric(num_val);
    result.res = pushJsonbValue(&result.parseState, WJB_VALUE, &val);

    // Second key
    key.type = jbvString;
    key.val.string.len = 4;
    key.val.string.val = "nest";
    result.res = pushJsonbValue(&result.parseState, WJB_KEY, &key);

    // Second value
    memset(&nested_result, 0, sizeof(JsonbInState));
    nested_result.res = pushJsonbValue(&nested_result.parseState, WJB_BEGIN_OBJECT, NULL);

    // First nested key
    key.type = jbvString;
    key.val.string.len = 1;
    key.val.string.val = "a";
    nested_result.res = pushJsonbValue(&nested_result.parseState, WJB_KEY, &key);

    // First nested value
    val.type = jbvNumeric;
    numd = DirectFunctionCall3(numeric_in, CStringGetDatum("1.0"), ObjectIdGetDatum(InvalidOid), Int32GetDatum(-1));
    val.val.numeric = DatumGetNumeric(numd);
    nested_result.res = pushJsonbValue(&nested_result.parseState, WJB_VALUE, &val);

    // Second nested key
    key.type = jbvString;
    key.val.string.len = 1;
    key.val.string.val = "b";
    nested_result.res = pushJsonbValue(&nested_result.parseState, WJB_KEY, &key);

    // Second nested value
    val.type = jbvNumeric;
    numd = DirectFunctionCall3(numeric_in, CStringGetDatum("2.0"), ObjectIdGetDatum(InvalidOid), Int32GetDatum(-1));
    val.val.numeric = DatumGetNumeric(numd);
    nested_result.res = pushJsonbValue(&nested_result.parseState, WJB_VALUE, &val);

    nested_result.res = pushJsonbValue(&nested_result.parseState, WJB_END_OBJECT, NULL);
    obj_val.type = jbvBinary;
    obj_val.val.binary.data = JsonbValueToJsonb(nested_result.res);

    result.res = pushJsonbValue(&result.parseState, WJB_VALUE, &obj_val);
    result.res = pushJsonbValue(&result.parseState, WJB_END_OBJECT, NULL);

    PG_RETURN_POINTER(JsonbValueToJsonb(result.res));

}
...