summaryrefslogtreecommitdiff
path: root/src/backend/utils/fmgr
diff options
context:
space:
mode:
authorPeter Eisentraut <peter_e@gmx.net>2011-02-08 23:04:18 +0200
committerPeter Eisentraut <peter_e@gmx.net>2011-02-08 23:04:18 +0200
commit414c5a2ea65cbd38d79ffdf9b1fde7cc75c134e0 (patch)
tree016efd0c7108f659ea4f3c52ea54d78e1e5449e1 /src/backend/utils/fmgr
parent1703f0e8da2e8e3eccb6e12879c011ba106f8a62 (diff)
Per-column collation support
This adds collation support for columns and domains, a COLLATE clause to override it per expression, and B-tree index support. Peter Eisentraut reviewed by Pavel Stehule, Itagaki Takahiro, Robert Haas, Noah Misch
Diffstat (limited to 'src/backend/utils/fmgr')
-rw-r--r--src/backend/utils/fmgr/fmgr.c66
-rw-r--r--src/backend/utils/fmgr/funcapi.c4
2 files changed, 69 insertions, 1 deletions
diff --git a/src/backend/utils/fmgr/fmgr.c b/src/backend/utils/fmgr/fmgr.c
index 54d50e96377..d05e4d2dd8f 100644
--- a/src/backend/utils/fmgr/fmgr.c
+++ b/src/backend/utils/fmgr/fmgr.c
@@ -192,6 +192,7 @@ fmgr_info_cxt_security(Oid functionId, FmgrInfo *finfo, MemoryContext mcxt,
* elogs.
*/
finfo->fn_oid = InvalidOid;
+ finfo->fn_collation = InvalidOid;
finfo->fn_extra = NULL;
finfo->fn_mcxt = mcxt;
finfo->fn_expr = NULL; /* caller may set this later */
@@ -420,6 +421,25 @@ fmgr_info_other_lang(Oid functionId, FmgrInfo *finfo, HeapTuple procedureTuple)
}
/*
+ * Initialize the fn_collation field
+ */
+void
+fmgr_info_collation(Oid collationId, FmgrInfo *finfo)
+{
+ finfo->fn_collation = collationId;
+}
+
+/*
+ * Initialize the fn_expr field and set the collation based on it
+ */
+void
+fmgr_info_expr(Node *expr, FmgrInfo *finfo)
+{
+ finfo->fn_expr = expr;
+ finfo->fn_collation = exprCollation(expr);
+}
+
+/*
* Fetch and validate the information record for the given external function.
* The function is specified by a handle for the containing library
* (obtained from load_external_function) as well as the function name.
@@ -1273,6 +1293,52 @@ DirectFunctionCall9(PGFunction func, Datum arg1, Datum arg2,
return result;
}
+Datum
+DirectFunctionCall1WithCollation(PGFunction func, Oid collation, Datum arg1)
+{
+ FunctionCallInfoData fcinfo;
+ FmgrInfo flinfo;
+ Datum result;
+
+ InitFunctionCallInfoData(fcinfo, &flinfo, 1, NULL, NULL);
+ fcinfo.flinfo->fn_collation = collation;
+
+ fcinfo.arg[0] = arg1;
+ fcinfo.argnull[0] = false;
+
+ result = (*func) (&fcinfo);
+
+ /* Check for null result, since caller is clearly not expecting one */
+ if (fcinfo.isnull)
+ elog(ERROR, "function %p returned NULL", (void *) func);
+
+ return result;
+}
+
+Datum
+DirectFunctionCall2WithCollation(PGFunction func, Oid collation, Datum arg1, Datum arg2)
+{
+ FunctionCallInfoData fcinfo;
+ FmgrInfo flinfo;
+ Datum result;
+
+ InitFunctionCallInfoData(fcinfo, &flinfo, 2, NULL, NULL);
+ fcinfo.flinfo->fn_collation = collation;
+
+ fcinfo.arg[0] = arg1;
+ fcinfo.arg[1] = arg2;
+ fcinfo.argnull[0] = false;
+ fcinfo.argnull[1] = false;
+
+ result = (*func) (&fcinfo);
+
+ /* Check for null result, since caller is clearly not expecting one */
+ if (fcinfo.isnull)
+ elog(ERROR, "function %p returned NULL", (void *) func);
+
+ return result;
+}
+
/*
* These are for invocation of a previously-looked-up function with a
diff --git a/src/backend/utils/fmgr/funcapi.c b/src/backend/utils/fmgr/funcapi.c
index e32c716392c..321b4e7f8ff 100644
--- a/src/backend/utils/fmgr/funcapi.c
+++ b/src/backend/utils/fmgr/funcapi.c
@@ -468,7 +468,6 @@ 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,
@@ -511,6 +510,9 @@ resolve_polymorphic_tupdesc(TupleDesc tupdesc, oidvector *declared_args,
default:
break;
}
+ /* Set collation based on actual argument types */
+ TupleDescInitEntryCollation(tupdesc, i + 1,
+ exprCollation(call_expr));
}
return true;