@ -3583,6 +3583,7 @@ coerceJsonFuncExpr(ParseState *pstate, Node *expr,
Node * res ;
Node * res ;
int location ;
int location ;
Oid exprtype = exprType ( expr ) ;
Oid exprtype = exprType ( expr ) ;
int32 baseTypmod = returning - > typmod ;
/* if output type is not specified or equals to function type, return */
/* if output type is not specified or equals to function type, return */
if ( ! OidIsValid ( returning - > typid ) | | returning - > typid = = exprtype )
if ( ! OidIsValid ( returning - > typid ) | | returning - > typid = = exprtype )
@ -3611,10 +3612,19 @@ coerceJsonFuncExpr(ParseState *pstate, Node *expr,
return ( Node * ) fexpr ;
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 */
/* try to coerce expression to the output type */
res = coerce_to_target_type ( pstate , expr , exprtype ,
res = coerce_to_target_type ( pstate , expr , exprtype ,
returning - > typid , returning - > typmod ,
returning - > typid , baseTypmod ,
baseTypmod > 0 ? COERCION_IMPLICIT :
COERCION_EXPLICIT ,
COERCION_EXPLICIT ,
baseTypmod > 0 ? COERCE_IMPLICIT_CAST :
COERCE_EXPLICIT_CAST ,
COERCE_EXPLICIT_CAST ,
location ) ;
location ) ;
@ -3640,6 +3650,7 @@ makeJsonConstructorExpr(ParseState *pstate, JsonConstructorType type,
JsonConstructorExpr * jsctor = makeNode ( JsonConstructorExpr ) ;
JsonConstructorExpr * jsctor = makeNode ( JsonConstructorExpr ) ;
Node * placeholder ;
Node * placeholder ;
Node * coercion ;
Node * coercion ;
int32 baseTypmod = returning - > typmod ;
jsctor - > args = args ;
jsctor - > args = args ;
jsctor - > func = fexpr ;
jsctor - > func = fexpr ;
@ -3677,6 +3688,17 @@ makeJsonConstructorExpr(ParseState *pstate, JsonConstructorType type,
placeholder = ( Node * ) cte ;
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 ) ;
coercion = coerceJsonFuncExpr ( pstate , placeholder , returning , true ) ;
if ( coercion ! = placeholder )
if ( coercion ! = placeholder )