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 9c4473c449b91f068b335ca389585fcfa989ca57..392c12d47abfa740cbfe6436f5bc652cd0c49fcb 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