diff options
Diffstat (limited to 'src/backend/utils/adt/json.c')
-rw-r--r-- | src/backend/utils/adt/json.c | 137 |
1 files changed, 10 insertions, 127 deletions
diff --git a/src/backend/utils/adt/json.c b/src/backend/utils/adt/json.c index 49080e5fbff..f6bef9c1484 100644 --- a/src/backend/utils/adt/json.c +++ b/src/backend/utils/adt/json.c @@ -19,7 +19,6 @@ #include "funcapi.h" #include "libpq/pqformat.h" #include "miscadmin.h" -#include "parser/parse_coerce.h" #include "utils/array.h" #include "utils/builtins.h" #include "utils/date.h" @@ -29,21 +28,6 @@ #include "utils/lsyscache.h" #include "utils/typcache.h" -typedef enum /* type categories for datum_to_json */ -{ - JSONTYPE_NULL, /* null, so we didn't bother to identify */ - JSONTYPE_BOOL, /* boolean (built-in types only) */ - JSONTYPE_NUMERIC, /* numeric (ditto) */ - JSONTYPE_DATE, /* we use special formatting for datetimes */ - JSONTYPE_TIMESTAMP, - JSONTYPE_TIMESTAMPTZ, - JSONTYPE_JSON, /* JSON itself (and JSONB) */ - JSONTYPE_ARRAY, /* array */ - JSONTYPE_COMPOSITE, /* composite */ - JSONTYPE_CAST, /* something with an explicit cast to JSON */ - JSONTYPE_OTHER /* all else */ -} JsonTypeCategory; - /* * Support for fast key uniqueness checking. @@ -107,9 +91,6 @@ static void array_dim_to_json(StringInfo result, int dim, int ndims, int *dims, bool use_line_feeds); static void array_to_json_internal(Datum array, StringInfo result, bool use_line_feeds); -static void json_categorize_type(Oid typoid, - JsonTypeCategory *tcategory, - Oid *outfuncoid); static void datum_to_json(Datum val, bool is_null, StringInfo result, JsonTypeCategory tcategory, Oid outfuncoid, bool key_scalar); @@ -183,106 +164,6 @@ json_recv(PG_FUNCTION_ARGS) } /* - * Determine how we want to print values of a given type in datum_to_json. - * - * Given the datatype OID, return its JsonTypeCategory, as well as the type's - * output function OID. If the returned category is JSONTYPE_CAST, we - * return the OID of the type->JSON cast function instead. - */ -static void -json_categorize_type(Oid typoid, - JsonTypeCategory *tcategory, - Oid *outfuncoid) -{ - bool typisvarlena; - - /* Look through any domain */ - typoid = getBaseType(typoid); - - *outfuncoid = InvalidOid; - - /* - * We need to get the output function for everything except date and - * timestamp types, array and composite types, booleans, and non-builtin - * types where there's a cast to json. - */ - - switch (typoid) - { - case BOOLOID: - *tcategory = JSONTYPE_BOOL; - break; - - case INT2OID: - case INT4OID: - case INT8OID: - case FLOAT4OID: - case FLOAT8OID: - case NUMERICOID: - getTypeOutputInfo(typoid, outfuncoid, &typisvarlena); - *tcategory = JSONTYPE_NUMERIC; - break; - - case DATEOID: - *tcategory = JSONTYPE_DATE; - break; - - case TIMESTAMPOID: - *tcategory = JSONTYPE_TIMESTAMP; - break; - - case TIMESTAMPTZOID: - *tcategory = JSONTYPE_TIMESTAMPTZ; - break; - - case JSONOID: - case JSONBOID: - getTypeOutputInfo(typoid, outfuncoid, &typisvarlena); - *tcategory = JSONTYPE_JSON; - break; - - default: - /* Check for arrays and composites */ - if (OidIsValid(get_element_type(typoid)) || typoid == ANYARRAYOID - || typoid == ANYCOMPATIBLEARRAYOID || typoid == RECORDARRAYOID) - *tcategory = JSONTYPE_ARRAY; - else if (type_is_rowtype(typoid)) /* includes RECORDOID */ - *tcategory = JSONTYPE_COMPOSITE; - else - { - /* It's probably the general case ... */ - *tcategory = JSONTYPE_OTHER; - /* but let's look for a cast to json, if it's not built-in */ - if (typoid >= FirstNormalObjectId) - { - Oid castfunc; - CoercionPathType ctype; - - ctype = find_coercion_pathway(JSONOID, typoid, - COERCION_EXPLICIT, - &castfunc); - if (ctype == COERCION_PATH_FUNC && OidIsValid(castfunc)) - { - *tcategory = JSONTYPE_CAST; - *outfuncoid = castfunc; - } - else - { - /* non builtin type with no cast */ - getTypeOutputInfo(typoid, outfuncoid, &typisvarlena); - } - } - else - { - /* any other builtin type */ - getTypeOutputInfo(typoid, outfuncoid, &typisvarlena); - } - } - break; - } -} - -/* * Turn a Datum into JSON text, appending the string to "result". * * tcategory and outfuncoid are from a previous call to json_categorize_type, @@ -591,7 +472,7 @@ array_to_json_internal(Datum array, StringInfo result, bool use_line_feeds) get_typlenbyvalalign(element_type, &typlen, &typbyval, &typalign); - json_categorize_type(element_type, + json_categorize_type(element_type, false, &tcategory, &outfuncoid); deconstruct_array(v, element_type, typlen, typbyval, @@ -665,7 +546,8 @@ composite_to_json(Datum composite, StringInfo result, bool use_line_feeds) outfuncoid = InvalidOid; } else - json_categorize_type(att->atttypid, &tcategory, &outfuncoid); + json_categorize_type(att->atttypid, false, &tcategory, + &outfuncoid); datum_to_json(val, isnull, result, tcategory, outfuncoid, false); } @@ -699,7 +581,7 @@ add_json(Datum val, bool is_null, StringInfo result, outfuncoid = InvalidOid; } else - json_categorize_type(val_type, + json_categorize_type(val_type, false, &tcategory, &outfuncoid); datum_to_json(val, is_null, result, tcategory, outfuncoid, key_scalar); @@ -784,12 +666,13 @@ to_json_is_immutable(Oid typoid) JsonTypeCategory tcategory; Oid outfuncoid; - json_categorize_type(typoid, &tcategory, &outfuncoid); + json_categorize_type(typoid, false, &tcategory, &outfuncoid); switch (tcategory) { case JSONTYPE_BOOL: case JSONTYPE_JSON: + case JSONTYPE_JSONB: case JSONTYPE_NULL: return true; @@ -830,7 +713,7 @@ to_json(PG_FUNCTION_ARGS) (errcode(ERRCODE_INVALID_PARAMETER_VALUE), errmsg("could not determine input data type"))); - json_categorize_type(val_type, + json_categorize_type(val_type, false, &tcategory, &outfuncoid); result = makeStringInfo(); @@ -880,7 +763,7 @@ json_agg_transfn_worker(FunctionCallInfo fcinfo, bool absent_on_null) MemoryContextSwitchTo(oldcontext); appendStringInfoChar(state->str, '['); - json_categorize_type(arg_type, &state->val_category, + json_categorize_type(arg_type, false, &state->val_category, &state->val_output_func); } else @@ -1112,7 +995,7 @@ json_object_agg_transfn_worker(FunctionCallInfo fcinfo, (errcode(ERRCODE_INVALID_PARAMETER_VALUE), errmsg("could not determine data type for argument %d", 1))); - json_categorize_type(arg_type, &state->key_category, + json_categorize_type(arg_type, false, &state->key_category, &state->key_output_func); arg_type = get_fn_expr_argtype(fcinfo->flinfo, 2); @@ -1122,7 +1005,7 @@ json_object_agg_transfn_worker(FunctionCallInfo fcinfo, (errcode(ERRCODE_INVALID_PARAMETER_VALUE), errmsg("could not determine data type for argument %d", 2))); - json_categorize_type(arg_type, &state->val_category, + json_categorize_type(arg_type, false, &state->val_category, &state->val_output_func); appendStringInfoString(state->str, "{ "); |