From b22391a2ff7bdfeff4438f7a9ab26de3e33fdeff Mon Sep 17 00:00:00 2001 From: Amit Langote Date: Fri, 21 Jul 2023 11:46:56 +0900 Subject: Some refactoring to export json(b) conversion functions This is to export datum_to_json(), datum_to_jsonb(), and jsonb_from_cstring(), though the last one is exported as jsonb_from_text(). A subsequent commit to add new SQL/JSON constructor functions will need them for calling from the executor. Discussion: https://postgr.es/m/20230720160252.ldk7jy6jqclxfxkq%40alvherre.pgsql --- src/backend/utils/adt/jsonb.c | 67 +++++++++++++++++++++++++++++++------------ 1 file changed, 48 insertions(+), 19 deletions(-) (limited to 'src/backend/utils/adt/jsonb.c') diff --git a/src/backend/utils/adt/jsonb.c b/src/backend/utils/adt/jsonb.c index fc64f568682..5ea582a8884 100644 --- a/src/backend/utils/adt/jsonb.c +++ b/src/backend/utils/adt/jsonb.c @@ -59,9 +59,9 @@ static void array_dim_to_jsonb(JsonbInState *result, int dim, int ndims, int *di Datum *vals, bool *nulls, int *valcount, JsonTypeCategory tcategory, Oid outfuncoid); static void array_to_jsonb_internal(Datum array, JsonbInState *result); -static void datum_to_jsonb(Datum val, bool is_null, JsonbInState *result, - JsonTypeCategory tcategory, Oid outfuncoid, - bool key_scalar); +static void datum_to_jsonb_internal(Datum val, bool is_null, JsonbInState *result, + JsonTypeCategory tcategory, Oid outfuncoid, + bool key_scalar); static void add_jsonb(Datum val, bool is_null, JsonbInState *result, Oid val_type, bool key_scalar); static JsonbParseState *clone_parse_state(JsonbParseState *state); @@ -141,6 +141,19 @@ jsonb_send(PG_FUNCTION_ARGS) PG_RETURN_BYTEA_P(pq_endtypsend(&buf)); } +/* + * jsonb_from_text + * + * Turns json text string into a jsonb Datum. + */ +Datum +jsonb_from_text(text *js) +{ + return jsonb_from_cstring(VARDATA_ANY(js), + VARSIZE_ANY_EXHDR(js), + NULL); +} + /* * Get the type name of a jsonb container. */ @@ -622,9 +635,9 @@ add_indent(StringInfo out, bool indent, int level) * will be thrown. */ static void -datum_to_jsonb(Datum val, bool is_null, JsonbInState *result, - JsonTypeCategory tcategory, Oid outfuncoid, - bool key_scalar) +datum_to_jsonb_internal(Datum val, bool is_null, JsonbInState *result, + JsonTypeCategory tcategory, Oid outfuncoid, + bool key_scalar) { char *outputstr; bool numeric_error; @@ -859,8 +872,8 @@ array_dim_to_jsonb(JsonbInState *result, int dim, int ndims, int *dims, Datum *v { if (dim + 1 == ndims) { - datum_to_jsonb(vals[*valcount], nulls[*valcount], result, tcategory, - outfuncoid, false); + datum_to_jsonb_internal(vals[*valcount], nulls[*valcount], result, tcategory, + outfuncoid, false); (*valcount)++; } else @@ -982,7 +995,8 @@ composite_to_jsonb(Datum composite, JsonbInState *result) json_categorize_type(att->atttypid, true, &tcategory, &outfuncoid); - datum_to_jsonb(val, isnull, result, tcategory, outfuncoid, false); + datum_to_jsonb_internal(val, isnull, result, tcategory, outfuncoid, + false); } result->res = pushJsonbValue(&result->parseState, WJB_END_OBJECT, NULL); @@ -1018,9 +1032,11 @@ add_jsonb(Datum val, bool is_null, JsonbInState *result, json_categorize_type(val_type, true, &tcategory, &outfuncoid); - datum_to_jsonb(val, is_null, result, tcategory, outfuncoid, key_scalar); + datum_to_jsonb_internal(val, is_null, result, tcategory, outfuncoid, + key_scalar); } + /* * Is the given type immutable when coming out of a JSONB context? * @@ -1072,7 +1088,6 @@ to_jsonb(PG_FUNCTION_ARGS) { Datum val = PG_GETARG_DATUM(0); Oid val_type = get_fn_expr_argtype(fcinfo->flinfo, 0); - JsonbInState result; JsonTypeCategory tcategory; Oid outfuncoid; @@ -1084,11 +1099,25 @@ to_jsonb(PG_FUNCTION_ARGS) json_categorize_type(val_type, true, &tcategory, &outfuncoid); + PG_RETURN_DATUM(datum_to_jsonb(val, tcategory, outfuncoid)); +} + +/* + * Turn a Datum into jsonb. + * + * tcategory and outfuncoid are from a previous call to json_categorize_type. + */ +Datum +datum_to_jsonb(Datum val, JsonTypeCategory tcategory, Oid outfuncoid) +{ + JsonbInState result; + memset(&result, 0, sizeof(JsonbInState)); - datum_to_jsonb(val, false, &result, tcategory, outfuncoid, false); + datum_to_jsonb_internal(val, false, &result, tcategory, outfuncoid, + false); - PG_RETURN_POINTER(JsonbValueToJsonb(result.res)); + return JsonbPGetDatum(JsonbValueToJsonb(result.res)); } Datum @@ -1525,8 +1554,8 @@ jsonb_agg_transfn_worker(FunctionCallInfo fcinfo, bool absent_on_null) memset(&elem, 0, sizeof(JsonbInState)); - datum_to_jsonb(val, PG_ARGISNULL(1), &elem, state->val_category, - state->val_output_func, false); + datum_to_jsonb_internal(val, PG_ARGISNULL(1), &elem, state->val_category, + state->val_output_func, false); jbelem = JsonbValueToJsonb(elem.res); @@ -1726,8 +1755,8 @@ jsonb_object_agg_transfn_worker(FunctionCallInfo fcinfo, memset(&elem, 0, sizeof(JsonbInState)); - datum_to_jsonb(val, false, &elem, state->key_category, - state->key_output_func, true); + datum_to_jsonb_internal(val, false, &elem, state->key_category, + state->key_output_func, true); jbkey = JsonbValueToJsonb(elem.res); @@ -1735,8 +1764,8 @@ jsonb_object_agg_transfn_worker(FunctionCallInfo fcinfo, memset(&elem, 0, sizeof(JsonbInState)); - datum_to_jsonb(val, PG_ARGISNULL(2), &elem, state->val_category, - state->val_output_func, false); + datum_to_jsonb_internal(val, PG_ARGISNULL(2), &elem, state->val_category, + state->val_output_func, false); jbval = JsonbValueToJsonb(elem.res); -- cgit v1.2.3