# `Bylaw.Ecto.Query.Checks.EmptyInPredicates`
[🔗](https://github.com/ryanzidago/bylaw/blob/v0.1.0-alpha.1/lib/bylaw/ecto/query/checks/empty_in_predicates.ex#L1)

Validates that root `where` predicates do not rely on empty `in` lists.

This catches filters whose candidate list is already known to contain no
non-nil values.

## Examples

Bad:

    ids = []

    from(Thing, as: :thing)
    |> where([thing: t], t.id in ^ids)

Why this is bad:

The query can never match a row because the candidate list has no non-nil
values. Running it still spends database work on a known-empty result.

Better:

    if Enum.empty?(ids) do
      []
    else
      from(Thing, as: :thing)
      |> where([thing: t], t.id in ^ids)
      |> Repo.all()
    end

Why this is better:

The caller uses a cheap application fast path and only queries the database
when there are candidates to match.

## Notes

This check only trusts supported root `in` predicates. It intentionally leaves
broader contradictory business logic to `ConflictingWherePredicates`.

Such queries usually have a cheaper fast path: return `[]` before calling the
repo. This check is separate from
`Bylaw.Ecto.Query.Checks.ConflictingWherePredicates` because an empty list is
usually a missing fast path rather than contradictory business logic.

The check is intentionally narrow. It evaluates root schema fields and only
trusts direct `in` predicates in `AND` where expressions. `Ecto.Enum` fields
are normalized through the schema enum mapping. `or_where` and `or`
expressions are handled as separate branches and only rejected when every
branch contains an empty `in` predicate. Fragments, subqueries, and non-root
bindings are ignored.

## Options

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

## Usage

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

# `validate`

```elixir
@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.

---

*Consult [api-reference.md](api-reference.md) for complete listing*
