Skip to content

feat: support offset option in lateral join queries#700

Merged
zachdaniel merged 1 commit intoash-project:mainfrom
nallwhy:feature/relationship-offset
Feb 25, 2026
Merged

feat: support offset option in lateral join queries#700
zachdaniel merged 1 commit intoash-project:mainfrom
nallwhy:feature/relationship-offset

Conversation

@nallwhy
Copy link
Contributor

@nallwhy nallwhy commented Feb 25, 2026

Summary

  • Apply relationship.offset to base_query in lateral join queries
  • Add second_latest_comment test relationship (has_one with sort + offset)
  • Add integration test verifying offset returns the correct record via lateral join

Related

Test plan

  • All 30 load tests pass
  • Full test suite: 7 pre-existing failures unrelated to this change

🤖 Generated with Claude Code

Applies relationship.offset to the lateral join base query so that
has_one/has_many relationships with offset work correctly in PostgreSQL.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Copilot AI review requested due to automatic review settings February 25, 2026 08:22
Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds support for applying relationship.offset when generating lateral-join queries in AshPostgres.DataLayer, with accompanying test coverage to validate loading a “second latest” has_one relationship.

Changes:

  • Apply relationship.offset to the destination base_query in the lateral-join query builder.
  • Add a second_latest_comment relationship on Post using sort + offset.
  • Add an integration test asserting the offset relationship returns the expected record when loaded.

Reviewed changes

Copilot reviewed 3 out of 3 changed files in this pull request and generated 3 comments.

File Description
lib/data_layer.ex Applies relationship.offset when constructing lateral join destination subqueries.
test/support/resources/post.ex Introduces second_latest_comment relationship to exercise sort+offset behavior.
test/load_test.exs Adds a load test covering has_one relationship loading with offset via lateral join.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.


has_one :second_latest_comment, AshPostgres.Test.Comment do
sort(created_at: :desc)
offset(1)
Copy link

Copilot AI Feb 25, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

second_latest_comment uses sort/1 and offset/1 to pick a single record from the comments collection, but it doesn't set from_many?(true) like latest_comment does. Without from_many?(true), the lateral-join query builder won't apply limit: 1, and for posts with 3+ comments the subquery can return multiple rows (all rows after the offset), making the loaded has_one nondeterministic.

Consider adding from_many?(true) (and keeping the existing sort/offset) so this relationship is guaranteed to resolve to exactly one comment.

Suggested change
offset(1)
offset(1)
from_many?(true)

Copilot uses AI. Check for mistakes.
Comment on lines +68 to +93
test "has_one with offset returns the correct record" do
post =
Post
|> Ash.Changeset.for_create(:create, %{title: "title"})
|> Ash.create!()

%{id: first_comment_id} =
Comment
|> Ash.Changeset.for_create(:create, %{title: "first"})
|> Ash.Changeset.manage_relationship(:post, post, type: :append_and_remove)
|> Ash.create!()

:timer.sleep(1)

Comment
|> Ash.Changeset.for_create(:create, %{title: "second"})
|> Ash.Changeset.manage_relationship(:post, post, type: :append_and_remove)
|> Ash.create!()

# second_latest_comment: sort(created_at: :desc), offset(1) => first comment
assert %{id: ^first_comment_id} =
Post
|> Ash.Query.load(:second_latest_comment)
|> Ash.read_one!()
|> Map.get(:second_latest_comment)
end
Copy link

Copilot AI Feb 25, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This test only inserts two comments, so offset(1) happens to leave a single remaining row even if the underlying lateral-join subquery doesn't apply limit: 1. To actually validate the "pick exactly one row after offset" behavior, add a third (or more) comment and assert the loaded second_latest_comment is still exactly the second-by-sort record (not any later record).

Copilot uses AI. Check for mistakes.
@zachdaniel zachdaniel merged commit 538ad04 into ash-project:main Feb 25, 2026
66 of 70 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants