1
0
mirror of https://github.com/postgres/postgres.git synced 2025-11-21 00:42:43 +03:00

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
This commit is contained in:
Amit Langote
2023-07-21 11:46:56 +09:00
parent bd88404d3c
commit b22391a2ff
3 changed files with 90 additions and 41 deletions

View File

@@ -91,9 +91,9 @@ static void array_dim_to_json(StringInfo result, int dim, int ndims, int *dims,
bool use_line_feeds);
static void array_to_json_internal(Datum array, StringInfo result,
bool use_line_feeds);
static void datum_to_json(Datum val, bool is_null, StringInfo result,
JsonTypeCategory tcategory, Oid outfuncoid,
bool key_scalar);
static void datum_to_json_internal(Datum val, bool is_null, StringInfo result,
JsonTypeCategory tcategory, Oid outfuncoid,
bool key_scalar);
static void add_json(Datum val, bool is_null, StringInfo result,
Oid val_type, bool key_scalar);
static text *catenate_stringinfo_string(StringInfo buffer, const char *addon);
@@ -173,9 +173,9 @@ json_recv(PG_FUNCTION_ARGS)
* it's of an acceptable type, and force it to be quoted.
*/
static void
datum_to_json(Datum val, bool is_null, StringInfo result,
JsonTypeCategory tcategory, Oid outfuncoid,
bool key_scalar)
datum_to_json_internal(Datum val, bool is_null, StringInfo result,
JsonTypeCategory tcategory, Oid outfuncoid,
bool key_scalar)
{
char *outputstr;
text *jsontext;
@@ -421,8 +421,9 @@ array_dim_to_json(StringInfo result, int dim, int ndims, int *dims, Datum *vals,
if (dim + 1 == ndims)
{
datum_to_json(vals[*valcount], nulls[*valcount], result, tcategory,
outfuncoid, false);
datum_to_json_internal(vals[*valcount], nulls[*valcount],
result, tcategory,
outfuncoid, false);
(*valcount)++;
}
else
@@ -549,7 +550,8 @@ composite_to_json(Datum composite, StringInfo result, bool use_line_feeds)
json_categorize_type(att->atttypid, false, &tcategory,
&outfuncoid);
datum_to_json(val, isnull, result, tcategory, outfuncoid, false);
datum_to_json_internal(val, isnull, result, tcategory, outfuncoid,
false);
}
appendStringInfoChar(result, '}');
@@ -584,7 +586,8 @@ add_json(Datum val, bool is_null, StringInfo result,
json_categorize_type(val_type, false,
&tcategory, &outfuncoid);
datum_to_json(val, is_null, result, tcategory, outfuncoid, key_scalar);
datum_to_json_internal(val, is_null, result, tcategory, outfuncoid,
key_scalar);
}
/*
@@ -704,7 +707,6 @@ to_json(PG_FUNCTION_ARGS)
{
Datum val = PG_GETARG_DATUM(0);
Oid val_type = get_fn_expr_argtype(fcinfo->flinfo, 0);
StringInfo result;
JsonTypeCategory tcategory;
Oid outfuncoid;
@@ -716,11 +718,23 @@ to_json(PG_FUNCTION_ARGS)
json_categorize_type(val_type, false,
&tcategory, &outfuncoid);
result = makeStringInfo();
PG_RETURN_DATUM(datum_to_json(val, tcategory, outfuncoid));
}
datum_to_json(val, false, result, tcategory, outfuncoid, false);
/*
* Turn a Datum into JSON text.
*
* tcategory and outfuncoid are from a previous call to json_categorize_type.
*/
Datum
datum_to_json(Datum val, JsonTypeCategory tcategory, Oid outfuncoid)
{
StringInfo result = makeStringInfo();
PG_RETURN_TEXT_P(cstring_to_text_with_len(result->data, result->len));
datum_to_json_internal(val, false, result, tcategory, outfuncoid,
false);
return PointerGetDatum(cstring_to_text_with_len(result->data, result->len));
}
/*
@@ -780,8 +794,8 @@ json_agg_transfn_worker(FunctionCallInfo fcinfo, bool absent_on_null)
/* fast path for NULLs */
if (PG_ARGISNULL(1))
{
datum_to_json((Datum) 0, true, state->str, JSONTYPE_NULL,
InvalidOid, false);
datum_to_json_internal((Datum) 0, true, state->str, JSONTYPE_NULL,
InvalidOid, false);
PG_RETURN_POINTER(state);
}
@@ -795,8 +809,8 @@ json_agg_transfn_worker(FunctionCallInfo fcinfo, bool absent_on_null)
appendStringInfoString(state->str, "\n ");
}
datum_to_json(val, false, state->str, state->val_category,
state->val_output_func, false);
datum_to_json_internal(val, false, state->str, state->val_category,
state->val_output_func, false);
/*
* The transition type for json_agg() is declared to be "internal", which
@@ -1059,8 +1073,8 @@ json_object_agg_transfn_worker(FunctionCallInfo fcinfo,
key_offset = out->len;
datum_to_json(arg, false, out, state->key_category,
state->key_output_func, true);
datum_to_json_internal(arg, false, out, state->key_category,
state->key_output_func, true);
if (unique_keys)
{
@@ -1082,8 +1096,9 @@ json_object_agg_transfn_worker(FunctionCallInfo fcinfo,
else
arg = PG_GETARG_DATUM(2);
datum_to_json(arg, PG_ARGISNULL(2), state->str, state->val_category,
state->val_output_func, false);
datum_to_json_internal(arg, PG_ARGISNULL(2), state->str,
state->val_category,
state->val_output_func, false);
PG_RETURN_POINTER(state);
}