Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 3c152a2

Browse files
amitlanalvherre
andcommitted
Unify JSON categorize type API and export for external use
This essentially removes the JsonbTypeCategory enum and jsonb_categorize_type() and integrates any jsonb-specific logic that was in jsonb_categorize_type() into json_categorize_type(), now moved to jsonfuncs.c. The remaining JsonTypeCategory enum and json_categorize_type() cover the needs of the callers in both json.c and jsonb.c. json_categorize_type() has grown a new parameter named is_jsonb for callers to engage the jsonb-specific behavior of json_categorize_type(). One notable change in the now exported API of json_categorize_type() is that it now always returns *outfuncoid even though a caller may have no need currently to see one. This is in preparation of later commits to implement additional SQL/JSON functions. Co-authored-by: Álvaro Herrera <[email protected]> Reviewed-by: Álvaro Herrera <[email protected]> Discussion: https://postgr.es/m/CA+HiwqE4XTdfb1nW=Ojoy_tQSRhYt-q_kb6i5d4xcKyrLC1Nbg@mail.gmail.com
1 parent 2a990ab commit 3c152a2

File tree

5 files changed

+199
-315
lines changed

5 files changed

+199
-315
lines changed

src/backend/utils/adt/json.c

Lines changed: 10 additions & 127 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,6 @@
1919
#include "funcapi.h"
2020
#include "libpq/pqformat.h"
2121
#include "miscadmin.h"
22-
#include "parser/parse_coerce.h"
2322
#include "utils/array.h"
2423
#include "utils/builtins.h"
2524
#include "utils/date.h"
@@ -29,21 +28,6 @@
2928
#include "utils/lsyscache.h"
3029
#include "utils/typcache.h"
3130

32-
typedef enum /* type categories for datum_to_json */
33-
{
34-
JSONTYPE_NULL, /* null, so we didn't bother to identify */
35-
JSONTYPE_BOOL, /* boolean (built-in types only) */
36-
JSONTYPE_NUMERIC, /* numeric (ditto) */
37-
JSONTYPE_DATE, /* we use special formatting for datetimes */
38-
JSONTYPE_TIMESTAMP,
39-
JSONTYPE_TIMESTAMPTZ,
40-
JSONTYPE_JSON, /* JSON itself (and JSONB) */
41-
JSONTYPE_ARRAY, /* array */
42-
JSONTYPE_COMPOSITE, /* composite */
43-
JSONTYPE_CAST, /* something with an explicit cast to JSON */
44-
JSONTYPE_OTHER /* all else */
45-
} JsonTypeCategory;
46-
4731

4832
/*
4933
* Support for fast key uniqueness checking.
@@ -107,9 +91,6 @@ static void array_dim_to_json(StringInfo result, int dim, int ndims, int *dims,
10791
bool use_line_feeds);
10892
static void array_to_json_internal(Datum array, StringInfo result,
10993
bool use_line_feeds);
110-
static void json_categorize_type(Oid typoid,
111-
JsonTypeCategory *tcategory,
112-
Oid *outfuncoid);
11394
static void datum_to_json(Datum val, bool is_null, StringInfo result,
11495
JsonTypeCategory tcategory, Oid outfuncoid,
11596
bool key_scalar);
@@ -182,106 +163,6 @@ json_recv(PG_FUNCTION_ARGS)
182163
PG_RETURN_TEXT_P(cstring_to_text_with_len(str, nbytes));
183164
}
184165

185-
/*
186-
* Determine how we want to print values of a given type in datum_to_json.
187-
*
188-
* Given the datatype OID, return its JsonTypeCategory, as well as the type's
189-
* output function OID. If the returned category is JSONTYPE_CAST, we
190-
* return the OID of the type->JSON cast function instead.
191-
*/
192-
static void
193-
json_categorize_type(Oid typoid,
194-
JsonTypeCategory *tcategory,
195-
Oid *outfuncoid)
196-
{
197-
bool typisvarlena;
198-
199-
/* Look through any domain */
200-
typoid = getBaseType(typoid);
201-
202-
*outfuncoid = InvalidOid;
203-
204-
/*
205-
* We need to get the output function for everything except date and
206-
* timestamp types, array and composite types, booleans, and non-builtin
207-
* types where there's a cast to json.
208-
*/
209-
210-
switch (typoid)
211-
{
212-
case BOOLOID:
213-
*tcategory = JSONTYPE_BOOL;
214-
break;
215-
216-
case INT2OID:
217-
case INT4OID:
218-
case INT8OID:
219-
case FLOAT4OID:
220-
case FLOAT8OID:
221-
case NUMERICOID:
222-
getTypeOutputInfo(typoid, outfuncoid, &typisvarlena);
223-
*tcategory = JSONTYPE_NUMERIC;
224-
break;
225-
226-
case DATEOID:
227-
*tcategory = JSONTYPE_DATE;
228-
break;
229-
230-
case TIMESTAMPOID:
231-
*tcategory = JSONTYPE_TIMESTAMP;
232-
break;
233-
234-
case TIMESTAMPTZOID:
235-
*tcategory = JSONTYPE_TIMESTAMPTZ;
236-
break;
237-
238-
case JSONOID:
239-
case JSONBOID:
240-
getTypeOutputInfo(typoid, outfuncoid, &typisvarlena);
241-
*tcategory = JSONTYPE_JSON;
242-
break;
243-
244-
default:
245-
/* Check for arrays and composites */
246-
if (OidIsValid(get_element_type(typoid)) || typoid == ANYARRAYOID
247-
|| typoid == ANYCOMPATIBLEARRAYOID || typoid == RECORDARRAYOID)
248-
*tcategory = JSONTYPE_ARRAY;
249-
else if (type_is_rowtype(typoid)) /* includes RECORDOID */
250-
*tcategory = JSONTYPE_COMPOSITE;
251-
else
252-
{
253-
/* It's probably the general case ... */
254-
*tcategory = JSONTYPE_OTHER;
255-
/* but let's look for a cast to json, if it's not built-in */
256-
if (typoid >= FirstNormalObjectId)
257-
{
258-
Oid castfunc;
259-
CoercionPathType ctype;
260-
261-
ctype = find_coercion_pathway(JSONOID, typoid,
262-
COERCION_EXPLICIT,
263-
&castfunc);
264-
if (ctype == COERCION_PATH_FUNC && OidIsValid(castfunc))
265-
{
266-
*tcategory = JSONTYPE_CAST;
267-
*outfuncoid = castfunc;
268-
}
269-
else
270-
{
271-
/* non builtin type with no cast */
272-
getTypeOutputInfo(typoid, outfuncoid, &typisvarlena);
273-
}
274-
}
275-
else
276-
{
277-
/* any other builtin type */
278-
getTypeOutputInfo(typoid, outfuncoid, &typisvarlena);
279-
}
280-
}
281-
break;
282-
}
283-
}
284-
285166
/*
286167
* Turn a Datum into JSON text, appending the string to "result".
287168
*
@@ -591,7 +472,7 @@ array_to_json_internal(Datum array, StringInfo result, bool use_line_feeds)
591472
get_typlenbyvalalign(element_type,
592473
&typlen, &typbyval, &typalign);
593474

594-
json_categorize_type(element_type,
475+
json_categorize_type(element_type, false,
595476
&tcategory, &outfuncoid);
596477

597478
deconstruct_array(v, element_type, typlen, typbyval,
@@ -665,7 +546,8 @@ composite_to_json(Datum composite, StringInfo result, bool use_line_feeds)
665546
outfuncoid = InvalidOid;
666547
}
667548
else
668-
json_categorize_type(att->atttypid, &tcategory, &outfuncoid);
549+
json_categorize_type(att->atttypid, false, &tcategory,
550+
&outfuncoid);
669551

670552
datum_to_json(val, isnull, result, tcategory, outfuncoid, false);
671553
}
@@ -699,7 +581,7 @@ add_json(Datum val, bool is_null, StringInfo result,
699581
outfuncoid = InvalidOid;
700582
}
701583
else
702-
json_categorize_type(val_type,
584+
json_categorize_type(val_type, false,
703585
&tcategory, &outfuncoid);
704586

705587
datum_to_json(val, is_null, result, tcategory, outfuncoid, key_scalar);
@@ -784,12 +666,13 @@ to_json_is_immutable(Oid typoid)
784666
JsonTypeCategory tcategory;
785667
Oid outfuncoid;
786668

787-
json_categorize_type(typoid, &tcategory, &outfuncoid);
669+
json_categorize_type(typoid, false, &tcategory, &outfuncoid);
788670

789671
switch (tcategory)
790672
{
791673
case JSONTYPE_BOOL:
792674
case JSONTYPE_JSON:
675+
case JSONTYPE_JSONB:
793676
case JSONTYPE_NULL:
794677
return true;
795678

@@ -830,7 +713,7 @@ to_json(PG_FUNCTION_ARGS)
830713
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
831714
errmsg("could not determine input data type")));
832715

833-
json_categorize_type(val_type,
716+
json_categorize_type(val_type, false,
834717
&tcategory, &outfuncoid);
835718

836719
result = makeStringInfo();
@@ -880,7 +763,7 @@ json_agg_transfn_worker(FunctionCallInfo fcinfo, bool absent_on_null)
880763
MemoryContextSwitchTo(oldcontext);
881764

882765
appendStringInfoChar(state->str, '[');
883-
json_categorize_type(arg_type, &state->val_category,
766+
json_categorize_type(arg_type, false, &state->val_category,
884767
&state->val_output_func);
885768
}
886769
else
@@ -1112,7 +995,7 @@ json_object_agg_transfn_worker(FunctionCallInfo fcinfo,
1112995
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
1113996
errmsg("could not determine data type for argument %d", 1)));
1114997

1115-
json_categorize_type(arg_type, &state->key_category,
998+
json_categorize_type(arg_type, false, &state->key_category,
1116999
&state->key_output_func);
11171000

11181001
arg_type = get_fn_expr_argtype(fcinfo->flinfo, 2);
@@ -1122,7 +1005,7 @@ json_object_agg_transfn_worker(FunctionCallInfo fcinfo,
11221005
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
11231006
errmsg("could not determine data type for argument %d", 2)));
11241007

1125-
json_categorize_type(arg_type, &state->val_category,
1008+
json_categorize_type(arg_type, false, &state->val_category,
11261009
&state->val_output_func);
11271010

11281011
appendStringInfoString(state->str, "{ ");

0 commit comments

Comments
 (0)