From 958f5ea34b44ab23c99192799cb295613a1d44ce Mon Sep 17 00:00:00 2001 From: zchenb <121908802+zchenb@users.noreply.github.com> Date: Tue, 13 Jun 2023 13:43:33 -0600 Subject: [PATCH] Disallow partial paths in the defaults of link properties (#5560) --- edb/schema/pointers.py | 20 +++++++++++++++++++- tests/test_schema.py | 20 ++++++++++++++++++++ 2 files changed, 39 insertions(+), 1 deletion(-) diff --git a/edb/schema/pointers.py b/edb/schema/pointers.py index 00fc009a59a..5cb0ae04b40 100644 --- a/edb/schema/pointers.py +++ b/edb/schema/pointers.py @@ -1440,6 +1440,7 @@ def _compile_expr( make_globals_empty: bool = False, source_context: Optional[parsing.ParserContext] = None, detached: bool = False, + should_set_path_prefix_anchor: bool = True ) -> s_expr.CompiledExpression: singletons: List[Union[s_types.Type, Pointer]] = [] @@ -1490,7 +1491,10 @@ def _compile_expr( modaliases=context.modaliases, schema_object_context=self.get_schema_metaclass(), anchors={qlast.Source().name: source}, - path_prefix_anchor=qlast.Source().name, + path_prefix_anchor=( + qlast.Source().name + if should_set_path_prefix_anchor + else None), singletons=singletons, apply_query_rewrites=( not context.stdmode and not no_query_rewrites @@ -1544,6 +1548,19 @@ def compile_expr_field( in_ddl_context_name = None detached = True + # If we are in a link property's default field + # do not set path prefix anchor, because link properties + # cannot have defaults that reference the object being inserted + should_set_path_prefix_anchor = True + if field.name == 'default': + # We are checking if the parent context is a pointer + # (i.e. a link or a property). + # If so, do not set the path prefix anchor. + parent_ctx = self.get_referrer_context_or_die(context) + source = parent_ctx.op.get_object(schema, context) + if isinstance(source, Pointer): + should_set_path_prefix_anchor = False + return self._compile_expr( schema, context, @@ -1551,6 +1568,7 @@ def compile_expr_field( in_ddl_context_name=in_ddl_context_name, track_schema_ref_exprs=track_schema_ref_exprs, detached=detached, + should_set_path_prefix_anchor=should_set_path_prefix_anchor, ) else: return super().compile_expr_field( diff --git a/tests/test_schema.py b/tests/test_schema.py index 9ae0d29d4b8..1ff1da506ce 100644 --- a/tests/test_schema.py +++ b/tests/test_schema.py @@ -362,6 +362,26 @@ def test_schema_link_prop_on_prop_01(self): }; """ + @tb.must_fail(errors.QueryError, + "could not resolve partial path") + def test_schema_partial_path_in_default_of_link_prop_01(self): + """ + module default { + type Person { + required name : str { + constraint exclusive; + } + + multi friends : Person { + note : str { + default := .name + } + } + + } + } + """ + @tb.must_fail(errors.InvalidPropertyTargetError, "invalid property type: expected a scalar type, " "or a scalar collection, got object type 'test::Object'",