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

Commit5f68d5c

Browse files
committed
Clean up loose end in LIKE optimization fix: parser's code would generate
<= and >= indexquals from a LIKE even if the index in question didn'tsupport those operators. (As, for example, a hash index does not.)
1 parent2784a5a commit5f68d5c

File tree

1 file changed

+115
-54
lines changed

1 file changed

+115
-54
lines changed

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

Lines changed: 115 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
*
99
*
1010
* IDENTIFICATION
11-
* $Header: /cvsroot/pgsql/src/backend/optimizer/path/indxpath.c,v 1.73 1999/11/22 17:56:07 momjian Exp $
11+
* $Header: /cvsroot/pgsql/src/backend/optimizer/path/indxpath.c,v 1.74 1999/12/31 03:41:03 tgl Exp $
1212
*
1313
*-------------------------------------------------------------------------
1414
*/
@@ -44,24 +44,30 @@ typedef enum {
4444
Prefix_None,Prefix_Partial,Prefix_Exact
4545
}Prefix_Status;
4646

47-
staticvoidmatch_index_orclauses(RelOptInfo*rel,RelOptInfo*index,intindexkey,
48-
intxclass,List*restrictinfo_list);
49-
staticList*match_index_orclause(RelOptInfo*rel,RelOptInfo*index,intindexkey,
50-
intxclass,List*or_clauses,List*other_matching_indices);
47+
staticvoidmatch_index_orclauses(RelOptInfo*rel,RelOptInfo*index,
48+
intindexkey,Oidopclass,
49+
List*restrictinfo_list);
50+
staticList*match_index_orclause(RelOptInfo*rel,RelOptInfo*index,
51+
intindexkey,Oidopclass,
52+
List*or_clauses,
53+
List*other_matching_indices);
5154
staticboolmatch_or_subclause_to_indexkey(RelOptInfo*rel,RelOptInfo*index,
52-
intindexkey,intxclass,
55+
intindexkey,Oidopclass,
5356
Expr*clause);
5457
staticList*group_clauses_by_indexkey(RelOptInfo*rel,RelOptInfo*index,
55-
int*indexkeys,Oid*classes,List*restrictinfo_list);
58+
int*indexkeys,Oid*classes,
59+
List*restrictinfo_list);
5660
staticList*group_clauses_by_ikey_for_joins(RelOptInfo*rel,RelOptInfo*index,
57-
int*indexkeys,Oid*classes,List*join_cinfo_list,List*restr_cinfo_list);
61+
int*indexkeys,Oid*classes,
62+
List*join_cinfo_list,
63+
List*restr_cinfo_list);
5864
staticboolmatch_clause_to_indexkey(RelOptInfo*rel,RelOptInfo*index,
59-
intindexkey,intxclass,
65+
intindexkey,Oidopclass,
6066
Expr*clause,booljoin);
61-
staticboolindexable_operator(Expr*clause,intxclass,Oidrelam,
67+
staticboolindexable_operator(Expr*clause,Oidopclass,Oidrelam,
6268
boolindexkey_on_left);
6369
staticboolpred_test(List*predicate_list,List*restrictinfo_list,
64-
List*joininfo_list);
70+
List*joininfo_list);
6571
staticboolone_pred_test(Expr*predicate,List*restrictinfo_list);
6672
staticboolone_pred_clause_expr_test(Expr*predicate,Node*clause);
6773
staticboolone_pred_clause_test(Expr*predicate,Node*clause);
@@ -77,13 +83,16 @@ static bool useful_for_ordering(Query *root, RelOptInfo *rel,
7783
RelOptInfo*index);
7884
staticboolmatch_index_to_operand(intindexkey,Var*operand,
7985
RelOptInfo*rel,RelOptInfo*index);
80-
staticboolfunction_index_operand(Expr*funcOpnd,RelOptInfo*rel,RelOptInfo*index);
81-
staticboolmatch_special_index_operator(Expr*clause,boolindexkey_on_left);
86+
staticboolfunction_index_operand(Expr*funcOpnd,RelOptInfo*rel,
87+
RelOptInfo*index);
88+
staticboolmatch_special_index_operator(Expr*clause,Oidopclass,Oidrelam,
89+
boolindexkey_on_left);
8290
staticPrefix_Statuslike_fixed_prefix(char*patt,char**prefix);
8391
staticPrefix_Statusregex_fixed_prefix(char*patt,boolcase_insensitive,
8492
char**prefix);
8593
staticList*prefix_quals(Var*leftop,Oidexpr_op,
8694
char*prefix,Prefix_Statuspstatus);
95+
staticOidfind_operator(constchar*opname,Oiddatatype);
8796

8897

8998
/*
@@ -255,7 +264,7 @@ static void
255264
match_index_orclauses(RelOptInfo*rel,
256265
RelOptInfo*index,
257266
intindexkey,
258-
intxclass,
267+
Oidopclass,
259268
List*restrictinfo_list)
260269
{
261270
List*i;
@@ -272,7 +281,7 @@ match_index_orclauses(RelOptInfo *rel,
272281
*/
273282
restrictinfo->subclauseindices=
274283
match_index_orclause(rel,index,
275-
indexkey,xclass,
284+
indexkey,opclass,
276285
restrictinfo->clause->args,
277286
restrictinfo->subclauseindices);
278287
}
@@ -304,7 +313,7 @@ static List *
304313
match_index_orclause(RelOptInfo*rel,
305314
RelOptInfo*index,
306315
intindexkey,
307-
intxclass,
316+
Oidopclass,
308317
List*or_clauses,
309318
List*other_matching_indices)
310319
{
@@ -330,7 +339,7 @@ match_index_orclause(RelOptInfo *rel,
330339
{
331340
Expr*clause=lfirst(clist);
332341

333-
if (match_or_subclause_to_indexkey(rel,index,indexkey,xclass,
342+
if (match_or_subclause_to_indexkey(rel,index,indexkey,opclass,
334343
clause))
335344
{
336345
/* OK to add this index to sublist for this subclause */
@@ -355,7 +364,7 @@ static bool
355364
match_or_subclause_to_indexkey(RelOptInfo*rel,
356365
RelOptInfo*index,
357366
intindexkey,
358-
intxclass,
367+
Oidopclass,
359368
Expr*clause)
360369
{
361370
if (and_clause((Node*)clause))
@@ -364,14 +373,14 @@ match_or_subclause_to_indexkey(RelOptInfo *rel,
364373

365374
foreach(item,clause->args)
366375
{
367-
if (!match_clause_to_indexkey(rel,index,indexkey,xclass,
376+
if (!match_clause_to_indexkey(rel,index,indexkey,opclass,
368377
lfirst(item), false))
369378
return false;
370379
}
371380
return true;
372381
}
373382
else
374-
returnmatch_clause_to_indexkey(rel,index,indexkey,xclass,
383+
returnmatch_clause_to_indexkey(rel,index,indexkey,opclass,
375384
clause, false);
376385
}
377386

@@ -588,7 +597,7 @@ group_clauses_by_ikey_for_joins(RelOptInfo *rel,
588597
* 'rel' is the relation of interest.
589598
* 'index' is an index on 'rel'.
590599
* 'indexkey' is a key of 'index'.
591-
* 'xclass' is the corresponding operator class.
600+
* 'opclass' is the corresponding operator class.
592601
* 'clause' is the clause to be tested.
593602
* 'join' is true if we are considering this clause for joins.
594603
*
@@ -601,7 +610,7 @@ static bool
601610
match_clause_to_indexkey(RelOptInfo*rel,
602611
RelOptInfo*index,
603612
intindexkey,
604-
intxclass,
613+
Oidopclass,
605614
Expr*clause,
606615
booljoin)
607616
{
@@ -627,26 +636,28 @@ match_clause_to_indexkey(RelOptInfo *rel,
627636
if ((IsA(rightop,Const)||IsA(rightop,Param))&&
628637
match_index_to_operand(indexkey,leftop,rel,index))
629638
{
630-
if (indexable_operator(clause,xclass,index->relam, true))
639+
if (indexable_operator(clause,opclass,index->relam, true))
631640
return true;
632641
/*
633642
* If we didn't find a member of the index's opclass,
634643
* see whether it is a "special" indexable operator.
635644
*/
636-
if (match_special_index_operator(clause, true))
645+
if (match_special_index_operator(clause,opclass,index->relam,
646+
true))
637647
return true;
638648
return false;
639649
}
640650
if ((IsA(leftop,Const)||IsA(leftop,Param))&&
641651
match_index_to_operand(indexkey,rightop,rel,index))
642652
{
643-
if (indexable_operator(clause,xclass,index->relam, false))
653+
if (indexable_operator(clause,opclass,index->relam, false))
644654
return true;
645655
/*
646656
* If we didn't find a member of the index's opclass,
647657
* see whether it is a "special" indexable operator.
648658
*/
649-
if (match_special_index_operator(clause, false))
659+
if (match_special_index_operator(clause,opclass,index->relam,
660+
false))
650661
return true;
651662
return false;
652663
}
@@ -666,7 +677,7 @@ match_clause_to_indexkey(RelOptInfo *rel,
666677
isIndexable= !intMember(lfirsti(rel->relids),othervarnos);
667678
freeList(othervarnos);
668679
if (isIndexable&&
669-
indexable_operator(clause,xclass,index->relam, true))
680+
indexable_operator(clause,opclass,index->relam, true))
670681
return true;
671682
}
672683
elseif (match_index_to_operand(indexkey,rightop,rel,index))
@@ -677,7 +688,7 @@ match_clause_to_indexkey(RelOptInfo *rel,
677688
isIndexable= !intMember(lfirsti(rel->relids),othervarnos);
678689
freeList(othervarnos);
679690
if (isIndexable&&
680-
indexable_operator(clause,xclass,index->relam, false))
691+
indexable_operator(clause,opclass,index->relam, false))
681692
return true;
682693
}
683694
}
@@ -706,7 +717,7 @@ match_clause_to_indexkey(RelOptInfo *rel,
706717
* a tad ugly...
707718
*/
708719
staticbool
709-
indexable_operator(Expr*clause,intxclass,Oidrelam,
720+
indexable_operator(Expr*clause,Oidopclass,Oidrelam,
710721
boolindexkey_on_left)
711722
{
712723
Oidexpr_op= ((Oper*)clause->oper)->opno;
@@ -723,7 +734,7 @@ indexable_operator(Expr *clause, int xclass, Oid relam,
723734
return false;
724735

725736
/* Done if the (commuted) operator is a member of the index's AM */
726-
if (op_class(commuted_op,xclass,relam))
737+
if (op_class(commuted_op,opclass,relam))
727738
return true;
728739

729740
/*
@@ -766,7 +777,7 @@ indexable_operator(Expr *clause, int xclass, Oid relam,
766777
if (commuted_op==InvalidOid)
767778
return false;
768779

769-
if (op_class(commuted_op,xclass,relam))
780+
if (op_class(commuted_op,opclass,relam))
770781
{
771782
/*
772783
* Success! Change the opclause to use the
@@ -1561,7 +1572,8 @@ function_index_operand(Expr *funcOpnd, RelOptInfo *rel, RelOptInfo *index)
15611572
* Return 'true' if we can do something with it anyway.
15621573
*/
15631574
staticbool
1564-
match_special_index_operator(Expr*clause,boolindexkey_on_left)
1575+
match_special_index_operator(Expr*clause,Oidopclass,Oidrelam,
1576+
boolindexkey_on_left)
15651577
{
15661578
boolisIndexable= false;
15671579
Var*leftop,
@@ -1625,6 +1637,51 @@ match_special_index_operator(Expr *clause, bool indexkey_on_left)
16251637
break;
16261638
}
16271639

1640+
/* done if the expression doesn't look indexable */
1641+
if (!isIndexable)
1642+
return false;
1643+
1644+
/*
1645+
* Must also check that index's opclass supports the operators we will
1646+
* want to apply. (A hash index, for example, will not support ">=".)
1647+
* We cheat a little by not checking for availability of "=" ... any
1648+
* index type should support "=", methinks.
1649+
*/
1650+
switch (expr_op)
1651+
{
1652+
caseOID_TEXT_LIKE_OP:
1653+
caseOID_TEXT_REGEXEQ_OP:
1654+
caseOID_TEXT_ICREGEXEQ_OP:
1655+
if (!op_class(find_operator(">=",TEXTOID),opclass,relam)||
1656+
!op_class(find_operator("<=",TEXTOID),opclass,relam))
1657+
isIndexable= false;
1658+
break;
1659+
1660+
caseOID_BPCHAR_LIKE_OP:
1661+
caseOID_BPCHAR_REGEXEQ_OP:
1662+
caseOID_BPCHAR_ICREGEXEQ_OP:
1663+
if (!op_class(find_operator(">=",BPCHAROID),opclass,relam)||
1664+
!op_class(find_operator("<=",BPCHAROID),opclass,relam))
1665+
isIndexable= false;
1666+
break;
1667+
1668+
caseOID_VARCHAR_LIKE_OP:
1669+
caseOID_VARCHAR_REGEXEQ_OP:
1670+
caseOID_VARCHAR_ICREGEXEQ_OP:
1671+
if (!op_class(find_operator(">=",VARCHAROID),opclass,relam)||
1672+
!op_class(find_operator("<=",VARCHAROID),opclass,relam))
1673+
isIndexable= false;
1674+
break;
1675+
1676+
caseOID_NAME_LIKE_OP:
1677+
caseOID_NAME_REGEXEQ_OP:
1678+
caseOID_NAME_ICREGEXEQ_OP:
1679+
if (!op_class(find_operator(">=",NAMEOID),opclass,relam)||
1680+
!op_class(find_operator("<=",NAMEOID),opclass,relam))
1681+
isIndexable= false;
1682+
break;
1683+
}
1684+
16281685
returnisIndexable;
16291686
}
16301687

@@ -1848,7 +1905,7 @@ prefix_quals(Var *leftop, Oid expr_op,
18481905
{
18491906
List*result;
18501907
Oiddatatype;
1851-
HeapTupleoptup;
1908+
Oidoproid;
18521909
void*conval;
18531910
Const*con;
18541911
Oper*op;
@@ -1893,12 +1950,8 @@ prefix_quals(Var *leftop, Oid expr_op,
18931950
*/
18941951
if (pstatus==Prefix_Exact)
18951952
{
1896-
optup=SearchSysCacheTuple(OPERNAME,
1897-
PointerGetDatum("="),
1898-
ObjectIdGetDatum(datatype),
1899-
ObjectIdGetDatum(datatype),
1900-
CharGetDatum('b'));
1901-
if (!HeapTupleIsValid(optup))
1953+
oproid=find_operator("=",datatype);
1954+
if (oproid==InvalidOid)
19021955
elog(ERROR,"prefix_quals: no = operator for type %u",datatype);
19031956
/* Note: we cheat a little by assuming that textin() will do for
19041957
* bpchar and varchar constants too...
@@ -1908,7 +1961,7 @@ prefix_quals(Var *leftop, Oid expr_op,
19081961
con=makeConst(datatype, ((datatype==NAMEOID) ?NAMEDATALEN :-1),
19091962
PointerGetDatum(conval),
19101963
false, false, false, false);
1911-
op=makeOper(optup->t_data->t_oid,InvalidOid,BOOLOID,0,NULL);
1964+
op=makeOper(oproid,InvalidOid,BOOLOID,0,NULL);
19121965
expr=make_opclause(op,leftop, (Var*)con);
19131966
result=lcons(expr,NIL);
19141967
returnresult;
@@ -1919,19 +1972,15 @@ prefix_quals(Var *leftop, Oid expr_op,
19191972
*
19201973
* We can always say "x >= prefix".
19211974
*/
1922-
optup=SearchSysCacheTuple(OPERNAME,
1923-
PointerGetDatum(">="),
1924-
ObjectIdGetDatum(datatype),
1925-
ObjectIdGetDatum(datatype),
1926-
CharGetDatum('b'));
1927-
if (!HeapTupleIsValid(optup))
1975+
oproid=find_operator(">=",datatype);
1976+
if (oproid==InvalidOid)
19281977
elog(ERROR,"prefix_quals: no >= operator for type %u",datatype);
19291978
conval= (datatype==NAMEOID) ?
19301979
(void*)namein(prefix) : (void*)textin(prefix);
19311980
con=makeConst(datatype, ((datatype==NAMEOID) ?NAMEDATALEN :-1),
19321981
PointerGetDatum(conval),
19331982
false, false, false, false);
1934-
op=makeOper(optup->t_data->t_oid,InvalidOid,BOOLOID,0,NULL);
1983+
op=makeOper(oproid,InvalidOid,BOOLOID,0,NULL);
19351984
expr=make_opclause(op,leftop, (Var*)con);
19361985
result=lcons(expr,NIL);
19371986

@@ -1947,22 +1996,34 @@ prefix_quals(Var *leftop, Oid expr_op,
19471996
prefix[prefixlen]='\377';
19481997
prefix[prefixlen+1]='\0';
19491998

1950-
optup=SearchSysCacheTuple(OPERNAME,
1951-
PointerGetDatum("<="),
1952-
ObjectIdGetDatum(datatype),
1953-
ObjectIdGetDatum(datatype),
1954-
CharGetDatum('b'));
1955-
if (!HeapTupleIsValid(optup))
1999+
oproid=find_operator("<=",datatype);
2000+
if (oproid==InvalidOid)
19562001
elog(ERROR,"prefix_quals: no <= operator for type %u",datatype);
19572002
conval= (datatype==NAMEOID) ?
19582003
(void*)namein(prefix) : (void*)textin(prefix);
19592004
con=makeConst(datatype, ((datatype==NAMEOID) ?NAMEDATALEN :-1),
19602005
PointerGetDatum(conval),
19612006
false, false, false, false);
1962-
op=makeOper(optup->t_data->t_oid,InvalidOid,BOOLOID,0,NULL);
2007+
op=makeOper(oproid,InvalidOid,BOOLOID,0,NULL);
19632008
expr=make_opclause(op,leftop, (Var*)con);
19642009
result=lappend(result,expr);
19652010
#endif
19662011

19672012
returnresult;
19682013
}
2014+
2015+
/* See if there is a binary op of the given name for the given datatype */
2016+
staticOid
2017+
find_operator(constchar*opname,Oiddatatype)
2018+
{
2019+
HeapTupleoptup;
2020+
2021+
optup=SearchSysCacheTuple(OPERNAME,
2022+
PointerGetDatum(opname),
2023+
ObjectIdGetDatum(datatype),
2024+
ObjectIdGetDatum(datatype),
2025+
CharGetDatum('b'));
2026+
if (!HeapTupleIsValid(optup))
2027+
returnInvalidOid;
2028+
returnoptup->t_data->t_oid;
2029+
}

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp