mirror of
https://github.com/postgres/postgres.git
synced 2025-11-07 19:06:32 +03:00
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 moment these 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 code refactoring 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 for quite some time, and will have even less use than that in the presence of run-time-lossy indexes.
This commit is contained in:
@@ -24,7 +24,7 @@
|
||||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $PostgreSQL: pgsql/src/backend/storage/large_object/inv_api.c,v 1.131 2008/03/26 21:10:38 alvherre Exp $
|
||||
* $PostgreSQL: pgsql/src/backend/storage/large_object/inv_api.c,v 1.132 2008/04/12 23:14:21 tgl Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@@ -201,7 +201,8 @@ inv_create(Oid lobjId)
|
||||
{
|
||||
open_lo_relation();
|
||||
|
||||
lobjId = GetNewOidWithIndex(lo_heap_r, lo_index_r);
|
||||
lobjId = GetNewOidWithIndex(lo_heap_r, LargeObjectLOidPNIndexId,
|
||||
Anum_pg_largeobject_loid);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -311,7 +312,7 @@ inv_getsize(LargeObjectDesc *obj_desc)
|
||||
bool found = false;
|
||||
uint32 lastbyte = 0;
|
||||
ScanKeyData skey[1];
|
||||
IndexScanDesc sd;
|
||||
SysScanDesc sd;
|
||||
HeapTuple tuple;
|
||||
|
||||
Assert(PointerIsValid(obj_desc));
|
||||
@@ -323,8 +324,8 @@ inv_getsize(LargeObjectDesc *obj_desc)
|
||||
BTEqualStrategyNumber, F_OIDEQ,
|
||||
ObjectIdGetDatum(obj_desc->id));
|
||||
|
||||
sd = index_beginscan(lo_heap_r, lo_index_r,
|
||||
obj_desc->snapshot, 1, skey);
|
||||
sd = systable_beginscan_ordered(lo_heap_r, lo_index_r,
|
||||
obj_desc->snapshot, 1, skey);
|
||||
|
||||
/*
|
||||
* Because the pg_largeobject index is on both loid and pageno, but we
|
||||
@@ -332,7 +333,7 @@ inv_getsize(LargeObjectDesc *obj_desc)
|
||||
* large object in reverse pageno order. So, it's sufficient to examine
|
||||
* the first valid tuple (== last valid page).
|
||||
*/
|
||||
while ((tuple = index_getnext(sd, BackwardScanDirection)) != NULL)
|
||||
while ((tuple = systable_getnext_ordered(sd, BackwardScanDirection)) != NULL)
|
||||
{
|
||||
Form_pg_largeobject data;
|
||||
bytea *datafield;
|
||||
@@ -356,7 +357,7 @@ inv_getsize(LargeObjectDesc *obj_desc)
|
||||
break;
|
||||
}
|
||||
|
||||
index_endscan(sd);
|
||||
systable_endscan_ordered(sd);
|
||||
|
||||
if (!found)
|
||||
ereport(ERROR,
|
||||
@@ -415,7 +416,7 @@ inv_read(LargeObjectDesc *obj_desc, char *buf, int nbytes)
|
||||
int32 pageno = (int32) (obj_desc->offset / LOBLKSIZE);
|
||||
uint32 pageoff;
|
||||
ScanKeyData skey[2];
|
||||
IndexScanDesc sd;
|
||||
SysScanDesc sd;
|
||||
HeapTuple tuple;
|
||||
|
||||
Assert(PointerIsValid(obj_desc));
|
||||
@@ -436,10 +437,10 @@ inv_read(LargeObjectDesc *obj_desc, char *buf, int nbytes)
|
||||
BTGreaterEqualStrategyNumber, F_INT4GE,
|
||||
Int32GetDatum(pageno));
|
||||
|
||||
sd = index_beginscan(lo_heap_r, lo_index_r,
|
||||
obj_desc->snapshot, 2, skey);
|
||||
sd = systable_beginscan_ordered(lo_heap_r, lo_index_r,
|
||||
obj_desc->snapshot, 2, skey);
|
||||
|
||||
while ((tuple = index_getnext(sd, ForwardScanDirection)) != NULL)
|
||||
while ((tuple = systable_getnext_ordered(sd, ForwardScanDirection)) != NULL)
|
||||
{
|
||||
Form_pg_largeobject data;
|
||||
bytea *datafield;
|
||||
@@ -450,7 +451,7 @@ inv_read(LargeObjectDesc *obj_desc, char *buf, int nbytes)
|
||||
data = (Form_pg_largeobject) GETSTRUCT(tuple);
|
||||
|
||||
/*
|
||||
* We assume the indexscan will deliver pages in order. However,
|
||||
* We expect the indexscan will deliver pages in order. However,
|
||||
* there may be missing pages if the LO contains unwritten "holes". We
|
||||
* want missing sections to read out as zeroes.
|
||||
*/
|
||||
@@ -495,7 +496,7 @@ inv_read(LargeObjectDesc *obj_desc, char *buf, int nbytes)
|
||||
break;
|
||||
}
|
||||
|
||||
index_endscan(sd);
|
||||
systable_endscan_ordered(sd);
|
||||
|
||||
return nread;
|
||||
}
|
||||
@@ -509,7 +510,7 @@ inv_write(LargeObjectDesc *obj_desc, const char *buf, int nbytes)
|
||||
int len;
|
||||
int32 pageno = (int32) (obj_desc->offset / LOBLKSIZE);
|
||||
ScanKeyData skey[2];
|
||||
IndexScanDesc sd;
|
||||
SysScanDesc sd;
|
||||
HeapTuple oldtuple;
|
||||
Form_pg_largeobject olddata;
|
||||
bool neednextpage;
|
||||
@@ -555,8 +556,8 @@ inv_write(LargeObjectDesc *obj_desc, const char *buf, int nbytes)
|
||||
BTGreaterEqualStrategyNumber, F_INT4GE,
|
||||
Int32GetDatum(pageno));
|
||||
|
||||
sd = index_beginscan(lo_heap_r, lo_index_r,
|
||||
obj_desc->snapshot, 2, skey);
|
||||
sd = systable_beginscan_ordered(lo_heap_r, lo_index_r,
|
||||
obj_desc->snapshot, 2, skey);
|
||||
|
||||
oldtuple = NULL;
|
||||
olddata = NULL;
|
||||
@@ -565,12 +566,12 @@ inv_write(LargeObjectDesc *obj_desc, const char *buf, int nbytes)
|
||||
while (nwritten < nbytes)
|
||||
{
|
||||
/*
|
||||
* If possible, get next pre-existing page of the LO. We assume the
|
||||
* If possible, get next pre-existing page of the LO. We expect the
|
||||
* indexscan will deliver these in order --- but there may be holes.
|
||||
*/
|
||||
if (neednextpage)
|
||||
{
|
||||
if ((oldtuple = index_getnext(sd, ForwardScanDirection)) != NULL)
|
||||
if ((oldtuple = systable_getnext_ordered(sd, ForwardScanDirection)) != NULL)
|
||||
{
|
||||
if (HeapTupleHasNulls(oldtuple)) /* paranoia */
|
||||
elog(ERROR, "null field found in pg_largeobject");
|
||||
@@ -685,7 +686,7 @@ inv_write(LargeObjectDesc *obj_desc, const char *buf, int nbytes)
|
||||
pageno++;
|
||||
}
|
||||
|
||||
index_endscan(sd);
|
||||
systable_endscan_ordered(sd);
|
||||
|
||||
CatalogCloseIndexes(indstate);
|
||||
|
||||
@@ -704,7 +705,7 @@ inv_truncate(LargeObjectDesc *obj_desc, int len)
|
||||
int32 pageno = (int32) (len / LOBLKSIZE);
|
||||
int off;
|
||||
ScanKeyData skey[2];
|
||||
IndexScanDesc sd;
|
||||
SysScanDesc sd;
|
||||
HeapTuple oldtuple;
|
||||
Form_pg_largeobject olddata;
|
||||
struct
|
||||
@@ -743,15 +744,15 @@ inv_truncate(LargeObjectDesc *obj_desc, int len)
|
||||
BTGreaterEqualStrategyNumber, F_INT4GE,
|
||||
Int32GetDatum(pageno));
|
||||
|
||||
sd = index_beginscan(lo_heap_r, lo_index_r,
|
||||
obj_desc->snapshot, 2, skey);
|
||||
sd = systable_beginscan_ordered(lo_heap_r, lo_index_r,
|
||||
obj_desc->snapshot, 2, skey);
|
||||
|
||||
/*
|
||||
* If possible, get the page the truncation point is in. The truncation
|
||||
* point may be beyond the end of the LO or in a hole.
|
||||
*/
|
||||
olddata = NULL;
|
||||
if ((oldtuple = index_getnext(sd, ForwardScanDirection)) != NULL)
|
||||
if ((oldtuple = systable_getnext_ordered(sd, ForwardScanDirection)) != NULL)
|
||||
{
|
||||
if (HeapTupleHasNulls(oldtuple)) /* paranoia */
|
||||
elog(ERROR, "null field found in pg_largeobject");
|
||||
@@ -846,12 +847,12 @@ inv_truncate(LargeObjectDesc *obj_desc, int len)
|
||||
/*
|
||||
* Delete any pages after the truncation point
|
||||
*/
|
||||
while ((oldtuple = index_getnext(sd, ForwardScanDirection)) != NULL)
|
||||
while ((oldtuple = systable_getnext_ordered(sd, ForwardScanDirection)) != NULL)
|
||||
{
|
||||
simple_heap_delete(lo_heap_r, &oldtuple->t_self);
|
||||
}
|
||||
|
||||
index_endscan(sd);
|
||||
systable_endscan_ordered(sd);
|
||||
|
||||
CatalogCloseIndexes(indstate);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user