19
19
#include "funcapi.h"
20
20
#include "libpq/pqformat.h"
21
21
#include "miscadmin.h"
22
- #include "parser/parse_coerce.h"
23
22
#include "utils/array.h"
24
23
#include "utils/builtins.h"
25
24
#include "utils/date.h"
29
28
#include "utils/lsyscache.h"
30
29
#include "utils/typcache.h"
31
30
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
-
47
31
48
32
/*
49
33
* Support for fast key uniqueness checking.
@@ -107,9 +91,6 @@ static void array_dim_to_json(StringInfo result, int dim, int ndims, int *dims,
107
91
bool use_line_feeds );
108
92
static void array_to_json_internal (Datum array , StringInfo result ,
109
93
bool use_line_feeds );
110
- static void json_categorize_type (Oid typoid ,
111
- JsonTypeCategory * tcategory ,
112
- Oid * outfuncoid );
113
94
static void datum_to_json (Datum val , bool is_null , StringInfo result ,
114
95
JsonTypeCategory tcategory , Oid outfuncoid ,
115
96
bool key_scalar );
@@ -182,106 +163,6 @@ json_recv(PG_FUNCTION_ARGS)
182
163
PG_RETURN_TEXT_P (cstring_to_text_with_len (str , nbytes ));
183
164
}
184
165
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
-
285
166
/*
286
167
* Turn a Datum into JSON text, appending the string to "result".
287
168
*
@@ -591,7 +472,7 @@ array_to_json_internal(Datum array, StringInfo result, bool use_line_feeds)
591
472
get_typlenbyvalalign (element_type ,
592
473
& typlen , & typbyval , & typalign );
593
474
594
- json_categorize_type (element_type ,
475
+ json_categorize_type (element_type , false,
595
476
& tcategory , & outfuncoid );
596
477
597
478
deconstruct_array (v , element_type , typlen , typbyval ,
@@ -665,7 +546,8 @@ composite_to_json(Datum composite, StringInfo result, bool use_line_feeds)
665
546
outfuncoid = InvalidOid ;
666
547
}
667
548
else
668
- json_categorize_type (att -> atttypid , & tcategory , & outfuncoid );
549
+ json_categorize_type (att -> atttypid , false, & tcategory ,
550
+ & outfuncoid );
669
551
670
552
datum_to_json (val , isnull , result , tcategory , outfuncoid , false);
671
553
}
@@ -699,7 +581,7 @@ add_json(Datum val, bool is_null, StringInfo result,
699
581
outfuncoid = InvalidOid ;
700
582
}
701
583
else
702
- json_categorize_type (val_type ,
584
+ json_categorize_type (val_type , false,
703
585
& tcategory , & outfuncoid );
704
586
705
587
datum_to_json (val , is_null , result , tcategory , outfuncoid , key_scalar );
@@ -784,12 +666,13 @@ to_json_is_immutable(Oid typoid)
784
666
JsonTypeCategory tcategory ;
785
667
Oid outfuncoid ;
786
668
787
- json_categorize_type (typoid , & tcategory , & outfuncoid );
669
+ json_categorize_type (typoid , false, & tcategory , & outfuncoid );
788
670
789
671
switch (tcategory )
790
672
{
791
673
case JSONTYPE_BOOL :
792
674
case JSONTYPE_JSON :
675
+ case JSONTYPE_JSONB :
793
676
case JSONTYPE_NULL :
794
677
return true;
795
678
@@ -830,7 +713,7 @@ to_json(PG_FUNCTION_ARGS)
830
713
(errcode (ERRCODE_INVALID_PARAMETER_VALUE ),
831
714
errmsg ("could not determine input data type" )));
832
715
833
- json_categorize_type (val_type ,
716
+ json_categorize_type (val_type , false,
834
717
& tcategory , & outfuncoid );
835
718
836
719
result = makeStringInfo ();
@@ -880,7 +763,7 @@ json_agg_transfn_worker(FunctionCallInfo fcinfo, bool absent_on_null)
880
763
MemoryContextSwitchTo (oldcontext );
881
764
882
765
appendStringInfoChar (state -> str , '[' );
883
- json_categorize_type (arg_type , & state -> val_category ,
766
+ json_categorize_type (arg_type , false, & state -> val_category ,
884
767
& state -> val_output_func );
885
768
}
886
769
else
@@ -1112,7 +995,7 @@ json_object_agg_transfn_worker(FunctionCallInfo fcinfo,
1112
995
(errcode (ERRCODE_INVALID_PARAMETER_VALUE ),
1113
996
errmsg ("could not determine data type for argument %d" , 1 )));
1114
997
1115
- json_categorize_type (arg_type , & state -> key_category ,
998
+ json_categorize_type (arg_type , false, & state -> key_category ,
1116
999
& state -> key_output_func );
1117
1000
1118
1001
arg_type = get_fn_expr_argtype (fcinfo -> flinfo , 2 );
@@ -1122,7 +1005,7 @@ json_object_agg_transfn_worker(FunctionCallInfo fcinfo,
1122
1005
(errcode (ERRCODE_INVALID_PARAMETER_VALUE ),
1123
1006
errmsg ("could not determine data type for argument %d" , 2 )));
1124
1007
1125
- json_categorize_type (arg_type , & state -> val_category ,
1008
+ json_categorize_type (arg_type , false, & state -> val_category ,
1126
1009
& state -> val_output_func );
1127
1010
1128
1011
appendStringInfoString (state -> str , "{ " );
0 commit comments