summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTom Lane2011-04-08 20:48:25 +0000
committerTom Lane2011-04-08 20:48:25 +0000
commit1766a5b63a950a667ed39c25256156bf366eb43c (patch)
tree042370605c4b067ed349de8d0785b48c3a3ea9f5
parentc5ff3ff49229e8fb7da0e46b463bfc9b12219078 (diff)
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.
-rw-r--r--src/backend/access/gin/ginutil.c26
1 files changed, 23 insertions, 3 deletions
diff --git a/src/backend/access/gin/ginutil.c b/src/backend/access/gin/ginutil.c
index 9c4473c449..392c12d47a 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