diff options
author | Peter Eisentraut <peter_e@gmx.net> | 2011-02-08 23:04:18 +0200 |
---|---|---|
committer | Peter Eisentraut <peter_e@gmx.net> | 2011-02-08 23:04:18 +0200 |
commit | 414c5a2ea65cbd38d79ffdf9b1fde7cc75c134e0 (patch) | |
tree | 016efd0c7108f659ea4f3c52ea54d78e1e5449e1 /src/backend/utils/fmgr | |
parent | 1703f0e8da2e8e3eccb6e12879c011ba106f8a62 (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.c | 66 | ||||
-rw-r--r-- | src/backend/utils/fmgr/funcapi.c | 4 |
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; |