Thanks a lot. Fixing `CREATE FUNCTION` statement fixed the crash issue.
On Tue, Mar 19, 2019 at 3:18 PM Michel Pelletier <pelletier.mic...@gmail.com> wrote: > For server crashes you can't beat gdb in my opinion. It's a challenge but > worth it in the long run to have gdb skills if you're coding in C (or > Python, since pdb shares many of gdb's keybindings). > > But just looking at the function I don't see what's immediately wrong, > what's your CREATE FUNCTION statement look like? > > On Tue, Mar 19, 2019 at 1:08 PM T L <tin...@gmail.com> wrote: > >> 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) >>>>>> >>>>>>