aboutsummaryrefslogtreecommitdiff
path: root/src/backend/utils/adt/ri_triggers.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/backend/utils/adt/ri_triggers.c')
-rw-r--r--src/backend/utils/adt/ri_triggers.c125
1 files changed, 124 insertions, 1 deletions
diff --git a/src/backend/utils/adt/ri_triggers.c b/src/backend/utils/adt/ri_triggers.c
index a5c7fe8b321..e2b38821d85 100644
--- a/src/backend/utils/adt/ri_triggers.c
+++ b/src/backend/utils/adt/ri_triggers.c
@@ -6,7 +6,7 @@
*
* 1999 Jan Wieck
*
- * $Header: /cvsroot/pgsql/src/backend/utils/adt/ri_triggers.c,v 1.11 2000/01/06 16:30:43 wieck Exp $
+ * $Header: /cvsroot/pgsql/src/backend/utils/adt/ri_triggers.c,v 1.12 2000/01/06 20:46:51 wieck Exp $
*
* ----------
*/
@@ -467,6 +467,34 @@ RI_FKey_check_upd (FmgrInfo *proinfo)
/* ----------
+ * RI_FKey_noaction_del -
+ *
+ * This is here only to let the trigger manager trace for
+ * "triggered data change violation"
+ * ----------
+ */
+HeapTuple
+RI_FKey_noaction_del (FmgrInfo *proinfo)
+{
+ return NULL;
+}
+
+
+/* ----------
+ * RI_FKey_noaction_upd -
+ *
+ * This is here only to let the trigger manager trace for
+ * "triggered data change violation"
+ * ----------
+ */
+HeapTuple
+RI_FKey_noaction_upd (FmgrInfo *proinfo)
+{
+ return NULL;
+}
+
+
+/* ----------
* RI_FKey_cascade_del -
*
* Cascaded delete foreign key references at delete event on PK table.
@@ -2252,6 +2280,101 @@ RI_FKey_setdefault_upd (FmgrInfo *proinfo)
}
+/* ----------
+ * RI_FKey_keyequal_upd -
+ *
+ * Check if we have a key change on update.
+ *
+ * This is no real trigger procedure. It is used by the deferred
+ * trigger queue manager to detect "triggered data change violation".
+ * ----------
+ */
+bool
+RI_FKey_keyequal_upd (void)
+{
+ TriggerData *trigdata;
+ int tgnargs;
+ char **tgargs;
+ Relation fk_rel;
+ Relation pk_rel;
+ HeapTuple new_row;
+ HeapTuple old_row;
+ RI_QueryKey qkey;
+
+ trigdata = CurrentTriggerData;
+ CurrentTriggerData = NULL;
+
+ /* ----------
+ * Check for the correct # of call arguments
+ * ----------
+ */
+ tgnargs = trigdata->tg_trigger->tgnargs;
+ tgargs = trigdata->tg_trigger->tgargs;
+ if (tgnargs < 4 || (tgnargs % 2) != 0)
+ elog(ERROR, "wrong # of arguments in call to RI_FKey_keyequal_upd()");
+ if (tgnargs > RI_MAX_ARGUMENTS)
+ elog(ERROR, "too many keys (%d max) in call to RI_FKey_keyequal_upd()",
+ RI_MAX_NUMKEYS);
+
+ /* ----------
+ * Nothing to do if no column names to compare given
+ * ----------
+ */
+ if (tgnargs == 4)
+ return true;
+
+ /* ----------
+ * Get the relation descriptors of the FK and PK tables and
+ * the new and old tuple.
+ * ----------
+ */
+ fk_rel = heap_openr(tgargs[RI_FK_RELNAME_ARGNO], NoLock);
+ pk_rel = trigdata->tg_relation;
+ new_row = trigdata->tg_newtuple;
+ old_row = trigdata->tg_trigtuple;
+
+ switch (ri_DetermineMatchType(tgargs[RI_MATCH_TYPE_ARGNO]))
+ {
+ /* ----------
+ * MATCH <UNSPECIFIED>
+ * ----------
+ */
+ case RI_MATCH_TYPE_UNSPECIFIED:
+ elog(ERROR, "MATCH <unspecified> not implemented yet");
+ break;
+
+ case RI_MATCH_TYPE_FULL:
+ ri_BuildQueryKeyFull(&qkey, trigdata->tg_trigger->tgoid,
+ 0,
+ fk_rel, pk_rel,
+ tgnargs, tgargs);
+ heap_close(fk_rel, NoLock);
+
+ /* ----------
+ * Return if key's are equal
+ * ----------
+ */
+ return ri_KeysEqual(pk_rel, old_row, new_row, &qkey,
+ RI_KEYPAIR_PK_IDX);
+
+ /* ----------
+ * Handle MATCH PARTIAL set null delete.
+ * ----------
+ */
+ case RI_MATCH_TYPE_PARTIAL:
+ elog(ERROR, "MATCH PARTIAL not yet supported");
+ break;
+ }
+
+ /* ----------
+ * Never reached
+ * ----------
+ */
+ elog(ERROR, "internal error #9 in ri_triggers.c");
+ return false;
+}
+
+