diff options
author | Andrew Dunstan | 2017-03-21 15:04:17 +0000 |
---|---|---|
committer | Andrew Dunstan | 2017-03-21 15:04:17 +0000 |
commit | 4ad0f88c443ca60de9b65cd0afd794fb80b10d86 (patch) | |
tree | 7988552d7b101d0e41819dc2b77b8933def06e61 /contrib/btree_gin/btree_gin.c | |
parent | f7946a92b689199cba64e7406a1c12d12637168a (diff) |
Add btree_gin support for enum types
Reviewed by Tom Lane and Anastasia Lubennikova
Discussion: http://postgr.es/m/[email protected]
Diffstat (limited to 'contrib/btree_gin/btree_gin.c')
-rw-r--r-- | contrib/btree_gin/btree_gin.c | 67 |
1 files changed, 59 insertions, 8 deletions
diff --git a/contrib/btree_gin/btree_gin.c b/contrib/btree_gin/btree_gin.c index 725456e9404..7191fbf54f7 100644 --- a/contrib/btree_gin/btree_gin.c +++ b/contrib/btree_gin/btree_gin.c @@ -25,7 +25,6 @@ typedef struct QueryInfo Datum (*typecmp) (FunctionCallInfo); } QueryInfo; - /*** GIN support functions shared by all datatypes ***/ static Datum @@ -112,13 +111,14 @@ gin_btree_compare_prefix(FunctionCallInfo fcinfo) int32 res, cmp; - cmp = DatumGetInt32(DirectFunctionCall2Coll( - data->typecmp, - PG_GET_COLLATION(), - (data->strategy == BTLessStrategyNumber || - data->strategy == BTLessEqualStrategyNumber) - ? data->datum : a, - b)); + cmp = DatumGetInt32(CallerFInfoFunctionCall2( + data->typecmp, + fcinfo->flinfo, + PG_GET_COLLATION(), + (data->strategy == BTLessStrategyNumber || + data->strategy == BTLessEqualStrategyNumber) + ? data->datum : a, + b)); switch (data->strategy) { @@ -426,3 +426,54 @@ leftmostvalue_numeric(void) } GIN_SUPPORT(numeric, true, leftmostvalue_numeric, gin_numeric_cmp) + +/* + * Use a similar trick to that used for numeric for enums, since we don't + * actually know the leftmost value of any enum without knowing the concrete + * type, so we use a dummy leftmost value of InvalidOid. + * + * Note that we use CallerFInfoFunctionCall2 here so that enum_cmp + * gets a valid fn_extra to work with. Unlike most other type comparison + * routines it needs it, so we can't use DirectFunctionCall2. + */ + + +#define ENUM_IS_LEFTMOST(x) ((x) == InvalidOid) + +PG_FUNCTION_INFO_V1(gin_enum_cmp); + +Datum +gin_enum_cmp(PG_FUNCTION_ARGS) +{ + Oid a = PG_GETARG_OID(0); + Oid b = PG_GETARG_OID(1); + int res = 0; + + if (ENUM_IS_LEFTMOST(a)) + { + res = (ENUM_IS_LEFTMOST(b)) ? 0 : -1; + } + else if (ENUM_IS_LEFTMOST(b)) + { + res = 1; + } + else + { + res = DatumGetInt32(CallerFInfoFunctionCall2( + enum_cmp, + fcinfo->flinfo, + PG_GET_COLLATION(), + ObjectIdGetDatum(a), + ObjectIdGetDatum(b))); + } + + PG_RETURN_INT32(res); +} + +static Datum +leftmostvalue_enum(void) +{ + return ObjectIdGetDatum(InvalidOid); +} + +GIN_SUPPORT(anyenum, false, leftmostvalue_enum, gin_enum_cmp) |