и/или "внучатыми" по отношению к T1, с "on delete cascade". При этом эти дочерние/внучатые таблицы друг на друга ещё ссылаются, "on delete restrict".
Ну например так:
T1 <- A <- B <- C — все связи cascade
T1 <- D — тоже cascade
C -> D — restrict
можно ли ожидать, что при удалении записи из T1 PG разберётся со всеми связими, сделает топологическую сортировку и удалит весь этот вложенный зоопарк в правильном порядке?
Хмм... а почему нет (если "зоопарк" можно удалить, т.е. restrict не мешают)? Можно же попробовать на конкретном примере, хотя бы...
похоже не, не умеет PG топологическую сортировку :/ https://gist.github.com/portnov/a58596ce86b68e81e623df6515d59781 https://sqlize.online/sql/psql15/52d62221f1ee706fc8a1e7b9e0752b07/
т.е. оно сначала пытается удалить из D. Ну хз почему, захотелось так.
> похоже не, не умеет PG топологическую сортировку :/ А вот должен ли он, я сходу не скажу... Хмм... а это в каких-то других СУБД удаляет все записи (а с NO ACTION какое поведение)?
https://sqlize.online/sql/oracle21/92285cd4e5627905f45bb17ff0327202/ на оракле работает.
Хмм... а точно: -- on delete restrict is oracle's default ? Это нарушает ISO SQL, я вот к чему (default должен быть NO ACTION ).
Oracle allows three different definitions under the definition of the foreign key: ON DELETE CASCADE (when a referenced parent table row is removed all the child are removed automatically) The ON DELETE SET NULL action allows data that references the parent key to be deleted, but not updated. When referenced data in the parent key is deleted, all rows in the child table that depend on those parent key values have their foreign keys set to null. ON DELETE NO ACTION (which is the default) prevents deleting a parent when there are children (would be nice arrangement for real life) так, а чем restrict от no action отличается?... в PG — похоже, ничем: если я в примере выше заменяю, ничего не меняется.
> ON DELETE NO ACTION (which is the default) Т.е. default правильный, а RESTRICT нет? > так, а чем restrict от no action отличается? "NOTE 72 — 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." © sql:2016 > в PG — похоже, ничем: если я в примере выше заменяю, ничего не меняется. Да, я тоже заметил. А вот правильно ли это — сходу не скажу (надо копаться в стандарте).
да, в оракле нет on delete restrict.
(Я тут обсудил это с некоторыми contributors) Вы могли бы написать bug report (да, на всякий случай — код repro должен быть в самом report / e-mail, а не ссылкой куда-то — а то они "протухают" N лет спустя, и архивы читать нормально не получается)?
хм, я не против написать репорт, только надо разобраться, куда именно :)
Либо в -bugs, либо прямо вот так: https://www.postgresql.org/account/submitbug/
юзайте deferrable initially deferred, говорят :)
Обсуждают сегодня