Skip to content

Commit 538ad04

Browse files
nallwhyclaude
andauthored
feat: support offset option in lateral join queries (#700)
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>
1 parent b13a3a0 commit 538ad04

3 files changed

Lines changed: 40 additions & 0 deletions

File tree

lib/data_layer.ex

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1116,6 +1116,13 @@ defmodule AshPostgres.DataLayer do
11161116
base_query
11171117
end
11181118

1119+
base_query =
1120+
if Map.get(relationship, :offset) do
1121+
from(row in base_query, offset: ^relationship.offset)
1122+
else
1123+
base_query
1124+
end
1125+
11191126
base_query =
11201127
cond do
11211128
Map.get(relationship, :manual) ->

test/load_test.exs

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,33 @@ defmodule AshPostgres.Test.LoadTest do
6565
|> Map.get(:latest_comment)
6666
end
6767

68+
test "has_one with offset returns the correct record" do
69+
post =
70+
Post
71+
|> Ash.Changeset.for_create(:create, %{title: "title"})
72+
|> Ash.create!()
73+
74+
%{id: first_comment_id} =
75+
Comment
76+
|> Ash.Changeset.for_create(:create, %{title: "first"})
77+
|> Ash.Changeset.manage_relationship(:post, post, type: :append_and_remove)
78+
|> Ash.create!()
79+
80+
:timer.sleep(1)
81+
82+
Comment
83+
|> Ash.Changeset.for_create(:create, %{title: "second"})
84+
|> Ash.Changeset.manage_relationship(:post, post, type: :append_and_remove)
85+
|> Ash.create!()
86+
87+
# second_latest_comment: sort(created_at: :desc), offset(1) => first comment
88+
assert %{id: ^first_comment_id} =
89+
Post
90+
|> Ash.Query.load(:second_latest_comment)
91+
|> Ash.read_one!()
92+
|> Map.get(:second_latest_comment)
93+
end
94+
6895
test "belongs_to relationships can be loaded" do
6996
assert %Comment{post: %Ash.NotLoaded{type: :relationship}} =
7097
comment =

test/support/resources/post.ex

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -762,6 +762,12 @@ defmodule AshPostgres.Test.Post do
762762
public?(true)
763763
end
764764

765+
has_one :second_latest_comment, AshPostgres.Test.Comment do
766+
sort(created_at: :desc)
767+
offset(1)
768+
public?(true)
769+
end
770+
765771
has_many :comments_matching_post_title, AshPostgres.Test.Comment do
766772
public?(true)
767773
filter(expr(title == parent_expr(title)))

0 commit comments

Comments
 (0)