Skip to content

Commit 74f6336

Browse files
authored
Fixed computed ptr with group by incorrectly inferring multiplicity. (#8485)
Fixes query errors caused by using group by in a computed pointer. For example, given the schema: ``` module default { type Foo { n: int64 }; type Bar { multi foo: Foo }; } ``` The query `SELECT Bar { g := (group .foo by .n) };` would produce the error: ``` QueryError: possibly not a distinct set returned by an expression for a computed link 'g' ┌─ <query>:1:14 │ 1 │ SELECT Bar { g := (group .foo by .n) }; │ ^^^^^^^^^^^^^^^^^^^^^^ You can use assert_distinct() around the expression to turn this into a runtime assertion, or the DISTINCT operator to silently discard duplicate elements. ```
1 parent 7ea207a commit 74f6336

File tree

3 files changed

+127
-3
lines changed

3 files changed

+127
-3
lines changed

edb/edgeql/compiler/inference/multiplicity.py

+5-3
Original file line numberDiff line numberDiff line change
@@ -815,9 +815,11 @@ def __infer_group_stmt(
815815
if set:
816816
infer_multiplicity(set, scope_tree=scope_tree, ctx=ctx)
817817

818-
# N.B: Since the type is usually a free object (except in some
819-
# internal tests), this will typically get turned UNIQUE by the
820-
# enclosing Set.
818+
# N.B: The type is usually a free object (except in some
819+
# internal tests), which are always unique
820+
if irtyputils.is_free_object(ir.typeref):
821+
return UNIQUE
822+
821823
return DUPLICATE
822824

823825

tests/test_edgeql_group.py

+114
Original file line numberDiff line numberDiff line change
@@ -3853,6 +3853,120 @@ async def test_edgeql_group_link_property_01(self):
38533853
],
38543854
)
38553855

3856+
async def test_edgeql_group_link_property_02(self):
3857+
await self.assert_query_result(
3858+
r'''
3859+
WITH MODULE cards
3860+
select User { cards := (group .deck { name } by .element) };
3861+
''',
3862+
tb.bag([
3863+
{
3864+
'cards': tb.bag([
3865+
{
3866+
'key': {'element': 'Water'},
3867+
'grouping': ['element'],
3868+
'elements': tb.bag([
3869+
{'name': 'Bog monster'},
3870+
{'name': 'Giant turtle'}
3871+
])
3872+
},
3873+
{
3874+
'key': {'element': 'Fire'},
3875+
'grouping': ['element'],
3876+
'elements': tb.bag([
3877+
{'name': 'Imp'},
3878+
{'name': 'Dragon'}
3879+
])
3880+
},
3881+
]),
3882+
},
3883+
{
3884+
'cards': tb.bag([
3885+
{
3886+
'key': {'element': 'Earth'},
3887+
'grouping': ['element'],
3888+
'elements': tb.bag([
3889+
{'name': 'Dwarf'},
3890+
{'name': 'Golem'}
3891+
])
3892+
},
3893+
{
3894+
'key': {'element': 'Water'},
3895+
'grouping': ['element'],
3896+
'elements': tb.bag([
3897+
{'name': 'Bog monster'},
3898+
{'name': 'Giant turtle'}
3899+
])
3900+
},
3901+
]),
3902+
},
3903+
{
3904+
'cards': tb.bag([
3905+
{
3906+
'key': {'element': 'Earth'},
3907+
'grouping': ['element'],
3908+
'elements': tb.bag([
3909+
{'name': 'Dwarf'},
3910+
{'name': 'Golem'}
3911+
])
3912+
},
3913+
{
3914+
'key': {'element': 'Water'},
3915+
'grouping': ['element'],
3916+
'elements': tb.bag([
3917+
{'name': 'Bog monster'},
3918+
{'name': 'Giant turtle'}
3919+
])
3920+
},
3921+
{
3922+
'key': {'element': 'Air'},
3923+
'grouping': ['element'],
3924+
'elements': tb.bag([
3925+
{'name': 'Sprite'},
3926+
{'name': 'Giant eagle'},
3927+
{'name': 'Djinn'}
3928+
])
3929+
},
3930+
]),
3931+
},
3932+
{
3933+
'cards': tb.bag([
3934+
{
3935+
'key': {'element': 'Earth'},
3936+
'grouping': ['element'],
3937+
'elements': tb.bag([
3938+
{'name': 'Golem'}
3939+
])
3940+
},
3941+
{
3942+
'key': {'element': 'Water'},
3943+
'grouping': ['element'],
3944+
'elements': tb.bag([
3945+
{'name': 'Bog monster'},
3946+
{'name': 'Giant turtle'}
3947+
])
3948+
},
3949+
{
3950+
'key': {'element': 'Fire'},
3951+
'grouping': ['element'],
3952+
'elements': tb.bag([
3953+
{'name': 'Dragon'}
3954+
])
3955+
},
3956+
{
3957+
'key': {'element': 'Air'},
3958+
'grouping': ['element'],
3959+
'elements': tb.bag([
3960+
{'name': 'Sprite'},
3961+
{'name': 'Giant eagle'},
3962+
{'name': 'Djinn'}
3963+
])
3964+
},
3965+
]),
3966+
},
3967+
]),
3968+
)
3969+
38563970
async def test_edgeql_group_destruct_immediately_01(self):
38573971
await self.assert_query_result(
38583972
r'''

tests/test_edgeql_ir_mult_inference.py

+8
Original file line numberDiff line numberDiff line change
@@ -870,6 +870,14 @@ def test_edgeql_ir_mult_inference_92(self):
870870
(insert User { name := "test" })
871871
else
872872
<User>{}
873+
% OK %
874+
UNIQUE
875+
"""
876+
877+
def test_edgeql_ir_mult_inference_93(self):
878+
"""
879+
with groupedCards := User { cards := (group .deck by .element) }
880+
select groupedCards.cards
873881
% OK %
874882
UNIQUE
875883
"""

0 commit comments

Comments
 (0)