Repository: edgedb/edgedb

Issue:
InternalServerError on migration with new constraint
I figured this constraint probably wouldn't work but wanted to try it anyway. It gives me an ISE.
<!-- 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: 2.13+ad0eb0f
- EdgeDB CLI Version: 3.0.0-dev.946+93cec91
- OS Version: macOS 13.2.1

Steps to Reproduce:

1. Create a project with `edgedb project init`
2. Add the problematic schema to `dbschema/default.esdl`
3. Attempt to create migration with `edgedb migration create`

<!-- If the issue is about a query error, please also provide your schema -->

Schema:

```
module default {
  type Cause {
    required property name -> str;
    required multi link charities -> Charity {
      property weight -> float64;
      constraint expression (sum(.charities@weight) <= 10);
    }
  }
  type Charity {
    required property name -> str;
  }
}
```


Discussion:
Could you include the ISE traceback?
There is an issue in the schema, which is that `(sum(.charities@weight) <= 10)` is an *argument* to the constraint, not a constraint subject (which would be `on (...)`)
But expression doesn't *take* any arguments, and the code path dereferences a `None`

We should produce a proper error message



Resolving patch:
diff --git a/edb/edgeql/utils.py b/edb/edgeql/utils.py
--- a/edb/edgeql/utils.py
+++ b/edb/edgeql/utils.py
@@ -23,6 +23,7 @@
 import itertools
 from typing import *
 
+from edb import errors
 from edb.common import ast
 from edb.schema import schema as s_schema
 from edb.schema import functions as s_func
@@ -80,10 +81,21 @@ def index_parameters(
     variadic = parameters.find_variadic(schema)
     variadic_num = variadic.get_num(schema) if variadic else -1  # type: ignore
 
+    params = parameters.objects(schema)
+
+    if not variadic and len(ql_args) > len(params):
+        # In error message we discount the implicit __subject__ param.
+        raise errors.SchemaDefinitionError(
+            f'Expected {len(params) - 1} arguments, but found '
+            f'{len(ql_args) - 1}',
+            context=ql_args[-1].context,
+            details='Did you mean to use ON (...) for specifying the subject?',
+        )
+
     e: qlast.Expr
     p: s_func.ParameterLike
     for iter in itertools.zip_longest(
-        enumerate(ql_args), parameters.objects(schema), fillvalue=None
+        enumerate(ql_args), params, fillvalue=None
     ):
         (i, e), p = iter  # type: ignore
         if isinstance(e, qlast.SelectQuery):


Test patch:
diff --git a/tests/test_constraints.py b/tests/test_constraints.py
--- a/tests/test_constraints.py
+++ b/tests/test_constraints.py
@@ -1727,3 +1727,18 @@ async def test_constraints_non_strict_01(self):
         await self.con.execute("""
             insert X { a := ['foo', 'bar', 'baz'], b := {} };
         """)
+
+    async def test_constraints_bad_args(self):
+        async with self.assertRaisesRegexTx(
+            edgedb.SchemaDefinitionError, "Expected 0 arguments, but found 1"
+        ):
+            await self.con.execute(
+                """
+                create type X {
+                    create property a -> bool;
+                    create link parent -> X {
+                        create constraint expression (false);
+                    }
+                };
+            """
+            )