Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

NO ACTION should be different from RESTRICT #2440

Open
Sanadis opened this issue Feb 12, 2020 · 3 comments
Open

NO ACTION should be different from RESTRICT #2440

Sanadis opened this issue Feb 12, 2020 · 3 comments

Comments

@Sanadis
Copy link

Sanadis commented Feb 12, 2020

We have a couple of foreign keys in our database that reference another record within the same table. As of release 1.4.200, if we attempt to delete records in which the first record is referenced by the second record, a Referential integrity constraint violation will occur. We were previously using 1.4.199 and this was not an issue, and I would not expect this to ever be an issue as the DBMS is typically designed to handle this scenario.

Here is the query I used to test with (Ran through the H2 web client):

DROP TABLE IF EXISTS TEST;
CREATE TABLE TEST(
  ID INT PRIMARY KEY,
  NAME VARCHAR(255),
  UPLINEID INT,
  FOREIGN KEY (UPLINEID) REFERENCES TEST(ID)
);

INSERT INTO TEST VALUES(1, 'A', NULL); 
INSERT INTO TEST VALUES(2, 'A', 1);

DELETE FROM TEST WHERE NAME='A';
DROP TABLE IF EXISTS TEST;
Update count: 0
(1 ms)

CREATE TABLE TEST(
  ID INT PRIMARY KEY,
  NAME VARCHAR(255),
  UPLINEID INT,
  FOREIGN KEY (UPLINEID) REFERENCES TEST(ID)
);
Update count: 0
(3 ms)

INSERT INTO TEST VALUES(1, 'A', NULL);
Update count: 1
(0 ms)
 
INSERT INTO TEST VALUES(2, 'A', 1);
Update count: 1
(0 ms)

DELETE FROM TEST WHERE NAME='A';
Referential integrity constraint violation: "CONSTRAINT_27: PUBLIC.TEST FOREIGN KEY(UPLINEID) REFERENCES PUBLIC.TEST(ID) (1)"; SQL statement:
DELETE FROM TEST WHERE NAME='A' [23503-200] 23503/23503 (Help)

ID 2 uses the UPLINEID to reference ID 1. I assume what is happening is that the delete is just sequentially attempts to delete the first first and then the second.

Edit:
I have also tested with using CASCADE on the constraint:
FOREIGN KEY (UPLINEID) REFERENCES TEST(ID) ON DELETE CASCADE

This does allow it to work, although this would make the behavior of H2 different than SQL Server, Oracle, etc since they handle this fine without cascading.

@katzyn
Copy link
Contributor

katzyn commented Feb 13, 2020

The SQL Standard determines behavior in the following way:

If a <referential constraint definition> does not specify any <delete rule>, then a <delete rule> with a <referential action> of NO ACTION is implicit.

A <delete rule> that does not specify NO ACTION specifies a referential delete action. Referential update actions and referential delete actions are collectively called referential actions. Referential actions are carried out before, and are not part of, the checking of a referential constraint.

ON DELETE NO ACTION (the default): there is no referential delete action; the referential constraint only specifies a constraint check.
NOTE — Even if constraint checking is not deferred, ON DELETE RESTRICT is a stricter condition than ON DELETE NO ACTION. ON DELETE RESTRICT prohibits a delete of a particular row if there are any matching rows; ON DELETE NO ACTION does not perform its constraint check until the entire set of rows to be deleted has been processed.

H2 incorrectly treats the default and explicit NO ACTION in the same way as RESTRICT.

@katzyn katzyn changed the title Same table Referential violation starting in release 1.4.200 NO ACTION should be different from RESTRICT Feb 13, 2020
@longstone
Copy link

@katzyn many thanks for your work!
Do you have plans to fix this problem? And if so, can you already give a possible (next release) date?

@katzyn
Copy link
Contributor

katzyn commented Mar 15, 2021

Sorry, I don't have enough time for this problem.

H2 is developed by its community and contributions are welcome, as usual. But this issue isn't trivial and may require good knowledge of H2's internals.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants