Repository: edgedb/edgedb

Issue:
False positive on shape check in default when an object global var is used
```
  global current_organization_id -> uuid;
  global current_organization := (
    select Organization filter .id = global current_organization_id
  );

  type Organization;

  type SomeOrgSpecificObject {
    required link organization -> Organization {
      default := global current_organization;
    }
  } 
```

```
error: SchemaDefinitionError: default expression may not include a shape
   ┌─ query:11:7
   │
11 │       default := global current_organization;
   │       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error
```


Discussion:
A very unpleasant bug, the consequence of which is the redundancy of the model code.
Is there any update on this bug?

As soon as I add globals to schema, setting defaults from globals becomes very tempting and handy to use . But this bug prevents it from using completely.
For edgedb 3.0 the bug is still relevant. When can we expect a fix?

Resolving patch:
diff --git a/edb/schema/pointers.py b/edb/schema/pointers.py
--- a/edb/schema/pointers.py
+++ b/edb/schema/pointers.py
@@ -1766,13 +1766,23 @@ def validate_object(
                     schema, context, default_expr.irast.expr)
 
             source_context = self.get_attribute_source_context('default')
-            default_schema = default_expr.irast.schema
-            default_type = default_expr.irast.stype
+            ir = default_expr.irast
+            default_schema = ir.schema
+            default_type = ir.stype
             assert default_type is not None
             ptr_target = scls.get_target(schema)
             assert ptr_target is not None
 
-            if default_type.is_view(default_schema):
+            if (
+                default_type.is_view(default_schema)
+                # Using an alias/global always creates a new subtype view,
+                # but we want to allow those here, so check whether there
+                # is a shape more directly.
+                and not (
+                    len(shape := ir.view_shapes.get(default_type, [])) == 1
+                    and shape[0].is_id_pointer(default_schema)
+                )
+            ):
                 raise errors.SchemaDefinitionError(
                     f'default expression may not include a shape',
                     context=source_context,


Test patch:
diff --git a/tests/test_edgeql_ddl.py b/tests/test_edgeql_ddl.py
--- a/tests/test_edgeql_ddl.py
+++ b/tests/test_edgeql_ddl.py
@@ -6946,6 +6946,68 @@ async def test_edgeql_ddl_global_08(self):
                 alter global foo set type str using ('lol');
             """)
 
+    async def test_edgeql_ddl_global_09(self):
+        await self.con.execute('''
+            create type Org;
+
+            create global current_org_id -> uuid;
+            create global current_org := (
+              select Org filter .id = global current_org_id
+            );
+
+            create type Widget {
+              create required link org -> Org {
+                set default := global current_org;
+              }
+            };
+        ''')
+
+        obj = await self.con.query_single('insert Org')
+        await self.con.execute(
+            '''
+            set global current_org_id := <uuid>$0
+            ''',
+            obj.id,
+        )
+        await self.con.execute('insert Widget')
+        await self.assert_query_result(
+            '''
+                select Widget { org }
+            ''',
+            [{'org': {'id': obj.id}}],
+        )
+
+    async def test_edgeql_ddl_global_10(self):
+        await self.con.execute('''
+            create type Org;
+
+            create global current_org_id -> uuid;
+            create global current_org := (
+              select Org filter .id = global current_org_id
+            );
+
+            create type Widget {
+              create required link org -> Org {
+                create rewrite insert using (global current_org)
+              }
+            };
+        ''')
+
+        obj = await self.con.query_single('insert Org')
+        await self.con.execute(
+            '''
+            set global current_org_id := <uuid>$0
+            ''',
+            obj.id,
+        )
+        await self.con.execute('insert Widget')
+        await self.assert_query_result(
+            '''
+                select Widget { org }
+            ''',
+            [{'org': {'id': obj.id}}],
+        )
+
     async def test_edgeql_ddl_global_default(self):
         await self.con.execute('''
             create global foo -> str;