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

Commit6912bee

Browse files
author
Thomas G. Lockhart
committed
Allow binary-compatible indices to be considered when checking for valid
indices for restriction clauses containing a constant.Note that if an index does not match directly (usually because the types on both side of the clause don't match), and if a binary-compatible index is identified, then the operator function will be replaced by a new one. Should not be a problem, but be sure that if types are listed as being binary compatible (in parse_coerce.h) then the comparison functions are also binary-compatible, giving equivalent results.
1 parent94f42ed commit6912bee

File tree

1 file changed

+115
-24
lines changed

1 file changed

+115
-24
lines changed

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

Lines changed: 115 additions & 24 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.28 1998/08/11 19:32:37 momjian Exp $
11+
* $Header: /cvsroot/pgsql/src/backend/optimizer/path/indxpath.c,v 1.29 1998/08/14 16:13:07 thomas Exp $
1212
*
1313
*-------------------------------------------------------------------------
1414
*/
@@ -39,6 +39,9 @@
3939
#include"optimizer/pathnode.h"
4040
#include"optimizer/xfunc.h"
4141
#include"parser/parsetree.h"/* for getrelid() */
42+
#include"parser/parse_expr.h"/* for exprType() */
43+
#include"parser/parse_oper.h"/* for oprid() and oper() */
44+
#include"parser/parse_coerce.h"/* for IS_BINARY_COMPATIBLE() */
4245
#include"utils/lsyscache.h"
4346

4447

@@ -80,8 +83,7 @@ static List *add_index_paths(List *indexpaths, List *new_indexpaths);
8083
staticboolfunction_index_operand(Expr*funcOpnd,RelOptInfo*rel,RelOptInfo*index);
8184

8285

83-
/*
84-
* find-index-paths--
86+
/* find_index_paths()
8587
* Finds all possible index paths by determining which indices in the
8688
* list 'indices' are usable.
8789
*
@@ -120,16 +122,16 @@ find_index_paths(Query *root,
120122
List*joinpaths=NIL;
121123
List*retval=NIL;
122124
List*ilist;
123-
125+
124126
foreach(ilist,indices)
125127
{
126128
index= (RelOptInfo*)lfirst(ilist);
127-
129+
128130
/* If this is a partial index, return if it fails the predicate test */
129131
if (index->indpred!=NIL)
130132
if (!pred_test(index->indpred,clauseinfo_list,joininfo_list))
131133
continue;
132-
134+
133135
/*
134136
* 1. Try matching the index against subclauses of an 'or' clause.
135137
* The fields of the clauseinfo nodes are marked with lists of the
@@ -143,7 +145,7 @@ find_index_paths(Query *root,
143145
index->indexkeys[0],
144146
index->classlist[0],
145147
clauseinfo_list);
146-
148+
147149
/*
148150
* 2. If the keys of this index match any of the available restriction
149151
* clauses, then create pathnodes corresponding to each group of
@@ -154,15 +156,15 @@ find_index_paths(Query *root,
154156
index->indexkeys,
155157
index->classlist,
156158
clauseinfo_list);
157-
159+
158160
scanpaths=NIL;
159161
if (scanclausegroups!=NIL)
160162
scanpaths=create_index_paths(root,
161163
rel,
162164
index,
163165
scanclausegroups,
164166
false);
165-
167+
166168
/*
167169
* 3. If this index can be used with any join clause, then create
168170
* pathnodes for each group of usable clauses.An index can be used
@@ -172,19 +174,19 @@ find_index_paths(Query *root,
172174
*/
173175
joinclausegroups=indexable_joinclauses(rel,index,joininfo_list,clauseinfo_list);
174176
joinpaths=NIL;
175-
177+
176178
if (joinclausegroups!=NIL)
177179
{
178180
List*new_join_paths=create_index_paths(root,rel,
179181
index,
180182
joinclausegroups,
181183
true);
182184
List*innerjoin_paths=index_innerjoin(root,rel,joinclausegroups,index);
183-
185+
184186
rel->innerjoin=nconc(rel->innerjoin,innerjoin_paths);
185187
joinpaths=new_join_paths;
186188
}
187-
189+
188190
/*
189191
* Some sanity checks to make sure that the indexpath is valid.
190192
*/
@@ -193,7 +195,7 @@ find_index_paths(Query *root,
193195
if (scanpaths!=NULL)
194196
retval=add_index_paths(scanpaths,retval);
195197
}
196-
198+
197199
returnretval;
198200

199201
}
@@ -252,8 +254,7 @@ match_index_orclauses(RelOptInfo *rel,
252254
}
253255
}
254256

255-
/*
256-
* match_index_operand--
257+
/* match_index_to_operand()
257258
* Generalize test for a match between an existing index's key
258259
* and the operand on the rhs of a restriction clause. Now check
259260
* for functional indices as well.
@@ -264,17 +265,22 @@ match_index_to_operand(int indexkey,
264265
RelOptInfo*rel,
265266
RelOptInfo*index)
266267
{
268+
boolresult;
267269

268270
/*
269271
* Normal index.
270272
*/
271273
if (index->indproc==InvalidOid)
272-
returnmatch_indexkey_operand(indexkey, (Var*)operand,rel);
274+
{
275+
result=match_indexkey_operand(indexkey, (Var*)operand,rel);
276+
returnresult;
277+
}
273278

274279
/*
275280
* functional index check
276281
*/
277-
return (function_index_operand(operand,rel,index));
282+
result=function_index_operand(operand,rel,index);
283+
returnresult;
278284
}
279285

280286
/*
@@ -320,7 +326,7 @@ match_index_orclause(RelOptInfo *rel,
320326
elsematching_indices=other_matching_indices;
321327

322328
index_list=matching_indices;
323-
329+
324330
foreach(clist,or_clauses)
325331
{
326332
clause=lfirst(clist);
@@ -555,8 +561,7 @@ group_clauses_by_ikey_for_joins(RelOptInfo *rel,
555561
* - vadim 01/22/97
556562
*/
557563

558-
/*
559-
* match_clause_to-indexkey--
564+
/* match_clause_to_indexkey()
560565
* Finds the first of a relation's available restriction clauses that
561566
* matches a key of an index.
562567
*
@@ -609,11 +614,56 @@ match_clause_to_indexkey(RelOptInfo *rel,
609614
(rightop&&IsA(rightop,Param)))
610615
{
611616
restrict_op= ((Oper*) ((Expr*)clause)->oper)->opno;
617+
612618
isIndexable= (op_class(restrict_op,xclass,index->relam)&&
613-
IndexScanableOperand(leftop,
619+
IndexScanableOperand(leftop,
620+
indexkey,
621+
rel,
622+
index));
623+
624+
#ifndefIGNORE_BINARY_COMPATIBLE_INDICES
625+
/* Didn't find an index?
626+
* Then maybe we can find another binary-compatible index instead...
627+
* thomas 1998-08-14
628+
*/
629+
if (!isIndexable)
630+
{
631+
Oidltype;
632+
Oidrtype;
633+
634+
ltype=exprType((Node*)leftop);
635+
rtype=exprType((Node*)rightop);
636+
637+
/* make sure we have two different binary-compatible types... */
638+
if ((ltype!=rtype)
639+
&&IS_BINARY_COMPATIBLE(ltype,rtype))
640+
{
641+
char*opname;
642+
Operatornewop;
643+
644+
opname=get_opname(restrict_op);
645+
newop=oper(opname,ltype,ltype, TRUE);
646+
647+
/* actually have a different operator to try? */
648+
if (HeapTupleIsValid(newop)&& (oprid(newop)!=restrict_op))
649+
{
650+
restrict_op=oprid(newop);
651+
652+
isIndexable=
653+
(op_class(restrict_op,xclass,index->relam)&&
654+
IndexScanableOperand(leftop,
614655
indexkey,
615656
rel,
616657
index));
658+
659+
if (isIndexable)
660+
{
661+
((Oper*) ((Expr*)clause)->oper)->opno=restrict_op;
662+
}
663+
}
664+
}
665+
}
666+
#endif
617667
}
618668

619669
/*
@@ -625,13 +675,54 @@ match_clause_to_indexkey(RelOptInfo *rel,
625675
restrict_op=
626676
get_commutator(((Oper*) ((Expr*)clause)->oper)->opno);
627677

628-
if ((restrict_op!=InvalidOid)&&
678+
isIndexable= ((restrict_op!=InvalidOid)&&
629679
op_class(restrict_op,xclass,index->relam)&&
630680
IndexScanableOperand(rightop,
631-
indexkey,rel,index))
681+
indexkey,rel,index));
682+
683+
#ifndefIGNORE_BINARY_COMPATIBLE_INDICES
684+
if (!isIndexable)
632685
{
633-
isIndexable= true;
686+
Oidltype;
687+
Oidrtype;
688+
689+
ltype=exprType((Node*)leftop);
690+
rtype=exprType((Node*)rightop);
691+
692+
if ((ltype!=rtype)
693+
&&IS_BINARY_COMPATIBLE(ltype,rtype))
694+
{
695+
char*opname;
696+
Operatornewop;
697+
698+
restrict_op= ((Oper*) ((Expr*)clause)->oper)->opno;
699+
700+
opname=get_opname(restrict_op);
701+
newop=oper(opname,rtype,rtype, TRUE);
702+
703+
if (HeapTupleIsValid(newop)&& (oprid(newop)!=restrict_op))
704+
{
705+
restrict_op=
706+
get_commutator(oprid(newop));
707+
708+
isIndexable= ((restrict_op!=InvalidOid)&&
709+
op_class(restrict_op,xclass,index->relam)&&
710+
IndexScanableOperand(rightop,
711+
indexkey,
712+
rel,
713+
index));
714+
715+
if (isIndexable)
716+
{
717+
((Oper*) ((Expr*)clause)->oper)->opno=oprid(newop);
718+
}
719+
}
720+
}
721+
}
722+
#endif
634723

724+
if (isIndexable)
725+
{
635726
/*
636727
* In place list modification. (op const var/func) -> (op
637728
* var/func const)

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp