2424#include "catalog/pg_opfamily.h"
2525#include "catalog/pg_type.h"
2626#include "nodes/makefuncs.h"
27- #include "nodes/nodeFuncs.h"
2827#include "optimizer/clauses.h"
2928#include "optimizer/cost.h"
3029#include "optimizer/pathnode.h"
@@ -101,6 +100,7 @@ static bool is_indexable_operator(Oid expr_op, Oid opfamily,
101100static bool match_rowcompare_to_indexcol (IndexOptInfo * index ,
102101int indexcol ,
103102Oid opfamily ,
103+ Oid idxcollation ,
104104RowCompareExpr * clause ,
105105Relids outer_relids );
106106static List * match_index_to_pathkeys (IndexOptInfo * index ,List * pathkeys );
@@ -113,11 +113,13 @@ static List *find_clauses_for_join(PlannerInfo *root, RelOptInfo *rel,
113113Relids outer_relids ,bool isouterjoin );
114114static bool match_boolean_index_clause (Node * clause ,int indexcol ,
115115IndexOptInfo * index );
116- static bool match_special_index_operator (Expr * clause ,Oid idxcolcollation ,Oid opfamily ,
116+ static bool match_special_index_operator (Expr * clause ,
117+ Oid opfamily ,Oid idxcollation ,
117118bool indexkey_on_left );
118119static Expr * expand_boolean_index_clause (Node * clause ,int indexcol ,
119120IndexOptInfo * index );
120- static List * expand_indexqual_opclause (RestrictInfo * rinfo ,Oid opfamily ,Oid collation );
121+ static List * expand_indexqual_opclause (RestrictInfo * rinfo ,
122+ Oid opfamily ,Oid idxcollation );
121123static RestrictInfo * expand_indexqual_rowcompare (RestrictInfo * rinfo ,
122124IndexOptInfo * index ,
123125int indexcol );
@@ -1158,7 +1160,7 @@ group_clauses_by_indexkey(IndexOptInfo *index,
11581160 * operator for this column, or is a "special" operator as recognized
11591161 * by match_special_index_operator();
11601162 * and
1161- * (3) must match the collation of the index.
1163+ * (3) must match the collation of the index, if collation is relevant .
11621164 *
11631165 * Our definition of "const" is pretty liberal: we allow Vars belonging
11641166 * to the caller-specified outer_relids relations (which had better not
@@ -1215,7 +1217,7 @@ match_clause_to_indexcol(IndexOptInfo *index,
12151217{
12161218Expr * clause = rinfo -> clause ;
12171219Oid opfamily = index -> opfamily [indexcol ];
1218- Oid collation = index -> indexcollations [indexcol ];
1220+ Oid idxcollation = index -> indexcollations [indexcol ];
12191221Node * leftop ,
12201222* rightop ;
12211223Relids left_relids ;
@@ -1276,7 +1278,8 @@ match_clause_to_indexcol(IndexOptInfo *index,
12761278}
12771279else if (clause && IsA (clause ,RowCompareExpr ))
12781280{
1279- return match_rowcompare_to_indexcol (index ,indexcol ,opfamily ,
1281+ return match_rowcompare_to_indexcol (index ,indexcol ,
1282+ opfamily ,idxcollation ,
12801283(RowCompareExpr * )clause ,
12811284outer_relids );
12821285}
@@ -1300,7 +1303,7 @@ match_clause_to_indexcol(IndexOptInfo *index,
13001303bms_is_subset (right_relids ,outer_relids )&&
13011304!contain_volatile_functions (rightop ))
13021305{
1303- if (collation == expr_coll &&
1306+ if (idxcollation == expr_coll &&
13041307is_indexable_operator (expr_op ,opfamily , true))
13051308return true;
13061309
@@ -1309,7 +1312,7 @@ match_clause_to_indexcol(IndexOptInfo *index,
13091312 * is a "special" indexable operator.
13101313 */
13111314if (plain_op &&
1312- match_special_index_operator (clause ,collation , opfamily , true))
1315+ match_special_index_operator (clause ,opfamily , idxcollation , true))
13131316return true;
13141317return false;
13151318}
@@ -1319,15 +1322,15 @@ match_clause_to_indexcol(IndexOptInfo *index,
13191322bms_is_subset (left_relids ,outer_relids )&&
13201323!contain_volatile_functions (leftop ))
13211324{
1322- if (collation == expr_coll &&
1325+ if (idxcollation == expr_coll &&
13231326is_indexable_operator (expr_op ,opfamily , false))
13241327return true;
13251328
13261329/*
13271330 * If we didn't find a member of the index's opfamily, see whether it
13281331 * is a "special" indexable operator.
13291332 */
1330- if (match_special_index_operator (clause ,collation , opfamily , false))
1333+ if (match_special_index_operator (clause ,opfamily , idxcollation , false))
13311334return true;
13321335return false;
13331336}
@@ -1367,12 +1370,14 @@ static bool
13671370match_rowcompare_to_indexcol (IndexOptInfo * index ,
13681371int indexcol ,
13691372Oid opfamily ,
1373+ Oid idxcollation ,
13701374RowCompareExpr * clause ,
13711375Relids outer_relids )
13721376{
13731377Node * leftop ,
13741378* rightop ;
13751379Oid expr_op ;
1380+ Oid expr_coll ;
13761381
13771382/* Forget it if we're not dealing with a btree index */
13781383if (index -> relam != BTREE_AM_OID )
@@ -1391,6 +1396,11 @@ match_rowcompare_to_indexcol(IndexOptInfo *index,
13911396leftop = (Node * )linitial (clause -> largs );
13921397rightop = (Node * )linitial (clause -> rargs );
13931398expr_op = linitial_oid (clause -> opnos );
1399+ expr_coll = linitial_oid (clause -> inputcollids );
1400+
1401+ /* Collations must match */
1402+ if (expr_coll != idxcollation )
1403+ return false;
13941404
13951405/*
13961406 * These syntactic tests are the same as in match_clause_to_indexcol()
@@ -1413,9 +1423,6 @@ match_rowcompare_to_indexcol(IndexOptInfo *index,
14131423else
14141424return false;
14151425
1416- if (index -> indexcollations [indexcol ]!= linitial_oid (clause -> inputcollids ))
1417- return false;
1418-
14191426/* We're good if the operator is the right type of opfamily member */
14201427switch (get_op_opfamily_strategy (expr_op ,opfamily ))
14211428{
@@ -1525,6 +1532,12 @@ match_index_to_pathkeys(IndexOptInfo *index, List *pathkeys)
15251532 * 'clause' is the ordering expression to be tested.
15261533 * 'pk_opfamily' is the btree opfamily describing the required sort order.
15271534 *
1535+ * Note that we currently do not consider the collation of the ordering
1536+ * operator's result. In practical cases the result type will be numeric
1537+ * and thus have no collation, and it's not very clear what to match to
1538+ * if it did have a collation. The index's collation should match the
1539+ * ordering operator's input collation, not its result.
1540+ *
15281541 * If successful, return 'clause' as-is if the indexkey is on the left,
15291542 * otherwise a commuted copy of 'clause'. If no match, return NULL.
15301543 */
@@ -1535,9 +1548,11 @@ match_clause_to_ordering_op(IndexOptInfo *index,
15351548Oid pk_opfamily )
15361549{
15371550Oid opfamily = index -> opfamily [indexcol ];
1551+ Oid idxcollation = index -> indexcollations [indexcol ];
15381552Node * leftop ,
15391553* rightop ;
15401554Oid expr_op ;
1555+ Oid expr_coll ;
15411556Oid sortfamily ;
15421557bool commuted ;
15431558
@@ -1551,6 +1566,13 @@ match_clause_to_ordering_op(IndexOptInfo *index,
15511566if (!leftop || !rightop )
15521567return NULL ;
15531568expr_op = ((OpExpr * )clause )-> opno ;
1569+ expr_coll = ((OpExpr * )clause )-> inputcollid ;
1570+
1571+ /*
1572+ * We can forget the whole thing right away if wrong collation.
1573+ */
1574+ if (expr_coll != idxcollation )
1575+ return NULL ;
15541576
15551577/*
15561578 * Check for clauses of the form: (indexkey operator constant) or
@@ -2175,6 +2197,12 @@ relation_has_unique_index_for(PlannerInfo *root, RelOptInfo *rel,
21752197if (!list_member_oid (rinfo -> mergeopfamilies ,ind -> opfamily [c ]))
21762198continue ;
21772199
2200+ /*
2201+ * XXX at some point we may need to check collations here
2202+ * too. For the moment we assume all collations reduce to
2203+ * the same notion of equality.
2204+ */
2205+
21782206/* OK, see if the condition operand matches the index key */
21792207if (rinfo -> outer_is_left )
21802208rexpr = get_rightop (rinfo -> clause );
@@ -2235,6 +2263,9 @@ flatten_clausegroups_list(List *clausegroups)
22352263 * operand: the nodetree to be compared to the index
22362264 * indexcol: the column number of the index (counting from 0)
22372265 * index: the index of interest
2266+ *
2267+ * Note that we aren't interested in collations here; the caller must check
2268+ * for a collation match, if it's dealing with an operator where that matters.
22382269 */
22392270bool
22402271match_index_to_operand (Node * operand ,
@@ -2409,7 +2440,7 @@ match_boolean_index_clause(Node *clause,
24092440 * Return 'true' if we can do something with it anyway.
24102441 */
24112442static bool
2412- match_special_index_operator (Expr * clause ,Oid idxcolcollation ,Oid opfamily ,
2443+ match_special_index_operator (Expr * clause ,Oid opfamily ,Oid idxcollation ,
24132444bool indexkey_on_left )
24142445{
24152446bool isIndexable = false;
@@ -2513,7 +2544,10 @@ match_special_index_operator(Expr *clause, Oid idxcolcollation, Oid opfamily,
25132544 *
25142545 * The non-pattern opclasses will not sort the way we need in most non-C
25152546 * locales. We can use such an index anyway for an exact match (simple
2516- * equality), but not for prefix-match cases.
2547+ * equality), but not for prefix-match cases. Note that we are looking
2548+ * at the index's collation, not the expression's collation -- this test
2549+ * is not dependent on the LIKE/regex operator's collation (which would
2550+ * only affect case folding behavior of ILIKE, anyway).
25172551 */
25182552switch (expr_op )
25192553{
@@ -2524,7 +2558,7 @@ match_special_index_operator(Expr *clause, Oid idxcolcollation, Oid opfamily,
25242558isIndexable =
25252559(opfamily == TEXT_PATTERN_BTREE_FAM_OID )||
25262560(opfamily == TEXT_BTREE_FAM_OID &&
2527- (pstatus == Pattern_Prefix_Exact || lc_collate_is_c (idxcolcollation )));
2561+ (pstatus == Pattern_Prefix_Exact || lc_collate_is_c (idxcollation )));
25282562break ;
25292563
25302564case OID_BPCHAR_LIKE_OP :
@@ -2534,7 +2568,7 @@ match_special_index_operator(Expr *clause, Oid idxcolcollation, Oid opfamily,
25342568isIndexable =
25352569(opfamily == BPCHAR_PATTERN_BTREE_FAM_OID )||
25362570(opfamily == BPCHAR_BTREE_FAM_OID &&
2537- (pstatus == Pattern_Prefix_Exact || lc_collate_is_c (idxcolcollation )));
2571+ (pstatus == Pattern_Prefix_Exact || lc_collate_is_c (idxcollation )));
25382572break ;
25392573
25402574case OID_NAME_LIKE_OP :
@@ -2555,25 +2589,6 @@ match_special_index_operator(Expr *clause, Oid idxcolcollation, Oid opfamily,
25552589break ;
25562590}
25572591
2558- if (!isIndexable )
2559- return false;
2560-
2561- /*
2562- * For case-insensitive matching, we also need to check that the
2563- * collations match.
2564- */
2565- switch (expr_op )
2566- {
2567- case OID_TEXT_ICLIKE_OP :
2568- case OID_TEXT_ICREGEXEQ_OP :
2569- case OID_BPCHAR_ICLIKE_OP :
2570- case OID_BPCHAR_ICREGEXEQ_OP :
2571- case OID_NAME_ICLIKE_OP :
2572- case OID_NAME_ICREGEXEQ_OP :
2573- isIndexable = (idxcolcollation == exprCollation ((Node * )clause ));
2574- break ;
2575- }
2576-
25772592return isIndexable ;
25782593}
25792594
@@ -2747,7 +2762,7 @@ expand_boolean_index_clause(Node *clause,
27472762 * expand special cases that were accepted by match_special_index_operator().
27482763 */
27492764static List *
2750- expand_indexqual_opclause (RestrictInfo * rinfo ,Oid opfamily ,Oid collation )
2765+ expand_indexqual_opclause (RestrictInfo * rinfo ,Oid opfamily ,Oid idxcollation )
27512766{
27522767Expr * clause = rinfo -> clause ;
27532768
@@ -2778,7 +2793,7 @@ expand_indexqual_opclause(RestrictInfo *rinfo, Oid opfamily, Oid collation)
27782793{
27792794pstatus = pattern_fixed_prefix (patt ,Pattern_Type_Like ,
27802795& prefix ,& rest );
2781- return prefix_quals (leftop ,opfamily ,collation ,prefix ,pstatus );
2796+ return prefix_quals (leftop ,opfamily ,idxcollation ,prefix ,pstatus );
27822797}
27832798break ;
27842799
@@ -2790,7 +2805,7 @@ expand_indexqual_opclause(RestrictInfo *rinfo, Oid opfamily, Oid collation)
27902805/* the right-hand const is type text for all of these */
27912806pstatus = pattern_fixed_prefix (patt ,Pattern_Type_Like_IC ,
27922807& prefix ,& rest );
2793- return prefix_quals (leftop ,opfamily ,collation ,prefix ,pstatus );
2808+ return prefix_quals (leftop ,opfamily ,idxcollation ,prefix ,pstatus );
27942809}
27952810break ;
27962811
@@ -2802,7 +2817,7 @@ expand_indexqual_opclause(RestrictInfo *rinfo, Oid opfamily, Oid collation)
28022817/* the right-hand const is type text for all of these */
28032818pstatus = pattern_fixed_prefix (patt ,Pattern_Type_Regex ,
28042819& prefix ,& rest );
2805- return prefix_quals (leftop ,opfamily ,collation ,prefix ,pstatus );
2820+ return prefix_quals (leftop ,opfamily ,idxcollation ,prefix ,pstatus );
28062821}
28072822break ;
28082823
@@ -2814,7 +2829,7 @@ expand_indexqual_opclause(RestrictInfo *rinfo, Oid opfamily, Oid collation)
28142829/* the right-hand const is type text for all of these */
28152830pstatus = pattern_fixed_prefix (patt ,Pattern_Type_Regex_IC ,
28162831& prefix ,& rest );
2817- return prefix_quals (leftop ,opfamily ,collation ,prefix ,pstatus );
2832+ return prefix_quals (leftop ,opfamily ,idxcollation ,prefix ,pstatus );
28182833}
28192834break ;
28202835
@@ -2965,6 +2980,7 @@ expand_indexqual_rowcompare(RestrictInfo *rinfo,
29652980largs_cell = lnext (largs_cell );
29662981rargs_cell = lnext (rargs_cell );
29672982opnos_cell = lnext (opnos_cell );
2983+ collids_cell = lnext (collids_cell );
29682984}
29692985
29702986/* Return clause as-is if it's all usable as index quals */
@@ -3158,7 +3174,10 @@ prefix_quals(Node *leftop, Oid opfamily, Oid collation,
31583174
31593175/*-------
31603176 * If we can create a string larger than the prefix, we can say
3161- * "x < greaterstr".
3177+ * "x < greaterstr". NB: we rely on make_greater_string() to generate
3178+ * a guaranteed-greater string, not just a probably-greater string.
3179+ * In general this is only guaranteed in C locale, so we'd better be
3180+ * using a C-locale index collation.
31623181 *-------
31633182 */
31643183oproid = get_opfamily_member (opfamily ,datatype ,datatype ,