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

Commitec498cd

Browse files
committed
Create new routines systable_beginscan_ordered, systable_getnext_ordered,
systable_endscan_ordered that have API similar to systable_beginscan etc(in particular, the passed-in scankeys have heap not index attnums),but guarantee ordered output, unlike the existing functions. For the momentthese are just very thin wrappers around index_beginscan/index_getnext/etc.Someday they might need to get smarter; but for now this is just a coderefactoring exercise to reduce the number of direct callers of index_getnext,in preparation for changing that function's API.In passing, remove index_getnext_indexitem, which has been dead code forquite some time, and will have even less use than that in the presenceof run-time-lossy indexes.
1 parent0083280 commitec498cd

File tree

9 files changed

+168
-124
lines changed

9 files changed

+168
-124
lines changed

‎src/backend/access/heap/tuptoaster.c

Lines changed: 23 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
*
99
*
1010
* IDENTIFICATION
11-
* $PostgreSQL: pgsql/src/backend/access/heap/tuptoaster.c,v 1.85 2008/03/26 21:10:37 alvherre Exp $
11+
* $PostgreSQL: pgsql/src/backend/access/heap/tuptoaster.c,v 1.86 2008/04/12 23:14:21 tgl Exp $
1212
*
1313
*
1414
* INTERFACE ROUTINES
@@ -1184,7 +1184,9 @@ toast_save_datum(Relation rel, Datum value,
11841184
toast_pointer.va_extsize=data_todo;
11851185
}
11861186

1187-
toast_pointer.va_valueid=GetNewOidWithIndex(toastrel,toastidx);
1187+
toast_pointer.va_valueid=GetNewOidWithIndex(toastrel,
1188+
RelationGetRelid(toastidx),
1189+
(AttrNumber)1);
11881190
toast_pointer.va_toastrelid=rel->rd_rel->reltoastrelid;
11891191

11901192
/*
@@ -1273,7 +1275,7 @@ toast_delete_datum(Relation rel, Datum value)
12731275
Relationtoastrel;
12741276
Relationtoastidx;
12751277
ScanKeyDatatoastkey;
1276-
IndexScanDesctoastscan;
1278+
SysScanDesctoastscan;
12771279
HeapTupletoasttup;
12781280

12791281
if (!VARATT_IS_EXTERNAL(attr))
@@ -1289,20 +1291,21 @@ toast_delete_datum(Relation rel, Datum value)
12891291
toastidx=index_open(toastrel->rd_rel->reltoastidxid,RowExclusiveLock);
12901292

12911293
/*
1292-
* Setup a scan key to fetch from the index by va_valueid (we don't
1293-
* particularly care whether we see them in sequence or not)
1294+
* Setup a scan key to find chunks with matching va_valueid
12941295
*/
12951296
ScanKeyInit(&toastkey,
12961297
(AttrNumber)1,
12971298
BTEqualStrategyNumber,F_OIDEQ,
12981299
ObjectIdGetDatum(toast_pointer.va_valueid));
12991300

13001301
/*
1301-
* Find the chunks by index
1302+
* Find all the chunks. (We don't actually care whether we see them in
1303+
* sequence or not, but since we've already locked the index we might
1304+
* as well use systable_beginscan_ordered.)
13021305
*/
1303-
toastscan=index_beginscan(toastrel,toastidx,
1304-
SnapshotToast,1,&toastkey);
1305-
while ((toasttup=index_getnext(toastscan,ForwardScanDirection))!=NULL)
1306+
toastscan=systable_beginscan_ordered(toastrel,toastidx,
1307+
SnapshotToast,1,&toastkey);
1308+
while ((toasttup=systable_getnext_ordered(toastscan,ForwardScanDirection))!=NULL)
13061309
{
13071310
/*
13081311
* Have a chunk, delete it
@@ -1313,7 +1316,7 @@ toast_delete_datum(Relation rel, Datum value)
13131316
/*
13141317
* End scan and close relations
13151318
*/
1316-
index_endscan(toastscan);
1319+
systable_endscan_ordered(toastscan);
13171320
index_close(toastidx,RowExclusiveLock);
13181321
heap_close(toastrel,RowExclusiveLock);
13191322
}
@@ -1332,7 +1335,7 @@ toast_fetch_datum(struct varlena * attr)
13321335
Relationtoastrel;
13331336
Relationtoastidx;
13341337
ScanKeyDatatoastkey;
1335-
IndexScanDesctoastscan;
1338+
SysScanDesctoastscan;
13361339
HeapTuplettup;
13371340
TupleDesctoasttupDesc;
13381341
structvarlena*result;
@@ -1383,9 +1386,9 @@ toast_fetch_datum(struct varlena * attr)
13831386
*/
13841387
nextidx=0;
13851388

1386-
toastscan=index_beginscan(toastrel,toastidx,
1387-
SnapshotToast,1,&toastkey);
1388-
while ((ttup=index_getnext(toastscan,ForwardScanDirection))!=NULL)
1389+
toastscan=systable_beginscan_ordered(toastrel,toastidx,
1390+
SnapshotToast,1,&toastkey);
1391+
while ((ttup=systable_getnext_ordered(toastscan,ForwardScanDirection))!=NULL)
13891392
{
13901393
/*
13911394
* Have a chunk, extract the sequence number and the data
@@ -1464,7 +1467,7 @@ toast_fetch_datum(struct varlena * attr)
14641467
/*
14651468
* End scan and close relations
14661469
*/
1467-
index_endscan(toastscan);
1470+
systable_endscan_ordered(toastscan);
14681471
index_close(toastidx,AccessShareLock);
14691472
heap_close(toastrel,AccessShareLock);
14701473

@@ -1485,7 +1488,7 @@ toast_fetch_datum_slice(struct varlena * attr, int32 sliceoffset, int32 length)
14851488
Relationtoastidx;
14861489
ScanKeyDatatoastkey[3];
14871490
intnscankeys;
1488-
IndexScanDesctoastscan;
1491+
SysScanDesctoastscan;
14891492
HeapTuplettup;
14901493
TupleDesctoasttupDesc;
14911494
structvarlena*result;
@@ -1592,9 +1595,9 @@ toast_fetch_datum_slice(struct varlena * attr, int32 sliceoffset, int32 length)
15921595
* The index is on (valueid, chunkidx) so they will come in order
15931596
*/
15941597
nextidx=startchunk;
1595-
toastscan=index_beginscan(toastrel,toastidx,
1596-
SnapshotToast,nscankeys,toastkey);
1597-
while ((ttup=index_getnext(toastscan,ForwardScanDirection))!=NULL)
1598+
toastscan=systable_beginscan_ordered(toastrel,toastidx,
1599+
SnapshotToast,nscankeys,toastkey);
1600+
while ((ttup=systable_getnext_ordered(toastscan,ForwardScanDirection))!=NULL)
15981601
{
15991602
/*
16001603
* Have a chunk, extract the sequence number and the data
@@ -1681,7 +1684,7 @@ toast_fetch_datum_slice(struct varlena * attr, int32 sliceoffset, int32 length)
16811684
/*
16821685
* End scan and close relations
16831686
*/
1684-
index_endscan(toastscan);
1687+
systable_endscan_ordered(toastscan);
16851688
index_close(toastidx,AccessShareLock);
16861689
heap_close(toastrel,AccessShareLock);
16871690

‎src/backend/access/index/genam.c

Lines changed: 85 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
*
99
*
1010
* IDENTIFICATION
11-
* $PostgreSQL: pgsql/src/backend/access/index/genam.c,v 1.66 2008/04/10 22:25:25 tgl Exp $
11+
* $PostgreSQL: pgsql/src/backend/access/index/genam.c,v 1.67 2008/04/12 23:14:21 tgl Exp $
1212
*
1313
* NOTES
1414
* many of the old access method routines have been turned into
@@ -258,3 +258,87 @@ systable_endscan(SysScanDesc sysscan)
258258

259259
pfree(sysscan);
260260
}
261+
262+
263+
/*
264+
* systable_beginscan_ordered --- set up for ordered catalog scan
265+
*
266+
* These routines have essentially the same API as systable_beginscan etc,
267+
* except that they guarantee to return multiple matching tuples in
268+
* index order. Also, for largely historical reasons, the index to use
269+
* is opened and locked by the caller, not here.
270+
*
271+
* Currently we do not support non-index-based scans here. (In principle
272+
* we could do a heapscan and sort, but the uses are in places that
273+
* probably don't need to still work with corrupted catalog indexes.)
274+
* For the moment, therefore, these functions are merely the thinnest of
275+
* wrappers around index_beginscan/index_getnext. The main reason for their
276+
* existence is to centralize possible future support of lossy operators
277+
* in catalog scans.
278+
*/
279+
SysScanDesc
280+
systable_beginscan_ordered(RelationheapRelation,
281+
RelationindexRelation,
282+
Snapshotsnapshot,
283+
intnkeys,ScanKeykey)
284+
{
285+
SysScanDescsysscan;
286+
inti;
287+
288+
/* REINDEX can probably be a hard error here ... */
289+
if (ReindexIsProcessingIndex(RelationGetRelid(indexRelation)))
290+
elog(ERROR,"cannot do ordered scan on index \"%s\", because it is the current REINDEX target",
291+
RelationGetRelationName(indexRelation));
292+
/* ... but we only throw a warning about violating IgnoreSystemIndexes */
293+
if (IgnoreSystemIndexes)
294+
elog(WARNING,"using index \"%s\" despite IgnoreSystemIndexes",
295+
RelationGetRelationName(indexRelation));
296+
297+
sysscan= (SysScanDesc)palloc(sizeof(SysScanDescData));
298+
299+
sysscan->heap_rel=heapRelation;
300+
sysscan->irel=indexRelation;
301+
302+
/*
303+
* Change attribute numbers to be index column numbers.
304+
*
305+
* This code could be generalized to search for the index key numbers
306+
* to substitute, but for now there's no need.
307+
*/
308+
for (i=0;i<nkeys;i++)
309+
{
310+
Assert(key[i].sk_attno==indexRelation->rd_index->indkey.values[i]);
311+
key[i].sk_attno=i+1;
312+
}
313+
314+
sysscan->iscan=index_beginscan(heapRelation,indexRelation,
315+
snapshot,nkeys,key);
316+
sysscan->scan=NULL;
317+
318+
returnsysscan;
319+
}
320+
321+
/*
322+
* systable_getnext_ordered --- get next tuple in an ordered catalog scan
323+
*/
324+
HeapTuple
325+
systable_getnext_ordered(SysScanDescsysscan,ScanDirectiondirection)
326+
{
327+
HeapTuplehtup;
328+
329+
Assert(sysscan->irel);
330+
htup=index_getnext(sysscan->iscan,direction);
331+
332+
returnhtup;
333+
}
334+
335+
/*
336+
* systable_endscan_ordered --- close scan, release resources
337+
*/
338+
void
339+
systable_endscan_ordered(SysScanDescsysscan)
340+
{
341+
Assert(sysscan->irel);
342+
index_endscan(sysscan->iscan);
343+
pfree(sysscan);
344+
}

‎src/backend/access/index/indexam.c

Lines changed: 2 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
*
99
*
1010
* IDENTIFICATION
11-
* $PostgreSQL: pgsql/src/backend/access/index/indexam.c,v 1.105 2008/04/10 22:25:25 tgl Exp $
11+
* $PostgreSQL: pgsql/src/backend/access/index/indexam.c,v 1.106 2008/04/12 23:14:21 tgl Exp $
1212
*
1313
* INTERFACE ROUTINES
1414
*index_open- open an index relation by relation OID
@@ -206,12 +206,7 @@ index_insert(Relation indexRelation,
206206
/*
207207
* index_beginscan - start a scan of an index with amgettuple
208208
*
209-
* Note: heapRelation may be NULL if there is no intention of calling
210-
* index_getnext on this scan; index_getnext_indexitem will not use the
211-
* heapRelation link (nor the snapshot). However, the caller had better
212-
* be holding some kind of lock on the heap relation in any case, to ensure
213-
* no one deletes it (or the index) out from under us.Caller must also
214-
* be holding a lock on the index.
209+
* Caller must be holding suitable locks on the heap and the index.
215210
*/
216211
IndexScanDesc
217212
index_beginscan(RelationheapRelation,
@@ -634,45 +629,6 @@ index_getnext(IndexScanDesc scan, ScanDirection direction)
634629
returnNULL;/* failure exit */
635630
}
636631

637-
/* ----------------
638-
*index_getnext_indexitem - get the next index tuple from a scan
639-
*
640-
* Finds the next index tuple satisfying the scan keys. Note that the
641-
* corresponding heap tuple is not accessed, and thus no time qual (snapshot)
642-
* check is done, other than the index AM's internal check for killed tuples
643-
* (which most callers of this routine will probably want to suppress by
644-
* setting scan->ignore_killed_tuples = false).
645-
*
646-
* On success (TRUE return), the heap TID of the found index entry is in
647-
* scan->xs_ctup.t_self. scan->xs_cbuf is untouched.
648-
* ----------------
649-
*/
650-
bool
651-
index_getnext_indexitem(IndexScanDescscan,
652-
ScanDirectiondirection)
653-
{
654-
FmgrInfo*procedure;
655-
boolfound;
656-
657-
SCAN_CHECKS;
658-
GET_SCAN_PROCEDURE(amgettuple);
659-
660-
/* just make sure this is false... */
661-
scan->kill_prior_tuple= false;
662-
663-
/*
664-
* have the am's gettuple proc do all the work.
665-
*/
666-
found=DatumGetBool(FunctionCall2(procedure,
667-
PointerGetDatum(scan),
668-
Int32GetDatum(direction)));
669-
670-
if (found)
671-
pgstat_count_index_tuples(scan->indexRelation,1);
672-
673-
returnfound;
674-
}
675-
676632
/* ----------------
677633
*index_getbitmap - get all tuples at once from an index scan
678634
*

‎src/backend/catalog/catalog.c

Lines changed: 11 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
*
1111
*
1212
* IDENTIFICATION
13-
* $PostgreSQL: pgsql/src/backend/catalog/catalog.c,v 1.74 2008/03/26 16:20:46 alvherre Exp $
13+
* $PostgreSQL: pgsql/src/backend/catalog/catalog.c,v 1.75 2008/04/12 23:14:21 tgl Exp $
1414
*
1515
*-------------------------------------------------------------------------
1616
*/
@@ -312,9 +312,7 @@ IsSharedRelation(Oid relationId)
312312
Oid
313313
GetNewOid(Relationrelation)
314314
{
315-
OidnewOid;
316315
OidoidIndex;
317-
Relationindexrel;
318316

319317
/* If relation doesn't have OIDs at all, caller is confused */
320318
Assert(relation->rd_rel->relhasoids);
@@ -342,11 +340,7 @@ GetNewOid(Relation relation)
342340
}
343341

344342
/* Otherwise, use the index to find a nonconflicting OID */
345-
indexrel=index_open(oidIndex,AccessShareLock);
346-
newOid=GetNewOidWithIndex(relation,indexrel);
347-
index_close(indexrel,AccessShareLock);
348-
349-
returnnewOid;
343+
returnGetNewOidWithIndex(relation,oidIndex,ObjectIdAttributeNumber);
350344
}
351345

352346
/*
@@ -357,16 +351,17 @@ GetNewOid(Relation relation)
357351
* an index that will not be recognized by RelationGetOidIndex: TOAST tables
358352
* and pg_largeobject have indexes that are usable, but have multiple columns
359353
* and are on ordinary columns rather than a true OID column. This code
360-
* will work anyway, so long as the OID is the index's first column.
354+
* will work anyway, so long as the OID is the index's first column. The
355+
* caller must pass in the actual heap attnum of the OID column, however.
361356
*
362357
* Caller must have a suitable lock on the relation.
363358
*/
364359
Oid
365-
GetNewOidWithIndex(Relationrelation,Relationindexrel)
360+
GetNewOidWithIndex(Relationrelation,OidindexId,AttrNumberoidcolumn)
366361
{
367362
OidnewOid;
368363
SnapshotDataSnapshotDirty;
369-
IndexScanDescscan;
364+
SysScanDescscan;
370365
ScanKeyDatakey;
371366
boolcollides;
372367

@@ -380,17 +375,17 @@ GetNewOidWithIndex(Relation relation, Relation indexrel)
380375
newOid=GetNewObjectId();
381376

382377
ScanKeyInit(&key,
383-
(AttrNumber)1,
378+
oidcolumn,
384379
BTEqualStrategyNumber,F_OIDEQ,
385380
ObjectIdGetDatum(newOid));
386381

387382
/* see notes above about using SnapshotDirty */
388-
scan=index_beginscan(relation,indexrel,
389-
&SnapshotDirty,1,&key);
383+
scan=systable_beginscan(relation,indexId, true,
384+
&SnapshotDirty,1,&key);
390385

391-
collides=HeapTupleIsValid(index_getnext(scan,ForwardScanDirection));
386+
collides=HeapTupleIsValid(systable_getnext(scan));
392387

393-
index_endscan(scan);
388+
systable_endscan(scan);
394389
}while (collides);
395390

396391
returnnewOid;

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp