Skip to content

Commit

Permalink
Fix and cleanup reference deletion propagation
Browse files Browse the repository at this point in the history
The current coding of inherited reference deletion propagation
mishandles object indexes that use fully-qualified names as keys.
  • Loading branch information
elprans committed May 11, 2020
1 parent 30397c9 commit 4e53ad5
Showing 1 changed file with 17 additions and 16 deletions.
33 changes: 17 additions & 16 deletions edb/schema/referencing.py
Original file line number Diff line number Diff line change
Expand Up @@ -1146,14 +1146,21 @@ def _delete_ref(
sd.AlterObject, referrer_class)

for child in referrer.children(schema):
assert isinstance(child, so.QualifiedObject)
child_coll = child.get_field_value(schema, refdict.attr)
existing = child_coll.get(schema, refname, None)
fq_refname_in_child = self._classname_from_name(
self_name,
child.get_name(schema),
)
child_refname = reftype.get_key_for_name(
schema, fq_refname_in_child)
existing = child_coll.get(schema, child_refname, None)

if existing is not None:
alter = alter_cmd(classname=child.get_name(schema))
with alter.new_context(schema, context, child):
schema, cmd = self._propagate_ref_deletion(
schema, context, refdict, self_name, child)
schema, context, refdict, child, existing)
alter.add(cmd)
self.add(alter)

Expand All @@ -1164,29 +1171,23 @@ def _propagate_ref_deletion(
schema: s_schema.Schema,
context: sd.CommandContext,
refdict: so.RefDict,
parent_fq_refname: sn.SchemaName,
child: so.InheritingObject
child: so.InheritingObject,
child_ref: ReferencedInheritingObjectT,
) -> Tuple[s_schema.Schema, sd.Command]:
get_cmd = sd.ObjectCommandMeta.get_command_class_or_die
mcls = type(self.scls)

ref_field_type = type(child).get_field(refdict.attr).type
refname = ref_field_type.get_key_for_name(schema, parent_fq_refname)
child_coll = child.get_field_value(schema, refdict.attr)
existing = child_coll.get(schema, refname)

name = child_ref.get_name(schema)
implicit_bases = self._get_implicit_ref_bases(
schema, context, child, refdict.attr, parent_fq_refname)
schema, context, child, refdict.attr, name)

cmd: sd.Command

if existing.get_is_local(schema) or implicit_bases:
name = existing.get_name(schema)

if child_ref.get_is_local(schema) or implicit_bases:
# Child is either defined locally or is inherited
# from another parent, so we need to do a rebase.
removed_bases, added_bases = self.get_ref_implicit_base_delta(
schema, context, existing, implicit_bases)
schema, context, child_ref, implicit_bases)
rebase_cmd_cls = get_cmd(inheriting.RebaseInheritingObject, mcls)
rebase_cmd = rebase_cmd_cls(
classname=name,
Expand All @@ -1195,13 +1196,13 @@ def _propagate_ref_deletion(
)

ref_alter_cmd = get_cmd(sd.AlterObject, mcls)
cmd = ref_alter_cmd(classname=existing.get_name(schema))
cmd = ref_alter_cmd(classname=name)
cmd.add(rebase_cmd)

else:
# The ref in child should no longer exist.
ref_del_cmd = get_cmd(sd.DeleteObject, mcls)
cmd = ref_del_cmd(classname=existing.get_name(schema))
cmd = ref_del_cmd(classname=name)

schema = cmd.apply(schema, context)

Expand Down

0 comments on commit 4e53ad5

Please sign in to comment.