Bylaw.Ecto.Query.Checks.HalfOpenTemporalIntervals
(bylaw_ecto_query v0.1.0-alpha.1)
Copy Markdown
View Source
Validates that root temporal interval predicates are half-open.
Half-open temporal intervals include the start boundary and exclude the end boundary.
Examples
Bad:
from(Event, as: :event)
|> where([event: e], e.occurred_at > ^start_at)
|> where([event: e], e.occurred_at <= ^end_at)Why this is bad:
The query excludes events exactly at start_at and includes events exactly at
end_at. Adjacent windows built this way leave a gap at the start boundary
and can double-count rows at the end boundary.
Better:
from(Event, as: :event)
|> where([event: e], e.occurred_at >= ^start_at)
|> where([event: e], e.occurred_at < ^end_at)Why this is better:
The query uses a half-open interval, [start_at, end_at). Adjacent windows
compose without gaps or overlap because each boundary value belongs to exactly
one window.
Notes
This check inspects direct root temporal field comparisons in where
expressions. It does not prove interval correctness when boundaries are hidden
inside fragments, non-root bindings, subqueries, or field-to-field
comparisons.
This catches the common off-by-one interval boundary shapes > for a lower
bound and <= for an upper bound on root temporal fields.
Options
:validate- explicitfalsedisables the check. Defaults totrue.:fields- optional non-empty list of root fields to validate. When omitted, the check validates temporal fields reflected from the root Ecto schema.
Example check spec:
{Bylaw.Ecto.Query.Checks.HalfOpenTemporalIntervals,
fields: [:inserted_at, :updated_at]}The check is static. It inspects direct root field comparisons in where
expressions and ignores field-to-field comparisons, non-root bindings,
fragments that hide field access, and schema-less queries without configured
fields.
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
Implements the Bylaw.Ecto.Query.Check validation callback.
Functions
@spec validate( Bylaw.Ecto.Query.Check.operation(), Bylaw.Ecto.Query.Check.query(), opts() ) :: Bylaw.Ecto.Query.Check.result()
Implements the Bylaw.Ecto.Query.Check validation callback.