Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014 #include "postgres.h"
00015
00016 #include "access/htup_details.h"
00017 #include "commands/trigger.h"
00018 #include "utils/builtins.h"
00019 #include "utils/rel.h"
00020
00021
00022
00023
00024
00025
00026
00027
00028 Datum
00029 suppress_redundant_updates_trigger(PG_FUNCTION_ARGS)
00030 {
00031 TriggerData *trigdata = (TriggerData *) fcinfo->context;
00032 HeapTuple newtuple,
00033 oldtuple,
00034 rettuple;
00035 HeapTupleHeader newheader,
00036 oldheader;
00037
00038
00039 if (!CALLED_AS_TRIGGER(fcinfo))
00040 ereport(ERROR,
00041 (errcode(ERRCODE_E_R_I_E_TRIGGER_PROTOCOL_VIOLATED),
00042 errmsg("suppress_redundant_updates_trigger: must be called as trigger")));
00043
00044
00045 if (!TRIGGER_FIRED_BY_UPDATE(trigdata->tg_event))
00046 ereport(ERROR,
00047 (errcode(ERRCODE_E_R_I_E_TRIGGER_PROTOCOL_VIOLATED),
00048 errmsg("suppress_redundant_updates_trigger: must be called on update")));
00049
00050
00051 if (!TRIGGER_FIRED_BEFORE(trigdata->tg_event))
00052 ereport(ERROR,
00053 (errcode(ERRCODE_E_R_I_E_TRIGGER_PROTOCOL_VIOLATED),
00054 errmsg("suppress_redundant_updates_trigger: must be called before update")));
00055
00056
00057 if (!TRIGGER_FIRED_FOR_ROW(trigdata->tg_event))
00058 ereport(ERROR,
00059 (errcode(ERRCODE_E_R_I_E_TRIGGER_PROTOCOL_VIOLATED),
00060 errmsg("suppress_redundant_updates_trigger: must be called for each row")));
00061
00062
00063 rettuple = newtuple = trigdata->tg_newtuple;
00064 oldtuple = trigdata->tg_trigtuple;
00065
00066 newheader = newtuple->t_data;
00067 oldheader = oldtuple->t_data;
00068
00069
00070
00071
00072
00073
00074
00075
00076 if (trigdata->tg_relation->rd_rel->relhasoids &&
00077 !OidIsValid(HeapTupleHeaderGetOid(newheader)))
00078 HeapTupleHeaderSetOid(newheader, HeapTupleHeaderGetOid(oldheader));
00079
00080
00081 if (newtuple->t_len == oldtuple->t_len &&
00082 newheader->t_hoff == oldheader->t_hoff &&
00083 (HeapTupleHeaderGetNatts(newheader) ==
00084 HeapTupleHeaderGetNatts(oldheader)) &&
00085 ((newheader->t_infomask & ~HEAP_XACT_MASK) ==
00086 (oldheader->t_infomask & ~HEAP_XACT_MASK)) &&
00087 memcmp(((char *) newheader) + offsetof(HeapTupleHeaderData, t_bits),
00088 ((char *) oldheader) + offsetof(HeapTupleHeaderData, t_bits),
00089 newtuple->t_len - offsetof(HeapTupleHeaderData, t_bits)) == 0)
00090 {
00091
00092 rettuple = NULL;
00093 }
00094
00095 return PointerGetDatum(rettuple);
00096 }