Thanks a lot for the suggestions. I changed the code below (with `pnstrdup` and `DatumGetCString`). But the code still crashes at the two problem lines (either one alone crashes the server). The input is:
select print_kv_pair('{"a":1, "b": 2}'); Any further insight? -- modified code -- 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); //?? do wee need this? // r1 = JsonbIteratorNext(&it1, &v1, false); //this seems unnecessary 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 lines!!! //either elog crashes pg server char *buf = pnstrdup(ptr->key.val.string.val, ptr->key.val.string.len); elog(NOTICE, "print_kv_pair(): k = %s", (ptr->key).val.string.val); //debug elog(NOTICE, "print_kv_pair(): v = %s", DatumGetCString(DirectFunctionCall1(numeric_out, NumericGetDatum(ptr->value.val.numeric))) ); //debug } elog(NOTICE, "print_kv_pair(): ok4"); PG_RETURN_JSONB_P(JsonbValueToJsonb(object)); } On Mon, Mar 18, 2019 at 3:20 PM Andrew Gierth <and...@tao11.riddles.org.uk> wrote: > >>>>> "T" == T L <tin...@gmail.com> writes: > > T> //Problem line!!! > T> // elog(NOTICE, "print_kv_pair(): k = %s, v = %s", > T> ptr-> key.val.string.val, numeric_out(ptr->value.val.numeric)); > > string.val isn't a C string (notice the "not null terminated" comment in > the structure definition), and you can't call numeric_out like that. > Either of those would crash it. > > You could use pnstrdup to get a valid C string, and use > DatumGetCString(DirectFunctionCall1( > numeric_out, > NumericGetDatum(ptr->value.val.numeric))) > > to get the numeric value as a C string. > > -- > Andrew (irc:RhodiumToad) >