Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008 #include "postgres.h"
00009
00010 #include "commands/trigger.h"
00011 #include "executor/spi.h"
00012 #include "libpq/be-fsstubs.h"
00013 #include "utils/rel.h"
00014
00015
00016 PG_MODULE_MAGIC;
00017
00018 #define atooid(x) ((Oid) strtoul((x), NULL, 10))
00019
00020
00021
00022 Datum lo_manage(PG_FUNCTION_ARGS);
00023
00024
00025
00026
00027
00028 PG_FUNCTION_INFO_V1(lo_manage);
00029
00030 Datum
00031 lo_manage(PG_FUNCTION_ARGS)
00032 {
00033 TriggerData *trigdata = (TriggerData *) fcinfo->context;
00034 int attnum;
00035 char **args;
00036 TupleDesc tupdesc;
00037 HeapTuple rettuple;
00038 bool isdelete;
00039 HeapTuple newtuple;
00040 HeapTuple trigtuple;
00041
00042 if (!CALLED_AS_TRIGGER(fcinfo))
00043 elog(ERROR, "not fired by trigger manager");
00044
00045
00046
00047
00048 newtuple = trigdata->tg_newtuple;
00049 trigtuple = trigdata->tg_trigtuple;
00050 tupdesc = trigdata->tg_relation->rd_att;
00051 args = trigdata->tg_trigger->tgargs;
00052
00053
00054 if (TRIGGER_FIRED_BY_UPDATE(trigdata->tg_event))
00055 rettuple = newtuple;
00056 else
00057 rettuple = trigtuple;
00058
00059
00060 isdelete = TRIGGER_FIRED_BY_DELETE(trigdata->tg_event);
00061
00062
00063 attnum = SPI_fnumber(tupdesc, args[0]);
00064
00065 if (attnum <= 0)
00066 elog(ERROR, "column \"%s\" does not exist", args[0]);
00067
00068
00069
00070
00071
00072
00073
00074 if (newtuple != NULL)
00075 {
00076 char *orig = SPI_getvalue(trigtuple, tupdesc, attnum);
00077 char *newv = SPI_getvalue(newtuple, tupdesc, attnum);
00078
00079 if (orig != NULL && (newv == NULL || strcmp(orig, newv) != 0))
00080 DirectFunctionCall1(lo_unlink,
00081 ObjectIdGetDatum(atooid(orig)));
00082
00083 if (newv)
00084 pfree(newv);
00085 if (orig)
00086 pfree(orig);
00087 }
00088
00089
00090
00091
00092
00093
00094 if (isdelete)
00095 {
00096 char *orig = SPI_getvalue(trigtuple, tupdesc, attnum);
00097
00098 if (orig != NULL)
00099 {
00100 DirectFunctionCall1(lo_unlink,
00101 ObjectIdGetDatum(atooid(orig)));
00102
00103 pfree(orig);
00104 }
00105 }
00106
00107 return PointerGetDatum(rettuple);
00108 }