diff --git a/src/backend/access/gin/ginutil.c b/src/backend/access/gin/ginutil.c index 9c4473c449b..392c12d47ab 100644 --- a/src/backend/access/gin/ginutil.c +++ b/src/backend/access/gin/ginutil.c @@ -16,13 +16,13 @@ #include "access/gin_private.h" #include "access/reloptions.h" +#include "catalog/pg_collation.h" #include "catalog/pg_type.h" #include "miscadmin.h" #include "storage/bufmgr.h" #include "storage/freespace.h" #include "storage/indexfsm.h" #include "storage/lmgr.h" -#include "utils/lsyscache.h" /* @@ -63,8 +63,23 @@ initGinState(GinState *state, Relation index) fmgr_info_copy(&(state->compareFn[i]), index_getprocinfo(index, i + 1, GIN_COMPARE_PROC), CurrentMemoryContext); - fmgr_info_set_collation(get_typcollation(index->rd_att->attrs[i]->atttypid), - &(state->compareFn[i])); + + /* + * If the index column has a specified collation, index_getprocinfo + * will have installed it into the fmgr info, and we should honor it. + * However, we may have a collatable storage type for a noncollatable + * indexed data type (for instance, hstore uses text index entries). + * If there's no index collation then specify default collation in + * case the comparison function needs one. This is harmless if the + * comparison function doesn't care about collation, so we just do it + * unconditionally. (We could alternatively call get_typcollation, + * but that seems like expensive overkill --- there aren't going to be + * any cases where a GIN storage type has a nondefault collation.) + */ + if (!OidIsValid(state->compareFn[i].fn_collation)) + fmgr_info_set_collation(DEFAULT_COLLATION_OID, + &(state->compareFn[i])); + fmgr_info_copy(&(state->extractValueFn[i]), index_getprocinfo(index, i + 1, GIN_EXTRACTVALUE_PROC), CurrentMemoryContext); @@ -84,6 +99,11 @@ initGinState(GinState *state, Relation index) index_getprocinfo(index, i + 1, GIN_COMPARE_PARTIAL_PROC), CurrentMemoryContext); + /* As above, install collation spec in case compare fn needs it */ + if (!OidIsValid(state->comparePartialFn[i].fn_collation)) + fmgr_info_set_collation(DEFAULT_COLLATION_OID, + &(state->comparePartialFn[i])); + state->canPartialMatch[i] = true; } else