]> granicus.if.org Git - postgresql/blob - src/backend/catalog/pg_largeobject.c
Fix all the places that called heap_update() and heap_delete() without
[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-2000, PostgreSQL, Inc
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.6 2001/01/23 04:32:21 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  * Return value is OID assigned to the page tuple (any use in it?)
35  */
36 Oid
37 LargeObjectCreate(Oid loid)
38 {
39         Oid                     retval;
40         Relation        pg_largeobject;
41         HeapTuple       ntup;
42         Relation        idescs[Num_pg_largeobject_indices];
43         Datum           values[Natts_pg_largeobject];
44         char            nulls[Natts_pg_largeobject];
45         int                     i;
46
47         pg_largeobject = heap_openr(LargeObjectRelationName, RowExclusiveLock);
48
49         /*
50          * Form new tuple
51          */
52         for (i = 0; i < Natts_pg_largeobject; i++)
53         {
54                 values[i] = (Datum)NULL;
55                 nulls[i] = ' ';
56         }
57
58         i = 0;
59         values[i++] = ObjectIdGetDatum(loid);
60         values[i++] = Int32GetDatum(0);
61         values[i++] = DirectFunctionCall1(byteain,
62                                                                           CStringGetDatum(""));
63         
64         ntup = heap_formtuple(pg_largeobject->rd_att, values, nulls);
65
66         /*
67          * Insert it
68          */
69         retval = heap_insert(pg_largeobject, ntup);
70
71         /*
72          * Update indices
73          */
74         if (!IsIgnoringSystemIndexes())
75         {
76                 CatalogOpenIndices(Num_pg_largeobject_indices, Name_pg_largeobject_indices, idescs);
77                 CatalogIndexInsert(idescs, Num_pg_largeobject_indices, pg_largeobject, ntup);
78                 CatalogCloseIndices(Num_pg_largeobject_indices, idescs);
79         }
80         
81         heap_close(pg_largeobject, RowExclusiveLock);
82
83         heap_freetuple(ntup);
84
85         return retval;
86 }
87
88 void
89 LargeObjectDrop(Oid loid)
90 {
91         bool            found = false;
92         Relation        pg_largeobject;
93         Relation        pg_lo_idx;
94         ScanKeyData     skey[1];
95         IndexScanDesc sd;
96         RetrieveIndexResult     indexRes;
97         HeapTupleData tuple;
98         Buffer          buffer;
99
100         ScanKeyEntryInitialize(&skey[0],
101                                                    (bits16) 0x0,
102                                                    (AttrNumber) 1,
103                                                    (RegProcedure) F_OIDEQ,
104                                                    ObjectIdGetDatum(loid));
105
106         pg_largeobject = heap_openr(LargeObjectRelationName, RowShareLock);
107         pg_lo_idx = index_openr(LargeObjectLOidPNIndex);
108
109         sd = index_beginscan(pg_lo_idx, false, 1, skey);
110
111         tuple.t_datamcxt = CurrentMemoryContext;
112         tuple.t_data = NULL;
113
114         while ((indexRes = index_getnext(sd, ForwardScanDirection)))
115         {
116                 tuple.t_self = indexRes->heap_iptr;
117                 heap_fetch(pg_largeobject, SnapshotNow, &tuple, &buffer);
118                 pfree(indexRes);
119                 if (tuple.t_data != NULL)
120                 {
121                         simple_heap_delete(pg_largeobject, &tuple.t_self);
122                         ReleaseBuffer(buffer);
123                         found = true;
124                 }
125         }
126
127         index_endscan(sd);
128
129         index_close(pg_lo_idx);
130         heap_close(pg_largeobject, RowShareLock);
131
132         if (!found)
133                 elog(ERROR, "LargeObjectDrop: large object %u not found", loid);
134 }
135
136 bool
137 LargeObjectExists(Oid loid)
138 {
139         bool            retval = false;
140         Relation        pg_largeobject;
141         Relation        pg_lo_idx;
142         ScanKeyData     skey[1];
143         IndexScanDesc sd;
144         RetrieveIndexResult     indexRes;
145         HeapTupleData tuple;
146         Buffer          buffer;
147
148         /*
149          * See if we can find any tuples belonging to the specified LO
150          */
151         ScanKeyEntryInitialize(&skey[0],
152                                                    (bits16) 0x0,
153                                                    (AttrNumber) 1,
154                                                    (RegProcedure) F_OIDEQ,
155                                                    ObjectIdGetDatum(loid));
156
157         pg_largeobject = heap_openr(LargeObjectRelationName, RowShareLock);
158         pg_lo_idx = index_openr(LargeObjectLOidPNIndex);
159
160         sd = index_beginscan(pg_lo_idx, false, 1, skey);
161
162         tuple.t_datamcxt = CurrentMemoryContext;
163         tuple.t_data = NULL;
164
165         while ((indexRes = index_getnext(sd, ForwardScanDirection)))
166         {
167                 tuple.t_self = indexRes->heap_iptr;
168                 heap_fetch(pg_largeobject, SnapshotNow, &tuple, &buffer);
169                 pfree(indexRes);
170                 if (tuple.t_data != NULL)
171                 {
172                         retval = true;
173                         ReleaseBuffer(buffer);
174                         break;
175                 }
176         }
177
178         index_endscan(sd);
179
180         index_close(pg_lo_idx);
181         heap_close(pg_largeobject, RowShareLock);
182
183         return retval;
184 }