Skip to content

Commit

Permalink
Fix crash when filtering on a composite exclusive constraint (geldata…
Browse files Browse the repository at this point in the history
…#3503)

card inference crashes because of inconsistent use of view pointers.
This means the crash occurs whenever there is a shape on the object
(either explicitly or because of type insertion or similar).

Fixes geldata#3502.
  • Loading branch information
msullivan authored Feb 16, 2022
1 parent cd894ca commit 81c7b97
Show file tree
Hide file tree
Showing 4 changed files with 26 additions and 6 deletions.
11 changes: 6 additions & 5 deletions edb/edgeql/compiler/inference/cardinality.py
Original file line number Diff line number Diff line change
Expand Up @@ -940,14 +940,15 @@ def extract_exclusive_filters(

results: List[Tuple[Tuple[s_pointers.Pointer, irast.Set], ...]] = []
if filtered_ptrs:
filtered_ptrs_map = dict(filtered_ptrs)
schema = ctx.env.schema
ptr_set = set()
filtered_ptrs_map = {
ptr.get_nearest_non_derived_parent(schema): expr
for ptr, expr in filtered_ptrs
}
ptr_set = set(filtered_ptrs_map)
# First look at each referenced pointer and see if it has
# an exclusive constraint.
for ptr, expr in filtered_ptrs:
ptr = ptr.get_nearest_non_derived_parent(schema)
ptr_set.add(ptr)
for ptr, expr in filtered_ptrs_map.items():
for constr in ptr.get_exclusive_constraints(schema):
# Bingo, got an equality filter on a pointer with a
# unique constraint
Expand Down
6 changes: 6 additions & 0 deletions tests/schemas/constraints.esdl
Original file line number Diff line number Diff line change
Expand Up @@ -257,3 +257,9 @@ type PropertyContainer {
constraint exclusive
}
}

type Pair {
required property x -> str;
required property y -> str;
constraint exclusive on (( .x, .y ));
}
13 changes: 13 additions & 0 deletions tests/test_constraints.py
Original file line number Diff line number Diff line change
Expand Up @@ -368,6 +368,19 @@ async def test_constraints_exclusive_delegation(self):
};
""")

async def test_constraints_exclusive_pair(self):
await self.assert_query_result(
r'''
select {
single z := (
select Pair {x, y} filter .x = 'a' and .y = 'b')
}
''',
[
{"z": None}
],
)

async def test_constraints_exclusive_multi_property_distinct(self):
await self.con.execute("""
INSERT PropertyContainer {
Expand Down
2 changes: 1 addition & 1 deletion tests/test_edgeql_ir_card_inference.py
Original file line number Diff line number Diff line change
Expand Up @@ -543,7 +543,7 @@ def test_edgeql_ir_card_inference_56(self):

def test_edgeql_ir_card_inference_57(self):
"""
SELECT Person FILTER .p = 7 AND .q = 3
SELECT Person { first } FILTER .p = 7 AND .q = 3
% OK %
AT_MOST_ONE
"""
Expand Down

0 comments on commit 81c7b97

Please sign in to comment.