Hi, I am trying to write a PostgreSQL (11.2) server side function to read the key-value pairs of an input JSONB object. The code I have assembled so far (by mimicking existing code I can find) is below. (This is the closest thing I can find/write, and I couldn't find any documentation by the way.)
PG_FUNCTION_INFO_V1(print_kv_pair); Datum print_kv_pair(PG_FUNCTION_ARGS) { Jsonb *jb1 = PG_GETARG_JSONB_P(0); JsonbIterator *it1; JsonbValue v1; JsonbIteratorToken r1; JsonbParseState *state = NULL; if (jb1 == NULL) PG_RETURN_JSONB_P(jb1); if (!JB_ROOT_IS_OBJECT(jb1)) ereport(ERROR, (errcode(ERRCODE_INVALID_PARAMETER_VALUE), errmsg("Can only take objects"))); elog(NOTICE, "print_kv_pair(): ok0"); it1 = JsonbIteratorInit(&jb1->root); r1 = JsonbIteratorNext(&it1, &v1, false); if (r1 != WJB_BEGIN_OBJECT) ereport(ERROR, (errcode(ERRCODE_INVALID_PARAMETER_VALUE), errmsg("Iterator was not an object"))); elog(NOTICE, "print_kv_pair(): ok1"); pushJsonbValue(&state, r1, NULL); r1 = JsonbIteratorNext(&it1, &v1, false); JsonbValue *object = &v1; elog(NOTICE, "print_kv_pair(): ok2"); Assert(object->type == jbvObject); elog(NOTICE, "print_kv_pair(): ok3, nPairs = %d", object->val.object.nPairs); //iterating through key-value pairs JsonbPair *ptr; for (ptr = object->val.object.pairs; ptr - object->val.object.pairs < object->val.object.nPairs; ptr++) { //Problem line!!! // elog(NOTICE, "print_kv_pair(): k = %s, v = %s", ptr->key.val.string.val, numeric_out(ptr->value.val.numeric)); } elog(NOTICE, "print_kv_pair(): ok4"); PG_RETURN_JSONB_P(JsonbValueToJsonb(object)); } --- For example, for sample input: select print_kv_pair('{"a":1, "b": 2}'); , I expect it to print something like: k = "a", v = 1 k = "b", v = 2 However, the code crashes the PostgreSQL server, when I try to print (at the `Problem line!!!`). *Can someone explain how to fix the code and correctly iterate through the key-value pairs?* Sample output with problem line disabled: => select print_kv_pair('{"a":1, "b": 2}'); NOTICE: print_kv_pair(): ok0 NOTICE: print_kv_pair(): ok1 NOTICE: print_kv_pair(): ok2 NOTICE: print_kv_pair(): ok3, nPairs = 1 NOTICE: print_kv_pair(): ok4 print_kv_pair --------------- "a" (1 row) One additional question: Without documentation, I don't understand what these two lines do, and whether they should be deleted. pushJsonbValue(&state, r1, NULL); r1 = JsonbIteratorNext(&it1, &v1, false); The doxygen page says that there is no reverse of `JsonbValueToJsonb` (i.e. ` JsonbToJsonbValue`). But I guess that's exactly what's needed here (to extract the JsonbValue from the JSONB object). I don't quite get the work around hinted there. Thanks in advance for your help,