OSDN Git Service

Tweak collation setup for GIN index comparison functions.
authorTom Lane <tgl@sss.pgh.pa.us>
Fri, 8 Apr 2011 20:48:25 +0000 (16:48 -0400)
committerTom Lane <tgl@sss.pgh.pa.us>
Fri, 8 Apr 2011 20:48:25 +0000 (16:48 -0400)
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.

src/backend/access/gin/ginutil.c

index 9c4473c..392c12d 100644 (file)
 
 #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