Repository: edgedb/edgedb

Issue:
Upsert query does not trigger a update rewrite
<!-- Please search existing issues to avoid creating duplicates. -->

<!--
For the EdgeDB Version: run `edgedb query 'select sys::get_version_as_str()'` from your project directory (or run `select sys::get_version_as_str();` in the EdgeDB interactive shell).
For the EdgeDB CLI Version: Run `edgedb --version` from anywhere
-->

- EdgeDB Version: 3.0-dev.7454+2fe06e5
- EdgeDB CLI Version: 3.0.0-dev.979+4666c49
- OS Version: endeavour os

🐛 : Upsert query does not trigger a rewrite on `update_at` property.

Steps to Reproduce:

1. apply schema
2. run query twice to do an upsert

query:
```
INSERT default::User {
  json_data := to_json($${"foo":"initial"}$$),
  my_id := <std::int32>1,
  data := (
    INSERT default::UserData {
      private_data := "initial"
    }
  )
}
UNLESS CONFLICT ON default::User.my_id
ELSE ((WITH
  __scope_0_defaultUser := default::User
UPDATE __scope_0_defaultUser SET {
  json_data := to_json($$"updated"$$),
  data := (
    std::assert_single((WITH
      __scope_1_defaultUserData := DETACHED default::User.data
    UPDATE __scope_1_defaultUserData SET {
      private_data := "updated"
    }))
  )
}))
```
The query is generated from the following edgedb-js query builder function:
```tsx
e
	.insert(e.User, {
		json_data: { foo: "initial" },
		my_id: 1,
		data: e.insert(e.UserData, {
			private_data: "initial",
		}),
	})
	.unlessConflict((user) => ({
		on: user.my_id,
		else: e.update(user, () => ({
			set: {
				json_data: "updated",
        data: e.update(user.data, () => ({
          set: {
            private_data: 'updated'
          }
        })).assert_single()
			},
		})),
	}));
```

I noticed it works when not detaching the objects, like:
```
INSERT default::User {
   json_data := to_json($${"foo":"initial"}$$),
   my_id := <std::int32>1,
   data := (
     INSERT default::UserData {
       private_data := "initial"
     }
   )
 }
 UNLESS CONFLICT ON default::User.my_id
 ELSE (
 UPDATE default::User SET {
   json_data := to_json($$"updated"$$),
   data := (
     std::assert_single((
     UPDATE User.data SET {
       private_data := "updated"
     }))
   )
 });
```
<!-- If the issue is about a query error, please also provide your schema -->

Schema: https://gist.github.com/lu-zen/4b3d72e8d3f3ae00708245c405236632



Discussion:

Resolving patch:
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
@@ -883,6 +883,8 @@ def _compile_rewrites(
     schema = ctx.env.schema
     by_type: Dict[irast.TypeRef, irast.RewritesOfType] = {}
     for ty, rewrites_of_type in rewrites_by_type.items():
+        ty = ty.real_material_type
+
         by_type[ty] = {}
         for element in rewrites_of_type.values():
             target = element.target_set


Test patch:
diff --git a/tests/test_edgeql_rewrites.py b/tests/test_edgeql_rewrites.py
--- a/tests/test_edgeql_rewrites.py
+++ b/tests/test_edgeql_rewrites.py
@@ -926,3 +926,30 @@ async def test_edgeql_rewrites_22(self):
                 ]
             ),
         )
+
+    async def test_edgeql_rewrites_23(self):
+        await self.con.execute(
+            '''
+            alter type Person {
+                alter property first_name {
+                    create rewrite update using ('updated');
+                };
+            };
+            insert Person { first_name := 'initial' };
+            '''
+        )
+        await self.assert_query_result(
+            'select Person { first_name }',
+            [{'first_name': 'initial'}],
+        )
+
+        await self.con.execute(
+            '''
+            with A := Person
+            update A set {};
+            '''
+        )
+        await self.assert_query_result(
+            'select Person { first_name }',
+            [{'first_name': 'updated'}],
+        )