From b092df2d6f7b3ddba0f4fd4fedf2b6b172d7b7a7 Mon Sep 17 00:00:00 2001
From: Amit Langote <amitlan@postgresql.org>
Date: Mon, 1 Jul 2024 17:09:19 +0900
Subject: [PATCH v6] SQL/JSON: Rethink c2d93c3802b

This essentially reverts all of c2d93c3802b and teaches
coerceJsonFuncExpr() to use COERCION_ASSIGNMENT instead of
COERCION_EXPLICIT so that the casts to types with typmod
are considered as implicit casts.

Discussion: https://postgr.es/m/202406291824.reofujy7xdj3@alvherre.pgsql
---
 src/backend/parser/parse_expr.c | 26 ++------------------------
 1 file changed, 2 insertions(+), 24 deletions(-)

diff --git a/src/backend/parser/parse_expr.c b/src/backend/parser/parse_expr.c
index 45c019627c..0c96f9e8e4 100644
--- a/src/backend/parser/parse_expr.c
+++ b/src/backend/parser/parse_expr.c
@@ -3582,7 +3582,6 @@ 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,19 +3610,10 @@ 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, baseTypmod,
-								baseTypmod > 0 ? COERCION_IMPLICIT :
-								COERCION_EXPLICIT,
-								baseTypmod > 0 ? COERCE_IMPLICIT_CAST :
+								returning->typid, returning->typmod,
+								COERCION_ASSIGNMENT,
 								COERCE_EXPLICIT_CAST,
 								location);
 
@@ -3649,7 +3639,6 @@ makeJsonConstructorExpr(ParseState *pstate, JsonConstructorType type,
 	JsonConstructorExpr *jsctor = makeNode(JsonConstructorExpr);
 	Node	   *placeholder;
 	Node	   *coercion;
-	int32		baseTypmod = returning->typmod;
 
 	jsctor->args = args;
 	jsctor->func = fexpr;
@@ -3687,17 +3676,6 @@ 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)
-- 
2.43.0

