]> granicus.if.org Git - postgresql/blob - src/backend/catalog/pg_largeobject.c
bce3a47b93128165675d440f7554333a4bfad2fc
[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-2005, PostgreSQL Global Development Group
7  * Portions Copyright (c) 1994, Regents of the University of California
8  *
9  *
10  * IDENTIFICATION
11  *        $PostgreSQL: pgsql/src/backend/catalog/pg_largeobject.c,v 1.23 2005/02/23 23:27:54 neilc 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         Datum           values[Natts_pg_largeobject];
40         char            nulls[Natts_pg_largeobject];
41         int                     i;
42
43         pg_largeobject = heap_openr(LargeObjectRelationName, RowExclusiveLock);
44
45         /*
46          * Form new tuple
47          */
48         for (i = 0; i < Natts_pg_largeobject; i++)
49         {
50                 values[i] = (Datum) NULL;
51                 nulls[i] = ' ';
52         }
53
54         i = 0;
55         values[i++] = ObjectIdGetDatum(loid);
56         values[i++] = Int32GetDatum(0);
57         values[i++] = DirectFunctionCall1(byteain,
58                                                                           CStringGetDatum(""));
59
60         ntup = heap_formtuple(pg_largeobject->rd_att, values, nulls);
61
62         /*
63          * Insert it
64          */
65         simple_heap_insert(pg_largeobject, ntup);
66
67         /* Update indexes */
68         CatalogUpdateIndexes(pg_largeobject, ntup);
69
70         heap_close(pg_largeobject, RowExclusiveLock);
71
72         heap_freetuple(ntup);
73 }
74
75 void
76 LargeObjectDrop(Oid loid)
77 {
78         bool            found = false;
79         Relation        pg_largeobject;
80         ScanKeyData skey[1];
81         SysScanDesc sd;
82         HeapTuple       tuple;
83
84         ScanKeyInit(&skey[0],
85                                 Anum_pg_largeobject_loid,
86                                 BTEqualStrategyNumber, F_OIDEQ,
87                                 ObjectIdGetDatum(loid));
88
89         pg_largeobject = heap_openr(LargeObjectRelationName, RowExclusiveLock);
90
91         sd = systable_beginscan(pg_largeobject, LargeObjectLOidPNIndex, true,
92                                                         SnapshotNow, 1, skey);
93
94         while ((tuple = systable_getnext(sd)) != NULL)
95         {
96                 simple_heap_delete(pg_largeobject, &tuple->t_self);
97                 found = true;
98         }
99
100         systable_endscan(sd);
101
102         heap_close(pg_largeobject, RowExclusiveLock);
103
104         if (!found)
105                 ereport(ERROR,
106                                 (errcode(ERRCODE_UNDEFINED_OBJECT),
107                                  errmsg("large object %u does not exist", loid)));
108 }
109
110 bool
111 LargeObjectExists(Oid loid)
112 {
113         bool            retval = false;
114         Relation        pg_largeobject;
115         ScanKeyData skey[1];
116         SysScanDesc sd;
117
118         /*
119          * See if we can find any tuples belonging to the specified LO
120          */
121         ScanKeyInit(&skey[0],
122                                 Anum_pg_largeobject_loid,
123                                 BTEqualStrategyNumber, F_OIDEQ,
124                                 ObjectIdGetDatum(loid));
125
126         pg_largeobject = heap_openr(LargeObjectRelationName, AccessShareLock);
127
128         sd = systable_beginscan(pg_largeobject, LargeObjectLOidPNIndex, true,
129                                                         SnapshotNow, 1, skey);
130
131         if (systable_getnext(sd) != NULL)
132                 retval = true;
133
134         systable_endscan(sd);
135
136         heap_close(pg_largeobject, AccessShareLock);
137
138         return retval;
139 }