@@ -349,7 +349,8 @@ defmodule AshSql.Join do
349349 has_parent_expr? =
350350 opts [ :require_lateral? ] ||
351351 ! ! query . __ash_bindings__ . context [ :data_layer ] [ :has_parent_expr? ] ||
352- not is_nil ( query . limit )
352+ not is_nil ( query . limit ) ||
353+ not is_nil ( query . offset )
353354
354355 query =
355356 if has_parent_expr? do
@@ -457,6 +458,13 @@ defmodule AshSql.Join do
457458 |> Ash.Query . unset ( :sort )
458459 end
459460 end )
461+ |> then ( fn query ->
462+ if not is_nil ( Map . get ( relationship , :offset ) ) do
463+ Ash.Query . offset ( query , relationship . offset )
464+ else
465+ query
466+ end
467+ end )
460468 |> set_has_parent_expr_context ( relationship )
461469 |> case do
462470 % { valid?: true } = related_query ->
@@ -544,14 +552,23 @@ defmodule AshSql.Join do
544552
545553 defp limit_from_many (
546554 query ,
547- % { from_many?: true , destination: destination } ,
555+ % { from_many?: true , destination: destination } = relationship ,
548556 filter ,
549557 filter_subquery? ,
550558 opts
551559 ) do
560+ offset = Map . get ( relationship , :offset )
561+
552562 if filter_subquery? do
563+ inner_query =
564+ if offset do
565+ from ( row in query , limit: 1 , offset: ^ offset )
566+ else
567+ from ( row in query , limit: 1 )
568+ end
569+
553570 query =
554- from ( row in Ecto.Query . subquery ( from ( row in query , limit: 1 ) ) ,
571+ from ( row in Ecto.Query . subquery ( inner_query ) ,
555572 as: ^ query . __ash_bindings__ . root_binding
556573 )
557574 |> Map . put ( :__ash_bindings__ , query . __ash_bindings__ )
@@ -578,7 +595,7 @@ defmodule AshSql.Join do
578595
579596 defp limit_from_many (
580597 query ,
581- % { limit: limit , destination: destination } ,
598+ % { limit: limit , destination: destination } = relationship ,
582599 filter ,
583600 filter_subquery? ,
584601 opts
@@ -587,11 +604,19 @@ defmodule AshSql.Join do
587604 # Check if query has parent expressions - if so, we can't wrap in a non-lateral subquery
588605 # because parent references won't resolve across the subquery boundary
589606 has_parent_expr? = ! ! query . __ash_bindings__ . context [ :data_layer ] [ :has_parent_expr? ]
607+ offset = Map . get ( relationship , :offset )
590608
591609 if filter_subquery? && ! has_parent_expr? do
592610 # Wrap the limited query in a subquery, then apply filter on top
611+ inner_query =
612+ if offset do
613+ from ( row in query , limit: ^ limit , offset: ^ offset )
614+ else
615+ from ( row in query , limit: ^ limit )
616+ end
617+
593618 query =
594- from ( row in Ecto.Query . subquery ( from ( row in query , limit: ^ limit ) ) ,
619+ from ( row in Ecto.Query . subquery ( inner_query ) ,
595620 as: ^ query . __ash_bindings__ . root_binding
596621 )
597622 |> Map . put ( :__ash_bindings__ , query . __ash_bindings__ )
0 commit comments