Thanks a lot for the hint. I've used the iteration style and cleaned up the code as far as I can. It now correctly prints the keys and values, but the server crashes near function return.
Any suggestions? -- function code -- PG_FUNCTION_INFO_V1(print_kv_pair); Datum print_kv_pair(PG_FUNCTION_ARGS) { //1. extracting JsonbValue Jsonb *jb = PG_GETARG_JSONB_P(0); JsonbIterator *it; JsonbValue v; JsonbIteratorToken r; JsonbParseState *state = NULL; if (jb == NULL) PG_RETURN_BOOL(false); if (!JB_ROOT_IS_OBJECT(jb)) ereport(ERROR, (errcode(ERRCODE_INVALID_PARAMETER_VALUE), errmsg("Can only take objects"))); it = JsonbIteratorInit(&jb->root); r = JsonbIteratorNext(&it, &v, false); if (r != WJB_BEGIN_OBJECT) ereport(ERROR, (errcode(ERRCODE_INVALID_PARAMETER_VALUE), errmsg("Iterator was not an object"))); //2. iterating through key-value pairs char *buf; while ((r = JsonbIteratorNext(&it, &v, true)) != WJB_DONE) { switch (r) { case WJB_KEY: buf = pnstrdup(v.val.string.val, v.val.string.len); elog(NOTICE, "print_kv_pair(): k = %s", buf); //debug break; case WJB_VALUE: if (v.type != jbvNumeric) { ereport(ERROR, (errcode(ERRCODE_INVALID_PARAMETER_VALUE), errmsg("value must be numeric"))); } elog(NOTICE, "print_kv_pair(): v = %s", DatumGetCString(DirectFunctionCall1(numeric_out, NumericGetDatum(v.val.numeric))) ); //debug break; case WJB_END_OBJECT: break; default: elog(ERROR, "invalid JsonbIteratorNext rc: %d", (int ) r); } } elog(NOTICE, "print_kv_pair(): ok4"); PG_RETURN_BOOL(true); } -- output -- => select print_kv_pair('{"a":1, "b": 2}'); NOTICE: print_kv_pair(): k = a NOTICE: print_kv_pair(): v = 1 NOTICE: print_kv_pair(): k = b NOTICE: print_kv_pair(): v = 2 NOTICE: print_kv_pair(): ok4 server closed the connection unexpectedly This probably means the server terminated abnormally before or while processing the request. The connection to the server was lost. Attempting reset: Failed. !> On Tue, Mar 19, 2019 at 2:22 PM Michel Pelletier <pelletier.mic...@gmail.com> wrote: > jsonb_each is a wrapper around each_worker_jsonb. It produces a row for > every key/value pair in an object. > > > https://doxygen.postgresql.org/jsonfuncs_8c.html#a7511a3aa3918eb956f3f4211d07bdbb0 > > the iteration is: > > while ((r = JsonbIteratorNext(&it, &v, skipNested)) != WJB_DONE) > > > > On Tue, Mar 19, 2019 at 11:20 AM T L <tin...@gmail.com> wrote: > >> I need this in my C code on the server side. Any link to the `jsonb_each` >> for this? Examples I found in a quick search are on the client side in SQL. >> >> I am just confused about the various jsonb types and how to effectively >> extract values and convert between them: >> >> There are Jsonb, JsonbValue (plus the associated JsonbPair ) to begin >> with. The ` JsonbToCStringWorker ` example that Andrew pointed out uses >> still another "JsonbContainer" type. >> But the type I get from "PG_GETARG_JSONB_P" is Jsonb. And it doesn't fit >> into " JsonbContainer" or the pointer math about "JsonPair" that I found >> online. >> >> What I am struggling with adapting some of the iterator code I saw is how >> to delete irrelevant code without breaking it. My use case is very >> restricted and handles hstore-like jsonb's. >> I don't need or want the code to have the ability to descend into nested >> objects or handle arrays etc., as they are invalid input in my case. >> >> I thought the pointer math example I found is easier to adapt, but I >> couldn't get a valid "JsonbPair" from the input parameter to feed into the >> pointer math. >> >> >> >> >> >> >> On Tue, Mar 19, 2019 at 9:50 AM Michel Pelletier < >> pelletier.mic...@gmail.com> wrote: >> >>> Yeah I'm not sure why you're looping using pointer math, the iterators >>> are there to provide that service. Another function to check out >>> 'jsonb_each', other than the set returning function parts, it does what it >>> looks like your are trying to do. >>> >>> -Michel >>> >>> On Mon, Mar 18, 2019 at 4:12 PM Andrew Gierth < >>> and...@tao11.riddles.org.uk> wrote: >>> >>>> >>>>> "T" == T L <tin...@gmail.com> writes: >>>> >>>> T> Below is my test. It prints a strange character instead of "a"; and >>>> T> says that the value isn't numeric. >>>> >>>> Yeah, there's plenty else wrong with your code. >>>> >>>> Did you look at how JsonbToCStringWorker does it? that looks like the >>>> best example I can find on a quick scan. >>>> >>>> -- >>>> Andrew (irc:RhodiumToad) >>>> >>>>