Repository: edgedb/edgedb

Issue:
Edgedb migrate fails with InternalServerError: cannot drop type edgedbpub
- EdgeDB Version: 2.12+5454e58
- EdgeDB CLI Version: EdgeDB CLI 2.3.1+ef99779
- OS Version: Microsoft Windows 11 Pro 10.0.22621 Build 22621



Steps to Reproduce:
1. edgedb migration create
2. edgedb migrate
error message:
```
edgedb error: InternalServerError: cannot drop type edgedbpub."a5778d8e-d192-11ed-af26-6d2d6d36467b_domain" because other objects depend on it
  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
  Server traceback:
      edb.errors.InternalServerError: cannot drop type edgedbpub."a5778d8e-d192-11ed-af26-6d2d6d36467b_domain" because other objects depend on it
```

Schema:
```
module default {
    scalar type Unit extending enum<Litre, Gram, Piece, Tablespoon, Teaspoon, Cup, Packet, Scoop, Dash, Stem, Bunch, Leaf, Can, `Drop`, Cube, Bottle>;
    type Recipe {
        required property name -> str;
        property serves -> int16;
        property preparation -> duration;
        property cooking -> duration;
        property directions -> array<str>;
        link rating -> Rating;
        multi link ingredients -> Ingredient {
            property amount_unit -> array<tuple<amount: float32, unit: Unit>>;
        }
    }

    type Ingredient {
        required property name -> str {
            constraint exclusive;
        };
    }

    type Rating {
        required property avg -> float32;
        property votes -> int32;
    }
}
```
EDIT: Adding last working migration and the one that has failed

```
CREATE MIGRATION m1vvylnsrqw7e2hweh63b2zc2zvnon3fqtyoptdnxxjqvkv2hpvzcq
    ONTO m1j4qz6smklcrtvwqet5djtpkwor5sxyiddrauyv2k4co4bmfsu3rq
{
  ALTER SCALAR TYPE default::Unit EXTENDING enum<Litre, Gram, Piece, Tablespoon, Teaspoon, Cup, Packet, Scoop, Dash, Stem, Bunch, Leaf, Can, `Drop`, Cube, Container>;
};
```
failing:
```
CREATE MIGRATION m1h7pw2jqthpbrw67ezruo64ksh2vve55okmqufrtxv5wdm2pn2dza
    ONTO m1vvylnsrqw7e2hweh63b2zc2zvnon3fqtyoptdnxxjqvkv2hpvzcq
{
  ALTER SCALAR TYPE default::Unit EXTENDING enum<Litre, Gram, Piece, Tablespoon, Teaspoon, Cup, Packet, Scoop, Dash, Stem, Bunch, Leaf, Can, `Drop`, Cube, Bottle>;
};
```



Discussion:

Resolving patch:
diff --git a/edb/pgsql/delta.py b/edb/pgsql/delta.py
--- a/edb/pgsql/delta.py
+++ b/edb/pgsql/delta.py
@@ -620,20 +620,16 @@ class TupleCommand(MetaCommand):
 
 class CreateTuple(TupleCommand, adapts=s_types.CreateTuple):
 
-    def apply(
-        self,
+    @classmethod
+    def create_tuple(
+        cls,
+        tup: s_types.Tuple,
         schema: s_schema.Schema,
-        context: sd.CommandContext,
-    ) -> s_schema.Schema:
-        schema = super().apply(schema, context)
-
-        if self.scls.is_polymorphic(schema):
-            return schema
-
-        elements = self.scls.get_element_types(schema).items(schema)
+    ) -> dbops.Command:
+        elements = tup.get_element_types(schema).items(schema)
 
         ctype = dbops.CompositeType(
-            name=common.get_backend_name(schema, self.scls, catenate=False),
+            name=common.get_backend_name(schema, tup, catenate=False),
             columns=[
                 dbops.Column(
                     name=n,
@@ -644,7 +640,19 @@ def apply(
             ]
         )
 
-        self.pgops.add(dbops.CreateCompositeType(type=ctype))
+        return dbops.CreateCompositeType(type=ctype)
+
+    def apply(
+        self,
+        schema: s_schema.Schema,
+        context: sd.CommandContext,
+    ) -> s_schema.Schema:
+        schema = super().apply(schema, context)
+
+        if self.scls.is_polymorphic(schema):
+            return schema
+
+        self.pgops.add(self.create_tuple(self.scls, schema))
 
         return schema
 
@@ -2550,8 +2558,10 @@ def _get_problematic_refs(
                 typs.append(obj)
             elif isinstance(obj, s_types.Collection):
                 wl.extend(schema.get_referrers(obj))
+                seen_other.add(obj)
             elif isinstance(obj, s_funcs.Parameter) and not composite_only:
                 wl.extend(schema.get_referrers(obj))
+                seen_other.add(obj)
             elif isinstance(obj, s_funcs.Function) and not composite_only:
                 wl.extend(schema.get_referrers(obj))
                 seen_other.add(obj)
@@ -2644,6 +2654,10 @@ def _undo_everything(
                     ConstraintCommand.delete_constraint(obj, schema, context))
             elif isinstance(obj, s_indexes.Index):
                 self.pgops.add(DeleteIndex.delete_index(obj, schema, context))
+            elif isinstance(obj, s_types.Tuple):
+                self.pgops.add(dbops.DropCompositeType(
+                    name=common.get_backend_name(schema, obj, catenate=False),
+                ))
             elif isinstance(obj, s_scalars.ScalarType):
                 self.pgops.add(DeleteScalarType.delete_scalar(obj, schema))
             elif isinstance(obj, s_props.Property):
@@ -2688,6 +2702,8 @@ def _redo_everything(
             elif isinstance(obj, s_indexes.Index):
                 self.pgops.add(
                     CreateIndex.create_index(obj, orig_schema, context))
+            elif isinstance(obj, s_types.Tuple):
+                self.pgops.add(CreateTuple.create_tuple(obj, orig_schema))
             elif isinstance(obj, s_scalars.ScalarType):
                 self.pgops.add(
                     CreateScalarType.create_scalar(


Test patch:
diff --git a/tests/test_edgeql_ddl.py b/tests/test_edgeql_ddl.py
--- a/tests/test_edgeql_ddl.py
+++ b/tests/test_edgeql_ddl.py
@@ -11343,11 +11343,14 @@ async def test_edgeql_ddl_enum_05(self):
                  <str>(x));
              CREATE FUNCTION asdf2() -> str USING (
                  asdf(<Color>'Red'));
+             CREATE FUNCTION asdf3(x: tuple<Color>) -> str USING (
+                 <str>(x.0));
 
              CREATE TYPE Entry {
                  CREATE PROPERTY num -> int64;
                  CREATE PROPERTY color -> Color;
                  CREATE PROPERTY colors -> array<Color>;
+                 CREATE PROPERTY colorst -> array<tuple<Color>>;
                  CREATE CONSTRAINT expression ON (
                      <str>.num != asdf2()
                  );
@@ -11358,7 +11361,9 @@ async def test_edgeql_ddl_enum_05(self):
              };
              INSERT Entry { num := 1, color := "Red" };
              INSERT Entry {
-                 num := 2, color := "Green", colors := ["Red", "Green"] };
+                 num := 2, color := "Green", colors := ["Red", "Green"],
+                 colorst := [("Red",), ("Green",)]
+             };
         ''')
 
         await self.con.execute('''
@@ -11373,10 +11378,14 @@ async def test_edgeql_ddl_enum_05(self):
 
         await self.assert_query_result(
             r"""
-                SELECT Entry { num, color } ORDER BY .color;
+                SELECT Entry { num, color, colorst } ORDER BY .color;
             """,
             [
-                {'num': 2, 'color': 'Green'},
+                {
+                    'num': 2,
+                    'color': 'Green',
+                    'colorst': [("Red",), ("Green",)],
+                },
                 {'num': 1, 'color': 'Red'},
             ],
         )