Repository: edgedb/edgedb

Issue:
InternalServerError: 'NoneType' object has no attribute 'start_point'
<!-- 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.1+1f030a7'
- EdgeDB CLI Version: EdgeDB CLI 3.5.0+907ff37
- OS Version: Ubuntu 20.04.5 LTS (Focal Fossa)

Steps to Reproduce:

1. Change the enum of a property in the schema
2. Create migration
3. Migrate ->` edgedb error: InternalServerError: 'NoneType' object has no attribute 'start_point'`

<!-- If the issue is about a query error, please also provide your schema -->

Migration:

```
CREATE MIGRATION m1g5vofi5ymiuemsn3h77gtte2rufxvejlgvjwiujcai7luckyp2ma
    ONTO m16ry2l6qmyyums43i2zdcyw7i34btq6265fiat4i45gcb7nzamdaa
{
  ALTER TYPE default::Test{
      ALTER PROPERTY test_prop{
          SET default := (<enums::TEST_ENUM>'-test-');
          SET TYPE enums::TEST_ENUM;
      };
  };
};
```

Full error: 

```
edgedb error: InternalServerError: 'NoneType' object has no attribute 'start_point'
  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 "/home/user_name/.local/share/edgedb/portable/3.1/lib/python3.11/site-packages/edb/schema/pointers.py", line 1507, in _compile_expr
          compiled = expr.compiled(
                     ^^^^^^^^^^^^^^
        File "/home/user_name/.local/share/edgedb/portable/3.1/lib/python3.11/site-packages/edb/schema/expr.py", line 199, in compiled
          ir = qlcompiler.compile_ast_to_ir(
               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
        File "/home/user_name/.local/share/edgedb/portable/3.1/lib/python3.11/site-packages/edb/edgeql/compiler/__init__.py", line 179, in wrapper
          return func(*args, **kwargs)
                 ^^^^^^^^^^^^^^^^^^^^^
        File "/home/user_name/.local/share/edgedb/portable/3.1/lib/python3.11/site-packages/edb/edgeql/compiler/__init__.py", line 237, in compile_ast_to_ir
          ir_set = dispatch_mod.compile(tree, ctx=ctx)
                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
        File "/home/user_name/.local/share/edgedb/portable/3.1/lib/python3.11/functools.py", line 909, in wrapper
          return dispatch(args[0].__class__)(*args, **kw)
                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
        File "/home/user_name/.local/share/edgedb/portable/3.1/lib/python3.11/site-packages/edb/edgeql/compiler/expr.py", line 626, in compile_TypeCast
          res = casts.compile_cast(
                ^^^^^^^^^^^^^^^^^^^
        File "/home/user_name/.local/share/edgedb/portable/3.1/lib/python3.11/site-packages/edb/edgeql/compiler/casts.py", line 247, in compile_cast
          return _compile_cast(
                 ^^^^^^^^^^^^^^
        File "/home/user_name/.local/share/edgedb/portable/3.1/lib/python3.11/site-packages/edb/edgeql/compiler/casts.py", line 300, in _compile_cast
          raise errors.QueryError(
      edb.errors.QueryError: cannot cast 'enums::REPORTING_COUNTY' to 'enums::REPORTING_CATEGORY'
      
      During handling of the above exception, another exception occurred:
      
      Traceback (most recent call last):
        File "/home/user_name/.local/share/edgedb/portable/3.1/lib/python3.11/site-packages/edb/server/compiler_pool/worker.py", line 186, in compile_in_tx
          units, cstate = COMPILER.compile_in_tx(cstate, *args, **kwargs)
                          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
        File "/home/user_name/.local/share/edgedb/portable/3.1/lib/python3.11/site-packages/edb/server/compiler/compiler.py", line 898, in compile_in_tx
          return compile(ctx=ctx, source=source), ctx.state
                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
        File "/home/user_name/.local/share/edgedb/portable/3.1/lib/python3.11/site-packages/edb/server/compiler/compiler.py", line 2030, in compile
          return _try_compile(ctx=ctx, source=source)
                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
        File "/home/user_name/.local/share/edgedb/portable/3.1/lib/python3.11/site-packages/edb/server/compiler/compiler.py", line 2098, in _try_compile
          comp, capabilities = _compile_dispatch_ql(
                               ^^^^^^^^^^^^^^^^^^^^^
        File "/home/user_name/.local/share/edgedb/portable/3.1/lib/python3.11/site-packages/edb/server/compiler/compiler.py", line 1937, in _compile_dispatch_ql
          query = ddl.compile_dispatch_ql_migration(
                  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
        File "/home/user_name/.local/share/edgedb/portable/3.1/lib/python3.11/site-packages/edb/server/compiler/ddl.py", line 379, in compile_dispatch_ql_migration
          return compile_and_apply_ddl_stmt(ctx, ql)
                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
        File "/home/user_name/.local/share/edgedb/portable/3.1/lib/python3.11/site-packages/edb/server/compiler/ddl.py", line 209, in compile_and_apply_ddl_stmt
          block, new_types, config_ops = _process_delta(ctx, delta)
                                         ^^^^^^^^^^^^^^^^^^^^^^^^^^
        File "/home/user_name/.local/share/edgedb/portable/3.1/lib/python3.11/site-packages/edb/server/compiler/ddl.py", line 326, in _process_delta
          schema = pgdelta.apply(schema, context)
                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
        File "/home/user_name/.local/share/edgedb/portable/3.1/lib/python3.11/site-packages/edb/pgsql/delta.py", line 7189, in apply
          schema = super().apply(schema, context)
                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
        File "/home/user_name/.local/share/edgedb/portable/3.1/lib/python3.11/site-packages/edb/schema/delta.py", line 1554, in apply
          schema = self.apply_subcommands(schema, context)
                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
        File "/home/user_name/.local/share/edgedb/portable/3.1/lib/python3.11/site-packages/edb/pgsql/delta.py", line 189, in apply_subcommands
          schema = super().apply_subcommands(schema, context)
                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
        File "/home/user_name/.local/share/edgedb/portable/3.1/lib/python3.11/site-packages/edb/schema/delta.py", line 1581, in apply_subcommands
          schema = objop.apply(schema, context)
                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
        File "/home/user_name/.local/share/edgedb/portable/3.1/lib/python3.11/site-packages/edb/schema/delta.py", line 3051, in apply
          schema = self._create_innards(schema, context)
                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
        File "/home/user_name/.local/share/edgedb/portable/3.1/lib/python3.11/site-packages/edb/schema/delta.py", line 3019, in _create_innards
          return self.apply_subcommands(schema, context)
                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
        File "/home/user_name/.local/share/edgedb/portable/3.1/lib/python3.11/site-packages/edb/pgsql/delta.py", line 189, in apply_subcommands
          schema = super().apply_subcommands(schema, context)
                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
        File "/home/user_name/.local/share/edgedb/portable/3.1/lib/python3.11/site-packages/edb/schema/delta.py", line 952, in apply_subcommands
          schema = op.apply(schema, context=context)
                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
        File "/home/user_name/.local/share/edgedb/portable/3.1/lib/python3.11/site-packages/edb/pgsql/delta.py", line 3739, in apply
          schema = super().apply(schema, context=context)
                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
        File "/home/user_name/.local/share/edgedb/portable/3.1/lib/python3.11/site-packages/edb/schema/delta.py", line 3516, in apply
          schema = self._alter_innards(schema, context)
                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
        File "/home/user_name/.local/share/edgedb/portable/3.1/lib/python3.11/site-packages/edb/schema/delta.py", line 3148, in _alter_innards
          return self.apply_subcommands(schema, context)
                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
        File "/home/user_name/.local/share/edgedb/portable/3.1/lib/python3.11/site-packages/edb/pgsql/delta.py", line 189, in apply_subcommands
          schema = super().apply_subcommands(schema, context)
                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
        File "/home/user_name/.local/share/edgedb/portable/3.1/lib/python3.11/site-packages/edb/schema/delta.py", line 952, in apply_subcommands
          schema = op.apply(schema, context=context)
                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
        File "/home/user_name/.local/share/edgedb/portable/3.1/lib/python3.11/site-packages/edb/schema/delta.py", line 3516, in apply
          schema = self._alter_innards(schema, context)
                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
        File "/home/user_name/.local/share/edgedb/portable/3.1/lib/python3.11/site-packages/edb/pgsql/delta.py", line 5677, in _alter_innards
          schema = super()._alter_innards(schema, context)
                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
        File "/home/user_name/.local/share/edgedb/portable/3.1/lib/python3.11/site-packages/edb/schema/delta.py", line 3148, in _alter_innards
          return self.apply_subcommands(schema, context)
                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
        File "/home/user_name/.local/share/edgedb/portable/3.1/lib/python3.11/site-packages/edb/pgsql/delta.py", line 189, in apply_subcommands
          schema = super().apply_subcommands(schema, context)
                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
        File "/home/user_name/.local/share/edgedb/portable/3.1/lib/python3.11/site-packages/edb/schema/delta.py", line 952, in apply_subcommands
          schema = op.apply(schema, context=context)
                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
        File "/home/user_name/.local/share/edgedb/portable/3.1/lib/python3.11/site-packages/edb/schema/delta.py", line 3201, in apply
          schema = self._alter_begin(schema, context)
                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
        File "/home/user_name/.local/share/edgedb/portable/3.1/lib/python3.11/site-packages/edb/pgsql/delta.py", line 5595, in _alter_begin
          self._alter_pointer_type(self.scls, schema, orig_schema, context)
        File "/home/user_name/.local/share/edgedb/portable/3.1/lib/python3.11/site-packages/edb/pgsql/delta.py", line 4316, in _alter_pointer_type
          (cast_expr_sql, expr_is_nullable) = self._compile_conversion_expr(
                                              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
        File "/home/user_name/.local/share/edgedb/portable/3.1/lib/python3.11/site-packages/edb/pgsql/delta.py", line 4509, in _compile_conversion_expr
          conv_expr = self._compile_expr(
                      ^^^^^^^^^^^^^^^^^^^
        File "/home/user_name/.local/share/edgedb/portable/3.1/lib/python3.11/site-packages/edb/schema/pointers.py", line 1527, in _compile_expr
          e.set_source_context(expr.qlast.context)
        File "/home/user_name/.local/share/edgedb/portable/3.1/lib/python3.11/site-packages/edb/errors/base.py", line 147, in set_source_context
          start = context.start_point
                  ^^^^^^^^^^^^^^^^^^^
      AttributeError: 'NoneType' object has no attribute 'start_point'
```


Discussion:
This doesn't have enough information for me to reproduce (I need a starting schema).

But, the specific internal server error looks like it is already fixed in 4.0 by #5693 (which adds a None check to `set_source_context`). I'll extract that and cherry-pick to 3.x

Resolving patch:
diff --git a/edb/errors/base.py b/edb/errors/base.py
--- a/edb/errors/base.py
+++ b/edb/errors/base.py
@@ -143,7 +143,10 @@ def set_hint_and_details(self, hint, details=None):
     def has_source_context(self):
         return FIELD_DETAILS in self._attrs
 
-    def set_source_context(self, context):
+    def set_source_context(self, context: Optional[pctx.ParserContext]):
+        if not context:
+            return
+
         start = context.start_point
         end = context.end_point
         ex.replace_context(self, context)


Test patch: