diff options
Diffstat (limited to 'src/backend/utils/fmgr/funcapi.c')
| -rw-r--r-- | src/backend/utils/fmgr/funcapi.c | 25 |
1 files changed, 22 insertions, 3 deletions
diff --git a/src/backend/utils/fmgr/funcapi.c b/src/backend/utils/fmgr/funcapi.c index 321b4e7f8f..cad4a371b7 100644 --- a/src/backend/utils/fmgr/funcapi.c +++ b/src/backend/utils/fmgr/funcapi.c @@ -411,6 +411,7 @@ resolve_polymorphic_tupdesc(TupleDesc tupdesc, oidvector *declared_args, bool have_anyenum = false; Oid anyelement_type = InvalidOid; Oid anyarray_type = InvalidOid; + Oid anycollation; int i; /* See if there are any polymorphic outputs; quick out if not */ @@ -468,6 +469,7 @@ resolve_polymorphic_tupdesc(TupleDesc tupdesc, oidvector *declared_args, /* If nothing found, parser messed up */ if (!OidIsValid(anyelement_type) && !OidIsValid(anyarray_type)) return false; + /* If needed, deduce one polymorphic type from the other */ if (have_anyelement_result && !OidIsValid(anyelement_type)) anyelement_type = resolve_generic_type(ANYELEMENTOID, @@ -486,6 +488,24 @@ resolve_polymorphic_tupdesc(TupleDesc tupdesc, oidvector *declared_args, if (have_anyenum && !type_is_enum(anyelement_type)) return false; + /* + * Identify the collation to use for polymorphic OUT parameters. + * (It'll necessarily be the same for both anyelement and anyarray.) + */ + anycollation = get_typcollation(OidIsValid(anyelement_type) ? anyelement_type : anyarray_type); + if (OidIsValid(anycollation)) + { + /* + * The types are collatable, so consider whether to use a nondefault + * collation. We do so if we can identify the input collation used + * for the function. + */ + Oid inputcollation = exprInputCollation(call_expr); + + if (OidIsValid(inputcollation)) + anycollation = inputcollation; + } + /* And finally replace the tuple column types as needed */ for (i = 0; i < natts; i++) { @@ -499,6 +519,7 @@ resolve_polymorphic_tupdesc(TupleDesc tupdesc, oidvector *declared_args, anyelement_type, -1, 0); + TupleDescInitEntryCollation(tupdesc, i + 1, anycollation); break; case ANYARRAYOID: TupleDescInitEntry(tupdesc, i + 1, @@ -506,13 +527,11 @@ resolve_polymorphic_tupdesc(TupleDesc tupdesc, oidvector *declared_args, anyarray_type, -1, 0); + TupleDescInitEntryCollation(tupdesc, i + 1, anycollation); break; default: break; } - /* Set collation based on actual argument types */ - TupleDescInitEntryCollation(tupdesc, i + 1, - exprCollation(call_expr)); } return true; |
