Bylaw.Ecto.Query.Checks.OffsetWithoutLimit (bylaw_ecto_query v0.1.0-alpha.1)

Copy Markdown View Source

Validates that queries do not use offset without limit.

Offset without limit skips rows and then returns every remaining row. That can create an unbounded scan from an arbitrary position, which is usually an accidental pagination shape.

Examples

Bad:

from(Post, as: :post)
|> order_by([post: p], asc: p.inserted_at)
|> offset(10_000)

Why this is bad:

The query skips 10,000 rows and then returns every remaining row. That is usually an accidental unbounded pagination query.

Better:

from(Post, as: :post)
|> order_by([post: p], asc: p.inserted_at)
|> limit(50)
|> offset(10_000)

Why this is better:

limit gives the page a bounded size. Pair this with Bylaw.Ecto.Query.Checks.RequiredOrder when the page also needs stable row order.

Notes

This check only verifies that offset has a paired limit. It does not prove the order is deterministic or that offset pagination is the best strategy for a large table.

Options

  • :validate - explicit false disables the check. Defaults to true.

The check applies to the root query and nested source subqueries, join subqueries, CTE queries, combination branches, and expression subqueries.

Usage

Add this module to the explicit check list passed through Bylaw.Ecto.Query. See Bylaw.Ecto.Query for the full Ecto.Repo.prepare_query/3 setup.

Summary

Functions

validate(operation, query, opts)

Implements the Bylaw.Ecto.Query.Check validation callback.