Skip to content

Commit

Permalink
Fix broken error messages for type mismatches in a number of schema o…
Browse files Browse the repository at this point in the history
…bjects (#8294)

Currently, for triggers, access policies, and function argument
defaults, if the inferred type is something that doesn't appear in the
schema (like a tuple), we a "cannot get item data" error.

Fix that by using the schemas generated while compiling the expressions.

Fixes #8291.
  • Loading branch information
msullivan authored Feb 4, 2025
1 parent e4a6db4 commit 7945efe
Show file tree
Hide file tree
Showing 5 changed files with 44 additions and 7 deletions.
7 changes: 5 additions & 2 deletions edb/schema/functions.py
Original file line number Diff line number Diff line change
Expand Up @@ -1940,13 +1940,16 @@ def _create_begin(

if check_default_type:
default_type = ir_default.stype
if not default_type.assignment_castable_to(p_type, schema):
if not default_type.assignment_castable_to(
p_type, ir_default.schema
):
raise errors.InvalidFunctionDefinitionError(
f'cannot create the `{signature}` function: '
f'invalid declaration of parameter '
f'{p.get_displayname(schema)!r}: '
f'unexpected type of the default expression: '
f'{default_type.get_displayname(schema)}, expected '
f'{default_type.get_displayname(ir_default.schema)}, '
f'expected '
f'{p_type.get_displayname(schema)}',
span=self.span)

Expand Down
2 changes: 1 addition & 1 deletion edb/schema/policies.py
Original file line number Diff line number Diff line change
Expand Up @@ -188,7 +188,7 @@ def canonicalize_attributes(
span = self.get_attribute_span(field)
raise errors.SchemaDefinitionError(
f'{vname} expression for {pol_name} is of invalid type: '
f'{expr_type.get_displayname(schema)}, '
f'{expr_type.get_displayname(expression.irast.schema)}, '
f'expected {target.get_displayname(schema)}',
span=self.span,
)
Expand Down
4 changes: 2 additions & 2 deletions edb/schema/triggers.py
Original file line number Diff line number Diff line change
Expand Up @@ -153,8 +153,8 @@ def canonicalize_attributes(
raise errors.SchemaDefinitionError(
f'{vname} expression for {trig_name} is of invalid '
f'type: '
f'{expr_type.get_displayname(schema)}, '
f'expected {target.get_displayname(schema)}',
f'{expr_type.get_displayname(expression.irast.schema)}'
f', expected {target.get_displayname(schema)}',
span=span,
)

Expand Down
22 changes: 21 additions & 1 deletion tests/test_edgeql_ddl.py
Original file line number Diff line number Diff line change
Expand Up @@ -4294,7 +4294,7 @@ async def test_edgeql_ddl_function_07(self):
""")

async def test_edgeql_ddl_function_08(self):
with self.assertRaisesRegex(
async with self.assertRaisesRegexTx(
edgedb.InvalidFunctionDefinitionError,
r'invalid declaration.*unexpected type of the default'):

Expand All @@ -4303,6 +4303,15 @@ async def test_edgeql_ddl_function_08(self):
USING EdgeQL $$ SELECT "1" $$;
""")

async with self.assertRaisesRegexTx(
edgedb.InvalidFunctionDefinitionError,
r'invalid declaration.*unexpected type of the default'):

await self.con.execute("""
CREATE FUNCTION ddlf_08(s: std::str = ()) -> std::str
USING EdgeQL $$ SELECT "1" $$;
""")

async def test_edgeql_ddl_function_09(self):
await self.con.execute("""
CREATE FUNCTION ddlf_09(
Expand Down Expand Up @@ -6865,6 +6874,17 @@ async def test_edgeql_ddl_policies_02(self):
};
""")

async with self.assertRaisesRegexTx(
edgedb.SchemaDefinitionError,
r"using expression.* is of invalid type",
):
await self.con.execute("""
create type X {
create access policy test
allow all using (());
};
""")

async with self.assertRaisesRegexTx(
edgedb.SchemaDefinitionError,
r"possibly an empty set returned",
Expand Down
16 changes: 15 additions & 1 deletion tests/test_edgeql_triggers.py
Original file line number Diff line number Diff line change
Expand Up @@ -1372,7 +1372,7 @@ async def test_edgeql_triggers_when_04(self):
['c'],
)

async def test_edgeql_triggers_when_bad(self):
async def test_edgeql_triggers_when_bad_01(self):
async with self.assertRaisesRegexTx(
edgedb.SchemaDefinitionError,
r"data-modifying statements are not allowed"):
Expand All @@ -1386,6 +1386,20 @@ async def test_edgeql_triggers_when_bad(self):
};
''')

async def test_edgeql_triggers_when_bad_02(self):
async with self.assertRaisesRegexTx(
edgedb.SchemaDefinitionError,
r"when expression.*is of invalid type"):
await self.con.query('''
alter type InsertTest {
create trigger log_new after insert, update for each
when (())
do (
insert Note { name := "new", note := __new__.name }
);
};
''')

async def test_edgeql_triggers_cached_global_01(self):
# Install FOR ALL triggers for everything
await self.con.execute('''
Expand Down

0 comments on commit 7945efe

Please sign in to comment.