Repository: edgedb/edgedb

Issue:
create-migration fails when a property was moved to an abstract base type
- EdgeDB Version: 1.0b1
- OS Version: macOS 10.15.7

Schema before:
```esdl
module commonplace {
    type User {
        required property name -> util::Slug {
            constraint exclusive;
        };
        index on (__subject__.name);
    };
};
```

Schema after:
```esdl
module commonplace {
    type User extending
        Named;

    type Content extending
        Named;

    abstract type Named {
        required property name -> util::Slug {
            constraint exclusive;
        };
        index on (__subject__.name);
    };
};
```

create-migration failing:
![2021-03-18 15 29 59](https://user-images.githubusercontent.com/55281/111643823-8ef89c80-87ff-11eb-80ee-7987f7544ff6.gif)



Discussion:
Trying to drop the index first results in a different error, about the exclusivity constraint now:
```
did you drop constraint 'std::exclusive' of property 'name'? [y,n,l,c,b,s,q,?]
y
error: cannot drop inherited constraint 'std::exclusive' of property 'name' of object type 'commonplace::User'
  ┌─ query:3:9
  │
3 │         DROP CONSTRAINT std::exclusive;
  │         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error
  │
  = constraint 'std::exclusive' of property 'name' of object type 'commonplace::User' is inherited from:
    - property 'name' of object type 'commonplace::Named'
```

Answering "no" to the question results in:
```
ERROR: InternalServerError: uncompiled expression in the field 'expr' of constraint <QualName commonplace::std|exclusive@commonplace|__||name&commonplace||User@da39a3ee5e6b4b0d3255bfef95601890afd80709>
```


> create-migration failing:

Confirmed.

> Trying to drop the index first 

Hm, the error seems to suggest `User` is already inherited from `Named`.  You cannot drop constraints inherited from parent type.

> Answering "no" to the question results in:

This was fixed in b2.nightly.

Resolving patch:
diff --git a/edb/schema/indexes.py b/edb/schema/indexes.py
--- a/edb/schema/indexes.py
+++ b/edb/schema/indexes.py
@@ -50,7 +50,10 @@ class Index(
     data_safe=True,
 ):
 
-    subject = so.SchemaField(so.Object)
+    subject = so.SchemaField(
+        so.Object,
+        compcoef=None,
+        inheritable=False)
 
     expr = so.SchemaField(
         s_expr.Expression,
@@ -241,18 +244,18 @@ def _cmd_from_ast(
         astnode: qlast.DDLOperation,
         context: sd.CommandContext,
     ) -> sd.ObjectCommand[Index]:
-        assert isinstance(astnode, qlast.IndexCommand)
         cmd = super()._cmd_from_ast(schema, astnode, context)
-        orig_text = cls.get_orig_expr_text(schema, astnode, 'expr')
-        cmd.set_ddl_identity(
-            'expr',
-            s_expr.Expression.from_ast(
-                astnode.expr,
-                schema,
-                context.modaliases,
-                orig_text=orig_text,
-            ),
-        )
+        if isinstance(astnode, qlast.IndexCommand):
+            orig_text = cls.get_orig_expr_text(schema, astnode, 'expr')
+            cmd.set_ddl_identity(
+                'expr',
+                s_expr.Expression.from_ast(
+                    astnode.expr,
+                    schema,
+                    context.modaliases,
+                    orig_text=orig_text,
+                ),
+            )
         return cmd
 
     def get_ast_attr_for_field(
diff --git a/edb/server/defines.py b/edb/server/defines.py
--- a/edb/server/defines.py
+++ b/edb/server/defines.py
@@ -34,7 +34,7 @@
 EDGEDB_SPECIAL_DBS = {EDGEDB_TEMPLATE_DB, EDGEDB_SYSTEM_DB}
 
 # Increment this whenever the database layout or stdlib changes.
-EDGEDB_CATALOG_VERSION = 2021_03_05_00_00
+EDGEDB_CATALOG_VERSION = 2021_03_19_00_00
 
 # Resource limit on open FDs for the server process.
 # By default, at least on macOS, the max number of open FDs


Test patch:
diff --git a/tests/test_schema.py b/tests/test_schema.py
--- a/tests/test_schema.py
+++ b/tests/test_schema.py
@@ -3659,6 +3659,25 @@ def test_schema_migrations_equivalence_49(self):
             };
         """])
 
+    def test_schema_migrations_equivalence_50(self):
+        self._assert_migration_equivalence([r"""
+            type User {
+                required property name -> str {
+                    constraint exclusive;
+                };
+                index on (__subject__.name);
+            };
+        """, r"""
+            type User extending Named;
+
+            abstract type Named {
+                required property name -> str {
+                    constraint exclusive;
+                };
+                index on (__subject__.name);
+            };
+        """])
+
     def test_schema_migrations_equivalence_compound_01(self):
         # Check that union types can be referenced in computables
         # Bug #2002.