Repository: edgedb/edgedb

Issue:
`IndexError: list index out of range` when dropping inherited type with certain access policy present
<!-- 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: 3.5 and 4.0-rc.2
- EdgeDB CLI Version: 3.5.0+e1ad387
- OS Version: macos 13

Steps to Reproduce:

1. Migrate to base schema
2. Drop `Principal` and `extending Principal`
3. Create a migration, receive `list index out of range` error
```
$ edgedb migration create
did you alter object type 'default::User'? [y,n,l,c,b,s,q,?]
> y
Error applying statement: InternalServerError: IndexError: list index out of range
  Hint: This is most likely a bug in EdgeDB. Please consider opening an issue ticket at https://github.com/edgedb/edgedb/issues/new?template=bug_report.md
Rolling back last operation...
```

<!-- If the issue is about a query error, please also provide your schema -->

Base Schema:
```
using future nonrecursive_access_policies;

module default {

    global current_user: uuid;
    global current_user_object := (
        select User filter .id = global current_user
    );


    type Organization {
        access policy allow_select_users
            allow select
            using (global current_user_object.organization.id ?= .id);
    }

    abstract type Principal {   }
    type User  extending Principal {
    # type User {
        required link organization: Organization;
    }

}
```


Discussion:
For future reference, creating migration from "base" schema to this schema fails:

```
using future nonrecursive_access_policies;

module default {

    global current_user: uuid;
    global current_user_object := (
        select User filter .id = global current_user
    );


    type Organization {
        access policy allow_select_users
            allow select
            using (global current_user_object.organization.id ?= .id);
    }

    type User {
        required link organization: Organization;
    }
}
```

Resolving patch:
diff --git a/edb/edgeql/compiler/policies.py b/edb/edgeql/compiler/policies.py
--- a/edb/edgeql/compiler/policies.py
+++ b/edb/edgeql/compiler/policies.py
@@ -362,17 +362,20 @@ def try_type_rewrite(
         ]
 
     # If we have multiple sets, union them together
+    rewritten_set: Optional[irast.Set]
     if len(sets) > 1:
         with ctx.new() as subctx:
             subctx.expr_exposed = context.Exposure.UNEXPOSED
             subctx.anchors = subctx.anchors.copy()
             parts: List[qlast.Expr] = [subctx.create_anchor(x) for x in sets]
-            filtered_set = dispatch.compile(
+            rewritten_set = dispatch.compile(
                 qlast.Set(elements=parts), ctx=subctx)
+    elif len(sets) > 0:
+        rewritten_set = sets[0]
     else:
-        filtered_set = sets[0]
+        rewritten_set = None
 
-    type_rewrites[rw_key] = filtered_set
+    type_rewrites[rw_key] = rewritten_set
 
 
 def compile_dml_write_policies(


Test patch:
diff --git a/tests/test_edgeql_policies.py b/tests/test_edgeql_policies.py
--- a/tests/test_edgeql_policies.py
+++ b/tests/test_edgeql_policies.py
@@ -1296,3 +1296,37 @@ async def test_edgeql_policies_empty_cast_01(self):
             __typenames__=True,
         )
         self.assertEqual(obj, [])
+
+    async def test_edgeql_policies_global_01(self):
+        # GH issue #6404
+
+        clan_and_global = '''
+            type Clan {
+                access policy allow_select_players
+                    allow select
+                    using (
+                        global current_player.clan.id ?= .id
+                    );
+            };
+            global current_player_id: uuid;
+            global current_player := (
+                select Player filter .id = global current_player_id
+            );
+        '''
+
+        await self.migrate(
+            '''
+            type Principal;
+            type Player extending Principal {
+                required link clan: Clan;
+            }
+            ''' + clan_and_global
+        )
+
+        await self.migrate(
+            '''
+            type Player {
+                required link clan: Clan;
+            }
+            ''' + clan_and_global
+        )