Repository: edgedb/edgedb

Issue:
Confusing error when using insert as conversion expression
<!-- Please search existing issues to avoid creating duplicates. -->
- EdgeDB Version: 2.2 (dgeDB CLI 2.0.5+f78cf34)
- OS Version: ubuntu 22.04

When applying a migration that uses an `insert` as a conversion expression I get an obscure error that seems to complain about the generated migration.

```bash
$ edgedb migration create
did you create link 'org' of object type 'default::Department'? [y,n,l,c,b,s,q,?]
> y
Please specify an expression to populate existing objects in order to make link 'org' of object type 'default::Department' required:
fill_expr> insert Organization { name := "default" }
$ edgedb migration apply
edgedb error: UnsupportedBackendFeatureError: WITH clause containing a data-modifying statement must be at the top level
```

### Schema 1
```
module default {
	type Organization {
		required property name -> str;
	}

	type Department {
		required property name -> str;
	}
}
```

### Schema 2
```
module default {
	type Organization {
		required property name -> str;
	}

	type Department {
		required property name -> str;
		required link org -> Organization;
	}
}
```


Discussion:
This is related to #3592, which suggests that doing this ought to work.
I'll leave this open as an easy "fix the error message" bug, and #3592 can be the issue for really fixing it.
In particular, fixing the error message means catching it in edgedb instead of having it pushed off to postgres and it means catching it while generating migrations instead of just when running them

Resolving patch:
diff --git a/edb/schema/pointers.py b/edb/schema/pointers.py
--- a/edb/schema/pointers.py
+++ b/edb/schema/pointers.py
@@ -2647,6 +2647,8 @@ def _alter_begin(
         schema: s_schema.Schema,
         context: sd.CommandContext,
     ) -> s_schema.Schema:
+        from edb.ir import utils as irutils
+
         orig_schema = schema
         schema = super()._alter_begin(schema, context)
         scls = self.scls
@@ -2699,6 +2701,13 @@ def _alter_begin(
                         context=self.source_context,
                     )
 
+                if irutils.contains_dml(self.fill_expr.ir_statement):
+                    raise errors.SchemaError(
+                        f'USING clause for the alteration of {vn} '
+                        f'cannot include mutating statements',
+                        context=self.source_context,
+                    )
+
             schema = self._propagate_if_expr_refs(
                 schema,
                 context,


Test patch:
diff --git a/tests/test_edgeql_data_migration.py b/tests/test_edgeql_data_migration.py
--- a/tests/test_edgeql_data_migration.py
+++ b/tests/test_edgeql_data_migration.py
@@ -10017,6 +10017,40 @@ async def test_edgeql_migration_user_input_04(self):
             ],
         )
 
+    async def test_edgeql_migration_user_input_05(self):
+        await self.migrate(
+            '''
+            type Organization {
+                required property name -> str;
+            }
+            type Department {
+                required property name -> str;
+            }
+            '''
+        )
+        await self.start_migration(
+            '''
+            type Organization {
+                required property name -> str;
+            }
+            type Department {
+                required link org -> Organization;
+            };
+            '''
+        )
+
+        async with self.assertRaisesRegexTx(
+            edgedb.SchemaError, "cannot include mutating statements"
+        ):
+            try:
+                await self.fast_forward_describe_migration(
+                    user_input=[
+                        'insert test::Organization { name := "default" }'
+                    ]
+                )
+            except Exception as e:
+                raise e.__cause__
+
     async def test_edgeql_migration_union_01(self):
         async with self.assertRaisesRegexTx(
             edgedb.QueryError,