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

Commit066926d

Browse files
committed
Refactor some lsyscache routines to eliminate duplicate code and save
a couple of syscache lookups in make_pathkey_from_sortinfo().
1 parent98218e9 commit066926d

File tree

3 files changed

+105
-104
lines changed

3 files changed

+105
-104
lines changed

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

Lines changed: 16 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
* Portions Copyright (c) 1994, Regents of the University of California
1212
*
1313
* IDENTIFICATION
14-
* $PostgreSQL: pgsql/src/backend/optimizer/path/pathkeys.c,v 1.82 2007/01/20 20:45:39 tgl Exp $
14+
* $PostgreSQL: pgsql/src/backend/optimizer/path/pathkeys.c,v 1.83 2007/01/21 00:57:15 tgl Exp $
1515
*
1616
*-------------------------------------------------------------------------
1717
*/
@@ -240,13 +240,11 @@ make_pathkey_from_sortinfo(PlannerInfo *root,
240240
boolnulls_first,
241241
boolcanonicalize)
242242
{
243+
Oidopfamily,
244+
opcintype;
245+
int16strategy;
243246
Oidequality_op;
244247
List*opfamilies;
245-
Oidopfamily,
246-
lefttype,
247-
righttype;
248-
intstrategy;
249-
ListCell*lc;
250248
EquivalenceClass*eclass;
251249

252250
/*
@@ -258,7 +256,17 @@ make_pathkey_from_sortinfo(PlannerInfo *root,
258256
* easily be bigger. So, look up the equality operator that goes with
259257
* the ordering operator (this should be unique) and get its membership.
260258
*/
261-
equality_op=get_equality_op_for_ordering_op(ordering_op);
259+
260+
/* Find the operator in pg_amop --- failure shouldn't happen */
261+
if (!get_ordering_op_properties(ordering_op,
262+
&opfamily,&opcintype,&strategy))
263+
elog(ERROR,"operator %u is not a valid ordering operator",
264+
ordering_op);
265+
/* Get matching equality operator */
266+
equality_op=get_opfamily_member(opfamily,
267+
opcintype,
268+
opcintype,
269+
BTEqualStrategyNumber);
262270
if (!OidIsValid(equality_op))/* shouldn't happen */
263271
elog(ERROR,"could not find equality operator for ordering operator %u",
264272
ordering_op);
@@ -267,33 +275,8 @@ make_pathkey_from_sortinfo(PlannerInfo *root,
267275
elog(ERROR,"could not find opfamilies for ordering operator %u",
268276
ordering_op);
269277

270-
/*
271-
* Next we have to determine the strategy number to put into the pathkey.
272-
* In the presence of reverse-sort opclasses there might be two answers.
273-
* We prefer the one associated with the first opfamilies member that
274-
* this ordering_op appears in (this will be consistently defined in
275-
* normal system operation; see comments for get_mergejoin_opfamilies()).
276-
*/
277-
opfamily=InvalidOid;
278-
strategy=0;
279-
foreach(lc,opfamilies)
280-
{
281-
opfamily=lfirst_oid(lc);
282-
strategy=get_op_opfamily_strategy(ordering_op,opfamily);
283-
if (strategy)
284-
break;
285-
}
286-
if (!(strategy==BTLessStrategyNumber||
287-
strategy==BTGreaterStrategyNumber))
288-
elog(ERROR,"ordering operator %u is has wrong strategy number %d",
289-
ordering_op,strategy);
290-
291-
/* Need the declared input type of the operator, too */
292-
op_input_types(ordering_op,&lefttype,&righttype);
293-
Assert(lefttype==righttype);
294-
295278
/* Now find or create a matching EquivalenceClass */
296-
eclass=get_eclass_for_sort_expr(root,expr,lefttype,opfamilies);
279+
eclass=get_eclass_for_sort_expr(root,expr,opcintype,opfamilies);
297280

298281
/* And finally we can find or create a PathKey node */
299282
if (canonicalize)

‎src/backend/utils/cache/lsyscache.c

Lines changed: 86 additions & 70 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
* Portions Copyright (c) 1994, Regents of the University of California
88
*
99
* IDENTIFICATION
10-
* $PostgreSQL: pgsql/src/backend/utils/cache/lsyscache.c,v 1.144 2007/01/20 20:45:40 tgl Exp $
10+
* $PostgreSQL: pgsql/src/backend/utils/cache/lsyscache.c,v 1.145 2007/01/21 00:57:15 tgl Exp $
1111
*
1212
* NOTES
1313
* Eventually, the index information should go through here, too.
@@ -139,40 +139,41 @@ get_opfamily_member(Oid opfamily, Oid lefttype, Oid righttype,
139139
}
140140

141141
/*
142-
* get_compare_function_for_ordering_op
143-
*Get the OID of the datatype-specific btree comparison function
144-
*associated with an ordering operator (a "<" or ">" operator).
142+
* get_ordering_op_properties
143+
*Given the OID of an ordering operator (a btree "<" or ">" operator),
144+
*determine its opfamily, its declared input datatype, and its
145+
*strategy number (BTLessStrategyNumber or BTGreaterStrategyNumber).
145146
*
146-
* *cmpfunc receives the comparison function OID.
147-
* *reverse is set FALSE if the operator is "<", TRUE if it's ">"
148-
* (indicating the comparison result must be negated before use).
149-
*
150-
* Returns TRUE if successful, FALSE if no btree function can be found.
147+
* Returns TRUE if successful, FALSE if no matching pg_amop entry exists.
151148
* (This indicates that the operator is not a valid ordering operator.)
149+
*
150+
* Note: the operator could be registered in multiple families, for example
151+
* if someone were to build a "reverse sort" opfamily. This would result in
152+
* uncertainty as to whether "ORDER BY USING op" would default to NULLS FIRST
153+
* or NULLS LAST, as well as inefficient planning due to failure to match up
154+
* pathkeys that should be the same. So we want a determinate result here.
155+
* Because of the way the syscache search works, we'll use the interpretation
156+
* associated with the opfamily with smallest OID, which is probably
157+
* determinate enough. Since there is no longer any particularly good reason
158+
* to build reverse-sort opfamilies, it doesn't seem worth expending any
159+
* additional effort on ensuring consistency.
152160
*/
153161
bool
154-
get_compare_function_for_ordering_op(Oidopno,Oid*cmpfunc,bool*reverse)
162+
get_ordering_op_properties(Oidopno,
163+
Oid*opfamily,Oid*opcintype,int16*strategy)
155164
{
156165
boolresult= false;
157166
CatCList*catlist;
158167
inti;
159168

160-
/* ensure outputs are set on failure */
161-
*cmpfunc=InvalidOid;
162-
*reverse= false;
169+
/* ensure outputs are initialized on failure */
170+
*opfamily=InvalidOid;
171+
*opcintype=InvalidOid;
172+
*strategy=0;
163173

164174
/*
165175
* Search pg_amop to see if the target operator is registered as the "<"
166-
* or ">" operator of any btree opfamily. It's possible that it might be
167-
* registered both ways (if someone were to build a "reverse sort"
168-
* opfamily); assume we can use either interpretation. (Note: the
169-
* existence of a reverse-sort opfamily would result in uncertainty as
170-
* to whether "ORDER BY USING op" would default to NULLS FIRST or NULLS
171-
* LAST. Since there is no longer any particularly good reason to build
172-
* reverse-sort opfamilies, we don't bother expending any extra work to
173-
* make this more determinate. In practice, because of the way the
174-
* syscache search works, we'll use the interpretation associated with
175-
* the opfamily with smallest OID, which is probably determinate enough.)
176+
* or ">" operator of any btree opfamily.
176177
*/
177178
catlist=SearchSysCacheList(AMOPOPID,1,
178179
ObjectIdGetDatum(opno),
@@ -190,18 +191,16 @@ get_compare_function_for_ordering_op(Oid opno, Oid *cmpfunc, bool *reverse)
190191
if (aform->amopstrategy==BTLessStrategyNumber||
191192
aform->amopstrategy==BTGreaterStrategyNumber)
192193
{
193-
/* Found a suitable opfamily, get matching support function */
194-
*reverse= (aform->amopstrategy==BTGreaterStrategyNumber);
195-
*cmpfunc=get_opfamily_proc(aform->amopfamily,
196-
aform->amoplefttype,
197-
aform->amoprighttype,
198-
BTORDER_PROC);
199-
if (!OidIsValid(*cmpfunc))/* should not happen */
200-
elog(ERROR,"missing support function %d(%u,%u) in opfamily %u",
201-
BTORDER_PROC,aform->amoplefttype,aform->amoprighttype,
202-
aform->amopfamily);
203-
result= true;
204-
break;
194+
/* Found it ... should have consistent input types */
195+
if (aform->amoplefttype==aform->amoprighttype)
196+
{
197+
/* Found a suitable opfamily, return info */
198+
*opfamily=aform->amopfamily;
199+
*opcintype=aform->amoplefttype;
200+
*strategy=aform->amopstrategy;
201+
result= true;
202+
break;
203+
}
205204
}
206205
}
207206

@@ -210,6 +209,47 @@ get_compare_function_for_ordering_op(Oid opno, Oid *cmpfunc, bool *reverse)
210209
returnresult;
211210
}
212211

212+
/*
213+
* get_compare_function_for_ordering_op
214+
*Get the OID of the datatype-specific btree comparison function
215+
*associated with an ordering operator (a "<" or ">" operator).
216+
*
217+
* *cmpfunc receives the comparison function OID.
218+
* *reverse is set FALSE if the operator is "<", TRUE if it's ">"
219+
* (indicating the comparison result must be negated before use).
220+
*
221+
* Returns TRUE if successful, FALSE if no btree function can be found.
222+
* (This indicates that the operator is not a valid ordering operator.)
223+
*/
224+
bool
225+
get_compare_function_for_ordering_op(Oidopno,Oid*cmpfunc,bool*reverse)
226+
{
227+
Oidopfamily;
228+
Oidopcintype;
229+
int16strategy;
230+
231+
/* Find the operator in pg_amop */
232+
if (get_ordering_op_properties(opno,
233+
&opfamily,&opcintype,&strategy))
234+
{
235+
/* Found a suitable opfamily, get matching support function */
236+
*cmpfunc=get_opfamily_proc(opfamily,
237+
opcintype,
238+
opcintype,
239+
BTORDER_PROC);
240+
if (!OidIsValid(*cmpfunc))/* should not happen */
241+
elog(ERROR,"missing support function %d(%u,%u) in opfamily %u",
242+
BTORDER_PROC,opcintype,opcintype,opfamily);
243+
*reverse= (strategy==BTGreaterStrategyNumber);
244+
return true;
245+
}
246+
247+
/* ensure outputs are set on failure */
248+
*cmpfunc=InvalidOid;
249+
*reverse= false;
250+
return false;
251+
}
252+
213253
/*
214254
* get_equality_op_for_ordering_op
215255
*Get the OID of the datatype-specific btree equality operator
@@ -222,45 +262,21 @@ Oid
222262
get_equality_op_for_ordering_op(Oidopno)
223263
{
224264
Oidresult=InvalidOid;
225-
CatCList*catlist;
226-
inti;
265+
Oidopfamily;
266+
Oidopcintype;
267+
int16strategy;
227268

228-
/*
229-
* Search pg_amop to see if the target operator is registered as the "<"
230-
* or ">" operator of any btree opfamily. This is exactly like
231-
* get_compare_function_for_ordering_op except we don't care whether the
232-
* ordering op is "<" or ">" ... the equality operator will be the same
233-
* either way.
234-
*/
235-
catlist=SearchSysCacheList(AMOPOPID,1,
236-
ObjectIdGetDatum(opno),
237-
0,0,0);
238-
239-
for (i=0;i<catlist->n_members;i++)
269+
/* Find the operator in pg_amop */
270+
if (get_ordering_op_properties(opno,
271+
&opfamily,&opcintype,&strategy))
240272
{
241-
HeapTupletuple=&catlist->members[i]->tuple;
242-
Form_pg_amopaform= (Form_pg_amop)GETSTRUCT(tuple);
243-
244-
/* must be btree */
245-
if (aform->amopmethod!=BTREE_AM_OID)
246-
continue;
247-
248-
if (aform->amopstrategy==BTLessStrategyNumber||
249-
aform->amopstrategy==BTGreaterStrategyNumber)
250-
{
251-
/* Found a suitable opfamily, get matching equality operator */
252-
result=get_opfamily_member(aform->amopfamily,
253-
aform->amoplefttype,
254-
aform->amoprighttype,
255-
BTEqualStrategyNumber);
256-
if (OidIsValid(result))
257-
break;
258-
/* failure probably shouldn't happen, but keep looking if so */
259-
}
273+
/* Found a suitable opfamily, get matching equality operator */
274+
result=get_opfamily_member(opfamily,
275+
opcintype,
276+
opcintype,
277+
BTEqualStrategyNumber);
260278
}
261279

262-
ReleaseSysCacheList(catlist);
263-
264280
returnresult;
265281
}
266282

‎src/include/utils/lsyscache.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
* Portions Copyright (c) 1996-2007, PostgreSQL Global Development Group
77
* Portions Copyright (c) 1994, Regents of the University of California
88
*
9-
* $PostgreSQL: pgsql/src/include/utils/lsyscache.h,v 1.113 2007/01/20 20:45:41 tgl Exp $
9+
* $PostgreSQL: pgsql/src/include/utils/lsyscache.h,v 1.114 2007/01/21 00:57:15 tgl Exp $
1010
*
1111
*-------------------------------------------------------------------------
1212
*/
@@ -35,6 +35,8 @@ extern void get_op_opfamily_properties(Oid opno, Oid opfamily,
3535
bool*recheck);
3636
externOidget_opfamily_member(Oidopfamily,Oidlefttype,Oidrighttype,
3737
int16strategy);
38+
externboolget_ordering_op_properties(Oidopno,
39+
Oid*opfamily,Oid*opcintype,int16*strategy);
3840
externboolget_compare_function_for_ordering_op(Oidopno,
3941
Oid*cmpfunc,bool*reverse);
4042
externOidget_equality_op_for_ordering_op(Oidopno);

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp