Tweak collation setup for GIN index comparison functions.

Honor index column's collation spec if there is one, don't go to the
expense of calling get_typcollation when we can reasonably assume that
all GIN storage types will use default collation, and be sure to set
a collation for the comparePartialFn too.
This commit is contained in:
Tom Lane 2011-04-08 16:48:25 -04:00
parent c5ff3ff492
commit 1766a5b63a
1 changed files with 23 additions and 3 deletions

View File

@ -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