summaryrefslogtreecommitdiff
path: root/src/backend/utils/fmgr/funcapi.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/backend/utils/fmgr/funcapi.c')
-rw-r--r--src/backend/utils/fmgr/funcapi.c25
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;