=== Applying patches on top of PostgreSQL commit ID 005a2907dc304eadb00719e5b6e08cd2cf329829 === /etc/rc.d/jail: WARNING: Per-jail configuration via jail_* variables is obsolete. Please consider migrating to /etc/jail.conf. Sun Dec 7 17:30:23 UTC 2025 On branch cf/5930 nothing to commit, working tree clean === using 'git am' to apply patch ./v5-0001-Revise-APIs-for-pushJsonbValue-and-associated-rou.patch === Applying: Revise APIs for pushJsonbValue() and associated routines. Using index info to reconstruct a base tree... M contrib/hstore/hstore_io.c M contrib/jsonb_plperl/jsonb_plperl.c M contrib/jsonb_plpython/jsonb_plpython.c M src/backend/utils/adt/jsonb.c M src/backend/utils/adt/jsonb_util.c M src/backend/utils/adt/jsonfuncs.c M src/backend/utils/adt/jsonpath_exec.c M src/include/utils/jsonb.h Falling back to patching base and 3-way merge... Auto-merging src/backend/utils/adt/jsonb_util.c CONFLICT (content): Merge conflict in src/backend/utils/adt/jsonb_util.c Auto-merging src/backend/utils/adt/jsonb.c CONFLICT (content): Merge conflict in src/backend/utils/adt/jsonb.c error: Failed to merge in the changes. hint: Use 'git am --show-current-patch=diff' to see the failed patch Patch failed at 0001 Revise APIs for pushJsonbValue() and associated routines. When you have resolved this problem, run "git am --continue". If you prefer to skip this patch, run "git am --skip" instead. To restore the original branch and stop patching, run "git am --abort". Unstaged changes after reset: M src/backend/utils/adt/jsonb.c M src/backend/utils/adt/jsonb_util.c === using patch(1) to apply patch ./v5-0001-Revise-APIs-for-pushJsonbValue-and-associated-rou.patch === patching file contrib/hstore/hstore_io.c Hunk #1 FAILED at 1439. Hunk #2 FAILED at 1453. Hunk #3 FAILED at 1465. Hunk #4 FAILED at 1482. Hunk #5 FAILED at 1499. Hunk #6 FAILED at 1541. 6 out of 6 hunks FAILED -- saving rejects to file contrib/hstore/hstore_io.c.rej patching file contrib/jsonb_plperl/jsonb_plperl.c Hunk #1 FAILED at 13. Hunk #2 FAILED at 127. Hunk #3 FAILED at 141. Hunk #4 FAILED at 167. Hunk #5 FAILED at 186. Hunk #6 FAILED at 259. Hunk #7 FAILED at 289. 7 out of 7 hunks FAILED -- saving rejects to file contrib/jsonb_plperl/jsonb_plperl.c.rej patching file contrib/jsonb_plpython/jsonb_plpython.c Hunk #1 FAILED at 26. Hunk #2 FAILED at 261. Hunk #3 FAILED at 297. Hunk #4 FAILED at 318. Hunk #5 FAILED at 336. Hunk #6 FAILED at 348. Hunk #7 FAILED at 406. Hunk #8 FAILED at 443. Hunk #9 FAILED at 458. 9 out of 9 hunks FAILED -- saving rejects to file contrib/jsonb_plpython/jsonb_plpython.c.rej patching file src/backend/utils/adt/jsonb.c Hunk #1 FAILED at 25. Hunk #2 FAILED at 270. Hunk #3 FAILED at 292. Hunk #4 FAILED at 303. Hunk #5 FAILED at 313. Hunk #6 FAILED at 323. Hunk #7 FAILED at 341. Hunk #8 FAILED at 435. Hunk #9 FAILED at 446. Hunk #10 FAILED at 795. Hunk #11 FAILED at 830. Hunk #12 FAILED at 841. Hunk #13 FAILED at 868. Hunk #14 FAILED at 885. Hunk #15 FAILED at 914. Hunk #16 FAILED at 962. Hunk #17 FAILED at 984. Hunk #18 FAILED at 1001. Hunk #19 FAILED at 1119. Hunk #20 FAILED at 1139. Hunk #21 FAILED at 1166. Hunk #22 FAILED at 1201. Hunk #23 FAILED at 1216. Hunk #24 FAILED at 1226. Hunk #25 FAILED at 1262. Hunk #26 FAILED at 1290. Hunk #27 FAILED at 1341. Hunk #28 FAILED at 1358. Hunk #29 FAILED at 1394. Hunk #30 FAILED at 1431. Hunk #31 FAILED at 1448. Hunk #32 FAILED at 1457. Hunk #33 FAILED at 1534. Hunk #34 FAILED at 1559. Hunk #35 FAILED at 1575. Hunk #36 FAILED at 1606. Hunk #37 FAILED at 1662. Hunk #38 FAILED at 1704. Hunk #39 FAILED at 1760. Hunk #40 FAILED at 1769. Hunk #41 FAILED at 1806. Hunk #42 FAILED at 1845. Hunk #43 FAILED at 1876. Hunk #44 FAILED at 1953. 44 out of 44 hunks FAILED -- saving rejects to file src/backend/utils/adt/jsonb.c.rej patching file src/backend/utils/adt/jsonb_util.c Hunk #1 FAILED at 14. Hunk #2 FAILED at 54. Hunk #3 FAILED at 95. Hunk #4 FAILED at 106. Hunk #5 FAILED at 547. Hunk #6 FAILED at 562. Hunk #7 FAILED at 581. Hunk #8 FAILED at 615. 8 out of 8 hunks FAILED -- saving rejects to file src/backend/utils/adt/jsonb_util.c.rej patching file src/backend/utils/adt/jsonfuncs.c Hunk #1 FAILED at 475. Hunk #2 FAILED at 1679. Hunk #3 FAILED at 1689. Hunk #4 FAILED at 1718. Hunk #5 FAILED at 1758. Hunk #6 FAILED at 1776. Hunk #7 FAILED at 1792. Hunk #8 FAILED at 4544. Hunk #9 FAILED at 4581. Hunk #10 FAILED at 4590. Hunk #11 FAILED at 4627. Hunk #12 FAILED at 4649. Hunk #13 FAILED at 4670. Hunk #14 FAILED at 4702. Hunk #15 FAILED at 4724. Hunk #16 FAILED at 4788. Hunk #17 FAILED at 4808. Hunk #18 FAILED at 4846. Hunk #19 FAILED at 4856. Hunk #20 FAILED at 4875. Hunk #21 FAILED at 4904. Hunk #22 FAILED at 4988. Hunk #23 FAILED at 5015. Hunk #24 FAILED at 5034. Hunk #25 FAILED at 5060. Hunk #26 FAILED at 5075. Hunk #27 FAILED at 5112. Hunk #28 FAILED at 5133. Hunk #29 FAILED at 5149. Hunk #30 FAILED at 5168. Hunk #31 FAILED at 5203. Hunk #32 FAILED at 5240. Hunk #33 FAILED at 5271. Hunk #34 FAILED at 5287. Hunk #35 FAILED at 5314. Hunk #36 FAILED at 5347. Hunk #37 FAILED at 5369. Hunk #38 FAILED at 5389. Hunk #39 FAILED at 5413. Hunk #40 FAILED at 5425. Hunk #41 FAILED at 5493. Hunk #42 FAILED at 5512. Hunk #43 FAILED at 5520. Hunk #44 FAILED at 5548. Hunk #45 FAILED at 5563. Hunk #46 FAILED at 5808. Hunk #47 FAILED at 5827. 47 out of 47 hunks FAILED -- saving rejects to file src/backend/utils/adt/jsonfuncs.c.rej patching file src/backend/utils/adt/jsonpath_exec.c Hunk #1 FAILED at 2874. Hunk #2 FAILED at 2889. Hunk #3 FAILED at 2901. Hunk #4 FAILED at 3649. Hunk #5 FAILED at 3659. 5 out of 5 hunks FAILED -- saving rejects to file src/backend/utils/adt/jsonpath_exec.c.rej patching file src/include/utils/jsonb.h Hunk #1 FAILED at 67. Hunk #2 FAILED at 315. Hunk #3 FAILED at 404. 3 out of 3 hunks FAILED -- saving rejects to file src/include/utils/jsonb.h.rej Removing contrib/hstore/hstore_io.c.rej Removing contrib/jsonb_plperl/jsonb_plperl.c.rej Removing contrib/jsonb_plpython/jsonb_plpython.c.rej Removing src/backend/utils/adt/jsonb.c.rej Removing src/backend/utils/adt/jsonb_util.c.rej Removing src/backend/utils/adt/jsonfuncs.c.rej Removing src/backend/utils/adt/jsonpath_exec.c.rej Removing src/include/utils/jsonb.h.rej === using 'git apply' to apply patch ./v5-0001-Revise-APIs-for-pushJsonbValue-and-associated-rou.patch === Applied patch to 'contrib/hstore/hstore_io.c' cleanly. Applied patch to 'contrib/jsonb_plperl/jsonb_plperl.c' cleanly. Applied patch to 'contrib/jsonb_plpython/jsonb_plpython.c' cleanly. Applied patch to 'src/backend/utils/adt/jsonb.c' with conflicts. Applied patch to 'src/backend/utils/adt/jsonb_util.c' with conflicts. Applied patch to 'src/backend/utils/adt/jsonfuncs.c' cleanly. Applied patch to 'src/backend/utils/adt/jsonpath_exec.c' cleanly. Applied patch to 'src/include/utils/jsonb.h' cleanly. U src/backend/utils/adt/jsonb.c U src/backend/utils/adt/jsonb_util.c diff --cc src/backend/utils/adt/jsonb.c index c4fe6e00dcd,dfd2771556f..00000000000 --- a/src/backend/utils/adt/jsonb.c +++ b/src/backend/utils/adt/jsonb.c @@@ -1528,10 -1520,12 +1528,19 @@@ jsonb_agg_transfn_worker(FunctionCallIn (errcode(ERRCODE_INVALID_PARAMETER_VALUE), errmsg("could not determine input data type"))); ++<<<<<<< ours + state = MemoryContextAllocZero(aggcontext, sizeof(JsonbAggState)); + result = &state->pstate; + result->outcontext = aggcontext; + pushJsonbValue(result, WJB_BEGIN_ARRAY, NULL); ++======= + oldcontext = MemoryContextSwitchTo(aggcontext); + state = palloc(sizeof(JsonbAggState)); + result = palloc0(sizeof(JsonbInState)); + state->res = result; + pushJsonbValue(result, WJB_BEGIN_ARRAY, NULL); + MemoryContextSwitchTo(oldcontext); ++>>>>>>> theirs json_categorize_type(arg_type, true, &state->val_category, &state->val_output_func); @@@ -1545,17 -1539,68 +1554,73 @@@ if (absent_on_null && PG_ARGISNULL(1)) PG_RETURN_POINTER(state); - /* turn the argument into jsonb in the normal function context */ - + /* + * We run this code in the normal function context, so that we don't leak + * any cruft from datatype output functions and such into the aggcontext. + * But the "result" JsonbValue will be constructed in aggcontext, so that + * it remains available across calls. + */ val = PG_ARGISNULL(1) ? (Datum) 0 : PG_GETARG_DATUM(1); - memset(&elem, 0, sizeof(JsonbInState)); - - datum_to_jsonb_internal(val, PG_ARGISNULL(1), &elem, state->val_category, + datum_to_jsonb_internal(val, PG_ARGISNULL(1), result, state->val_category, state->val_output_func, false); ++<<<<<<< ours ++======= + jbelem = JsonbValueToJsonb(elem.result); + + /* switch to the aggregate context for accumulation operations */ + + oldcontext = MemoryContextSwitchTo(aggcontext); + + it = JsonbIteratorInit(&jbelem->root); + + while ((type = JsonbIteratorNext(&it, &v, false)) != WJB_DONE) + { + switch (type) + { + case WJB_BEGIN_ARRAY: + if (v.val.array.rawScalar) + single_scalar = true; + else + pushJsonbValue(result, type, NULL); + break; + case WJB_END_ARRAY: + if (!single_scalar) + pushJsonbValue(result, type, NULL); + break; + case WJB_BEGIN_OBJECT: + case WJB_END_OBJECT: + pushJsonbValue(result, type, NULL); + break; + case WJB_ELEM: + case WJB_KEY: + case WJB_VALUE: + if (v.type == jbvString) + { + /* copy string values in the aggregate context */ + char *buf = palloc(v.val.string.len + 1); + + snprintf(buf, v.val.string.len + 1, "%s", v.val.string.val); + v.val.string.val = buf; + } + else if (v.type == jbvNumeric) + { + /* same for numeric */ + v.val.numeric = + DatumGetNumeric(DirectFunctionCall1(numeric_uplus, + NumericGetDatum(v.val.numeric))); + } + pushJsonbValue(result, type, &v); + break; + default: + elog(ERROR, "unknown jsonb iterator token type"); + } + } + + MemoryContextSwitchTo(oldcontext); + ++>>>>>>> theirs PG_RETURN_POINTER(state); } @@@ -1593,17 -1638,16 +1658,21 @@@ jsonb_agg_finalfn(PG_FUNCTION_ARGS arg = (JsonbAggState *) PG_GETARG_POINTER(0); /* - * We need to do a shallow clone of the argument in case the final - * function is called more than once, so we avoid changing the argument. A - * shallow clone is sufficient as we aren't going to change any of the - * values, just add the final array end marker. + * The final function can be called more than once, so we must not change + * the stored JsonbValue data structure. Fortunately, the WJB_END_ARRAY + * action will only change fields in the JsonbInState struct itself, so we + * can simply invoke pushJsonbValue on a local copy of that. */ - memset(&result, 0, sizeof(JsonbInState)); + result = arg->pstate; - result.parseState = clone_parse_state(arg->res->parseState); + pushJsonbValue(&result, WJB_END_ARRAY, NULL); ++<<<<<<< ours + /* We expect result.parseState == NULL after closing the array */ + Assert(result.parseState == NULL); ++======= + pushJsonbValue(&result, WJB_END_ARRAY, NULL); ++>>>>>>> theirs out = JsonbValueToJsonb(result.result); @@@ -1632,9 -1684,10 +1701,16 @@@ jsonb_object_agg_transfn_worker(Functio { Oid arg_type; ++<<<<<<< ours + state = MemoryContextAllocZero(aggcontext, sizeof(JsonbAggState)); + result = &state->pstate; + result->outcontext = aggcontext; ++======= + oldcontext = MemoryContextSwitchTo(aggcontext); + state = palloc(sizeof(JsonbAggState)); + result = palloc0(sizeof(JsonbInState)); + state->res = result; ++>>>>>>> theirs pushJsonbValue(result, WJB_BEGIN_OBJECT, NULL); result->parseState->unique_keys = unique_keys; result->parseState->skip_nulls = absent_on_null; @@@ -1679,22 -1736,133 +1755,141 @@@ if (skip && !unique_keys) PG_RETURN_POINTER(state); + /* + * We run this code in the normal function context, so that we don't leak + * any cruft from datatype output functions and such into the aggcontext. + * But the "result" JsonbValue will be constructed in aggcontext, so that + * it remains available across calls. + */ val = PG_GETARG_DATUM(1); - memset(&elem, 0, sizeof(JsonbInState)); - - datum_to_jsonb_internal(val, false, &elem, state->key_category, + datum_to_jsonb_internal(val, false, result, state->key_category, state->key_output_func, true); ++<<<<<<< ours ++======= + jbkey = JsonbValueToJsonb(elem.result); + ++>>>>>>> theirs val = PG_ARGISNULL(2) ? (Datum) 0 : PG_GETARG_DATUM(2); - memset(&elem, 0, sizeof(JsonbInState)); - - datum_to_jsonb_internal(val, PG_ARGISNULL(2), &elem, state->val_category, + datum_to_jsonb_internal(val, PG_ARGISNULL(2), result, state->val_category, state->val_output_func, false); ++<<<<<<< ours ++======= + jbval = JsonbValueToJsonb(elem.result); + + it = JsonbIteratorInit(&jbkey->root); + + /* switch to the aggregate context for accumulation operations */ + + oldcontext = MemoryContextSwitchTo(aggcontext); + + /* + * keys should be scalar, and we should have already checked for that + * above when calling datum_to_jsonb, so we only need to look for these + * things. + */ + + while ((type = JsonbIteratorNext(&it, &v, false)) != WJB_DONE) + { + switch (type) + { + case WJB_BEGIN_ARRAY: + if (!v.val.array.rawScalar) + elog(ERROR, "unexpected structure for key"); + break; + case WJB_ELEM: + if (v.type == jbvString) + { + /* copy string values in the aggregate context */ + char *buf = palloc(v.val.string.len + 1); + + snprintf(buf, v.val.string.len + 1, "%s", v.val.string.val); + v.val.string.val = buf; + } + else + { + ereport(ERROR, + (errcode(ERRCODE_INVALID_PARAMETER_VALUE), + errmsg("object keys must be strings"))); + } + pushJsonbValue(result, WJB_KEY, &v); + + if (skip) + { + v.type = jbvNull; + pushJsonbValue(result, WJB_VALUE, &v); + MemoryContextSwitchTo(oldcontext); + PG_RETURN_POINTER(state); + } + + break; + case WJB_END_ARRAY: + break; + default: + elog(ERROR, "unexpected structure for key"); + break; + } + } + + it = JsonbIteratorInit(&jbval->root); + + single_scalar = false; + + /* + * values can be anything, including structured and null, so we treat them + * as in json_agg_transfn, except that single scalars are always pushed as + * WJB_VALUE items. + */ + + while ((type = JsonbIteratorNext(&it, &v, false)) != WJB_DONE) + { + switch (type) + { + case WJB_BEGIN_ARRAY: + if (v.val.array.rawScalar) + single_scalar = true; + else + pushJsonbValue(result, type, NULL); + break; + case WJB_END_ARRAY: + if (!single_scalar) + pushJsonbValue(result, type, NULL); + break; + case WJB_BEGIN_OBJECT: + case WJB_END_OBJECT: + pushJsonbValue(result, type, NULL); + break; + case WJB_ELEM: + case WJB_KEY: + case WJB_VALUE: + if (v.type == jbvString) + { + /* copy string values in the aggregate context */ + char *buf = palloc(v.val.string.len + 1); + + snprintf(buf, v.val.string.len + 1, "%s", v.val.string.val); + v.val.string.val = buf; + } + else if (v.type == jbvNumeric) + { + /* same for numeric */ + v.val.numeric = + DatumGetNumeric(DirectFunctionCall1(numeric_uplus, + NumericGetDatum(v.val.numeric))); + } + pushJsonbValue(result, single_scalar ? WJB_VALUE : type, &v); + break; + default: + elog(ERROR, "unknown jsonb iterator token type"); + } + } + + MemoryContextSwitchTo(oldcontext); + ++>>>>>>> theirs PG_RETURN_POINTER(state); } @@@ -1751,19 -1919,17 +1946,23 @@@ jsonb_object_agg_finalfn(PG_FUNCTION_AR arg = (JsonbAggState *) PG_GETARG_POINTER(0); /* - * We need to do a shallow clone of the argument's res field in case the - * final function is called more than once, so we avoid changing the - * aggregate state value. A shallow clone is sufficient as we aren't - * going to change any of the values, just add the final object end - * marker. + * The final function can be called more than once, so we must not change + * the stored JsonbValue data structure. Fortunately, the WJB_END_OBJECT + * action will only destructively change fields in the JsonbInState struct + * itself, so we can simply invoke pushJsonbValue on a local copy of that. + * (This technique results in running uniqueifyJsonbObject each time, but + * for now we won't bother trying to avoid that.) */ - memset(&result, 0, sizeof(JsonbInState)); + result = arg->pstate; - result.parseState = clone_parse_state(arg->res->parseState); + pushJsonbValue(&result, WJB_END_OBJECT, NULL); ++<<<<<<< ours + /* We expect result.parseState == NULL after closing the object */ + Assert(result.parseState == NULL); ++======= + pushJsonbValue(&result, WJB_END_OBJECT, NULL); ++>>>>>>> theirs out = JsonbValueToJsonb(result.result); diff --cc src/backend/utils/adt/jsonb_util.c index 1eb8dffa8bd,2f6afcab5b1..00000000000 --- a/src/backend/utils/adt/jsonb_util.c +++ b/src/backend/utils/adt/jsonb_util.c @@@ -912,7 -911,7 +912,11 @@@ copyScalarSubstructure(JsonbValue *v, M /* pass-by-reference */ oldcontext = MemoryContextSwitchTo(outcontext); v->val.datetime.value = datumCopy(v->val.datetime.value, ++<<<<<<< ours + false, TIMETZ_TYPLEN); ++======= + false, 12); ++>>>>>>> theirs MemoryContextSwitchTo(oldcontext); break; default: