mirror of https://github.com/postgres/postgres
this is patch v 0.4 to support transactions with BLOBs. All BLOBs are in one table. You need to make initdb. -- Sincerely Yours, Denis PerchineREL7_1_STABLE
parent
d8e582e236
commit
cf5a950c10
@ -0,0 +1,138 @@ |
|||||||
|
/*-------------------------------------------------------------------------
|
||||||
|
* |
||||||
|
* pg_largeobject.c |
||||||
|
* routines to support manipulation of the pg_largeobject relation |
||||||
|
* |
||||||
|
* Portions Copyright (c) 1996-2000, PostgreSQL, Inc |
||||||
|
* Portions Copyright (c) 1994, Regents of the University of California |
||||||
|
* |
||||||
|
* |
||||||
|
* IDENTIFICATION |
||||||
|
* $Header: /cvsroot/pgsql/src/backend/catalog/pg_largeobject.c,v 1.1 2000/10/08 03:18:53 momjian Exp $ |
||||||
|
* |
||||||
|
*------------------------------------------------------------------------- |
||||||
|
*/ |
||||||
|
#include "postgres.h" |
||||||
|
|
||||||
|
#include "access/genam.h" |
||||||
|
#include "access/heapam.h" |
||||||
|
#include "access/itup.h" |
||||||
|
#include "catalog/catname.h" |
||||||
|
#include "catalog/indexing.h" |
||||||
|
#include "catalog/pg_largeobject.h" |
||||||
|
#include "miscadmin.h" |
||||||
|
#include "parser/parse_func.h" |
||||||
|
#include "utils/builtins.h" |
||||||
|
#include "utils/syscache.h" |
||||||
|
|
||||||
|
bytea *_byteain(const char *data, int32 size); |
||||||
|
|
||||||
|
bytea *_byteain(const char *data, int32 size) { |
||||||
|
bytea *result; |
||||||
|
|
||||||
|
result = (bytea *)palloc(size + VARHDRSZ); |
||||||
|
result->vl_len = size + VARHDRSZ; |
||||||
|
if (size > 0) |
||||||
|
memcpy(result->vl_dat, data, size); |
||||||
|
|
||||||
|
return result; |
||||||
|
} |
||||||
|
|
||||||
|
Oid LargeobjectCreate(Oid loid) { |
||||||
|
Oid retval; |
||||||
|
Relation pg_largeobject; |
||||||
|
HeapTuple ntup = (HeapTuple) palloc(sizeof(HeapTupleData)); |
||||||
|
Relation idescs[Num_pg_largeobject_indices]; |
||||||
|
Datum values[Natts_pg_largeobject]; |
||||||
|
char nulls[Natts_pg_largeobject]; |
||||||
|
int i; |
||||||
|
|
||||||
|
for (i=0; i<Natts_pg_largeobject; i++) { |
||||||
|
nulls[i] = ' '; |
||||||
|
values[i] = (Datum)NULL; |
||||||
|
} |
||||||
|
|
||||||
|
i = 0; |
||||||
|
values[i++] = ObjectIdGetDatum(loid); |
||||||
|
values[i++] = Int32GetDatum(0); |
||||||
|
values[i++] = (Datum) _byteain(NULL, 0); |
||||||
|
|
||||||
|
pg_largeobject = heap_openr(LargeobjectRelationName, RowExclusiveLock); |
||||||
|
ntup = heap_formtuple(pg_largeobject->rd_att, values, nulls); |
||||||
|
retval = heap_insert(pg_largeobject, ntup); |
||||||
|
|
||||||
|
if (!IsIgnoringSystemIndexes()) { |
||||||
|
CatalogOpenIndices(Num_pg_largeobject_indices, Name_pg_largeobject_indices, idescs); |
||||||
|
CatalogIndexInsert(idescs, Num_pg_largeobject_indices, pg_largeobject, ntup); |
||||||
|
CatalogCloseIndices(Num_pg_largeobject_indices, idescs); |
||||||
|
} |
||||||
|
|
||||||
|
heap_close(pg_largeobject, RowExclusiveLock); |
||||||
|
heap_freetuple(ntup); |
||||||
|
|
||||||
|
CommandCounterIncrement(); |
||||||
|
|
||||||
|
return retval; |
||||||
|
} |
||||||
|
|
||||||
|
void LargeobjectDrop(Oid loid) { |
||||||
|
Relation pg_largeobject; |
||||||
|
Relation pg_lo_id; |
||||||
|
ScanKeyData skey; |
||||||
|
IndexScanDesc sd = (IndexScanDesc) NULL; |
||||||
|
RetrieveIndexResult indexRes; |
||||||
|
int found = 0; |
||||||
|
|
||||||
|
ScanKeyEntryInitialize(&skey, |
||||||
|
(bits16) 0x0, |
||||||
|
(AttrNumber) 1, |
||||||
|
(RegProcedure) F_OIDEQ, |
||||||
|
ObjectIdGetDatum(loid)); |
||||||
|
|
||||||
|
pg_largeobject = heap_openr(LargeobjectRelationName, RowShareLock); |
||||||
|
pg_lo_id = index_openr(LargeobjectLOIdIndex); |
||||||
|
|
||||||
|
sd = index_beginscan(pg_lo_id, false, 1, &skey); |
||||||
|
|
||||||
|
while((indexRes = index_getnext(sd, ForwardScanDirection))) { |
||||||
|
found++; |
||||||
|
heap_delete(pg_largeobject, &indexRes->heap_iptr, NULL); |
||||||
|
pfree(indexRes); |
||||||
|
} |
||||||
|
|
||||||
|
index_endscan(sd); |
||||||
|
|
||||||
|
index_close(pg_lo_id); |
||||||
|
heap_close(pg_largeobject, RowShareLock); |
||||||
|
if (found == 0) |
||||||
|
elog(ERROR, "LargeobjectDrop: large object %d not found", loid); |
||||||
|
} |
||||||
|
|
||||||
|
int LargeobjectFind(Oid loid) { |
||||||
|
int retval = 0; |
||||||
|
Relation pg_lo_id; |
||||||
|
ScanKeyData skey; |
||||||
|
IndexScanDesc sd = (IndexScanDesc) NULL; |
||||||
|
RetrieveIndexResult indexRes; |
||||||
|
|
||||||
|
ScanKeyEntryInitialize(&skey, |
||||||
|
(bits16) 0x0, |
||||||
|
(AttrNumber) 1, |
||||||
|
(RegProcedure) F_OIDEQ, |
||||||
|
ObjectIdGetDatum(loid)); |
||||||
|
|
||||||
|
pg_lo_id = index_openr(LargeobjectLOIdIndex); |
||||||
|
|
||||||
|
sd = index_beginscan(pg_lo_id, false, 1, &skey); |
||||||
|
|
||||||
|
if ((indexRes = index_getnext(sd, ForwardScanDirection))) { |
||||||
|
retval = 1; |
||||||
|
pfree(indexRes); |
||||||
|
} |
||||||
|
|
||||||
|
index_endscan(sd); |
||||||
|
|
||||||
|
index_close(pg_lo_id); |
||||||
|
return retval; |
||||||
|
} |
||||||
|
|
||||||
@ -0,0 +1,63 @@ |
|||||||
|
/*-------------------------------------------------------------------------
|
||||||
|
* |
||||||
|
* pg_largeobject.h |
||||||
|
* definition of the system "largeobject" relation (pg_largeobject) |
||||||
|
* along with the relation's initial contents. |
||||||
|
* |
||||||
|
* |
||||||
|
* Portions Copyright (c) 1996-2000, PostgreSQL, Inc |
||||||
|
* Portions Copyright (c) 1994, Regents of the University of California |
||||||
|
* |
||||||
|
* $Id: pg_largeobject.h,v 1.1 2000/10/08 03:18:56 momjian Exp $ |
||||||
|
* |
||||||
|
* NOTES |
||||||
|
* the genbki.sh script reads this file and generates .bki |
||||||
|
* information from the DATA() statements. |
||||||
|
* |
||||||
|
*------------------------------------------------------------------------- |
||||||
|
*/ |
||||||
|
#ifndef PG_LARGEOBJECT_H |
||||||
|
#define PG_LARGEOBJECT_H |
||||||
|
|
||||||
|
/* ----------------
|
||||||
|
* postgres.h contains the system type definintions and the |
||||||
|
* CATALOG(), BOOTSTRAP and DATA() sugar words so this file |
||||||
|
* can be read by both genbki.sh and the C compiler. |
||||||
|
* ---------------- |
||||||
|
*/ |
||||||
|
|
||||||
|
/* ----------------
|
||||||
|
* pg_largeobject definition. cpp turns this into |
||||||
|
* typedef struct FormData_pg_largeobject. Large object id |
||||||
|
* is stored in loid; |
||||||
|
* ---------------- |
||||||
|
*/ |
||||||
|
|
||||||
|
CATALOG(pg_largeobject) |
||||||
|
{ |
||||||
|
Oid loid; |
||||||
|
int4 pageno; |
||||||
|
bytea data; |
||||||
|
} FormData_pg_largeobject; |
||||||
|
|
||||||
|
/* ----------------
|
||||||
|
* Form_pg_largeobject corresponds to a pointer to a tuple with |
||||||
|
* the format of pg_largeobject relation. |
||||||
|
* ---------------- |
||||||
|
*/ |
||||||
|
typedef FormData_pg_largeobject *Form_pg_largeobject; |
||||||
|
|
||||||
|
/* ----------------
|
||||||
|
* compiler constants for pg_largeobject |
||||||
|
* ---------------- |
||||||
|
*/ |
||||||
|
#define Natts_pg_largeobject 3 |
||||||
|
#define Anum_pg_largeobject_loid 1 |
||||||
|
#define Anum_pg_largeobject_pageno 2 |
||||||
|
#define Anum_pg_largeobject_data 3 |
||||||
|
|
||||||
|
Oid LargeobjectCreate(Oid loid); |
||||||
|
void LargeobjectDrop(Oid loid); |
||||||
|
int LargeobjectFind(Oid loid); |
||||||
|
|
||||||
|
#endif /* PG_LARGEOBJECT_H */ |
||||||
Loading…
Reference in new issue