aboutsummaryrefslogtreecommitdiff
path: root/src/backend/utils/adt/jsonb.c
diff options
context:
space:
mode:
authorAmit Langote <amitlan@postgresql.org>2023-07-21 11:46:56 +0900
committerAmit Langote <amitlan@postgresql.org>2023-07-26 17:06:03 +0900
commitb22391a2ff7bdfeff4438f7a9ab26de3e33fdeff (patch)
treed19d03ff3d672900360a84cae910419d1d4eeb30 /src/backend/utils/adt/jsonb.c
parentbd88404d3cda53810e0b0144713c4b1a1dd965a8 (diff)
downloadpostgresql-b22391a2ff7bdfeff4438f7a9ab26de3e33fdeff.tar.gz
postgresql-b22391a2ff7bdfeff4438f7a9ab26de3e33fdeff.zip
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
Diffstat (limited to 'src/backend/utils/adt/jsonb.c')
-rw-r--r--src/backend/utils/adt/jsonb.c67
1 files changed, 48 insertions, 19 deletions
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);
@@ -142,6 +142,19 @@ jsonb_send(PG_FUNCTION_ARGS)
}
/*
+ * 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.
*/
static const char *
@@ -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);