Repository: edgedb/edgedb

Issue:
InternalServerError when coalescing object with string
- EdgeDB Version: EdgeDB 1.0-alpha.6+dev.5078.gd187a933.d20200921
```
edgedb> describe schema;
CREATE MODULE default IF NOT EXISTS;
CREATE TYPE default::Object {
    CREATE OPTIONAL SINGLE PROPERTY opt1 -> std::str;
    CREATE OPTIONAL SINGLE PROPERTY opt2 -> std::str;
    CREATE REQUIRED SINGLE PROPERTY req1 -> std::str;
};
CREATE TYPE default::Parent {
    CREATE REQUIRED SINGLE LINK req -> default::Object;
};
edgedb> for p in {Parent} union (select p.req ?? 'x');
ERROR: InternalServerError:
  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 "/work/edb/server/procpool/worker.py", line 75, in worker
          res = await meth(*args)
        File "/work/edb/server/compiler/compiler.py", line 1803, in compile_eql_tokens
          return self._compile(ctx=ctx, tokens=eql_tokens)
        File "/work/edb/server/compiler/compiler.py", line 1437, in _compile
          comp: dbstate.BaseQuery = self._compile_dispatch_ql(ctx, stmt)
        File "/work/edb/server/compiler/compiler.py", line 1400, in _compile_dispatch_ql
          return self._compile_ql_query(ctx, ql)
        File "/work/edb/server/compiler/compiler.py", line 592, in _compile_ql_query
          ir = qlcompiler.compile_ast_to_ir(
        File "/work/edb/edgeql/compiler/__init__.py", line 175, in wrapper
          return func(*args, **kwargs)
        File "/work/edb/edgeql/compiler/__init__.py", line 223, in compile_ast_to_ir
          ir_set = dispatch_mod.compile(tree, ctx=ctx)
        File "/usr/lib/python3.8/functools.py", line 875, in wrapper
          return dispatch(args[0].__class__)(*args, **kw)
        File "/work/edb/edgeql/compiler/stmt.py", line 187, in compile_ForQuery
          stmt.result = compile_result_clause(
        File "/work/edb/edgeql/compiler/stmt.py", line 1034, in compile_result_clause
          dispatch.compile(result_expr, ctx=sctx), ctx=sctx)
        File "/usr/lib/python3.8/functools.py", line 875, in wrapper
          return dispatch(args[0].__class__)(*args, **kw)
        File "/work/edb/edgeql/compiler/stmt.py", line 86, in compile_SelectQuery
          stmt.result = compile_result_clause(
        File "/work/edb/edgeql/compiler/stmt.py", line 1034, in compile_result_clause
          dispatch.compile(result_expr, ctx=sctx), ctx=sctx)
        File "/usr/lib/python3.8/functools.py", line 875, in wrapper
          return dispatch(args[0].__class__)(*args, **kw)
        File "/work/edb/edgeql/compiler/expr.py", line 77, in compile_BinOp
          op_node = func.compile_operator(
        File "/work/edb/edgeql/compiler/func.py", line 400, in compile_operator
          matched = polyres.find_callable(opers, args=args, kwargs={}, ctx=ctx)
        File "/work/edb/edgeql/compiler/polyres.py", line 86, in find_callable
          call = try_bind_call_args(args, kwargs, candidate, ctx=ctx)
        File "/work/edb/edgeql/compiler/polyres.py", line 330, in try_bind_call_args
          cd = _get_cast_distance(arg_val, arg_type, param_type)
        File "/work/edb/edgeql/compiler/polyres.py", line 183, in _get_cast_distance
          resolved_poly_base_type.find_common_implicitly_castable_type(
        File "/work/edb/schema/objtypes.py", line 170, in find_common_implicitly_castable_type
          assert isinstance(other, ObjectType)
      AssertionError
```


Discussion:
Hm, this is just error when coalescing object and string: `SELECT Object ?? 'x';`

Resolving patch:
diff --git a/edb/schema/objtypes.py b/edb/schema/objtypes.py
--- a/edb/schema/objtypes.py
+++ b/edb/schema/objtypes.py
@@ -191,7 +191,9 @@ def find_common_implicitly_castable_type(
         other: s_types.Type,
         schema: s_schema.Schema,
     ) -> Tuple[s_schema.Schema, Optional[ObjectType]]:
-        assert isinstance(other, ObjectType)
+        if not isinstance(other, ObjectType):
+            return schema, None
+
         nearest_common_ancestor = utils.get_class_nearest_common_ancestor(
             schema, [self, other]
         )


Test patch:
diff --git a/tests/test_edgeql_expressions.py b/tests/test_edgeql_expressions.py
--- a/tests/test_edgeql_expressions.py
+++ b/tests/test_edgeql_expressions.py
@@ -4629,3 +4629,13 @@ async def test_edgeql_expr_error_after_extraction_01(self):
             await self.con.query("""
                 SELECT '''1''';
             """)
+
+    async def test_edgeql_expr_invalid_object_scalar_op_01(self):
+        with self.assertRaisesRegex(
+                edgedb.QueryError,
+                r"operator '\?\?' cannot be applied to operands of type"
+                r" 'std::Object' and 'std::str'"):
+
+            await self.con.query("""
+                SELECT Object ?? '';
+            """)