Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
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 <alvherre@alvh.no-ip.org> Reviewed-by: Álvaro Herrera <alvherre@alvh.no-ip.org> 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

+10-127
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)