Cascading foreign keys in mariadb, do they activate triggers? - triggers

From http://dev.mysql.com/doc/refman/5.6/en/innodb-restrictions.html
Currently, cascaded foreign key actions do not activate triggers.
Does this work in MariaDB?

According to the documentation, it seems that it doesn't work in MariaDB either:
The following restrictions apply to triggers.
[...]
Triggers are not activated by foreign key actions.
"Foreign key actions" refers to the action to perform (RESTRICT, CASCADE, SET NULL, NO ACTION, SET DEFAULT) on the rows in the current table which references deleted or updated rows in the referenced table.
Also see related bugs:
MySQL: https://bugs.mysql.com/bug.php?id=11472
MariaDB: https://jira.mariadb.org/browse/MDEV-19402

Related

Postgres: DISABLE TRIGGER ALL and ON UPDATE CASCADE

It seems like when I
ALTER TABLE foo DISABLE TRIGGER ALL;
DELETE FROM foo;
The deletions don't get cascaded to other tables with
FOREIGN KEY ("fooId") REFERENCES "foo"("id") ON DELETE CASCADE
constraints, but I can't find anything in the documentation about this.
I also don't see any triggers I didn't create in
SELECT * FROM information_schema.triggers;
I'm guessing ON UPDATE/ON DELETE are implemented internally as triggers (which aren't visible in pgAdmin)? Does anyone know where this is documented?
Try here:
DISABLE/ENABLE [ REPLICA | ALWAYS ] TRIGGER
These forms configure the firing of trigger(s) belonging to the table. A disabled trigger is still known to the system, but is not executed when its triggering event occurs. For a deferred trigger, the enable status is checked when the event occurs, not when the trigger function is actually executed. One can disable or enable a single trigger specified by name, or all triggers on the table, or only user triggers (this option excludes internally generated constraint triggers such as those that are used to implement foreign key constraints or deferrable uniqueness and exclusion constraints). Disabling or enabling internally generated constraint triggers requires superuser privileges; it should be done with caution since of course the integrity of the constraint cannot be guaranteed if the triggers are not executed.

Disable all constraints besides uniques

What is the query to disable all constraints like foreign keys, primary keys but leave uniques?
PostgreSQL does not allow to disable constraints generally speaking. You can only disable foreign key constraints by disabling the related trigger used to implement the foreign keys.
See https://www.postgresql.org/docs/12/sql-altertable.html#SQL-ALTERTABLE-NOTES
DISABLE/ENABLE [ REPLICA | ALWAYS ] TRIGGER
One can disable or enable a single trigger specified by name, or all
triggers on the table, or only user triggers (this option excludes
internally generated constraint triggers such as those that are used
to implement foreign key constraints or deferrable uniqueness and
exclusion constraints). Disabling or enabling internally generated
constraint triggers requires superuser privileges; it should be done
with caution since of course the integrity of the constraint cannot be
guaranteed if the triggers are not executed.

FOR KEY SHARE - what are 'key values'?

The documentation states
A key-shared lock blocks other transactions from performing DELETE or any UPDATE that changes the key values.
Does "key values" refer to the primary key, or the unique keys, or the indexed keys, or the columns used for the SELECT query?
The term key values refers foreign keys.
Alvaro Herrera, the author of the patch in Postgres 9.3 wrote (per this source):
Foreign key triggers now use FOR KEY SHARE instead of FOR SHARE; this
means the concurrency improvement applies to them, which is the whole
point of this patch.
You can also find this mention in the documentation:
Currently, the set of columns considered for the UPDATE case are those that have a unique index on them that can be used in a foreign key (so partial indexes and expressional indexes are not considered), but this may change in the future.

What is deferrable in Sequelize foreign key?

I am learning Sequelize and models' foreign keys, however I don't understand what's the purpose deferable field
It will create a foreign key that will check the constraints
I don't understand what's constraints(limitations) here. should I define it? I already viewed the code on official docs but It's no help and can't understand its' usage. Would appreciate if someone help me understand.
The docs mention:
A collection of properties related to deferrable constraints. It can
be used to make foreign key constraints deferrable and to set the
constraints within a transaction. This is only supported in
PostgreSQL.
So, that's your hint to google for postgres foreign key deferrable or similar. The postgres docs say:
SET CONSTRAINTS sets the behavior of constraint checking within the
current transaction. IMMEDIATE constraints are checked at the end of
each statement. DEFERRED constraints are not checked until transaction
commit. Each constraint has its own IMMEDIATE or DEFERRED mode.
Upon creation, a constraint is given one of three characteristics:
DEFERRABLE INITIALLY DEFERRED, DEFERRABLE INITIALLY IMMEDIATE, or NOT
DEFERRABLE. The third class is always IMMEDIATE and is not affected by
the SET CONSTRAINTS command. The first two classes start every
transaction in the indicated mode, but their behavior can be changed
within a transaction by SET CONSTRAINTS.
Unpacking that: deferrable means you can "defer" the checking of foreign key constraints til the end of a transaction. (Transactions, by the way, are basically "groups of queries" that either all succeed, or, if one of them fails, all the others are rolled back too.)
Let's take a contrived example: imagine you have a blogs table that has a foreign key that points to a categories table. When you insert a new blog post, the category it links to must exist - otherwise that blogs to categories foreign key constraint will fail. BUT... if we use the deffered feature, then we could do something like this (in psuedo-code):
1. Being a transaction
2. Tell postgres to use deferred foreign key constraints for this transaction
3. Insert a blog that links to the "Hello World" category (which does not yet exist)
3a. (Note this is where Postgres would normally check the foreign key constraint and fail)
4. Insert the "Hello World" Category
5. Commit the transaction
6. Because we're using the DEFERRED feature, the foreign key check
will happen now, at the end of the transaction, instead of at 3a,
and it will succeed, because "Hello Wolrd" category now exists!
To cut a long story short, you should leave out the deferrable key (or set it to false) unless you know you need it.

Cascade deletion of an object that can be related to itself

In my database, I have a number of objects that can be related to each other.
This is fine, until I decide I want to delete these objects. Because of the relation record, I need to implement cascade delete to prevent an exception from being thrown.
When an object that is on either side of the relation is deleted, I want the relation record to be deleted too. I would like to create a database structure that looks like this:
CREATE TABLE [MyObject]
(
[ID] [int] IDENTITY PRIMARY KEY,
...
);
CREATE TABLE [MyObjectRelation]
(
[ID] [int] IDENTITY PRIMARY KEY,
[MyObjectID] [int] FOREIGN KEY REFERENCES [MyObject] ([ID]) ON DELETE CASCADE,
[RelatedMyObjectID] [int] FOREIGN KEY REFERENCES [MyObject] ([ID]) ON DELETE CASCADE
)
However, whenever I attempt to run this on my database, I receive this error message:
Introducing FOREIGN KEY constraint '...' on table 'MyObjectRelation' may cause cycles or multiple cascade paths. Specify ON DELETE NO ACTION or ON UPDATE NO ACTION, or modify other FOREIGN KEY constraints.
I have read the documentation about this, but I do not see how this layout could cause a cycle. It is entirely possible of course, that I have misinterpreted the documentation on MSDN for cascade delete, and the database layout above will not achieve what I want here.
I would be very interested in hearing what I can do to implement the behaviour that I want.
You receive this error message because in SQL Server, a table cannot appear more than one time in a list of all the cascading referential actions that are started by either a DELETE or an UPDATE statement. For example, the tree of cascading referential actions must only have one path to a particular table on the cascading referential actions tree.
You can use triggers to achieve the same behavior.