Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit69f1d5f

Browse files
committed
Clean up minor collation issues in indxpath.c.
Get rid of bogus collation test in match_special_index_operator (even forILIKE, the pattern match operator's collation doesn't matter here, and evenif it did the test was testing the wrong thing).Fix broken looping logic in expand_indexqual_rowcompare.Add collation check in match_clause_to_ordering_op.Make naming and argument ordering more consistent; improve comments.
1 parent466dac8 commit69f1d5f

File tree

1 file changed

+61
-42
lines changed

1 file changed

+61
-42
lines changed

‎src/backend/optimizer/path/indxpath.c

Lines changed: 61 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,6 @@
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,
101100
staticboolmatch_rowcompare_to_indexcol(IndexOptInfo*index,
102101
intindexcol,
103102
Oidopfamily,
103+
Oididxcollation,
104104
RowCompareExpr*clause,
105105
Relidsouter_relids);
106106
staticList*match_index_to_pathkeys(IndexOptInfo*index,List*pathkeys);
@@ -113,11 +113,13 @@ static List *find_clauses_for_join(PlannerInfo *root, RelOptInfo *rel,
113113
Relidsouter_relids,boolisouterjoin);
114114
staticboolmatch_boolean_index_clause(Node*clause,intindexcol,
115115
IndexOptInfo*index);
116-
staticboolmatch_special_index_operator(Expr*clause,Oididxcolcollation,Oidopfamily,
116+
staticboolmatch_special_index_operator(Expr*clause,
117+
Oidopfamily,Oididxcollation,
117118
boolindexkey_on_left);
118119
staticExpr*expand_boolean_index_clause(Node*clause,intindexcol,
119120
IndexOptInfo*index);
120-
staticList*expand_indexqual_opclause(RestrictInfo*rinfo,Oidopfamily,Oidcollation);
121+
staticList*expand_indexqual_opclause(RestrictInfo*rinfo,
122+
Oidopfamily,Oididxcollation);
121123
staticRestrictInfo*expand_indexqual_rowcompare(RestrictInfo*rinfo,
122124
IndexOptInfo*index,
123125
intindexcol);
@@ -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
{
12161218
Expr*clause=rinfo->clause;
12171219
Oidopfamily=index->opfamily[indexcol];
1218-
Oidcollation=index->indexcollations[indexcol];
1220+
Oididxcollation=index->indexcollations[indexcol];
12191221
Node*leftop,
12201222
*rightop;
12211223
Relidsleft_relids;
@@ -1276,7 +1278,8 @@ match_clause_to_indexcol(IndexOptInfo *index,
12761278
}
12771279
elseif (clause&&IsA(clause,RowCompareExpr))
12781280
{
1279-
returnmatch_rowcompare_to_indexcol(index,indexcol,opfamily,
1281+
returnmatch_rowcompare_to_indexcol(index,indexcol,
1282+
opfamily,idxcollation,
12801283
(RowCompareExpr*)clause,
12811284
outer_relids);
12821285
}
@@ -1300,7 +1303,7 @@ match_clause_to_indexcol(IndexOptInfo *index,
13001303
bms_is_subset(right_relids,outer_relids)&&
13011304
!contain_volatile_functions(rightop))
13021305
{
1303-
if (collation==expr_coll&&
1306+
if (idxcollation==expr_coll&&
13041307
is_indexable_operator(expr_op,opfamily, true))
13051308
return true;
13061309

@@ -1309,7 +1312,7 @@ match_clause_to_indexcol(IndexOptInfo *index,
13091312
* is a "special" indexable operator.
13101313
*/
13111314
if (plain_op&&
1312-
match_special_index_operator(clause,collation,opfamily, true))
1315+
match_special_index_operator(clause,opfamily,idxcollation, true))
13131316
return true;
13141317
return false;
13151318
}
@@ -1319,15 +1322,15 @@ match_clause_to_indexcol(IndexOptInfo *index,
13191322
bms_is_subset(left_relids,outer_relids)&&
13201323
!contain_volatile_functions(leftop))
13211324
{
1322-
if (collation==expr_coll&&
1325+
if (idxcollation==expr_coll&&
13231326
is_indexable_operator(expr_op,opfamily, false))
13241327
return 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))
13311334
return true;
13321335
return false;
13331336
}
@@ -1367,12 +1370,14 @@ static bool
13671370
match_rowcompare_to_indexcol(IndexOptInfo*index,
13681371
intindexcol,
13691372
Oidopfamily,
1373+
Oididxcollation,
13701374
RowCompareExpr*clause,
13711375
Relidsouter_relids)
13721376
{
13731377
Node*leftop,
13741378
*rightop;
13751379
Oidexpr_op;
1380+
Oidexpr_coll;
13761381

13771382
/* Forget it if we're not dealing with a btree index */
13781383
if (index->relam!=BTREE_AM_OID)
@@ -1391,6 +1396,11 @@ match_rowcompare_to_indexcol(IndexOptInfo *index,
13911396
leftop= (Node*)linitial(clause->largs);
13921397
rightop= (Node*)linitial(clause->rargs);
13931398
expr_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,
14131423
else
14141424
return 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 */
14201427
switch (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,
15351548
Oidpk_opfamily)
15361549
{
15371550
Oidopfamily=index->opfamily[indexcol];
1551+
Oididxcollation=index->indexcollations[indexcol];
15381552
Node*leftop,
15391553
*rightop;
15401554
Oidexpr_op;
1555+
Oidexpr_coll;
15411556
Oidsortfamily;
15421557
boolcommuted;
15431558

@@ -1551,6 +1566,13 @@ match_clause_to_ordering_op(IndexOptInfo *index,
15511566
if (!leftop|| !rightop)
15521567
returnNULL;
15531568
expr_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+
returnNULL;
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,
21752197
if (!list_member_oid(rinfo->mergeopfamilies,ind->opfamily[c]))
21762198
continue;
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 */
21792207
if (rinfo->outer_is_left)
21802208
rexpr=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
*/
22392270
bool
22402271
match_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
*/
24112442
staticbool
2412-
match_special_index_operator(Expr*clause,Oididxcolcollation,Oidopfamily,
2443+
match_special_index_operator(Expr*clause,Oidopfamily,Oididxcollation,
24132444
boolindexkey_on_left)
24142445
{
24152446
boolisIndexable= 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
*/
25182552
switch (expr_op)
25192553
{
@@ -2524,7 +2558,7 @@ match_special_index_operator(Expr *clause, Oid idxcolcollation, Oid opfamily,
25242558
isIndexable=
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)));
25282562
break;
25292563

25302564
caseOID_BPCHAR_LIKE_OP:
@@ -2534,7 +2568,7 @@ match_special_index_operator(Expr *clause, Oid idxcolcollation, Oid opfamily,
25342568
isIndexable=
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)));
25382572
break;
25392573

25402574
caseOID_NAME_LIKE_OP:
@@ -2555,25 +2589,6 @@ match_special_index_operator(Expr *clause, Oid idxcolcollation, Oid opfamily,
25552589
break;
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-
caseOID_TEXT_ICLIKE_OP:
2568-
caseOID_TEXT_ICREGEXEQ_OP:
2569-
caseOID_BPCHAR_ICLIKE_OP:
2570-
caseOID_BPCHAR_ICREGEXEQ_OP:
2571-
caseOID_NAME_ICLIKE_OP:
2572-
caseOID_NAME_ICREGEXEQ_OP:
2573-
isIndexable= (idxcolcollation==exprCollation((Node*)clause));
2574-
break;
2575-
}
2576-
25772592
returnisIndexable;
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
*/
27492764
staticList*
2750-
expand_indexqual_opclause(RestrictInfo*rinfo,Oidopfamily,Oidcollation)
2765+
expand_indexqual_opclause(RestrictInfo*rinfo,Oidopfamily,Oididxcollation)
27512766
{
27522767
Expr*clause=rinfo->clause;
27532768

@@ -2778,7 +2793,7 @@ expand_indexqual_opclause(RestrictInfo *rinfo, Oid opfamily, Oid collation)
27782793
{
27792794
pstatus=pattern_fixed_prefix(patt,Pattern_Type_Like,
27802795
&prefix,&rest);
2781-
returnprefix_quals(leftop,opfamily,collation,prefix,pstatus);
2796+
returnprefix_quals(leftop,opfamily,idxcollation,prefix,pstatus);
27822797
}
27832798
break;
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 */
27912806
pstatus=pattern_fixed_prefix(patt,Pattern_Type_Like_IC,
27922807
&prefix,&rest);
2793-
returnprefix_quals(leftop,opfamily,collation,prefix,pstatus);
2808+
returnprefix_quals(leftop,opfamily,idxcollation,prefix,pstatus);
27942809
}
27952810
break;
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 */
28032818
pstatus=pattern_fixed_prefix(patt,Pattern_Type_Regex,
28042819
&prefix,&rest);
2805-
returnprefix_quals(leftop,opfamily,collation,prefix,pstatus);
2820+
returnprefix_quals(leftop,opfamily,idxcollation,prefix,pstatus);
28062821
}
28072822
break;
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 */
28152830
pstatus=pattern_fixed_prefix(patt,Pattern_Type_Regex_IC,
28162831
&prefix,&rest);
2817-
returnprefix_quals(leftop,opfamily,collation,prefix,pstatus);
2832+
returnprefix_quals(leftop,opfamily,idxcollation,prefix,pstatus);
28182833
}
28192834
break;
28202835

@@ -2965,6 +2980,7 @@ expand_indexqual_rowcompare(RestrictInfo *rinfo,
29652980
largs_cell=lnext(largs_cell);
29662981
rargs_cell=lnext(rargs_cell);
29672982
opnos_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
*/
31643183
oproid=get_opfamily_member(opfamily,datatype,datatype,

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp