diff --git a/src/backend/utils/adt/jsonfuncs.c b/src/backend/utils/adt/jsonfuncs.c index 89dc96a77f9..386a70d6d82 100644 --- a/src/backend/utils/adt/jsonfuncs.c +++ b/src/backend/utils/adt/jsonfuncs.c @@ -507,6 +507,8 @@ static JsonParseErrorType transform_string_values_array_element_start(void *stat static JsonParseErrorType transform_string_values_scalar(void *state, char *token, JsonTokenType tokentype); static Oid get_json_cast_for_type(Oid typoid); +static void json_check_mutability_internal(Oid typoid, bool use_casts, + bool *has_mutable); /* * pg_parse_json_or_errsave @@ -6079,6 +6081,17 @@ json_categorize_type(Oid typoid, bool is_jsonb, */ void json_check_mutability(Oid typoid, bool *has_mutable) +{ + json_check_mutability_internal(typoid, true, has_mutable); +} + +/* + * use_casts is false below a range or multirange: those are printed by + * range_out/multirange_out, which call the subtype's output function and + * never a cast to json. + */ +static void +json_check_mutability_internal(Oid typoid, bool use_casts, bool *has_mutable) { char att_typtype = get_typtype(typoid); @@ -6092,7 +6105,8 @@ json_check_mutability(Oid typoid, bool *has_mutable) if (att_typtype == TYPTYPE_DOMAIN) { - json_check_mutability(getBaseType(typoid), has_mutable); + json_check_mutability_internal(getBaseType(typoid), use_casts, + has_mutable); return; } else if (att_typtype == TYPTYPE_COMPOSITE) @@ -6108,7 +6122,7 @@ json_check_mutability(Oid typoid, bool *has_mutable) att_typtype == TYPTYPE_MULTIRANGE) { /* a cast to json, if any, is used instead of the output function */ - Oid castfunc = get_json_cast_for_type(typoid); + Oid castfunc = use_casts ? get_json_cast_for_type(typoid) : InvalidOid; if (OidIsValid(castfunc)) { @@ -6116,9 +6130,11 @@ json_check_mutability(Oid typoid, bool *has_mutable) *has_mutable = true; } else if (att_typtype == TYPTYPE_RANGE) - json_check_mutability(get_range_subtype(typoid), has_mutable); + json_check_mutability_internal(get_range_subtype(typoid), false, + has_mutable); else - json_check_mutability(get_multirange_range(typoid), has_mutable); + json_check_mutability_internal(get_multirange_range(typoid), false, + has_mutable); return; } else @@ -6128,7 +6144,7 @@ json_check_mutability(Oid typoid, bool *has_mutable) if (OidIsValid(att_typelem)) { /* recurse into array element type */ - json_check_mutability(att_typelem, has_mutable); + json_check_mutability_internal(att_typelem, use_casts, has_mutable); return; } } @@ -6166,7 +6182,7 @@ json_check_mutability(Oid typoid, bool *has_mutable) default: { - Oid funcoid = get_json_cast_for_type(typoid); + Oid funcoid = use_casts ? get_json_cast_for_type(typoid) : InvalidOid; if (!OidIsValid(funcoid)) {