2
* PostgreSQL definitions for managed Large Objects.
10
/* Required for SPI */
11
#include "executor/spi.h"
13
/* Required for largeobjects */
14
#include "libpq/be-fsstubs.h"
15
#include "libpq/libpq-fs.h"
17
/* Required for triggers */
18
#include "commands/trigger.h"
22
#define atooid(x) ((Oid) strtoul((x), NULL, 10))
25
/* forward declarations */
26
Datum lo_manage(PG_FUNCTION_ARGS);
30
* This is the trigger that protects us from orphaned large objects
32
PG_FUNCTION_INFO_V1(lo_manage);
35
lo_manage(PG_FUNCTION_ARGS)
37
TriggerData *trigdata = (TriggerData *) fcinfo->context;
38
int attnum; /* attribute number to monitor */
39
char **args; /* Args containing attr name */
40
TupleDesc tupdesc; /* Tuple Descriptor */
41
HeapTuple rettuple; /* Tuple to be returned */
42
bool isdelete; /* are we deleting? */
43
HeapTuple newtuple; /* The new value for tuple */
44
HeapTuple trigtuple; /* The original value of tuple */
46
if (!CALLED_AS_TRIGGER(fcinfo)) /* internal error */
47
elog(ERROR, "not fired by trigger manager");
50
* Fetch some values from trigdata
52
newtuple = trigdata->tg_newtuple;
53
trigtuple = trigdata->tg_trigtuple;
54
tupdesc = trigdata->tg_relation->rd_att;
55
args = trigdata->tg_trigger->tgargs;
57
/* tuple to return to Executor */
58
if (TRIGGER_FIRED_BY_UPDATE(trigdata->tg_event))
63
/* Are we deleting the row? */
64
isdelete = TRIGGER_FIRED_BY_DELETE(trigdata->tg_event);
66
/* Get the column we're interested in */
67
attnum = SPI_fnumber(tupdesc, args[0]);
70
elog(ERROR, "column \"%s\" does not exist", args[0]);
75
* Here, if the value of the monitored attribute changes, then the large
76
* object associated with the original value is unlinked.
80
char *orig = SPI_getvalue(trigtuple, tupdesc, attnum);
81
char *newv = SPI_getvalue(newtuple, tupdesc, attnum);
83
if (orig != NULL && (newv == NULL || strcmp(orig, newv) != 0))
84
DirectFunctionCall1(lo_unlink,
85
ObjectIdGetDatum(atooid(orig)));
94
* Handle deleting of rows
96
* Here, we unlink the large object associated with the managed attribute
100
char *orig = SPI_getvalue(trigtuple, tupdesc, attnum);
104
DirectFunctionCall1(lo_unlink,
105
ObjectIdGetDatum(atooid(orig)));
111
return PointerGetDatum(rettuple);