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

Commit610dfa6

Browse files
committed
Combine index_info and find_secondary_indexes into a single routine that
returns a list of RelOptInfos, eliminating the need for static statein index_info. That static state was a direct cause of coredumps; ifanything decided to elog(ERROR) partway through an index_info search ofpg_index, the next query would try to close a scan pointer that waspointing at no-longer-valid memory. Another example of the reasons toavoid static state variables...
1 parent40d3e92 commit610dfa6

File tree

3 files changed

+115
-214
lines changed

3 files changed

+115
-214
lines changed

‎src/backend/optimizer/util/indexnode.c

Lines changed: 2 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -7,21 +7,16 @@
77
*
88
*
99
* IDENTIFICATION
10-
* $Header: /cvsroot/pgsql/src/backend/optimizer/util/Attic/indexnode.c,v 1.20 1999/08/16 02:17:57 tgl Exp $
10+
* $Header: /cvsroot/pgsql/src/backend/optimizer/util/Attic/indexnode.c,v 1.21 1999/11/21 23:25:47 tgl Exp $
1111
*
1212
*-------------------------------------------------------------------------
1313
*/
14-
#include<sys/types.h>
15-
1614
#include"postgres.h"
1715

18-
1916
#include"optimizer/pathnode.h"
2017
#include"optimizer/plancat.h"
2118

2219

23-
staticList*find_secondary_index(Query*root,Oidrelid);
24-
2520
/*
2621
* find_relation_indices
2722
* Returns a list of index nodes containing appropriate information for
@@ -32,56 +27,7 @@ List *
3227
find_relation_indices(Query*root,RelOptInfo*rel)
3328
{
3429
if (rel->indexed)
35-
returnfind_secondary_index(root,lfirsti(rel->relids));
30+
returnfind_secondary_indexes(root,lfirsti(rel->relids));
3631
else
3732
returnNIL;
3833
}
39-
40-
/*
41-
* find_secondary_index
42-
* Creates a list of RelOptInfo nodes containing information for each
43-
* secondary index defined on a relation by searching through the index
44-
* catalog.
45-
*
46-
* 'relid' is the OID of the relation for which indices are being located
47-
*
48-
* Returns a list of new index RelOptInfo nodes.
49-
*/
50-
staticList*
51-
find_secondary_index(Query*root,Oidrelid)
52-
{
53-
IdxInfoRetvalindexinfo;
54-
List*indexes=NIL;
55-
boolfirst= true;
56-
57-
while (index_info(root,first,relid,&indexinfo))
58-
{
59-
RelOptInfo*indexnode=makeNode(RelOptInfo);
60-
61-
indexnode->relids=lconsi(indexinfo.relid,NIL);
62-
indexnode->relam=indexinfo.relam;
63-
indexnode->pages=indexinfo.pages;
64-
indexnode->tuples=indexinfo.tuples;
65-
indexnode->classlist=indexinfo.classlist;
66-
indexnode->indexkeys=indexinfo.indexkeys;
67-
indexnode->ordering=indexinfo.orderOprs;
68-
indexnode->indproc=indexinfo.indproc;
69-
indexnode->indpred= (List*)indexinfo.indpred;
70-
71-
indexnode->indexed= false;/* not indexed itself */
72-
indexnode->size=0;
73-
indexnode->width=0;
74-
indexnode->targetlist=NIL;
75-
indexnode->pathlist=NIL;
76-
indexnode->cheapestpath=NULL;
77-
indexnode->pruneable= true;
78-
indexnode->restrictinfo=NIL;
79-
indexnode->joininfo=NIL;
80-
indexnode->innerjoin=NIL;
81-
82-
indexes=lcons(indexnode,indexes);
83-
first= false;
84-
}
85-
86-
returnindexes;
87-
}

‎src/backend/optimizer/util/plancat.c

Lines changed: 107 additions & 131 deletions
Original file line numberDiff line numberDiff line change
@@ -8,13 +8,14 @@
88
*
99
*
1010
* IDENTIFICATION
11-
* $Header: /cvsroot/pgsql/src/backend/optimizer/util/plancat.c,v 1.38 1999/09/18 19:07:06 tgl Exp $
11+
* $Header: /cvsroot/pgsql/src/backend/optimizer/util/plancat.c,v 1.39 1999/11/21 23:25:47 tgl Exp $
1212
*
1313
*-------------------------------------------------------------------------
1414
*/
1515
#include<math.h>
1616

1717
#include"postgres.h"
18+
1819
#include"access/genam.h"
1920
#include"access/heapam.h"
2021
#include"catalog/catname.h"
@@ -38,8 +39,8 @@ static void IndexSelectivity(Oid indexrelid, Oid baserelid, int nIndexKeys,
3839

3940
/*
4041
* relation_info -
41-
* Retrieves catalog information for a given relation. Given the oid of
42-
* the relation, return the followinginformation:
42+
* Retrieves catalog information for a given relation.
43+
*Giventherangetable index of therelation, return the followinginfo:
4344
*whether the relation has secondary indices
4445
*number of pages
4546
*number of tuples
@@ -54,166 +55,141 @@ relation_info(Query *root, Index relid,
5455

5556
relationObjectId=getrelid(relid,root->rtable);
5657
relationTuple=SearchSysCacheTuple(RELOID,
57-
ObjectIdGetDatum(relationObjectId),
58+
ObjectIdGetDatum(relationObjectId),
5859
0,0,0);
5960
if (HeapTupleIsValid(relationTuple))
6061
{
6162
relation= (Form_pg_class)GETSTRUCT(relationTuple);
6263

63-
*hasindex= (relation->relhasindex) ?TRUE :FALSE;
64+
*hasindex= (relation->relhasindex) ?true :false;
6465
*pages=relation->relpages;
6566
*tuples=relation->reltuples;
6667
}
6768
else
6869
{
69-
elog(ERROR,"RelationCatalogInformation: Relation %u not found",
70+
elog(ERROR,"relation_info: Relation %u not found",
7071
relationObjectId);
7172
}
72-
73-
return;
7473
}
7574

76-
7775
/*
78-
* index_info
79-
* Retrieves catalog information on an index on a given relation.
76+
* find_secondary_indexes
77+
* Creates a list of RelOptInfo nodes containing information for each
78+
* secondary index defined on the given relation.
8079
*
81-
* The index relation is opened on the first invocation. The current
82-
* retrieves the next index relation within the catalog that has not
83-
* already been retrieved by a previous call. The index catalog
84-
* is closed when no more indices for 'relid' can be found.
85-
*
86-
* 'first' is 1 if this is the first call
87-
*
88-
* Returns true if successful and false otherwise. Index info is returned
89-
* via the transient data structure 'info'.
80+
* 'relid' is the RT index of the relation for which indices are being located
9081
*
82+
* Returns a list of new index RelOptInfo nodes.
9183
*/
92-
bool
93-
index_info(Query*root,boolfirst,intrelid,IdxInfoRetval*info)
84+
List*
85+
find_secondary_indexes(Query*root,Indexrelid)
9486
{
95-
inti;
96-
HeapTupleindexTuple,
97-
amopTuple;
98-
Form_pg_indexindex;
99-
RelationindexRelation;
100-
uint16amstrategy;
101-
Oidrelam;
102-
Oidindrelid;
103-
104-
staticRelationrelation= (Relation)NULL;
105-
staticHeapScanDescscan= (HeapScanDesc)NULL;
106-
staticScanKeyDataindexKey;
87+
List*indexes=NIL;
88+
Oidindrelid=getrelid(relid,root->rtable);
89+
Relationrelation;
90+
HeapScanDescscan;
91+
ScanKeyDataindexKey;
92+
HeapTupleindexTuple;
10793

94+
/* Scan pg_index for tuples describing indexes of this rel */
95+
relation=heap_openr(IndexRelationName,AccessShareLock);
10896

109-
/* find the oid of the indexed relation */
110-
indrelid=getrelid(relid,root->rtable);
97+
ScanKeyEntryInitialize(&indexKey,0,
98+
Anum_pg_index_indrelid,
99+
F_OIDEQ,
100+
ObjectIdGetDatum(indrelid));
111101

112-
MemSet(info,0,sizeof(IdxInfoRetval));
102+
scan=heap_beginscan(relation,0,SnapshotNow,
103+
1,&indexKey);
113104

114-
/*
115-
* the maximum number of elements in each of the following arrays is
116-
* 8. We allocate one more for a terminating 0 to indicate the end of
117-
* the array.
118-
*/
119-
info->indexkeys= (int*)palloc(sizeof(int)*9);
120-
MemSet(info->indexkeys,0,sizeof(int)*9);
121-
info->orderOprs= (Oid*)palloc(sizeof(Oid)*9);
122-
MemSet(info->orderOprs,0,sizeof(Oid)*9);
123-
info->classlist= (Oid*)palloc(sizeof(Oid)*9);
124-
MemSet(info->classlist,0,sizeof(Oid)*9);
125-
126-
/* Find an index on the given relation */
127-
if (first)
128-
{
129-
if (HeapScanIsValid(scan))
130-
heap_endscan(scan);
131-
scan= (HeapScanDesc)NULL;
132-
if (RelationIsValid(relation))
133-
heap_close(relation,AccessShareLock);
134-
relation= (Relation)NULL;
135-
136-
ScanKeyEntryInitialize(&indexKey,0,
137-
Anum_pg_index_indrelid,
138-
F_OIDEQ,
139-
ObjectIdGetDatum(indrelid));
140-
141-
relation=heap_openr(IndexRelationName,AccessShareLock);
142-
scan=heap_beginscan(relation,0,SnapshotNow,
143-
1,&indexKey);
144-
}
145-
if (!HeapScanIsValid(scan))
146-
elog(ERROR,"index_info: scan not started");
147-
indexTuple=heap_getnext(scan,0);
148-
if (!HeapTupleIsValid(indexTuple))
149-
{
150-
heap_endscan(scan);
151-
heap_close(relation,AccessShareLock);
152-
scan= (HeapScanDesc)NULL;
153-
relation= (Relation)NULL;
154-
return0;
155-
}
156-
157-
/* Extract info from the index tuple */
158-
index= (Form_pg_index)GETSTRUCT(indexTuple);
159-
info->relid=index->indexrelid;/* index relation */
160-
for (i=0;i<INDEX_MAX_KEYS;i++)
161-
info->indexkeys[i]=index->indkey[i];
162-
for (i=0;i<INDEX_MAX_KEYS;i++)
163-
info->classlist[i]=index->indclass[i];
164-
165-
info->indproc=index->indproc;/* functional index ?? */
166-
167-
/* partial index ?? */
168-
if (VARSIZE(&index->indpred)!=0)
105+
while (HeapTupleIsValid(indexTuple=heap_getnext(scan,0)))
169106
{
107+
Form_pg_indexindex= (Form_pg_index)GETSTRUCT(indexTuple);
108+
RelOptInfo*info=makeNode(RelOptInfo);
109+
inti;
110+
RelationindexRelation;
111+
uint16amstrategy;
112+
Oidrelam;
170113

171114
/*
172-
* The memory allocated here for the predicate (in lispReadString)
173-
* only needs to stay around until it's used in find_index_paths,
174-
* which is all within a command, so the automatic pfree at end of
175-
* transaction should be ok.
115+
* Need to make these arrays large enough to be sure there is a
116+
* terminating 0 at the end of each one.
176117
*/
177-
char*predString;
118+
info->classlist= (Oid*)palloc(sizeof(Oid)* (INDEX_MAX_KEYS+1));
119+
info->indexkeys= (int*)palloc(sizeof(int)* (INDEX_MAX_KEYS+1));
120+
info->ordering= (Oid*)palloc(sizeof(Oid)* (INDEX_MAX_KEYS+1));
121+
122+
/* Extract info from the pg_index tuple */
123+
info->relids=lconsi(index->indexrelid,NIL);
124+
info->indproc=index->indproc;/* functional index ?? */
125+
if (VARSIZE(&index->indpred)!=0)/* partial index ?? */
126+
{
127+
char*predString=fmgr(F_TEXTOUT,&index->indpred);
128+
info->indpred= (List*)stringToNode(predString);
129+
pfree(predString);
130+
}
131+
else
132+
info->indpred=NIL;
178133

179-
predString=fmgr(F_TEXTOUT,&index->indpred);
180-
info->indpred= (Node*)stringToNode(predString);
181-
pfree(predString);
182-
}
134+
for (i=0;i<INDEX_MAX_KEYS;i++)
135+
info->indexkeys[i]=index->indkey[i];
136+
info->indexkeys[INDEX_MAX_KEYS]=0;
137+
for (i=0;i<INDEX_MAX_KEYS;i++)
138+
info->classlist[i]=index->indclass[i];
139+
info->classlist[INDEX_MAX_KEYS]= (Oid)0;
183140

184-
/* Extract info from the relation descriptor for the index */
185-
indexRelation=index_open(index->indexrelid);
141+
/* Extract info from the relation descriptor for the index */
142+
indexRelation=index_open(index->indexrelid);
186143
#ifdefnotdef
187-
/* XXX should iterate through strategies -- but how? use #1 for now */
188-
amstrategy=indexRelation->rd_am->amstrategies;
144+
/* XXX should iterate through strategies -- but how? use #1 for now */
145+
amstrategy=indexRelation->rd_am->amstrategies;
189146
#endif/* notdef */
190-
amstrategy=1;
191-
relam=indexRelation->rd_rel->relam;
192-
info->relam=relam;
193-
info->pages=indexRelation->rd_rel->relpages;
194-
info->tuples=indexRelation->rd_rel->reltuples;
195-
index_close(indexRelation);
147+
amstrategy=1;
148+
relam=indexRelation->rd_rel->relam;
149+
info->relam=relam;
150+
info->pages=indexRelation->rd_rel->relpages;
151+
info->tuples=indexRelation->rd_rel->reltuples;
152+
index_close(indexRelation);
196153

197-
/*
198-
* Find the index ordering keys
199-
*
200-
* Must use indclass to know when to stop looking since with functional
201-
* indices there could be several keys (args) for one opclass. -mer 27
202-
* Sept 1991
203-
*/
204-
for (i=0;i<8&&index->indclass[i];++i)
205-
{
206-
amopTuple=SearchSysCacheTuple(AMOPSTRATEGY,
154+
/*
155+
* Fetch the ordering operators associated with the index.
156+
*
157+
* XXX what if it's a hash or other unordered index?
158+
*/
159+
MemSet(info->ordering,0,sizeof(Oid)* (INDEX_MAX_KEYS+1));
160+
for (i=0;i<INDEX_MAX_KEYS&&index->indclass[i];i++)
161+
{
162+
HeapTupleamopTuple;
163+
164+
amopTuple=SearchSysCacheTuple(AMOPSTRATEGY,
207165
ObjectIdGetDatum(relam),
208-
ObjectIdGetDatum(index->indclass[i]),
166+
ObjectIdGetDatum(index->indclass[i]),
209167
UInt16GetDatum(amstrategy),
210168
0);
211-
if (!HeapTupleIsValid(amopTuple))
212-
elog(ERROR,"index_info: no amop %u %u %d",
213-
relam,index->indclass[i],amstrategy);
214-
info->orderOprs[i]= ((Form_pg_amop)GETSTRUCT(amopTuple))->amopopr;
169+
if (!HeapTupleIsValid(amopTuple))
170+
elog(ERROR,"find_secondary_indexes: no amop %u %u %d",
171+
relam,index->indclass[i],amstrategy);
172+
info->ordering[i]= ((Form_pg_amop)GETSTRUCT(amopTuple))->amopopr;
173+
}
174+
175+
info->indexed= false;/* not indexed itself */
176+
info->size=0;
177+
info->width=0;
178+
info->targetlist=NIL;
179+
info->pathlist=NIL;
180+
info->cheapestpath=NULL;
181+
info->pruneable= true;
182+
info->restrictinfo=NIL;
183+
info->joininfo=NIL;
184+
info->innerjoin=NIL;
185+
186+
indexes=lcons(info,indexes);
215187
}
216-
return TRUE;
188+
189+
heap_endscan(scan);
190+
heap_close(relation,AccessShareLock);
191+
192+
returnindexes;
217193
}
218194

219195
/*
@@ -370,10 +346,10 @@ join_selectivity(Oid functionObjectId,
370346
}
371347

372348
/*
373-
*find_all_inheritors
349+
*find_inheritance_children
374350
*
375-
* Returnsa LISP list containing the OIDs of all relations which
376-
*inherits from the relation with OID 'inhparent'.
351+
* Returnsan integer list containing the OIDs of all relations which
352+
*inherit *directly* from the relation with OID 'inhparent'.
377353
*/
378354
List*
379355
find_inheritance_children(Oidinhparent)
@@ -390,8 +366,8 @@ find_inheritance_children(Oid inhparent)
390366

391367
fmgr_info(F_OIDEQ,&key[0].sk_func);
392368
key[0].sk_nargs=key[0].sk_func.fn_nargs;
369+
key[0].sk_argument=ObjectIdGetDatum(inhparent);
393370

394-
key[0].sk_argument=ObjectIdGetDatum((Oid)inhparent);
395371
relation=heap_openr(InheritsRelationName,AccessShareLock);
396372
scan=heap_beginscan(relation,0,SnapshotNow,1,key);
397373
while (HeapTupleIsValid(inheritsTuple=heap_getnext(scan,0)))

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp