diff options
Diffstat (limited to 'src/backend/parser/parse_expr.c')
-rw-r--r-- | src/backend/parser/parse_expr.c | 24 |
1 files changed, 23 insertions, 1 deletions
diff --git a/src/backend/parser/parse_expr.c b/src/backend/parser/parse_expr.c index 233b7b1cc99..df766cdec19 100644 --- a/src/backend/parser/parse_expr.c +++ b/src/backend/parser/parse_expr.c @@ -3583,6 +3583,7 @@ coerceJsonFuncExpr(ParseState *pstate, Node *expr, Node *res; int location; Oid exprtype = exprType(expr); + int32 baseTypmod = returning->typmod; /* if output type is not specified or equals to function type, return */ if (!OidIsValid(returning->typid) || returning->typid == exprtype) @@ -3611,10 +3612,19 @@ coerceJsonFuncExpr(ParseState *pstate, Node *expr, return (Node *) fexpr; } + /* + * For domains, consider the base type's typmod to decide whether to setup + * an implicit or explicit cast. + */ + if (get_typtype(returning->typid) == TYPTYPE_DOMAIN) + (void) getBaseTypeAndTypmod(returning->typid, &baseTypmod); + /* try to coerce expression to the output type */ res = coerce_to_target_type(pstate, expr, exprtype, - returning->typid, returning->typmod, + returning->typid, baseTypmod, + baseTypmod > 0 ? COERCION_IMPLICIT : COERCION_EXPLICIT, + baseTypmod > 0 ? COERCE_IMPLICIT_CAST : COERCE_EXPLICIT_CAST, location); @@ -3640,6 +3650,7 @@ makeJsonConstructorExpr(ParseState *pstate, JsonConstructorType type, JsonConstructorExpr *jsctor = makeNode(JsonConstructorExpr); Node *placeholder; Node *coercion; + int32 baseTypmod = returning->typmod; jsctor->args = args; jsctor->func = fexpr; @@ -3677,6 +3688,17 @@ makeJsonConstructorExpr(ParseState *pstate, JsonConstructorType type, placeholder = (Node *) cte; } + /* + * Convert the source expression to text, because coerceJsonFuncExpr() + * will create an implicit cast to the RETURNING types with typmod and + * there are no implicit casts from json(b) to such types. For domains, + * the base type's typmod will be considered, so do so here too. + */ + if (get_typtype(returning->typid) == TYPTYPE_DOMAIN) + (void) getBaseTypeAndTypmod(returning->typid, &baseTypmod); + if (baseTypmod > 0) + placeholder = coerce_to_specific_type(pstate, placeholder, TEXTOID, + "JSON_CONSTRUCTOR()"); coercion = coerceJsonFuncExpr(pstate, placeholder, returning, true); if (coercion != placeholder) |