Repository: edgedb/edgedb

Issue:
Invalid `Data` message returned for insert/update query when `INJECT_OUTPUT_TYPE_IDS` flag is set
- EdgeDB Version: 3.0-dev.6803+local

Steps to Reproduce:
1. Run the following query in the ui repl with the example db:
```
with
  update1 := (insert Movie {title := 'test'})
select {
  update1
}
```
2. Invalid `Data` message is returned causing this error: `ProtocolError: cannot decode Object: expected 3 elements, got 1758044706`. Valid data is returned if the `INJECT_OUTPUT_TYPE_IDS` and `INJECT_OUTPUT_TYPE_NAMES` compilation flags are not set.



Discussion:

Resolving patch:
diff --git a/edb/edgeql/compiler/stmt.py b/edb/edgeql/compiler/stmt.py
--- a/edb/edgeql/compiler/stmt.py
+++ b/edb/edgeql/compiler/stmt.py
@@ -1063,8 +1063,10 @@ def init_stmt(
         elif (
             (dv := ctx.defining_view) is not None
             and dv.get_expr_type(ctx.env.schema) is s_types.ExprType.Select
-            and not irutils.is_trivial_free_object(
-                not_none(ctx.partial_path_prefix))
+            and not (
+                ctx.partial_path_prefix
+                and irutils.is_trivial_free_object(ctx.partial_path_prefix)
+            )
         ):
             # This is some shape in a regular query. Although
             # DML is not allowed in the computable, but it may
diff --git a/edb/edgeql/compiler/viewgen.py b/edb/edgeql/compiler/viewgen.py
--- a/edb/edgeql/compiler/viewgen.py
+++ b/edb/edgeql/compiler/viewgen.py
@@ -32,6 +32,7 @@
 
 from edb.ir import ast as irast
 from edb.ir import typeutils
+from edb.ir import utils as irutils
 
 from edb.schema import links as s_links
 from edb.schema import name as sn
@@ -755,6 +756,10 @@ def _normalize_view_ptr_expr(
                     raise
 
         qlexpr = astutils.ensure_qlstmt(compexpr)
+        # HACK: For scope tree related reasons, DML inside of free objects
+        # needs to be wrapped in a SELECT. This is probably fixable.
+        if irutils.is_trivial_free_object(ir_source):
+            qlexpr = astutils.ensure_ql_select(qlexpr)
 
         if ((ctx.expr_exposed or ctx.stmt is ctx.toplevel_stmt)
                 and ctx.implicit_limit
@@ -1489,7 +1494,7 @@ def _late_compile_view_shapes_in_set(
     # This is to avoid losing subquery distinctions (in cases
     # like test_edgeql_scope_tuple_15), and generally seems more natural.
     if (
-            isinstance(ir_set.expr, irast.Stmt)
+            isinstance(ir_set.expr, (irast.SelectStmt, irast.GroupStmt))
             and not (ir_set.rptr and not ir_set.rptr.is_definition)
             and (setgen.get_set_type(ir_set, ctx=ctx) ==
                  setgen.get_set_type(ir_set.expr.result, ctx=ctx))):
@@ -1507,11 +1512,7 @@ def _late_compile_view_shapes_in_set(
                 parent_view_type=parent_view_type,
                 ctx=scopectx)
 
-        # Don't reach into mutation result fields when populating
-        # shape_source, because mutation results are *not* the source
-        # for linkprops.
-        if not isinstance(ir_set.expr, irast.MutatingStmt):
-            ir_set.shape_source = child if child.shape else child.shape_source
+        ir_set.shape_source = child if child.shape else child.shape_source
         return
 
     if shape_ptrs:


Test patch:
diff --git a/tests/test_edgeql_insert.py b/tests/test_edgeql_insert.py
--- a/tests/test_edgeql_insert.py
+++ b/tests/test_edgeql_insert.py
@@ -5534,3 +5534,24 @@ async def test_edgeql_insert_in_free_object_02(self):
                      )
                 };
             ''')
+
+    async def test_edgeql_insert_rebind_with_typenames_01(self):
+        await self.assert_query_result(
+            '''
+            with
+              update1 := (insert InsertTest {l2:=1}),
+            select (select update1);
+            ''',
+            [{'id': str}],
+            always_typenames=True,
+        )
+
+        await self.assert_query_result(
+            '''
+            with
+              update1 := (insert InsertTest {l2:=1}),
+            select {update1};
+            ''',
+            [{'id': str}],
+            always_typenames=True,
+        )