Repository navigation
Conversation
…nship An aggregate whose own filter references a to-many relationship joined the related rows into the lateral subquery, so each aggregated record was counted once per matching related row: two comments with three matching ratings summed to 6 instead of 4, and an OR across the relationship and an attribute double-counted too. Evaluate such a filter inside exists over the aggregated resource, correlated by primary key. Each record is aggregated once, and the whole filter stays in one exists, so conditions on one relationship still hold for the same related row. Filters that use parent/1 are left unchanged, as their references would need to move one level out.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
The problem
On AshPostgres, an aggregate whose own filter references a to-many relationship counts each record once per matching related row:
orfilters across a relationship and an attribute double-count as well. The wrong numbers come back without any error.Why
The lateral strategy applies the aggregate's filter with a join into the aggregate's subquery:
Each comment then appears once per matching rating before
count,sum,avg,listor a custom aggregate runs.The fix
When the aggregate's filter references a to-many relationship, it is now evaluated inside
existsover the aggregated resource, correlated by primary key:exists. Conditions on one relationship, such asratings.score > 8 and ratings.score < 10, still have to hold for the same related row, as Ash's filter semantics require. Rewriting each condition as its ownexistswould break that.exists-over-a-resource translation AshSQL already has, which sets the tenant and actor from the outer query.It applies to root aggregates and to aggregates over a direct relationship. These are unchanged:
parent/1, since their references would need to move one level out;can_group?already keeps to-many filters in their own subquery.Tests
The regression tests are in AshPostgres: wtsnz/ash_postgres#7. They check count, sum and list through a to-many filter, two conditions that must hold for the same related row, and an
oracross the relationship and an attribute.orsum 13 instead of 11.ASH_SQL_VERSION=local).Also checked:
mainin the local test database, and nothing new.Found by
The data-layer conformance suite (wtsnz/ash#7), gap
filter-fanout. With this branch, all 9 Postgres scenarios behind it pass (count, sum, avg, list, custom, AND, OR, a record count and a composite-key count), and no other result changes on Postgres or SQLite.