mirror of
https://git.postgresql.org/git/postgresql.git
synced 2024-08-22 08:33:22 +02:00
hardwired lists of index names for each catalog, use the relcache's mechanism for caching lists of OIDs of indexes of any table. This reduces the common case of updating system catalog indexes to a single line, makes it much easier to add a new system index (in fact, you can now do so on-the-fly if you want to), and as a nice side benefit improves performance a little. Per recent pghackers discussion.
145 lines
3.3 KiB
C
145 lines
3.3 KiB
C
/*-------------------------------------------------------------------------
|
|
*
|
|
* pg_largeobject.c
|
|
* routines to support manipulation of the pg_largeobject relation
|
|
*
|
|
* Portions Copyright (c) 1996-2002, PostgreSQL Global Development Group
|
|
* Portions Copyright (c) 1994, Regents of the University of California
|
|
*
|
|
*
|
|
* IDENTIFICATION
|
|
* $Header: /cvsroot/pgsql/src/backend/catalog/pg_largeobject.c,v 1.14 2002/08/05 03:29:16 tgl Exp $
|
|
*
|
|
*-------------------------------------------------------------------------
|
|
*/
|
|
#include "postgres.h"
|
|
|
|
#include "access/genam.h"
|
|
#include "access/heapam.h"
|
|
#include "catalog/catname.h"
|
|
#include "catalog/indexing.h"
|
|
#include "catalog/pg_largeobject.h"
|
|
#include "miscadmin.h"
|
|
#include "utils/builtins.h"
|
|
#include "utils/fmgroids.h"
|
|
|
|
|
|
/*
|
|
* Create a large object having the given LO identifier.
|
|
*
|
|
* We do this by inserting an empty first page, so that the object will
|
|
* appear to exist with size 0. Note that the unique index will reject
|
|
* an attempt to create a duplicate page.
|
|
*/
|
|
void
|
|
LargeObjectCreate(Oid loid)
|
|
{
|
|
Relation pg_largeobject;
|
|
HeapTuple ntup;
|
|
Datum values[Natts_pg_largeobject];
|
|
char nulls[Natts_pg_largeobject];
|
|
int i;
|
|
|
|
pg_largeobject = heap_openr(LargeObjectRelationName, RowExclusiveLock);
|
|
|
|
/*
|
|
* Form new tuple
|
|
*/
|
|
for (i = 0; i < Natts_pg_largeobject; i++)
|
|
{
|
|
values[i] = (Datum) NULL;
|
|
nulls[i] = ' ';
|
|
}
|
|
|
|
i = 0;
|
|
values[i++] = ObjectIdGetDatum(loid);
|
|
values[i++] = Int32GetDatum(0);
|
|
values[i++] = DirectFunctionCall1(byteain,
|
|
CStringGetDatum(""));
|
|
|
|
ntup = heap_formtuple(pg_largeobject->rd_att, values, nulls);
|
|
|
|
/*
|
|
* Insert it
|
|
*/
|
|
simple_heap_insert(pg_largeobject, ntup);
|
|
|
|
/* Update indexes */
|
|
CatalogUpdateIndexes(pg_largeobject, ntup);
|
|
|
|
heap_close(pg_largeobject, RowExclusiveLock);
|
|
|
|
heap_freetuple(ntup);
|
|
}
|
|
|
|
void
|
|
LargeObjectDrop(Oid loid)
|
|
{
|
|
bool found = false;
|
|
Relation pg_largeobject;
|
|
Relation pg_lo_idx;
|
|
ScanKeyData skey[1];
|
|
IndexScanDesc sd;
|
|
HeapTuple tuple;
|
|
|
|
ScanKeyEntryInitialize(&skey[0],
|
|
(bits16) 0x0,
|
|
(AttrNumber) 1,
|
|
(RegProcedure) F_OIDEQ,
|
|
ObjectIdGetDatum(loid));
|
|
|
|
pg_largeobject = heap_openr(LargeObjectRelationName, RowShareLock);
|
|
pg_lo_idx = index_openr(LargeObjectLOidPNIndex);
|
|
|
|
sd = index_beginscan(pg_largeobject, pg_lo_idx, SnapshotNow, 1, skey);
|
|
|
|
while ((tuple = index_getnext(sd, ForwardScanDirection)) != NULL)
|
|
{
|
|
simple_heap_delete(pg_largeobject, &tuple->t_self);
|
|
found = true;
|
|
}
|
|
|
|
index_endscan(sd);
|
|
|
|
index_close(pg_lo_idx);
|
|
heap_close(pg_largeobject, RowShareLock);
|
|
|
|
if (!found)
|
|
elog(ERROR, "LargeObjectDrop: large object %u not found", loid);
|
|
}
|
|
|
|
bool
|
|
LargeObjectExists(Oid loid)
|
|
{
|
|
bool retval = false;
|
|
Relation pg_largeobject;
|
|
Relation pg_lo_idx;
|
|
ScanKeyData skey[1];
|
|
IndexScanDesc sd;
|
|
HeapTuple tuple;
|
|
|
|
/*
|
|
* See if we can find any tuples belonging to the specified LO
|
|
*/
|
|
ScanKeyEntryInitialize(&skey[0],
|
|
(bits16) 0x0,
|
|
(AttrNumber) 1,
|
|
(RegProcedure) F_OIDEQ,
|
|
ObjectIdGetDatum(loid));
|
|
|
|
pg_largeobject = heap_openr(LargeObjectRelationName, RowShareLock);
|
|
pg_lo_idx = index_openr(LargeObjectLOidPNIndex);
|
|
|
|
sd = index_beginscan(pg_largeobject, pg_lo_idx, SnapshotNow, 1, skey);
|
|
|
|
if ((tuple = index_getnext(sd, ForwardScanDirection)) != NULL)
|
|
retval = true;
|
|
|
|
index_endscan(sd);
|
|
|
|
index_close(pg_lo_idx);
|
|
heap_close(pg_largeobject, RowShareLock);
|
|
|
|
return retval;
|
|
}
|