From 6f9883b8b2ab1d3cb68e623e662be99fc5de68ad Mon Sep 17 00:00:00 2001 From: "Michael J. Sullivan" Date: Fri, 28 Feb 2025 11:45:54 -0800 Subject: [PATCH] Fix `ON TARGET DELETE ALLOW` behavior when link optionality is changed (#8419) Currently, if you change whether a link is required, the behavior of `ON TARGET DELETE ALLOW` isn't updated, so it might either incorrectly allow or disallow deleting the last link, depending. Fixes #8417. --- edb/pgsql/delta.py | 11 +++++++++++ tests/test_edgeql_ddl.py | 40 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 51 insertions(+) diff --git a/edb/pgsql/delta.py b/edb/pgsql/delta.py index b447e6a4c07..82447d29499 100644 --- a/edb/pgsql/delta.py +++ b/edb/pgsql/delta.py @@ -5278,6 +5278,17 @@ def apply( self._alter_pointer_optionality( schema, orig_schema, context, fill_expr=self.fill_expr) + # If the link has an Allow on target delete action, we + # need to refresh the triggers, since required and + # optional behave differently. (Required does a + # check.) + if ( + self.scls.get_on_target_delete(schema) == + s_links.LinkTargetDeleteAction.Allow + ): + self.schedule_endpoint_delete_action_update( + self.scls, orig_schema, schema, context) + return schema diff --git a/tests/test_edgeql_ddl.py b/tests/test_edgeql_ddl.py index ceb26985f85..aedd5d56194 100644 --- a/tests/test_edgeql_ddl.py +++ b/tests/test_edgeql_ddl.py @@ -16259,6 +16259,46 @@ async def test_edgeql_ddl_link_policy_16(self): [], ) + async def test_edgeql_ddl_link_policy_17(self): + # Make sure that ALLOW works when changing optionality + await self.con.execute(r""" + CREATE TYPE Tgt; + CREATE TYPE Src { + CREATE MULTI LINK tgt -> Tgt { + ON TARGET DELETE ALLOW; + } + }; + """) + + await self.con.execute(r""" + INSERT Src { tgt := (INSERT Tgt) }; + """) + + await self.con.execute(r""" + ALTER TYPE Src { + ALTER LINK tgt { + SET REQUIRED + } + }; + """) + + async with self.assertRaisesRegexTx(edgedb.MissingRequiredError, ''): + await self.con.execute(""" + DELETE Tgt; + """) + + await self.con.execute(r""" + ALTER TYPE Src { + ALTER LINK tgt { + SET OPTIONAL + } + }; + """) + + await self.con.execute(""" + DELETE Tgt; + """) + async def test_edgeql_ddl_link_policy_implicit_01(self): await self.con.execute(""" create type T;