Repository: edgedb/edgedb

Issue:
InternalServerError when creating scalar type extending array/tuple type
- EdgeDB Version: 2.0-dev.6602+local

Steps to Reproduce:

1. Try to create scalar type extending an array or tuple type:
```
edgedb> create scalar type str_arr extending array<str>;
edgedb error: InternalServerError: 'Array' object has no attribute 'get_bases'

edgedb> create scalar type my_tuple extending tuple<str, bool, int64>;
edgedb error: InternalServerError: 'Tuple' object has no attribute 'get_bases'
```

Edit: It seems it's only an ISE if the array/tuple type already exists as the type of a property somewhere (eg. `type Something { property abc -> array<str> }`). Otherwise there's a different error:
```
edgedb> create scalar type bool_arr extending array<bool>;
edgedb error: InvalidReferenceError: reference to a non-existent schema item 1589453d-48e2-202a-8534-083f6d24f9c1 in schema <FlatSchema gen:1 at 0x7f2918916560>

edgedb> create scalar type my_tuple extending tuple<str, bool>;
edgedb error: InvalidReferenceError: reference to a non-existent schema item 34601760-ce34-d017-fbef-8da85ebdc2c2 in schema <FlatSchema gen:1 at 0x7f2918916560>
```


Discussion:
Creating array/tuple aliases is currently not supported, though we obviously need to raise a proper error.
Also honestly those InvalidReferenceErrors probably should be reported as ISEs

Resolving patch:
diff --git a/edb/schema/scalars.py b/edb/schema/scalars.py
--- a/edb/schema/scalars.py
+++ b/edb/schema/scalars.py
@@ -408,6 +408,12 @@ def _cmd_tree_from_ast(
             ]
             is_enum = any(
                 isinstance(br, AnonymousEnumTypeShell) for br in bases)
+            for ab, b in zip(astnode.bases, bases):
+                if isinstance(b, s_types.CollectionTypeShell):
+                    raise errors.SchemaError(
+                        f'scalar type may not have a collection base type',
+                        context=ab.context,
+                    )
 
             # We don't support FINAL, but old dumps and migrations specify
             # it on enum CREATE SCALAR TYPEs, so we need to permit it in those
@@ -583,6 +589,13 @@ def apply(
         else:
             old_concrete = self.scls.maybe_get_topmost_concrete_base(schema)
 
+            for b in [b for bs, _ in self.added_bases for b in bs]:
+                if isinstance(b, s_types.CollectionTypeShell):
+                    raise errors.SchemaError(
+                        f'scalar type may not have a collection base type',
+                        context=self.source_context,
+                    )
+
             schema = super().apply(schema, context)
 
             self.validate_scalar_bases(schema, 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
@@ -5389,6 +5389,27 @@ async def test_edgeql_ddl_scalar_12(self):
                 };
             ''')
 
+    async def test_edgeql_ddl_scalar_13(self):
+        async with self.assertRaisesRegexTx(
+                edgedb.SchemaError,
+                r'scalar type may not have a collection base type'):
+            await self.con.execute('''
+                create scalar type Foo extending array<str>;
+            ''')
+
+        await self.con.execute('''
+            create scalar type Foo extending str;
+        ''')
+
+        async with self.assertRaisesRegexTx(
+                edgedb.SchemaError,
+                r'scalar type may not have a collection base type'):
+            await self.con.execute('''
+                alter scalar type Foo {
+                    drop extending str; extending array<str> last;
+                };
+            ''')
+
     async def test_edgeql_ddl_cast_01(self):
         await self.con.execute('''
             CREATE SCALAR TYPE type_a EXTENDING std::str;