@@ -94,7 +94,8 @@ static Node *transformJsonFuncExpr(ParseState *pstate, JsonFuncExpr *func);
9494static void transformJsonPassingArgs (ParseState * pstate , const char * constructName ,
9595 JsonFormatType format , List * args ,
9696 List * * passing_values , List * * passing_names );
97- static JsonBehavior * transformJsonBehavior (ParseState * pstate , JsonBehavior * behavior ,
97+ static JsonBehavior * transformJsonBehavior (ParseState * pstate , JsonExpr * jsexpr ,
98+ JsonBehavior * behavior ,
9899 JsonBehaviorType default_behavior ,
99100 JsonReturning * returning );
100101static Node * GetJsonBehaviorConst (JsonBehaviorType btype , int location );
@@ -4529,13 +4530,16 @@ transformJsonFuncExpr(ParseState *pstate, JsonFuncExpr *func)
45294530 {
45304531 jsexpr -> returning -> typid = BOOLOID ;
45314532 jsexpr -> returning -> typmod = -1 ;
4533+ jsexpr -> collation = InvalidOid ;
45324534 }
45334535
45344536 /* JSON_TABLE() COLUMNS can specify a non-boolean type. */
45354537 if (jsexpr -> returning -> typid != BOOLOID )
45364538 jsexpr -> use_json_coercion = true;
45374539
4538- jsexpr -> on_error = transformJsonBehavior (pstate , func -> on_error ,
4540+ jsexpr -> on_error = transformJsonBehavior (pstate ,
4541+ jsexpr ,
4542+ func -> on_error ,
45394543 JSON_BEHAVIOR_FALSE ,
45404544 jsexpr -> returning );
45414545 break ;
@@ -4550,6 +4554,8 @@ transformJsonFuncExpr(ParseState *pstate, JsonFuncExpr *func)
45504554 ret -> typmod = -1 ;
45514555 }
45524556
4557+ jsexpr -> collation = get_typcollation (jsexpr -> returning -> typid );
4558+
45534559 /*
45544560 * Keep quotes on scalar strings by default, omitting them only if
45554561 * OMIT QUOTES is specified.
@@ -4566,11 +4572,15 @@ transformJsonFuncExpr(ParseState *pstate, JsonFuncExpr *func)
45664572 jsexpr -> use_json_coercion = true;
45674573
45684574 /* Assume NULL ON EMPTY when ON EMPTY is not specified. */
4569- jsexpr -> on_empty = transformJsonBehavior (pstate , func -> on_empty ,
4575+ jsexpr -> on_empty = transformJsonBehavior (pstate ,
4576+ jsexpr ,
4577+ func -> on_empty ,
45704578 JSON_BEHAVIOR_NULL ,
45714579 jsexpr -> returning );
45724580 /* Assume NULL ON ERROR when ON ERROR is not specified. */
4573- jsexpr -> on_error = transformJsonBehavior (pstate , func -> on_error ,
4581+ jsexpr -> on_error = transformJsonBehavior (pstate ,
4582+ jsexpr ,
4583+ func -> on_error ,
45744584 JSON_BEHAVIOR_NULL ,
45754585 jsexpr -> returning );
45764586 break ;
@@ -4582,6 +4592,7 @@ transformJsonFuncExpr(ParseState *pstate, JsonFuncExpr *func)
45824592 jsexpr -> returning -> typid = TEXTOID ;
45834593 jsexpr -> returning -> typmod = -1 ;
45844594 }
4595+ jsexpr -> collation = get_typcollation (jsexpr -> returning -> typid );
45854596
45864597 /*
45874598 * Override whatever transformJsonOutput() set these to, which
@@ -4607,11 +4618,15 @@ transformJsonFuncExpr(ParseState *pstate, JsonFuncExpr *func)
46074618 }
46084619
46094620 /* Assume NULL ON EMPTY when ON EMPTY is not specified. */
4610- jsexpr -> on_empty = transformJsonBehavior (pstate , func -> on_empty ,
4621+ jsexpr -> on_empty = transformJsonBehavior (pstate ,
4622+ jsexpr ,
4623+ func -> on_empty ,
46114624 JSON_BEHAVIOR_NULL ,
46124625 jsexpr -> returning );
46134626 /* Assume NULL ON ERROR when ON ERROR is not specified. */
4614- jsexpr -> on_error = transformJsonBehavior (pstate , func -> on_error ,
4627+ jsexpr -> on_error = transformJsonBehavior (pstate ,
4628+ jsexpr ,
4629+ func -> on_error ,
46154630 JSON_BEHAVIOR_NULL ,
46164631 jsexpr -> returning );
46174632 break ;
@@ -4622,14 +4637,17 @@ transformJsonFuncExpr(ParseState *pstate, JsonFuncExpr *func)
46224637 jsexpr -> returning -> typid = exprType (jsexpr -> formatted_expr );
46234638 jsexpr -> returning -> typmod = -1 ;
46244639 }
4640+ jsexpr -> collation = get_typcollation (jsexpr -> returning -> typid );
46254641
46264642 /*
46274643 * Assume EMPTY ARRAY ON ERROR when ON ERROR is not specified.
46284644 *
46294645 * ON EMPTY cannot be specified at the top level but it can be for
46304646 * the individual columns.
46314647 */
4632- jsexpr -> on_error = transformJsonBehavior (pstate , func -> on_error ,
4648+ jsexpr -> on_error = transformJsonBehavior (pstate ,
4649+ jsexpr ,
4650+ func -> on_error ,
46334651 JSON_BEHAVIOR_EMPTY_ARRAY ,
46344652 jsexpr -> returning );
46354653 break ;
@@ -4705,7 +4723,8 @@ ValidJsonBehaviorDefaultExpr(Node *expr, void *context)
47054723 * Transform a JSON BEHAVIOR clause.
47064724 */
47074725static JsonBehavior *
4708- transformJsonBehavior (ParseState * pstate , JsonBehavior * behavior ,
4726+ transformJsonBehavior (ParseState * pstate , JsonExpr * jsexpr ,
4727+ JsonBehavior * behavior ,
47094728 JsonBehaviorType default_behavior ,
47104729 JsonReturning * returning )
47114730{
@@ -4720,7 +4739,11 @@ transformJsonBehavior(ParseState *pstate, JsonBehavior *behavior,
47204739 location = behavior -> location ;
47214740 if (btype == JSON_BEHAVIOR_DEFAULT )
47224741 {
4742+ Oid targetcoll = jsexpr -> collation ;
4743+ Oid exprcoll ;
4744+
47234745 expr = transformExprRecurse (pstate , behavior -> expr );
4746+
47244747 if (!ValidJsonBehaviorDefaultExpr (expr , NULL ))
47254748 ereport (ERROR ,
47264749 (errcode (ERRCODE_DATATYPE_MISMATCH ),
@@ -4736,6 +4759,24 @@ transformJsonBehavior(ParseState *pstate, JsonBehavior *behavior,
47364759 (errcode (ERRCODE_DATATYPE_MISMATCH ),
47374760 errmsg ("DEFAULT expression must not return a set" ),
47384761 parser_errposition (pstate , exprLocation (expr ))));
4762+
4763+ /*
4764+ * Reject a DEFAULT expression whose collation differs from the
4765+ * enclosing JSON expression's result collation
4766+ * (jsexpr->collation), as chosen by the RETURNING clause.
4767+ */
4768+ exprcoll = exprCollation (expr );
4769+ if (!OidIsValid (exprcoll ))
4770+ exprcoll = get_typcollation (exprType (expr ));
4771+ if (OidIsValid (targetcoll ) && OidIsValid (exprcoll ) &&
4772+ targetcoll != exprcoll )
4773+ ereport (ERROR ,
4774+ errcode (ERRCODE_COLLATION_MISMATCH ),
4775+ errmsg ("the collation of DEFAULT expression conflicts with RETURNING clause" ),
4776+ errdetail ("\"%s\" versus \"%s\"" ,
4777+ get_collation_name (exprcoll ),
4778+ get_collation_name (targetcoll )),
4779+ parser_errposition (pstate , exprLocation (expr )));
47394780 }
47404781 }
47414782
0 commit comments