@@ -63,23 +63,6 @@ initGinState(GinState *state, Relation index)
6363fmgr_info_copy (& (state -> compareFn [i ]),
6464index_getprocinfo (index ,i + 1 ,GIN_COMPARE_PROC ),
6565CurrentMemoryContext );
66-
67- /*
68- * If the index column has a specified collation, index_getprocinfo
69- * will have installed it into the fmgr info, and we should honor it.
70- * However, we may have a collatable storage type for a noncollatable
71- * indexed data type (for instance, hstore uses text index entries).
72- * If there's no index collation then specify default collation in
73- * case the comparison function needs one.This is harmless if the
74- * comparison function doesn't care about collation, so we just do it
75- * unconditionally. (We could alternatively call get_typcollation,
76- * but that seems like expensive overkill --- there aren't going to be
77- * any cases where a GIN storage type has a nondefault collation.)
78- */
79- if (!OidIsValid (state -> compareFn [i ].fn_collation ))
80- fmgr_info_set_collation (DEFAULT_COLLATION_OID ,
81- & (state -> compareFn [i ]));
82-
8366fmgr_info_copy (& (state -> extractValueFn [i ]),
8467index_getprocinfo (index ,i + 1 ,GIN_EXTRACTVALUE_PROC ),
8568CurrentMemoryContext );
@@ -98,18 +81,29 @@ initGinState(GinState *state, Relation index)
9881fmgr_info_copy (& (state -> comparePartialFn [i ]),
9982index_getprocinfo (index ,i + 1 ,GIN_COMPARE_PARTIAL_PROC ),
10083CurrentMemoryContext );
101-
102- /* As above, install collation spec in case compare fn needs it */
103- if (!OidIsValid (state -> comparePartialFn [i ].fn_collation ))
104- fmgr_info_set_collation (DEFAULT_COLLATION_OID ,
105- & (state -> comparePartialFn [i ]));
106-
10784state -> canPartialMatch [i ]= true;
10885}
10986else
11087{
11188state -> canPartialMatch [i ]= false;
11289}
90+
91+ /*
92+ * If the index column has a specified collation, we should honor that
93+ * while doing comparisons. However, we may have a collatable storage
94+ * type for a noncollatable indexed data type (for instance, hstore
95+ * uses text index entries). If there's no index collation then
96+ * specify default collation in case the comparison function needs
97+ * collation. This is harmless if the comparison function doesn't
98+ * care about collation, so we just do it unconditionally. (We could
99+ * alternatively call get_typcollation, but that seems like expensive
100+ * overkill --- there aren't going to be any cases where a GIN storage
101+ * type has a nondefault collation.)
102+ */
103+ if (OidIsValid (index -> rd_indcollation [i ]))
104+ state -> compareCollation [i ]= index -> rd_indcollation [i ];
105+ else
106+ state -> compareCollation [i ]= DEFAULT_COLLATION_OID ;
113107}
114108}
115109
@@ -298,8 +292,9 @@ ginCompareEntries(GinState *ginstate, OffsetNumber attnum,
298292return 0 ;
299293
300294/* both not null, so safe to call the compareFn */
301- return DatumGetInt32 (FunctionCall2 (& ginstate -> compareFn [attnum - 1 ],
302- a ,b ));
295+ return DatumGetInt32 (FunctionCall2Coll (& ginstate -> compareFn [attnum - 1 ],
296+ ginstate -> compareCollation [attnum - 1 ],
297+ a ,b ));
303298}
304299
305300/*
@@ -334,6 +329,7 @@ typedef struct
334329typedef struct
335330{
336331FmgrInfo * cmpDatumFunc ;
332+ Oid collation ;
337333bool haveDups ;
338334}cmpEntriesArg ;
339335
@@ -355,8 +351,9 @@ cmpEntries(const void *a, const void *b, void *arg)
355351else if (bb -> isnull )
356352res = -1 ;/* not-NULL "<" NULL */
357353else
358- res = DatumGetInt32 (FunctionCall2 (data -> cmpDatumFunc ,
359- aa -> datum ,bb -> datum ));
354+ res = DatumGetInt32 (FunctionCall2Coll (data -> cmpDatumFunc ,
355+ data -> collation ,
356+ aa -> datum ,bb -> datum ));
360357
361358/*
362359 * Detect if we have any duplicates. If there are equal keys, qsort must
@@ -456,6 +453,7 @@ ginExtractEntries(GinState *ginstate, OffsetNumber attnum,
456453}
457454
458455arg .cmpDatumFunc = & ginstate -> compareFn [attnum - 1 ];
456+ arg .collation = ginstate -> compareCollation [attnum - 1 ];
459457arg .haveDups = false;
460458qsort_arg (keydata ,* nentries ,sizeof (keyEntryData ),
461459cmpEntries , (void * )& arg );