Repository: edgedb/edgedb

Issue:
Guaranteed ISE on nested insert on a `required multi link`
Schema:

```
module default {
    type B {
        required multi link c -> default::C;
    };
    type C {
        required property x -> std::int64;
    };
};
```

Query:

```
insert B {
  c := (
    for i in {(x := 90), (x := 240)}
    union (
      insert C {
        x := i.x,
      }
    )
  ),
};
```

Result:

```
edgedb error: InternalServerError: duplicate key value violates unique constraint "96db17f1-c393-11ec-81bf-b3f038f3cc4b_source_target_key"
  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: duplicate key value violates unique constraint "96db17f1-c393-11ec-81bf-b3f038f3cc4b_source_target_key"
```

Context in #3786 


Discussion:
Additionally, if I replace the tuple with a straight integer set:

```
insert B {
  c := (
    for i in {90, 240}
    union (
      insert C {
        x := i,
      }
    )
  ),
};
```

I get:

```
edgedb error: InternalServerError: operator does not exist: bigint = uuid
  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: operator does not exist: bigint = uuid
```

This could be a related or independent bug, but it still only occurs if the link is `required multi`.

Resolving patch:
diff --git a/edb/pgsql/compiler/dml.py b/edb/pgsql/compiler/dml.py
--- a/edb/pgsql/compiler/dml.py
+++ b/edb/pgsql/compiler/dml.py
@@ -1959,35 +1959,6 @@ def process_link_values(
 
             dispatch.visit(ir_expr, ctx=input_rel_ctx)
 
-            if (
-                isinstance(ir_expr.expr, irast.Stmt)
-                and ir_expr.expr.iterator_stmt is not None
-            ):
-                # The link value is computaed by a FOR expression,
-                # check if the statement is a DML statement, and if so,
-                # pull the iterator scope so that link property expressions
-                # have the correct context.
-                inner_iterator_cte = None
-                inner_iterator_path_id = ir_expr.expr.iterator_stmt.path_id
-                for cte in (input_rel_ctx.toplevel_stmt.ctes or ()):
-                    if cte.query.path_id == inner_iterator_path_id:
-                        inner_iterator_cte = cte
-                        break
-                if inner_iterator_cte is not None:
-                    inner_iterator_rvar = relctx.rvar_for_rel(
-                        inner_iterator_cte, lateral=True, ctx=subrelctx)
-
-                    relctx.include_rvar(
-                        input_rel,
-                        inner_iterator_rvar,
-                        path_id=inner_iterator_path_id,
-                        ctx=subrelctx,
-                    )
-
-                    input_rel_ctx.path_scope[inner_iterator_path_id] = (
-                        input_rel
-                    )
-
     input_stmt: pgast.Query = input_rel
 
     input_rvar = pgast.RangeSubselect(


Test patch:
diff --git a/tests/test_edgeql_update.py b/tests/test_edgeql_update.py
--- a/tests/test_edgeql_update.py
+++ b/tests/test_edgeql_update.py
@@ -2807,6 +2807,38 @@ async def test_edgeql_update_subtract_required(self):
                 ) FILTER false;
             """)
 
+    async def test_edgeql_insert_multi_required_01(self):
+        await self.con.execute("""
+            insert MultiRequiredTest {
+              name := "___",
+              prop := "!",
+              tags := (
+                for i in {(x := "90"), (x := "240")}
+                union (
+                  insert Tag {
+                    name := i.x,
+                  }
+                )
+              ),
+            };
+        """)
+
+    async def test_edgeql_insert_multi_required_02(self):
+        await self.con.execute("""
+            insert MultiRequiredTest {
+              name := "___",
+              prop := "!",
+              tags := (
+                for i in {"90", "240"}
+                union (
+                  insert Tag {
+                    name := i,
+                  }
+                )
+              ),
+            };
+        """)
+
     async def test_edgeql_subtract_badness_01(self):
         with self.assertRaisesRegex(
             edgedb.QueryError,