Repository: edgedb/edgedb

Issue:
EdgeDB fails to handle a schema definition
<!-- Please search existing issues to avoid creating duplicates. -->
- EdgeDB Version: EdgeDB CLI 2.0.1+b407f6f
- OS Version: Darwin Kernel Version 21.5.0: Tue Apr 26 21:08:22 PDT 2022; root:xnu-8020.121.3~4/RELEASE_X86_64

Steps to Reproduce:

1. execute edgedb migration create 

<!-- If the issue is about a query error, please also provide your schema -->
Schema:
```
module default {
  type Person {
    required property name -> str {
      # empty block
    }
  }
}
```

Edgedb should either accept empty block as simple semi-colon or show a message that empty block are invalid syntax.
instead we have an InternalServerError with:
```
edgedb error: InternalServerError: 'NoneType' object is not iterable
  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:
      Traceback (most recent call last):
        File "/Users/a_random_username/Library/Application Support/edgedb/portable/2.0/lib/python3.10/site-packages/edb/server/compiler_pool/worker_proc.py", line 55, in worker
          res = meth(*args)
        File "/Users/a_random_username/Library/Application Support/edgedb/portable/2.0/lib/python3.10/site-packages/edb/server/compiler_pool/worker.py", line 160, in compile
          units, cstate = COMPILER.compile(
        File "/Users/a_random_username/Library/Application Support/edgedb/portable/2.0/lib/python3.10/site-packages/edb/server/compiler/compiler.py", line 2207, in compile
          unit_group = self._compile(ctx=ctx, source=source)
        File "/Users/a_random_username/Library/Application Support/edgedb/portable/2.0/lib/python3.10/site-packages/edb/server/compiler/compiler.py", line 1738, in _compile
          return self._try_compile(ctx=ctx, source=source)
        File "/Users/a_random_username/Library/Application Support/edgedb/portable/2.0/lib/python3.10/site-packages/edb/server/compiler/compiler.py", line 1802, in _try_compile
          comp, capabilities = self._compile_dispatch_ql(
        File "/Users/a_random_username/Library/Application Support/edgedb/portable/2.0/lib/python3.10/site-packages/edb/server/compiler/compiler.py", line 1668, in _compile_dispatch_ql
          query = self._compile_ql_migration(
        File "/Users/a_random_username/Library/Application Support/edgedb/portable/2.0/lib/python3.10/site-packages/edb/server/compiler/compiler.py", line 1049, in _compile_ql_migration
          target_schema = s_ddl.apply_sdl(
        File "/Users/a_random_username/Library/Application Support/edgedb/portable/2.0/lib/python3.10/site-packages/edb/schema/ddl.py", line 485, in apply_sdl
          ddl_stmts = s_decl.sdl_to_ddl(current_schema, documents)
        File "/Users/a_random_username/Library/Application Support/edgedb/portable/2.0/lib/python3.10/site-packages/edb/edgeql/declarative.py", line 419, in sdl_to_ddl
          trace_dependencies(decl_ast, ctx=tracectx)
        File "/Users/a_random_username/Library/Application Support/edgedb/portable/2.0/lib/python3.10/functools.py", line 889, in wrapper
          return dispatch(args[0].__class__)(*args, **kw)
        File "/Users/a_random_username/Library/Application Support/edgedb/portable/2.0/lib/python3.10/site-packages/edb/edgeql/declarative.py", line 926, in trace_default
          _register_item(node, ctx=ctx)
        File "/Users/a_random_username/Library/Application Support/edgedb/portable/2.0/lib/python3.10/site-packages/edb/edgeql/declarative.py", line 1057, in _register_item
          trace_dependencies(cmd, ctx=ctx)
        File "/Users/a_random_username/Library/Application Support/edgedb/portable/2.0/lib/python3.10/functools.py", line 889, in wrapper
          return dispatch(args[0].__class__)(*args, **kw)
        File "/Users/a_random_username/Library/Application Support/edgedb/portable/2.0/lib/python3.10/site-packages/edb/edgeql/declarative.py", line 838, in trace_ConcretePointer
          _register_item(
        File "/Users/a_random_username/Library/Application Support/edgedb/portable/2.0/lib/python3.10/site-packages/edb/edgeql/declarative.py", line 1072, in _register_item
          tdeps = qltracer.trace_refs(
        File "/Users/a_random_username/Library/Application Support/edgedb/portable/2.0/lib/python3.10/site-packages/edb/edgeql/tracer.py", line 285, in trace_refs
          trace(qltree, ctx=ctx)
        File "/Users/a_random_username/Library/Application Support/edgedb/portable/2.0/lib/python3.10/functools.py", line 889, in wrapper
          return dispatch(args[0].__class__)(*args, **kw)
        File "/Users/a_random_username/Library/Application Support/edgedb/portable/2.0/lib/python3.10/site-packages/edb/edgeql/tracer.py", line 881, in trace_Shape
          for element in node.elements:
      TypeError: 'NoneType' object is not iterable
```


Discussion:
Is this the full schema that produces this failure for you? It works when I try it.
I can produce this backtrace with this somewhat similar (but solidly broken) schema:
```
  type Person {
    required property name := str {
      # empty block
    }
  }
```
where we write `:=` instead of `->` and so `str { }` is interpreted as a shape.

Resolving patch:
diff --git a/edb/edgeql/parser/grammar/expressions.py b/edb/edgeql/parser/grammar/expressions.py
--- a/edb/edgeql/parser/grammar/expressions.py
+++ b/edb/edgeql/parser/grammar/expressions.py
@@ -351,7 +351,7 @@ class WithDeclList(ListNonterm, element=WithDecl,
 
 class Shape(Nonterm):
     def reduce_LBRACE_RBRACE(self, *kids):
-        self.val = None
+        self.val = []
 
     def reduce_LBRACE_ShapeElementList_RBRACE(self, *kids):
         self.val = kids[1].val


Test patch:
diff --git a/tests/test_schema.py b/tests/test_schema.py
--- a/tests/test_schema.py
+++ b/tests/test_schema.py
@@ -371,6 +371,17 @@ def test_schema_bad_prop_06(self):
             abstract link foo extending foo;
         """
 
+    @tb.must_fail(errors.InvalidReferenceError,
+                  "object type or alias 'std::str' does not exist")
+    def test_schema_bad_prop_07(self):
+        """
+            type Person {
+                required property name := str {
+                    # empty block
+                }
+            }
+        """
+
     @tb.must_fail(errors.InvalidReferenceError,
                   "type 'test::int' does not exist",
                   position=73)