Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Skip to content

Commit b22391a

Browse files
committed
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
1 parent bd88404 commit b22391a

File tree

3 files changed

+90
-41
lines changed

3 files changed

+90
-41
lines changed

src/backend/utils/adt/json.c

+37-22
Original file line numberDiff line numberDiff line change
@@ -91,9 +91,9 @@ static void array_dim_to_json(StringInfo result, int dim, int ndims, int *dims,
9191
bool use_line_feeds);
9292
static void array_to_json_internal(Datum array, StringInfo result,
9393
bool use_line_feeds);
94-
static void datum_to_json(Datum val, bool is_null, StringInfo result,
95-
JsonTypeCategory tcategory, Oid outfuncoid,
96-
bool key_scalar);
94+
static void datum_to_json_internal(Datum val, bool is_null, StringInfo result,
95+
JsonTypeCategory tcategory, Oid outfuncoid,
96+
bool key_scalar);
9797
static void add_json(Datum val, bool is_null, StringInfo result,
9898
Oid val_type, bool key_scalar);
9999
static text *catenate_stringinfo_string(StringInfo buffer, const char *addon);
@@ -173,9 +173,9 @@ json_recv(PG_FUNCTION_ARGS)
173173
* it's of an acceptable type, and force it to be quoted.
174174
*/
175175
static void
176-
datum_to_json(Datum val, bool is_null, StringInfo result,
177-
JsonTypeCategory tcategory, Oid outfuncoid,
178-
bool key_scalar)
176+
datum_to_json_internal(Datum val, bool is_null, StringInfo result,
177+
JsonTypeCategory tcategory, Oid outfuncoid,
178+
bool key_scalar)
179179
{
180180
char *outputstr;
181181
text *jsontext;
@@ -421,8 +421,9 @@ array_dim_to_json(StringInfo result, int dim, int ndims, int *dims, Datum *vals,
421421

422422
if (dim + 1 == ndims)
423423
{
424-
datum_to_json(vals[*valcount], nulls[*valcount], result, tcategory,
425-
outfuncoid, false);
424+
datum_to_json_internal(vals[*valcount], nulls[*valcount],
425+
result, tcategory,
426+
outfuncoid, false);
426427
(*valcount)++;
427428
}
428429
else
@@ -549,7 +550,8 @@ composite_to_json(Datum composite, StringInfo result, bool use_line_feeds)
549550
json_categorize_type(att->atttypid, false, &tcategory,
550551
&outfuncoid);
551552

552-
datum_to_json(val, isnull, result, tcategory, outfuncoid, false);
553+
datum_to_json_internal(val, isnull, result, tcategory, outfuncoid,
554+
false);
553555
}
554556

555557
appendStringInfoChar(result, '}');
@@ -584,7 +586,8 @@ add_json(Datum val, bool is_null, StringInfo result,
584586
json_categorize_type(val_type, false,
585587
&tcategory, &outfuncoid);
586588

587-
datum_to_json(val, is_null, result, tcategory, outfuncoid, key_scalar);
589+
datum_to_json_internal(val, is_null, result, tcategory, outfuncoid,
590+
key_scalar);
588591
}
589592

590593
/*
@@ -704,7 +707,6 @@ to_json(PG_FUNCTION_ARGS)
704707
{
705708
Datum val = PG_GETARG_DATUM(0);
706709
Oid val_type = get_fn_expr_argtype(fcinfo->flinfo, 0);
707-
StringInfo result;
708710
JsonTypeCategory tcategory;
709711
Oid outfuncoid;
710712

@@ -716,11 +718,23 @@ to_json(PG_FUNCTION_ARGS)
716718
json_categorize_type(val_type, false,
717719
&tcategory, &outfuncoid);
718720

719-
result = makeStringInfo();
721+
PG_RETURN_DATUM(datum_to_json(val, tcategory, outfuncoid));
722+
}
720723

721-
datum_to_json(val, false, result, tcategory, outfuncoid, false);
724+
/*
725+
* Turn a Datum into JSON text.
726+
*
727+
* tcategory and outfuncoid are from a previous call to json_categorize_type.
728+
*/
729+
Datum
730+
datum_to_json(Datum val, JsonTypeCategory tcategory, Oid outfuncoid)
731+
{
732+
StringInfo result = makeStringInfo();
722733

723-
PG_RETURN_TEXT_P(cstring_to_text_with_len(result->data, result->len));
734+
datum_to_json_internal(val, false, result, tcategory, outfuncoid,
735+
false);
736+
737+
return PointerGetDatum(cstring_to_text_with_len(result->data, result->len));
724738
}
725739

726740
/*
@@ -780,8 +794,8 @@ json_agg_transfn_worker(FunctionCallInfo fcinfo, bool absent_on_null)
780794
/* fast path for NULLs */
781795
if (PG_ARGISNULL(1))
782796
{
783-
datum_to_json((Datum) 0, true, state->str, JSONTYPE_NULL,
784-
InvalidOid, false);
797+
datum_to_json_internal((Datum) 0, true, state->str, JSONTYPE_NULL,
798+
InvalidOid, false);
785799
PG_RETURN_POINTER(state);
786800
}
787801

@@ -795,8 +809,8 @@ json_agg_transfn_worker(FunctionCallInfo fcinfo, bool absent_on_null)
795809
appendStringInfoString(state->str, "\n ");
796810
}
797811

798-
datum_to_json(val, false, state->str, state->val_category,
799-
state->val_output_func, false);
812+
datum_to_json_internal(val, false, state->str, state->val_category,
813+
state->val_output_func, false);
800814

801815
/*
802816
* The transition type for json_agg() is declared to be "internal", which
@@ -1059,8 +1073,8 @@ json_object_agg_transfn_worker(FunctionCallInfo fcinfo,
10591073

10601074
key_offset = out->len;
10611075

1062-
datum_to_json(arg, false, out, state->key_category,
1063-
state->key_output_func, true);
1076+
datum_to_json_internal(arg, false, out, state->key_category,
1077+
state->key_output_func, true);
10641078

10651079
if (unique_keys)
10661080
{
@@ -1082,8 +1096,9 @@ json_object_agg_transfn_worker(FunctionCallInfo fcinfo,
10821096
else
10831097
arg = PG_GETARG_DATUM(2);
10841098

1085-
datum_to_json(arg, PG_ARGISNULL(2), state->str, state->val_category,
1086-
state->val_output_func, false);
1099+
datum_to_json_internal(arg, PG_ARGISNULL(2), state->str,
1100+
state->val_category,
1101+
state->val_output_func, false);
10871102

10881103
PG_RETURN_POINTER(state);
10891104
}

src/backend/utils/adt/jsonb.c

+48-19
Original file line numberDiff line numberDiff line change
@@ -59,9 +59,9 @@ static void array_dim_to_jsonb(JsonbInState *result, int dim, int ndims, int *di
5959
Datum *vals, bool *nulls, int *valcount,
6060
JsonTypeCategory tcategory, Oid outfuncoid);
6161
static void array_to_jsonb_internal(Datum array, JsonbInState *result);
62-
static void datum_to_jsonb(Datum val, bool is_null, JsonbInState *result,
63-
JsonTypeCategory tcategory, Oid outfuncoid,
64-
bool key_scalar);
62+
static void datum_to_jsonb_internal(Datum val, bool is_null, JsonbInState *result,
63+
JsonTypeCategory tcategory, Oid outfuncoid,
64+
bool key_scalar);
6565
static void add_jsonb(Datum val, bool is_null, JsonbInState *result,
6666
Oid val_type, bool key_scalar);
6767
static JsonbParseState *clone_parse_state(JsonbParseState *state);
@@ -141,6 +141,19 @@ jsonb_send(PG_FUNCTION_ARGS)
141141
PG_RETURN_BYTEA_P(pq_endtypsend(&buf));
142142
}
143143

144+
/*
145+
* jsonb_from_text
146+
*
147+
* Turns json text string into a jsonb Datum.
148+
*/
149+
Datum
150+
jsonb_from_text(text *js)
151+
{
152+
return jsonb_from_cstring(VARDATA_ANY(js),
153+
VARSIZE_ANY_EXHDR(js),
154+
NULL);
155+
}
156+
144157
/*
145158
* Get the type name of a jsonb container.
146159
*/
@@ -622,9 +635,9 @@ add_indent(StringInfo out, bool indent, int level)
622635
* will be thrown.
623636
*/
624637
static void
625-
datum_to_jsonb(Datum val, bool is_null, JsonbInState *result,
626-
JsonTypeCategory tcategory, Oid outfuncoid,
627-
bool key_scalar)
638+
datum_to_jsonb_internal(Datum val, bool is_null, JsonbInState *result,
639+
JsonTypeCategory tcategory, Oid outfuncoid,
640+
bool key_scalar)
628641
{
629642
char *outputstr;
630643
bool numeric_error;
@@ -859,8 +872,8 @@ array_dim_to_jsonb(JsonbInState *result, int dim, int ndims, int *dims, Datum *v
859872
{
860873
if (dim + 1 == ndims)
861874
{
862-
datum_to_jsonb(vals[*valcount], nulls[*valcount], result, tcategory,
863-
outfuncoid, false);
875+
datum_to_jsonb_internal(vals[*valcount], nulls[*valcount], result, tcategory,
876+
outfuncoid, false);
864877
(*valcount)++;
865878
}
866879
else
@@ -982,7 +995,8 @@ composite_to_jsonb(Datum composite, JsonbInState *result)
982995
json_categorize_type(att->atttypid, true, &tcategory,
983996
&outfuncoid);
984997

985-
datum_to_jsonb(val, isnull, result, tcategory, outfuncoid, false);
998+
datum_to_jsonb_internal(val, isnull, result, tcategory, outfuncoid,
999+
false);
9861000
}
9871001

9881002
result->res = pushJsonbValue(&result->parseState, WJB_END_OBJECT, NULL);
@@ -1018,9 +1032,11 @@ add_jsonb(Datum val, bool is_null, JsonbInState *result,
10181032
json_categorize_type(val_type, true,
10191033
&tcategory, &outfuncoid);
10201034

1021-
datum_to_jsonb(val, is_null, result, tcategory, outfuncoid, key_scalar);
1035+
datum_to_jsonb_internal(val, is_null, result, tcategory, outfuncoid,
1036+
key_scalar);
10221037
}
10231038

1039+
10241040
/*
10251041
* Is the given type immutable when coming out of a JSONB context?
10261042
*
@@ -1072,7 +1088,6 @@ to_jsonb(PG_FUNCTION_ARGS)
10721088
{
10731089
Datum val = PG_GETARG_DATUM(0);
10741090
Oid val_type = get_fn_expr_argtype(fcinfo->flinfo, 0);
1075-
JsonbInState result;
10761091
JsonTypeCategory tcategory;
10771092
Oid outfuncoid;
10781093

@@ -1084,11 +1099,25 @@ to_jsonb(PG_FUNCTION_ARGS)
10841099
json_categorize_type(val_type, true,
10851100
&tcategory, &outfuncoid);
10861101

1102+
PG_RETURN_DATUM(datum_to_jsonb(val, tcategory, outfuncoid));
1103+
}
1104+
1105+
/*
1106+
* Turn a Datum into jsonb.
1107+
*
1108+
* tcategory and outfuncoid are from a previous call to json_categorize_type.
1109+
*/
1110+
Datum
1111+
datum_to_jsonb(Datum val, JsonTypeCategory tcategory, Oid outfuncoid)
1112+
{
1113+
JsonbInState result;
1114+
10871115
memset(&result, 0, sizeof(JsonbInState));
10881116

1089-
datum_to_jsonb(val, false, &result, tcategory, outfuncoid, false);
1117+
datum_to_jsonb_internal(val, false, &result, tcategory, outfuncoid,
1118+
false);
10901119

1091-
PG_RETURN_POINTER(JsonbValueToJsonb(result.res));
1120+
return JsonbPGetDatum(JsonbValueToJsonb(result.res));
10921121
}
10931122

10941123
Datum
@@ -1525,8 +1554,8 @@ jsonb_agg_transfn_worker(FunctionCallInfo fcinfo, bool absent_on_null)
15251554

15261555
memset(&elem, 0, sizeof(JsonbInState));
15271556

1528-
datum_to_jsonb(val, PG_ARGISNULL(1), &elem, state->val_category,
1529-
state->val_output_func, false);
1557+
datum_to_jsonb_internal(val, PG_ARGISNULL(1), &elem, state->val_category,
1558+
state->val_output_func, false);
15301559

15311560
jbelem = JsonbValueToJsonb(elem.res);
15321561

@@ -1726,17 +1755,17 @@ jsonb_object_agg_transfn_worker(FunctionCallInfo fcinfo,
17261755

17271756
memset(&elem, 0, sizeof(JsonbInState));
17281757

1729-
datum_to_jsonb(val, false, &elem, state->key_category,
1730-
state->key_output_func, true);
1758+
datum_to_jsonb_internal(val, false, &elem, state->key_category,
1759+
state->key_output_func, true);
17311760

17321761
jbkey = JsonbValueToJsonb(elem.res);
17331762

17341763
val = PG_ARGISNULL(2) ? (Datum) 0 : PG_GETARG_DATUM(2);
17351764

17361765
memset(&elem, 0, sizeof(JsonbInState));
17371766

1738-
datum_to_jsonb(val, PG_ARGISNULL(2), &elem, state->val_category,
1739-
state->val_output_func, false);
1767+
datum_to_jsonb_internal(val, PG_ARGISNULL(2), &elem, state->val_category,
1768+
state->val_output_func, false);
17401769

17411770
jbval = JsonbValueToJsonb(elem.res);
17421771

src/include/utils/jsonfuncs.h

+5
Original file line numberDiff line numberDiff line change
@@ -82,5 +82,10 @@ typedef enum
8282

8383
extern void json_categorize_type(Oid typoid, bool is_jsonb,
8484
JsonTypeCategory *tcategory, Oid *outfuncoid);
85+
extern Datum datum_to_json(Datum val, JsonTypeCategory tcategory,
86+
Oid outfuncoid);
87+
extern Datum datum_to_jsonb(Datum val, JsonTypeCategory tcategory,
88+
Oid outfuncoid);
89+
extern Datum jsonb_from_text(text *js);
8590

8691
#endif

0 commit comments

Comments
 (0)