aboutsummaryrefslogtreecommitdiff
path: root/src/backend/parser/parse_expr.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/backend/parser/parse_expr.c')
-rw-r--r--src/backend/parser/parse_expr.c24
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)