Repository: edgedb/edgedb

Issue:
`cannot find scope statement` querying a link property inside of `assert_exists`
<!-- Please search existing issues to avoid creating duplicates. -->

<!--
For the EdgeDB Version: run `edgedb query 'select sys::get_version_as_str()'` from your project directory (or run `select sys::get_version_as_str();` in the EdgeDB interactive shell).
For the EdgeDB CLI Version: Run `edgedb --version` from anywhere
-->

- EdgeDB Version: 2.9+4fbadd2
- EdgeDB CLI Version: 2.2.6+7eabbf9
- OS Version: macOS 13.1

Steps to Reproduce:

1. Query a link property inside of an `assert_exists`. 

The `assert_exists` was for a filter but have left that out + much else for simplicity.

```typescript
e.assert_exists(
  e.select(e.Survey, survey => ({
    recipients: {
      "@destination": true,
    },
  })),
);
```

```
std::assert_exists((WITH
  __scope_0_defaultSurvey := DETACHED default::Survey
SELECT __scope_0_defaultSurvey {
  recipients := (
    WITH
      __scope_1_defaultUser := (
        SELECT __scope_0_defaultSurvey.recipients {
          __linkprop_destination := __scope_0_defaultSurvey.recipients@destination
        }
      )
    SELECT __scope_1_defaultUser {
      single @destination := __scope_1_defaultUser.__linkprop_destination
    }
  )
}))
```

Error: `cannot find scope statement for (__derived__::expr~8).>recipients[IS default::User]`


Alternatively, working case without `assert_exists`:

```typescript
 e.select(e.Survey, survey => ({
    recipients: {
      "@destination": true,
    },
  }))
```

```
WITH
  __scope_0_defaultSurvey := DETACHED default::Survey
SELECT __scope_0_defaultSurvey {
  recipients := (
    WITH
      __scope_1_defaultUser := (
        SELECT __scope_0_defaultSurvey.recipients {
          __linkprop_destination := __scope_0_defaultSurvey.recipients@destination
        }
      )
    SELECT __scope_1_defaultUser {
      single @destination := __scope_1_defaultUser.__linkprop_destination
    }
  )
}
```

<!-- If the issue is about a query error, please also provide your schema -->

Simplified schema:

```
type Survey {
    multi link recipients -> User {
        property destination -> str {
            default := "email";
        }
    }
}
type User {}
```



Discussion:
Possibly also hit here
https://discord.com/channels/841451783728529451/849374705210490900/1065734816265416896

Resolving patch:
diff --git a/edb/edgeql/compiler/viewgen.py b/edb/edgeql/compiler/viewgen.py
--- a/edb/edgeql/compiler/viewgen.py
+++ b/edb/edgeql/compiler/viewgen.py
@@ -1020,6 +1020,8 @@ def _normalize_view_ptr_expr(
                 ptrcls = existing
             elif ptr_target.implicitly_castable_to(
                     existing_target, ctx.env.schema):
+
+                ctx.env.ptr_ref_cache.pop(existing, None)
                 ctx.env.schema = existing.set_target(
                     ctx.env.schema, ptr_target)
                 ptrcls = existing
@@ -1047,6 +1049,7 @@ def _normalize_view_ptr_expr(
                 ctx=ctx)
 
     elif ptrcls.get_target(ctx.env.schema) != ptr_target:
+        ctx.env.ptr_ref_cache.pop(ptrcls, None)
         ctx.env.schema = ptrcls.set_target(ctx.env.schema, ptr_target)
 
     assert ptrcls is not None


Test patch:
diff --git a/tests/test_edgeql_scope.py b/tests/test_edgeql_scope.py
--- a/tests/test_edgeql_scope.py
+++ b/tests/test_edgeql_scope.py
@@ -3764,6 +3764,39 @@ async def test_edgeql_select_outer_rebind_07b(self):
             ])
         )
 
+    async def test_edgeql_scope_linkprop_rebinding_01(self):
+        # This is a lot like code the querybuilder generates
+        # See issue #4961
+        await self.assert_query_result(
+            r'''
+            select assert_exists((WITH
+              __user := DETACHED User
+            SELECT __user {
+              deck := (
+                WITH
+                  __user2 := (
+                    SELECT __user.deck {
+                      __linkprop_count := __user.deck@count
+                    }
+                  )
+                SELECT __user2 {
+                  single @count := __user2.__linkprop_count
+                }
+              )
+            } filter .name = 'Alice'));
+            ''',
+            [
+                {
+                    "deck": tb.bag([
+                        {"@count": 2},
+                        {"@count": 2},
+                        {"@count": 3},
+                        {"@count": 3},
+                    ])
+                }
+            ]
+        )
+
     async def test_edgeql_scope_for_with_computable_01(self):
         await self.assert_query_result(
             r'''