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

Copy Markdown View Source

Validates that date fields are not compared to datetime fields without explicit truncation.

This catches queries where a field backed by :date is compared directly to a field backed by :utc_datetime, :utc_datetime_usec, :naive_datetime, or :naive_datetime_usec.

Examples

Bad:

from(Event, as: :event)
|> where([event: e], e.event_date <= e.inserted_at)

Why this is bad:

PostgreSQL can implicitly cast across date and timestamp types. With UTC timestamp fields, that cast may depend on the database session timezone. The date boundary is not visible in the query.

Better:

from(Event, as: :event)
|> where([event: e], e.event_date <= type(e.inserted_at, :date))

Why this is better:

The datetime side is explicitly treated as a date, so the boundary decision is visible to reviewers.

Notes

This check inspects supported direct field-to-field comparisons and in predicates. It ignores values, schema-less sources, hidden fragment access, and subqueries.

Options

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

The check is static. It inspects direct field-to-field comparisons and in predicates in where, having, and direct join on predicates, reflecting field types from the root schema, direct explicit join schemas, and association join schemas when the owner binding schema is known. It detects dot field access, field/2, named bindings, dynamic predicates, and type(field, :date) wrappers used as explicit truncation. It ignores values, schema-less sources, fragments that hide field access, and 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.