Repository: edgedb/edgedb

Issue:
`InvalidReferenceError` on group queries generated by ts querybuilder
- EdgeDB Version: EdgeDB 3.0-dev.7275+local

Steps to Reproduce:

```
_example> WITH
.........   __scope_0_defaultMovie := DETACHED default::Movie,
.........   __scope_0_defaultMovie_groups := (
.........     GROUP __scope_0_defaultMovie
.........     USING
.........       release_year := __scope_0_defaultMovie.release_year
.........     BY release_year
......... )
......... SELECT __scope_0_defaultMovie_groups {
.........   key: {release_year},
.........   grouping,
.........   elements: {
.........     release_year,
.........     title,
.........     multi actors := (
.........       WITH
.........         __scope_1_defaultPerson := __scope_0_defaultMovie_groups.elements.actors
.........       SELECT __scope_1_defaultPerson {
.........         name
.........       }
.........     )
.........   }
......... };
error: InvalidReferenceError: object type or alias 'default::__scope_0_defaultMovie_groups' does not exist
   ┌─ query:17:36
   │
17 │         __scope_1_defaultPerson := __scope_0_defaultMovie_groups.elements.actors
   │                                    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error

```

Schema: UI `_example` schema


Discussion:

Resolving patch:
diff --git a/edb/edgeql/compiler/astutils.py b/edb/edgeql/compiler/astutils.py
--- a/edb/edgeql/compiler/astutils.py
+++ b/edb/edgeql/compiler/astutils.py
@@ -152,13 +152,16 @@ def find_parameters(
     return v.params
 
 
-class alias_view(view_patterns.ViewPattern[str], targets=(qlast.Base,)):
+class alias_view(
+    view_patterns.ViewPattern[tuple[str, list[qlast.PathElement]]],
+    targets=(qlast.Base,),
+):
     @staticmethod
-    def match(obj: object) -> str:
+    def match(obj: object) -> tuple[str, list[qlast.PathElement]]:
         match obj:
             case qlast.Path(
-                steps=[qlast.ObjectRef(module=None, name=alias)],
+                steps=[qlast.ObjectRef(module=None, name=alias), *rest],
                 partial=False,
             ):
-                return alias
+                return alias, rest
         raise view_patterns.NoMatch
diff --git a/edb/edgeql/desugar_group.py b/edb/edgeql/desugar_group.py
--- a/edb/edgeql/desugar_group.py
+++ b/edb/edgeql/desugar_group.py
@@ -174,7 +174,7 @@ def _count_alias_uses(
     uses = 0
     for child in ast.find_children(node, qlast.Path):
         match child:
-            case astutils.alias_view(alias2) if alias == alias2:
+            case astutils.alias_view((alias2, _)) if alias == alias2:
                 uses += 1
     return uses
 
@@ -222,7 +222,7 @@ def try_group_rewrite(
                 qlast.AliasedExpr(alias=alias, expr=qlast.GroupQuery() as grp)
             ] as qaliases,
             result=qlast.Shape(
-                expr=astutils.alias_view(alias2),
+                expr=astutils.alias_view((alias2, [])),
                 elements=elements,
             ) as result,
         ) if alias == alias2 and _count_alias_uses(result, alias) == 1:
@@ -236,7 +236,7 @@ def try_group_rewrite(
                 *_,
                 qlast.AliasedExpr(alias=alias, expr=qlast.GroupQuery() as grp)
             ] as qaliases,
-            iterator=astutils.alias_view(alias2),
+            iterator=astutils.alias_view((alias2, [])),
             result=result,
         ) if alias == alias2 and _count_alias_uses(result, alias) == 0:
             node = node.replace(


Test patch:
diff --git a/tests/test_edgeql_group.py b/tests/test_edgeql_group.py
--- a/tests/test_edgeql_group.py
+++ b/tests/test_edgeql_group.py
@@ -1329,3 +1329,19 @@ async def test_edgeql_group_enumerate_02(self):
                 }
             ]),
         )
+
+    async def test_edgeql_group_uses_name_01(self):
+        # Make sure that our crappy optimizations don't break anything
+        await self.con.query(
+            r'''
+            WITH g := (GROUP cards::Card BY .cost)
+            SELECT g {
+              key: {cost},
+              grouping,
+              elements: {
+                name,
+                multi owners := g.elements.owners { name },
+              }
+            };
+            ''',
+        )