]> granicus.if.org Git - postgresql/blob - src/backend/catalog/pg_largeobject.c
d4b5e6bfeb3c34f9f822b3f2adca6cd540bf858a
[postgresql] / src / backend / catalog / pg_largeobject.c
1 /*-------------------------------------------------------------------------
2  *
3  * pg_largeobject.c
4  *        routines to support manipulation of the pg_largeobject relation
5  *
6  * Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
7  * Portions Copyright (c) 1994, Regents of the University of California
8  *
9  *
10  * IDENTIFICATION
11  *        $Header: /cvsroot/pgsql/src/backend/catalog/pg_largeobject.c,v 1.11 2002/05/20 23:51:42 tgl Exp $
12  *
13  *-------------------------------------------------------------------------
14  */
15 #include "postgres.h"
16
17 #include "access/genam.h"
18 #include "access/heapam.h"
19 #include "catalog/catname.h"
20 #include "catalog/indexing.h"
21 #include "catalog/pg_largeobject.h"
22 #include "miscadmin.h"
23 #include "utils/builtins.h"
24 #include "utils/fmgroids.h"
25
26
27 /*
28  * Create a large object having the given LO identifier.
29  *
30  * We do this by inserting an empty first page, so that the object will
31  * appear to exist with size 0.  Note that the unique index will reject
32  * an attempt to create a duplicate page.
33  */
34 void
35 LargeObjectCreate(Oid loid)
36 {
37         Relation        pg_largeobject;
38         HeapTuple       ntup;
39         Relation        idescs[Num_pg_largeobject_indices];
40         Datum           values[Natts_pg_largeobject];
41         char            nulls[Natts_pg_largeobject];
42         int                     i;
43
44         pg_largeobject = heap_openr(LargeObjectRelationName, RowExclusiveLock);
45
46         /*
47          * Form new tuple
48          */
49         for (i = 0; i < Natts_pg_largeobject; i++)
50         {
51                 values[i] = (Datum) NULL;
52                 nulls[i] = ' ';
53         }
54
55         i = 0;
56         values[i++] = ObjectIdGetDatum(loid);
57         values[i++] = Int32GetDatum(0);
58         values[i++] = DirectFunctionCall1(byteain,
59                                                                           CStringGetDatum(""));
60
61         ntup = heap_formtuple(pg_largeobject->rd_att, values, nulls);
62
63         /*
64          * Insert it
65          */
66         heap_insert(pg_largeobject, ntup);
67
68         /*
69          * Update indices
70          */
71         if (!IsIgnoringSystemIndexes())
72         {
73                 CatalogOpenIndices(Num_pg_largeobject_indices, Name_pg_largeobject_indices, idescs);
74                 CatalogIndexInsert(idescs, Num_pg_largeobject_indices, pg_largeobject, ntup);
75                 CatalogCloseIndices(Num_pg_largeobject_indices, idescs);
76         }
77
78         heap_close(pg_largeobject, RowExclusiveLock);
79
80         heap_freetuple(ntup);
81 }
82
83 void
84 LargeObjectDrop(Oid loid)
85 {
86         bool            found = false;
87         Relation        pg_largeobject;
88         Relation        pg_lo_idx;
89         ScanKeyData skey[1];
90         IndexScanDesc sd;
91         HeapTuple       tuple;
92
93         ScanKeyEntryInitialize(&skey[0],
94                                                    (bits16) 0x0,
95                                                    (AttrNumber) 1,
96                                                    (RegProcedure) F_OIDEQ,
97                                                    ObjectIdGetDatum(loid));
98
99         pg_largeobject = heap_openr(LargeObjectRelationName, RowShareLock);
100         pg_lo_idx = index_openr(LargeObjectLOidPNIndex);
101
102         sd = index_beginscan(pg_largeobject, pg_lo_idx, SnapshotNow, 1, skey);
103
104         while ((tuple = index_getnext(sd, ForwardScanDirection)) != NULL)
105         {
106                 simple_heap_delete(pg_largeobject, &tuple->t_self);
107                 found = true;
108         }
109
110         index_endscan(sd);
111
112         index_close(pg_lo_idx);
113         heap_close(pg_largeobject, RowShareLock);
114
115         if (!found)
116                 elog(ERROR, "LargeObjectDrop: large object %u not found", loid);
117 }
118
119 bool
120 LargeObjectExists(Oid loid)
121 {
122         bool            retval = false;
123         Relation        pg_largeobject;
124         Relation        pg_lo_idx;
125         ScanKeyData skey[1];
126         IndexScanDesc sd;
127         HeapTuple       tuple;
128
129         /*
130          * See if we can find any tuples belonging to the specified LO
131          */
132         ScanKeyEntryInitialize(&skey[0],
133                                                    (bits16) 0x0,
134                                                    (AttrNumber) 1,
135                                                    (RegProcedure) F_OIDEQ,
136                                                    ObjectIdGetDatum(loid));
137
138         pg_largeobject = heap_openr(LargeObjectRelationName, RowShareLock);
139         pg_lo_idx = index_openr(LargeObjectLOidPNIndex);
140
141         sd = index_beginscan(pg_largeobject, pg_lo_idx, SnapshotNow, 1, skey);
142
143         if ((tuple = index_getnext(sd, ForwardScanDirection)) != NULL)
144                 retval = true;
145
146         index_endscan(sd);
147
148         index_close(pg_lo_idx);
149         heap_close(pg_largeobject, RowShareLock);
150
151         return retval;
152 }